only support indexed color mode, get rid of enum/branching on color modes
This commit is contained in:
parent
9f657ffcf9
commit
e0a5d34d29
25 changed files with 142 additions and 286 deletions
|
|
@ -1,4 +1,3 @@
|
|||
{:title "pxl8 demo"
|
||||
:pixel-mode "indexed"
|
||||
:resolution "640x360"
|
||||
:window-size [1280 720]}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
(local SIM_FLAG_GROUNDED 4)
|
||||
|
||||
(local door-spawn-x 860)
|
||||
(local door-spawn-z 416)
|
||||
(local door-spawn-yaw 1.5708)
|
||||
|
||||
(local sim-cfg (pxl8.sim_config {:move_speed 150
|
||||
:gravity 600
|
||||
:jump_velocity 180
|
||||
|
|
@ -48,7 +52,7 @@
|
|||
(var light-time 0)
|
||||
(var glows nil)
|
||||
(var lights nil)
|
||||
(var bsp-materials-setup false)
|
||||
(var materials-for-chunk 0)
|
||||
(var network nil)
|
||||
(var portal-cooldown 0)
|
||||
(var real-time 0)
|
||||
|
|
@ -136,17 +140,25 @@
|
|||
(setup-textures 1))
|
||||
|
||||
(fn setup-materials []
|
||||
(when (and world (not bsp-materials-setup) floor-tex trim-tex wall-tex)
|
||||
(when (not world) (lua "return"))
|
||||
(when (not network) (lua "return"))
|
||||
(let [net-chunk (network:chunk_id)]
|
||||
(when (or (= net-chunk 0) (= materials-for-chunk net-chunk)) (lua "return"))
|
||||
(when (not= current-bsp-id net-chunk)
|
||||
(setup-textures net-chunk))
|
||||
(when (not floor-tex) (lua "return"))
|
||||
(when (not wall-tex) (lua "return"))
|
||||
(let [chunk (world:active_chunk)]
|
||||
(when (and chunk (chunk:ready))
|
||||
(let [floor-mat (pxl8.create_material {:texture floor-tex :lighting true :double_sided true})
|
||||
trim-mat (pxl8.create_material {:texture trim-tex :lighting true :double_sided true})
|
||||
wall-mat (pxl8.create_material {:texture wall-tex :lighting true :double_sided true})]
|
||||
(world:set_bsp_material 0 floor-mat)
|
||||
(world:set_bsp_material 1 wall-mat)
|
||||
(world:set_bsp_material 3 trim-mat)
|
||||
(entities.setup-lighting (chunk:bsp) 2)
|
||||
(set bsp-materials-setup true))))))
|
||||
(when (not chunk) (lua "return"))
|
||||
(when (not (chunk:ready)) (lua "return"))
|
||||
(let [floor-mat (pxl8.create_material {:texture floor-tex :lighting true :double_sided true})
|
||||
trim-mat (pxl8.create_material {:texture trim-tex :lighting true :double_sided true})
|
||||
wall-mat (pxl8.create_material {:texture wall-tex :lighting true :double_sided true})]
|
||||
(world:set_bsp_material 0 floor-mat)
|
||||
(world:set_bsp_material 1 wall-mat)
|
||||
(world:set_bsp_material 3 trim-mat)
|
||||
(entities.setup-lighting (chunk:bsp) 2)
|
||||
(set materials-for-chunk net-chunk)))))
|
||||
|
||||
(fn sample-input []
|
||||
(when (pxl8.key_pressed "`")
|
||||
|
|
@ -187,27 +199,31 @@
|
|||
(if (= current-id 1)
|
||||
(do
|
||||
(pxl8.info "Door: BSP 1 -> BSP 2")
|
||||
(network:enter_scene 1 2 416 0 416)
|
||||
(world:init_local_player 416 0 416)
|
||||
(set cam-x 416)
|
||||
(network:enter_scene 1 2 door-spawn-x 0 door-spawn-z)
|
||||
(world:init_local_player door-spawn-x 0 door-spawn-z)
|
||||
(world:set_look door-spawn-yaw 0)
|
||||
(set cam-x door-spawn-x)
|
||||
(set cam-y 0)
|
||||
(set cam-z 416)
|
||||
(set smooth-cam-x 416)
|
||||
(set smooth-cam-z 416)
|
||||
(set bsp-materials-setup false)
|
||||
(set cam-z door-spawn-z)
|
||||
(set cam-yaw door-spawn-yaw)
|
||||
(set cam-pitch 0)
|
||||
(set smooth-cam-x door-spawn-x)
|
||||
(set smooth-cam-z door-spawn-z)
|
||||
(setup-textures 2)
|
||||
(set portal-cooldown 2.0))
|
||||
(= current-id 2)
|
||||
(do
|
||||
(pxl8.info "Door: BSP 2 -> BSP 1")
|
||||
(network:enter_scene 1 1 416 0 416)
|
||||
(world:init_local_player 416 0 416)
|
||||
(set cam-x 416)
|
||||
(network:enter_scene 1 1 door-spawn-x 0 door-spawn-z)
|
||||
(world:init_local_player door-spawn-x 0 door-spawn-z)
|
||||
(world:set_look door-spawn-yaw 0)
|
||||
(set cam-x door-spawn-x)
|
||||
(set cam-y 0)
|
||||
(set cam-z 416)
|
||||
(set smooth-cam-x 416)
|
||||
(set smooth-cam-z 416)
|
||||
(set bsp-materials-setup false)
|
||||
(set cam-z door-spawn-z)
|
||||
(set cam-yaw door-spawn-yaw)
|
||||
(set cam-pitch 0)
|
||||
(set smooth-cam-x door-spawn-x)
|
||||
(set smooth-cam-z door-spawn-z)
|
||||
(setup-textures 1)
|
||||
(set portal-cooldown 2.0)))))))
|
||||
|
||||
|
|
@ -282,7 +298,8 @@
|
|||
r2 (* 0.04 (math.sin (+ (* real-time 3.2) phase)))
|
||||
light-radius (* 150 (+ 0.95 r1 r2))]
|
||||
(lights:clear)
|
||||
(lights:add light-x light-y light-z 2 light-intensity light-radius)
|
||||
(when (= current-bsp-id 1)
|
||||
(lights:add light-x light-y light-z 2 light-intensity light-radius))
|
||||
|
||||
(pxl8.push_target)
|
||||
(pxl8.begin_frame_3d camera lights {
|
||||
|
|
@ -300,7 +317,7 @@
|
|||
(pxl8.set_wireframe (menu.is-wireframe))
|
||||
(world:render [smooth-cam-x eye-y smooth-cam-z])
|
||||
|
||||
(when chunk
|
||||
(when (and chunk (= current-bsp-id 1))
|
||||
(entities.render-fireball light-x light-y light-z (menu.is-wireframe)))
|
||||
|
||||
(entities.render-door (menu.is-wireframe) 0)
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
|
|||
|
||||
if let Some(pid) = player_id {
|
||||
if let Some(_player) = sim.get_player_position(pid) {
|
||||
let mut burst = false;
|
||||
while let Some(chunk_id) = client_chunks.next_pending() {
|
||||
match chunk_id {
|
||||
ChunkId::Bsp(id) => {
|
||||
|
|
@ -182,13 +183,15 @@ pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
|
|||
let msgs = bsp_to_messages(bsp, id, chunk.version());
|
||||
client_chunks.queue_messages(msgs);
|
||||
client_chunks.mark_sent(chunk_id, chunk.version());
|
||||
burst = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _ in 0..8 {
|
||||
let send_limit = if burst { 256 } else { 8 };
|
||||
for _ in 0..send_limit {
|
||||
if let Some(msg) = client_chunks.next_message() {
|
||||
transport.send_chunk(&msg, sequence);
|
||||
sequence = sequence.wrapping_add(1);
|
||||
|
|
|
|||
|
|
@ -169,7 +169,15 @@ fn build_bsp_node_grid(ctx: &mut BspBuildContext, x0: i32, y0: i32, x1: i32, y1:
|
|||
let plane_idx = ctx.plane_offset;
|
||||
ctx.plane_offset += 1;
|
||||
|
||||
if depth % 2 == 0 {
|
||||
let split_x = if x1 - x0 <= 1 {
|
||||
false
|
||||
} else if y1 - y0 <= 1 {
|
||||
true
|
||||
} else {
|
||||
depth % 2 == 0
|
||||
};
|
||||
|
||||
if split_x {
|
||||
let mid_x = (x0 + x1) / 2;
|
||||
let split_pos = mid_x as f32 * CELL_SIZE;
|
||||
|
||||
|
|
@ -479,6 +487,16 @@ fn compute_vertex_ao(bsp: &BspBuilder, pos: Vec3, normal: Vec3) -> f32 {
|
|||
continue;
|
||||
}
|
||||
|
||||
let cx = offset_pos.x.max(face.aabb_min.x).min(face.aabb_max.x);
|
||||
let cy = offset_pos.y.max(face.aabb_min.y).min(face.aabb_max.y);
|
||||
let cz = offset_pos.z.max(face.aabb_min.z).min(face.aabb_max.z);
|
||||
let dx = offset_pos.x - cx;
|
||||
let dy = offset_pos.y - cy;
|
||||
let dz = offset_pos.z - cz;
|
||||
if dx * dx + dy * dy + dz * dz > AO_RAY_LENGTH * AO_RAY_LENGTH {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut verts = [Vec3::new(0.0, 0.0, 0.0); 4];
|
||||
let mut num_verts = 0usize;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ struct pxl8_cart {
|
|||
char* title;
|
||||
pxl8_resolution resolution;
|
||||
pxl8_size window_size;
|
||||
pxl8_pixel_mode pixel_mode;
|
||||
bool is_folder;
|
||||
bool is_mounted;
|
||||
};
|
||||
|
|
@ -156,7 +155,6 @@ pxl8_cart* pxl8_cart_create(void) {
|
|||
if (cart) {
|
||||
cart->resolution = PXL8_RESOLUTION_640x360;
|
||||
cart->window_size = (pxl8_size){1280, 720};
|
||||
cart->pixel_mode = PXL8_PIXEL_INDEXED;
|
||||
}
|
||||
return cart;
|
||||
}
|
||||
|
|
@ -364,14 +362,6 @@ void pxl8_cart_set_window_size(pxl8_cart* cart, pxl8_size size) {
|
|||
if (cart) cart->window_size = size;
|
||||
}
|
||||
|
||||
pxl8_pixel_mode pxl8_cart_get_pixel_mode(const pxl8_cart* cart) {
|
||||
return cart ? cart->pixel_mode : PXL8_PIXEL_INDEXED;
|
||||
}
|
||||
|
||||
void pxl8_cart_set_pixel_mode(pxl8_cart* cart, pxl8_pixel_mode mode) {
|
||||
if (cart) cart->pixel_mode = mode;
|
||||
}
|
||||
|
||||
bool pxl8_cart_is_packed(const pxl8_cart* cart) {
|
||||
return cart && !cart->is_folder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,9 @@ const char* pxl8_cart_get_base_path(const pxl8_cart* cart);
|
|||
const char* pxl8_cart_get_title(const pxl8_cart* cart);
|
||||
pxl8_resolution pxl8_cart_get_resolution(const pxl8_cart* cart);
|
||||
pxl8_size pxl8_cart_get_window_size(const pxl8_cart* cart);
|
||||
pxl8_pixel_mode pxl8_cart_get_pixel_mode(const pxl8_cart* cart);
|
||||
void pxl8_cart_set_title(pxl8_cart* cart, const char* title);
|
||||
void pxl8_cart_set_resolution(pxl8_cart* cart, pxl8_resolution resolution);
|
||||
void pxl8_cart_set_window_size(pxl8_cart* cart, pxl8_size size);
|
||||
void pxl8_cart_set_pixel_mode(pxl8_cart* cart, pxl8_pixel_mode mode);
|
||||
bool pxl8_cart_is_packed(const pxl8_cart* cart);
|
||||
bool pxl8_cart_has_embedded(const char* exe_path);
|
||||
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
|
|||
const char* window_title = pxl8_cart_get_title(sys->cart);
|
||||
if (!window_title) window_title = "pxl8";
|
||||
pxl8_resolution resolution = pxl8_cart_get_resolution(sys->cart);
|
||||
pxl8_pixel_mode pixel_mode = pxl8_cart_get_pixel_mode(sys->cart);
|
||||
pxl8_size window_size = pxl8_cart_get_window_size(sys->cart);
|
||||
pxl8_size render_size = pxl8_get_resolution_dimensions(resolution);
|
||||
|
||||
|
|
@ -249,7 +248,7 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
|
|||
return PXL8_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
game->gfx = pxl8_gfx_create(sys->hal, sys->platform_data, pixel_mode, resolution);
|
||||
game->gfx = pxl8_gfx_create(sys->hal, sys->platform_data, resolution);
|
||||
if (!game->gfx) {
|
||||
pxl8_error("failed to create graphics context");
|
||||
return PXL8_ERROR_INITIALIZATION_FAILED;
|
||||
|
|
|
|||
|
|
@ -31,12 +31,6 @@ typedef __int128_t i128;
|
|||
typedef __uint128_t u128;
|
||||
#endif
|
||||
|
||||
typedef enum pxl8_pixel_mode {
|
||||
PXL8_PIXEL_INDEXED = 1,
|
||||
PXL8_PIXEL_HICOLOR = 2,
|
||||
PXL8_PIXEL_RGBA = 4,
|
||||
} pxl8_pixel_mode;
|
||||
|
||||
typedef enum pxl8_cursor {
|
||||
PXL8_CURSOR_ARROW,
|
||||
PXL8_CURSOR_HAND
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
#include "pxl8_atlas.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pxl8_color.h"
|
||||
#include "pxl8_log.h"
|
||||
#include "pxl8_mem.h"
|
||||
|
||||
|
|
@ -144,15 +141,14 @@ static void pxl8_skyline_compact(pxl8_skyline* skyline) {
|
|||
}
|
||||
}
|
||||
|
||||
pxl8_atlas* pxl8_atlas_create(u32 width, u32 height, pxl8_pixel_mode pixel_mode) {
|
||||
pxl8_atlas* pxl8_atlas_create(u32 width, u32 height) {
|
||||
pxl8_atlas* atlas = (pxl8_atlas*)pxl8_calloc(1, sizeof(pxl8_atlas));
|
||||
if (!atlas) return NULL;
|
||||
|
||||
atlas->height = height;
|
||||
atlas->width = width;
|
||||
|
||||
i32 bytes_per_pixel = pxl8_bytes_per_pixel(pixel_mode);
|
||||
atlas->pixels = (u8*)pxl8_calloc(width * height, bytes_per_pixel);
|
||||
atlas->pixels = (u8*)pxl8_calloc(width * height, 1);
|
||||
if (!atlas->pixels) {
|
||||
pxl8_free(atlas);
|
||||
return NULL;
|
||||
|
|
@ -226,14 +222,13 @@ void pxl8_atlas_clear(pxl8_atlas* atlas, u32 preserve_count) {
|
|||
atlas->dirty = true;
|
||||
}
|
||||
|
||||
bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_pixel_mode pixel_mode) {
|
||||
bool pxl8_atlas_expand(pxl8_atlas* atlas) {
|
||||
if (!atlas || atlas->width >= 4096) return false;
|
||||
|
||||
i32 bytes_per_pixel = pxl8_bytes_per_pixel(pixel_mode);
|
||||
u32 new_size = atlas->width * 2;
|
||||
u32 old_width = atlas->width;
|
||||
|
||||
u8* new_pixels = (u8*)pxl8_calloc(new_size * new_size, bytes_per_pixel);
|
||||
u8* new_pixels = (u8*)pxl8_calloc(new_size * new_size, 1);
|
||||
if (!new_pixels) return false;
|
||||
|
||||
pxl8_skyline new_skyline;
|
||||
|
|
@ -268,11 +263,7 @@ bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_pixel_mode pixel_mode) {
|
|||
for (u32 x = 0; x < (u32)atlas->entries[i].w; x++) {
|
||||
u32 src_idx = (atlas->entries[i].y + y) * old_width + (atlas->entries[i].x + x);
|
||||
u32 dst_idx = (fit.pos.y + y) * new_size + (fit.pos.x + x);
|
||||
if (bytes_per_pixel == 2) {
|
||||
((u16*)new_pixels)[dst_idx] = ((u16*)atlas->pixels)[src_idx];
|
||||
} else {
|
||||
new_pixels[dst_idx] = atlas->pixels[src_idx];
|
||||
}
|
||||
new_pixels[dst_idx] = atlas->pixels[src_idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,15 +295,14 @@ u32 pxl8_atlas_add_texture(
|
|||
pxl8_atlas* atlas,
|
||||
const u8* pixels,
|
||||
u32 w,
|
||||
u32 h,
|
||||
pxl8_pixel_mode pixel_mode
|
||||
u32 h
|
||||
) {
|
||||
if (!atlas || !pixels) return UINT32_MAX;
|
||||
|
||||
pxl8_skyline_fit fit =
|
||||
pxl8_skyline_find_position(&atlas->skyline, atlas->width, atlas->height, w, h);
|
||||
if (!fit.found) {
|
||||
if (!pxl8_atlas_expand(atlas, pixel_mode)) {
|
||||
if (!pxl8_atlas_expand(atlas)) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
|
|
@ -347,17 +337,11 @@ u32 pxl8_atlas_add_texture(
|
|||
entry->h = h;
|
||||
entry->log2_w = pxl8_log2(w);
|
||||
|
||||
i32 bytes_per_pixel = pxl8_bytes_per_pixel(pixel_mode);
|
||||
for (u32 y = 0; y < h; y++) {
|
||||
for (u32 x = 0; x < w; x++) {
|
||||
u32 src_idx = y * w + x;
|
||||
u32 dst_idx = (fit.pos.y + y) * atlas->width + (fit.pos.x + x);
|
||||
|
||||
if (bytes_per_pixel == 2) {
|
||||
((u16*)atlas->pixels)[dst_idx] = ((const u16*)pixels)[src_idx];
|
||||
} else {
|
||||
atlas->pixels[dst_idx] = pixels[src_idx];
|
||||
}
|
||||
atlas->pixels[dst_idx] = pixels[src_idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,11 +30,11 @@ static inline u8 pxl8_log2(u32 v) {
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
u32 pxl8_atlas_add_texture(pxl8_atlas* atlas, const u8* pixels, u32 w, u32 h, pxl8_pixel_mode pixel_mode);
|
||||
u32 pxl8_atlas_add_texture(pxl8_atlas* atlas, const u8* pixels, u32 w, u32 h);
|
||||
void pxl8_atlas_clear(pxl8_atlas* atlas, u32 preserve_count);
|
||||
pxl8_atlas* pxl8_atlas_create(u32 width, u32 height, pxl8_pixel_mode pixel_mode);
|
||||
pxl8_atlas* pxl8_atlas_create(u32 width, u32 height);
|
||||
void pxl8_atlas_destroy(pxl8_atlas* atlas);
|
||||
bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_pixel_mode pixel_mode);
|
||||
bool pxl8_atlas_expand(pxl8_atlas* atlas);
|
||||
const pxl8_atlas_entry* pxl8_atlas_get_entry(const pxl8_atlas* atlas, u32 id);
|
||||
u32 pxl8_atlas_get_entry_count(const pxl8_atlas* atlas);
|
||||
u32 pxl8_atlas_get_height(const pxl8_atlas* atlas);
|
||||
|
|
|
|||
|
|
@ -1,34 +1,7 @@
|
|||
#include "pxl8_blit.h"
|
||||
|
||||
void pxl8_blit_hicolor(u16* fb, u32 fb_width, const u16* sprite, u32 atlas_width,
|
||||
i32 x, i32 y, u32 w, u32 h) {
|
||||
u16* dest_base = fb + y * fb_width + x;
|
||||
const u16* src_base = sprite;
|
||||
|
||||
for (u32 row = 0; row < h; row++) {
|
||||
u16* dest_row = dest_base + row * fb_width;
|
||||
const u16* src_row = src_base + row * atlas_width;
|
||||
|
||||
u32 col = 0;
|
||||
u32 count2 = w / 2;
|
||||
for (u32 i = 0; i < count2; i++) {
|
||||
u32 pixels = ((const u32*)src_row)[i];
|
||||
if (pixels == 0) {
|
||||
col += 2;
|
||||
continue;
|
||||
}
|
||||
dest_row[col] = pxl8_blend_hicolor((u16)(pixels), dest_row[col]);
|
||||
dest_row[col + 1] = pxl8_blend_hicolor((u16)(pixels >> 16), dest_row[col + 1]);
|
||||
col += 2;
|
||||
}
|
||||
if (w & 1) {
|
||||
dest_row[col] = pxl8_blend_hicolor(src_row[col], dest_row[col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pxl8_blit_indexed(u8* fb, u32 fb_width, const u8* sprite, u32 atlas_width,
|
||||
i32 x, i32 y, u32 w, u32 h) {
|
||||
void pxl8_blit(u8* fb, u32 fb_width, const u8* sprite, u32 atlas_width,
|
||||
i32 x, i32 y, u32 w, u32 h) {
|
||||
u8* dest_base = fb + y * fb_width + x;
|
||||
const u8* src_base = sprite;
|
||||
|
||||
|
|
@ -44,14 +17,14 @@ void pxl8_blit_indexed(u8* fb, u32 fb_width, const u8* sprite, u32 atlas_width,
|
|||
col += 4;
|
||||
continue;
|
||||
}
|
||||
dest_row[col] = pxl8_blend_indexed((u8)(pixels), dest_row[col]);
|
||||
dest_row[col + 1] = pxl8_blend_indexed((u8)(pixels >> 8), dest_row[col + 1]);
|
||||
dest_row[col + 2] = pxl8_blend_indexed((u8)(pixels >> 16), dest_row[col + 2]);
|
||||
dest_row[col + 3] = pxl8_blend_indexed((u8)(pixels >> 24), dest_row[col + 3]);
|
||||
dest_row[col] = pxl8_blit_mask((u8)(pixels), dest_row[col]);
|
||||
dest_row[col + 1] = pxl8_blit_mask((u8)(pixels >> 8), dest_row[col + 1]);
|
||||
dest_row[col + 2] = pxl8_blit_mask((u8)(pixels >> 16), dest_row[col + 2]);
|
||||
dest_row[col + 3] = pxl8_blit_mask((u8)(pixels >> 24), dest_row[col + 3]);
|
||||
col += 4;
|
||||
}
|
||||
for (; col < w; col++) {
|
||||
dest_row[col] = pxl8_blend_indexed(src_row[col], dest_row[col]);
|
||||
dest_row[col] = pxl8_blit_mask(src_row[col], dest_row[col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,22 +6,12 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline u8 pxl8_blend_indexed(u8 src, u8 dst) {
|
||||
static inline u8 pxl8_blit_mask(u8 src, u8 dst) {
|
||||
u8 m = (u8)(-(src != 0));
|
||||
return (src & m) | (dst & ~m);
|
||||
}
|
||||
|
||||
static inline u16 pxl8_blend_hicolor(u16 src, u16 dst) {
|
||||
u16 m = (u16)(-(src != 0));
|
||||
return (src & m) | (dst & ~m);
|
||||
}
|
||||
|
||||
void pxl8_blit_hicolor(
|
||||
u16* fb, u32 fb_width,
|
||||
const u16* sprite, u32 atlas_width,
|
||||
i32 x, i32 y, u32 w, u32 h
|
||||
);
|
||||
void pxl8_blit_indexed(
|
||||
void pxl8_blit(
|
||||
u8* fb, u32 fb_width,
|
||||
const u8* sprite, u32 atlas_width,
|
||||
i32 x, i32 y, u32 w, u32 h
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
#include "pxl8_types.h"
|
||||
|
||||
static inline i32 pxl8_bytes_per_pixel(pxl8_pixel_mode mode) {
|
||||
return (i32)mode;
|
||||
}
|
||||
|
||||
static inline u32 pxl8_color_from_rgba(u32 rgba) {
|
||||
u8 r = (rgba >> 24) & 0xFF;
|
||||
u8 g = (rgba >> 16) & 0xFF;
|
||||
|
|
@ -76,30 +72,10 @@ static inline void pxl8_rgb332_unpack(u8 c, u8* r, u8* g, u8* b) {
|
|||
*b = (bi << 6) | (bi << 4) | (bi << 2) | bi;
|
||||
}
|
||||
|
||||
static inline u16 pxl8_rgb565_pack(u8 r, u8 g, u8 b) {
|
||||
return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
|
||||
}
|
||||
|
||||
static inline void pxl8_rgb565_unpack(u16 color, u8* r, u8* g, u8* b) {
|
||||
*r = (color >> 11) << 3;
|
||||
*g = ((color >> 5) & 0x3F) << 2;
|
||||
*b = (color & 0x1F) << 3;
|
||||
}
|
||||
|
||||
static inline u32 pxl8_rgb565_to_rgba32(u16 color) {
|
||||
u8 r, g, b;
|
||||
pxl8_rgb565_unpack(color, &r, &g, &b);
|
||||
return r | ((u32)g << 8) | ((u32)b << 16) | 0xFF000000;
|
||||
}
|
||||
|
||||
static inline u32 pxl8_rgba32_pack(u8 r, u8 g, u8 b, u8 a) {
|
||||
return r | ((u32)g << 8) | ((u32)b << 16) | ((u32)a << 24);
|
||||
}
|
||||
|
||||
static inline u16 pxl8_rgba32_to_rgb565(u32 rgba) {
|
||||
return pxl8_rgb565_pack(rgba & 0xFF, (rgba >> 8) & 0xFF, (rgba >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
static inline void pxl8_rgba32_unpack(u32 color, u8* r, u8* g, u8* b, u8* a) {
|
||||
*r = color & 0xFF;
|
||||
*g = (color >> 8) & 0xFF;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include "pxl8_ase.h"
|
||||
#include "pxl8_atlas.h"
|
||||
#include "pxl8_blit.h"
|
||||
#include "pxl8_color.h"
|
||||
#include "pxl8_colormap.h"
|
||||
#include "pxl8_font.h"
|
||||
#include "pxl8_glows.h"
|
||||
|
|
@ -72,7 +71,6 @@ struct pxl8_gfx {
|
|||
pxl8_palette_cube* palette_cube;
|
||||
pxl8_gfx_pass frame_pass;
|
||||
pxl8_frame_resources frame_res;
|
||||
pxl8_pixel_mode pixel_mode;
|
||||
void* platform_data;
|
||||
pxl8_sprite_cache_entry* sprite_cache;
|
||||
u32 sprite_cache_capacity;
|
||||
|
|
@ -100,20 +98,11 @@ pxl8_bounds pxl8_gfx_get_bounds(pxl8_gfx* gfx) {
|
|||
return bounds;
|
||||
}
|
||||
|
||||
pxl8_pixel_mode pxl8_gfx_get_pixel_mode(pxl8_gfx* gfx) {
|
||||
return gfx ? gfx->pixel_mode : PXL8_PIXEL_INDEXED;
|
||||
}
|
||||
|
||||
u8* pxl8_gfx_get_framebuffer_indexed(pxl8_gfx* gfx) {
|
||||
if (!gfx || gfx->pixel_mode == PXL8_PIXEL_HICOLOR) return NULL;
|
||||
u8* pxl8_gfx_framebuffer(pxl8_gfx* gfx) {
|
||||
if (!gfx) return NULL;
|
||||
return (u8*)pxl8_texture_get_data(gfx->renderer, gfx->color_target);
|
||||
}
|
||||
|
||||
u16* pxl8_gfx_get_framebuffer_hicolor(pxl8_gfx* gfx) {
|
||||
if (!gfx || gfx->pixel_mode != PXL8_PIXEL_HICOLOR) return NULL;
|
||||
return (u16*)pxl8_texture_get_data(gfx->renderer, gfx->color_target);
|
||||
}
|
||||
|
||||
i32 pxl8_gfx_get_height(const pxl8_gfx* gfx) {
|
||||
return gfx ? gfx->framebuffer_height : 0;
|
||||
}
|
||||
|
|
@ -125,9 +114,8 @@ u32* pxl8_gfx_get_output(pxl8_gfx* gfx) {
|
|||
|
||||
void pxl8_gfx_resolve(pxl8_gfx* gfx) {
|
||||
if (!gfx || !gfx->initialized) return;
|
||||
if (gfx->pixel_mode != PXL8_PIXEL_INDEXED) return;
|
||||
|
||||
const u32* pal = gfx->palette ? pxl8_palette_colors(gfx->palette) : NULL;
|
||||
const u32* pal = pxl8_palette_colors(gfx->palette);
|
||||
if (!pal) {
|
||||
pxl8_error("resolve: no palette!");
|
||||
return;
|
||||
|
|
@ -180,10 +168,8 @@ i32 pxl8_gfx_load_palette(pxl8_gfx* gfx, const char* filepath) {
|
|||
if (!gfx || !gfx->palette || !filepath) return -1;
|
||||
pxl8_result result = pxl8_palette_load_ase(gfx->palette, filepath);
|
||||
if (result != PXL8_OK) return (i32)result;
|
||||
if (gfx->pixel_mode != PXL8_PIXEL_HICOLOR) {
|
||||
if (gfx->colormap) {
|
||||
pxl8_colormap_generate(gfx->colormap, pxl8_palette_colors(gfx->palette));
|
||||
}
|
||||
if (gfx->colormap) {
|
||||
pxl8_colormap_generate(gfx->colormap, pxl8_palette_colors(gfx->palette));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -191,7 +177,6 @@ i32 pxl8_gfx_load_palette(pxl8_gfx* gfx, const char* filepath) {
|
|||
pxl8_gfx* pxl8_gfx_create(
|
||||
const pxl8_hal* hal,
|
||||
void* platform_data,
|
||||
pxl8_pixel_mode mode,
|
||||
pxl8_resolution resolution
|
||||
) {
|
||||
pxl8_shader_registry_init();
|
||||
|
|
@ -205,7 +190,6 @@ pxl8_gfx* pxl8_gfx_create(
|
|||
gfx->hal = hal;
|
||||
gfx->platform_data = platform_data;
|
||||
|
||||
gfx->pixel_mode = mode;
|
||||
pxl8_size size = pxl8_get_resolution_dimensions(resolution);
|
||||
gfx->framebuffer_width = size.w;
|
||||
gfx->framebuffer_height = size.h;
|
||||
|
|
@ -216,9 +200,7 @@ pxl8_gfx* pxl8_gfx_create(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (mode != PXL8_PIXEL_HICOLOR) {
|
||||
gfx->palette = pxl8_palette_create();
|
||||
}
|
||||
gfx->palette = pxl8_palette_create();
|
||||
|
||||
gfx->renderer = pxl8_renderer_create(gfx->framebuffer_width, gfx->framebuffer_height);
|
||||
if (!gfx->renderer) {
|
||||
|
|
@ -258,9 +240,7 @@ pxl8_gfx* pxl8_gfx_create(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (mode != PXL8_PIXEL_HICOLOR) {
|
||||
gfx->colormap = pxl8_calloc(1, sizeof(pxl8_colormap));
|
||||
}
|
||||
gfx->colormap = pxl8_calloc(1, sizeof(pxl8_colormap));
|
||||
|
||||
gfx->target_stack[0] = (pxl8_target_entry){
|
||||
.color = gfx->color_target,
|
||||
|
|
@ -313,7 +293,7 @@ void pxl8_gfx_destroy(pxl8_gfx* gfx) {
|
|||
|
||||
static pxl8_result pxl8_gfx_ensure_atlas(pxl8_gfx* gfx) {
|
||||
if (gfx->atlas) return PXL8_OK;
|
||||
gfx->atlas = pxl8_atlas_create(PXL8_DEFAULT_ATLAS_SIZE, PXL8_DEFAULT_ATLAS_SIZE, gfx->pixel_mode);
|
||||
gfx->atlas = pxl8_atlas_create(PXL8_DEFAULT_ATLAS_SIZE, PXL8_DEFAULT_ATLAS_SIZE);
|
||||
return gfx->atlas ? PXL8_OK : PXL8_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
|
@ -335,7 +315,7 @@ pxl8_result pxl8_gfx_create_texture(pxl8_gfx* gfx, const u8* pixels, u32 width,
|
|||
pxl8_result result = pxl8_gfx_ensure_atlas(gfx);
|
||||
if (result != PXL8_OK) return result;
|
||||
|
||||
u32 texture_id = pxl8_atlas_add_texture(gfx->atlas, pixels, width, height, gfx->pixel_mode);
|
||||
u32 texture_id = pxl8_atlas_add_texture(gfx->atlas, pixels, width, height);
|
||||
if (texture_id == UINT32_MAX) {
|
||||
pxl8_error("Texture doesn't fit in atlas");
|
||||
return PXL8_ERROR_INVALID_SIZE;
|
||||
|
|
@ -381,8 +361,7 @@ pxl8_result pxl8_gfx_load_sprite(pxl8_gfx* gfx, const char* path) {
|
|||
gfx->atlas,
|
||||
ase_file.frames[0].pixels,
|
||||
ase_file.header.width,
|
||||
ase_file.header.height,
|
||||
gfx->pixel_mode
|
||||
ase_file.header.height
|
||||
);
|
||||
|
||||
pxl8_ase_destroy(&ase_file);
|
||||
|
|
@ -426,28 +405,14 @@ pxl8_result pxl8_gfx_load_font_atlas(pxl8_gfx* gfx) {
|
|||
void pxl8_gfx_upload_framebuffer(pxl8_gfx* gfx) {
|
||||
if (!gfx || !gfx->initialized || !gfx->hal) return;
|
||||
|
||||
if (gfx->pixel_mode == PXL8_PIXEL_INDEXED) {
|
||||
pxl8_gfx_resolve(gfx);
|
||||
gfx->hal->upload_texture(
|
||||
gfx->platform_data,
|
||||
gfx->output,
|
||||
gfx->framebuffer_width,
|
||||
gfx->framebuffer_height,
|
||||
PXL8_PIXEL_RGBA,
|
||||
NULL
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
u32* colors = gfx->palette ? pxl8_palette_colors(gfx->palette) : NULL;
|
||||
u8* framebuffer = (u8*)pxl8_texture_get_data(gfx->renderer, gfx->color_target);
|
||||
pxl8_gfx_resolve(gfx);
|
||||
gfx->hal->upload_texture(
|
||||
gfx->platform_data,
|
||||
framebuffer,
|
||||
gfx->output,
|
||||
gfx->framebuffer_width,
|
||||
gfx->framebuffer_height,
|
||||
gfx->pixel_mode,
|
||||
colors
|
||||
4,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -639,7 +604,7 @@ void pxl8_2d_sprite(pxl8_gfx* gfx, u32 sprite_id, i32 x, i32 y, i32 w, i32 h, bo
|
|||
|
||||
if (is_1to1_scale && is_unclipped && !is_flipped) {
|
||||
const u8* sprite_data = atlas_pixels + entry->y * atlas_width + entry->x;
|
||||
pxl8_blit_indexed(framebuffer, fb_width, sprite_data, atlas_width, x, y, w, h);
|
||||
pxl8_blit(framebuffer, fb_width, sprite_data, atlas_width, x, y, w, h);
|
||||
} else {
|
||||
for (i32 py = 0; py < draw_height; py++) {
|
||||
for (i32 px = 0; px < draw_width; px++) {
|
||||
|
|
@ -652,7 +617,7 @@ void pxl8_2d_sprite(pxl8_gfx* gfx, u32 sprite_id, i32 x, i32 y, i32 w, i32 h, bo
|
|||
i32 src_idx = src_y * atlas_width + src_x;
|
||||
i32 dest_idx = (dest_y + py) * fb_width + (dest_x + px);
|
||||
|
||||
framebuffer[dest_idx] = pxl8_blend_indexed(atlas_pixels[src_idx], framebuffer[dest_idx]);
|
||||
framebuffer[dest_idx] = pxl8_blit_mask(atlas_pixels[src_idx], framebuffer[dest_idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ typedef enum pxl8_gfx_effect {
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
pxl8_gfx* pxl8_gfx_create(const pxl8_hal* hal, void* platform_data, pxl8_pixel_mode mode, pxl8_resolution resolution);
|
||||
pxl8_gfx* pxl8_gfx_create(const pxl8_hal* hal, void* platform_data, pxl8_resolution resolution);
|
||||
void pxl8_gfx_destroy(pxl8_gfx* gfx);
|
||||
|
||||
void pxl8_gfx_present(pxl8_gfx* gfx);
|
||||
|
|
@ -46,14 +46,12 @@ void pxl8_gfx_upload_framebuffer(pxl8_gfx* gfx);
|
|||
u8 pxl8_gfx_find_color(pxl8_gfx* gfx, u32 color);
|
||||
|
||||
pxl8_bounds pxl8_gfx_get_bounds(pxl8_gfx* gfx);
|
||||
u8* pxl8_gfx_get_framebuffer_indexed(pxl8_gfx* gfx);
|
||||
u16* pxl8_gfx_get_framebuffer_hicolor(pxl8_gfx* gfx);
|
||||
u8* pxl8_gfx_framebuffer(pxl8_gfx* gfx);
|
||||
i32 pxl8_gfx_get_height(const pxl8_gfx* gfx);
|
||||
const u32* pxl8_gfx_palette_colors(pxl8_gfx* gfx);
|
||||
u16* pxl8_gfx_get_zbuffer(pxl8_gfx* gfx);
|
||||
pxl8_palette* pxl8_gfx_palette(pxl8_gfx* gfx);
|
||||
pxl8_colormap* pxl8_gfx_colormap(pxl8_gfx* gfx);
|
||||
pxl8_pixel_mode pxl8_gfx_get_pixel_mode(pxl8_gfx* gfx);
|
||||
i32 pxl8_gfx_get_width(const pxl8_gfx* gfx);
|
||||
|
||||
i32 pxl8_gfx_load_palette(pxl8_gfx* gfx, const char* filepath);
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ static u8 palette_find_closest(const u32* palette, u8 r, u8 g, u8 b) {
|
|||
return best_idx;
|
||||
}
|
||||
|
||||
static u8 blend_indexed(
|
||||
static u8 blend_colors(
|
||||
const pxl8_gfx_pipeline_desc* pipeline,
|
||||
u8 src,
|
||||
u8 dst,
|
||||
|
|
@ -540,7 +540,7 @@ static void rasterize_triangle(
|
|||
if (color != 0) {
|
||||
u8 out_color = color;
|
||||
if (blend_enabled) {
|
||||
out_color = blend_indexed(pipeline, color, prow[px], palette);
|
||||
out_color = blend_colors(pipeline, color, prow[px], palette);
|
||||
}
|
||||
|
||||
prow[px] = out_color;
|
||||
|
|
@ -586,7 +586,7 @@ static void rasterize_triangle(
|
|||
if (color != 0) {
|
||||
u8 out_color = color;
|
||||
if (blend_enabled) {
|
||||
out_color = blend_indexed(pipeline, color, prow[px], palette);
|
||||
out_color = blend_colors(pipeline, color, prow[px], palette);
|
||||
}
|
||||
|
||||
prow[px] = out_color;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ struct pxl8_tilesheet {
|
|||
u32 tiles_per_row;
|
||||
u32 total_tiles;
|
||||
u32 width;
|
||||
pxl8_pixel_mode pixel_mode;
|
||||
u32 ref_count;
|
||||
pxl8_tile_animation* animations;
|
||||
u32 animation_count;
|
||||
|
|
@ -547,7 +546,6 @@ pxl8_result pxl8_tilemap_load_ase(pxl8_tilemap* tilemap, const char* filepath, u
|
|||
tilemap->tilesheet->height = tilesheet_height;
|
||||
tilemap->tilesheet->tiles_per_row = tiles_per_row;
|
||||
tilemap->tilesheet->total_tiles = tileset->tile_count;
|
||||
tilemap->tilesheet->pixel_mode = PXL8_PIXEL_INDEXED;
|
||||
|
||||
if (tilemap->tilesheet->tile_valid) pxl8_free(tilemap->tilesheet->tile_valid);
|
||||
tilemap->tilesheet->tile_valid = pxl8_calloc(tileset->tile_count + 1, sizeof(bool));
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "pxl8_ase.h"
|
||||
#include "pxl8_color.h"
|
||||
#include "pxl8_gfx.h"
|
||||
#include "pxl8_log.h"
|
||||
#include "pxl8_mem.h"
|
||||
|
|
@ -20,7 +19,6 @@ struct pxl8_tilesheet {
|
|||
u32 total_tiles;
|
||||
u32 width;
|
||||
|
||||
pxl8_pixel_mode pixel_mode;
|
||||
u32 ref_count;
|
||||
|
||||
pxl8_tile_animation* animations;
|
||||
|
|
@ -106,14 +104,10 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
|
|||
tilesheet->height = height;
|
||||
tilesheet->tiles_per_row = width / tilesheet->tile_size;
|
||||
tilesheet->total_tiles = (width / tilesheet->tile_size) * (height / tilesheet->tile_size);
|
||||
tilesheet->pixel_mode = pxl8_gfx_get_pixel_mode(gfx);
|
||||
|
||||
u32 pixel_count = width * height;
|
||||
u16 ase_depth = ase_file.header.color_depth;
|
||||
bool gfx_hicolor = (tilesheet->pixel_mode == PXL8_PIXEL_HICOLOR);
|
||||
|
||||
usize data_size = pixel_count * pxl8_bytes_per_pixel(tilesheet->pixel_mode);
|
||||
tilesheet->data = pxl8_malloc(data_size);
|
||||
tilesheet->data = pxl8_malloc(pixel_count);
|
||||
if (!tilesheet->data) {
|
||||
pxl8_ase_destroy(&ase_file);
|
||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
|
|
@ -122,34 +116,10 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
|
|||
if (ase_file.frame_count > 0 && ase_file.frames[0].pixels) {
|
||||
const u8* src = ase_file.frames[0].pixels;
|
||||
|
||||
if (ase_depth == 8 && !gfx_hicolor) {
|
||||
memcpy(tilesheet->data, src, pixel_count);
|
||||
} else if (ase_depth == 32 && gfx_hicolor) {
|
||||
u16* dst = (u16*)tilesheet->data;
|
||||
const u32* rgba = (const u32*)src;
|
||||
for (u32 i = 0; i < pixel_count; i++) {
|
||||
u32 c = rgba[i];
|
||||
u8 a = (c >> 24) & 0xFF;
|
||||
if (a == 0) {
|
||||
dst[i] = 0;
|
||||
} else {
|
||||
dst[i] = pxl8_rgba32_to_rgb565(c);
|
||||
}
|
||||
}
|
||||
} else if (ase_depth == 8 && gfx_hicolor) {
|
||||
pxl8_warn("Indexed ASE with hicolor gfx - storing as indexed");
|
||||
tilesheet->pixel_mode = PXL8_PIXEL_INDEXED;
|
||||
u8* new_data = pxl8_realloc(tilesheet->data, pixel_count);
|
||||
if (!new_data) {
|
||||
pxl8_free(tilesheet->data);
|
||||
tilesheet->data = NULL;
|
||||
pxl8_ase_destroy(&ase_file);
|
||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
tilesheet->data = new_data;
|
||||
if (ase_depth == 8) {
|
||||
memcpy(tilesheet->data, src, pixel_count);
|
||||
} else {
|
||||
pxl8_error("Unsupported ASE color depth %d for gfx mode", ase_depth);
|
||||
pxl8_error("Unsupported ASE color depth %d (expected indexed 8-bit)", ase_depth);
|
||||
pxl8_free(tilesheet->data);
|
||||
tilesheet->data = NULL;
|
||||
pxl8_ase_destroy(&ase_file);
|
||||
|
|
@ -166,7 +136,6 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
|
|||
}
|
||||
|
||||
u32 valid_tiles = 0;
|
||||
bool is_hicolor = (tilesheet->pixel_mode == PXL8_PIXEL_HICOLOR);
|
||||
|
||||
for (u32 tile_id = 1; tile_id <= tilesheet->total_tiles; tile_id++) {
|
||||
u32 tile_x = ((tile_id - 1) % tilesheet->tiles_per_row) * tilesheet->tile_size;
|
||||
|
|
@ -176,16 +145,9 @@ pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath,
|
|||
for (u32 py = 0; py < tilesheet->tile_size && !has_content; py++) {
|
||||
for (u32 px = 0; px < tilesheet->tile_size; px++) {
|
||||
u32 idx = (tile_y + py) * width + (tile_x + px);
|
||||
if (is_hicolor) {
|
||||
if (((u16*)tilesheet->data)[idx] != 0) {
|
||||
has_content = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (tilesheet->data[idx] != 0) {
|
||||
has_content = true;
|
||||
break;
|
||||
}
|
||||
if (tilesheet->data[idx] != 0) {
|
||||
has_content = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -312,7 +274,6 @@ pxl8_result pxl8_tilesheet_set_tile_pixels(pxl8_tilesheet* tilesheet, u16 tile_i
|
|||
|
||||
u32 tile_x = (tile_id - 1) % tilesheet->tiles_per_row;
|
||||
u32 tile_y = (tile_id - 1) / tilesheet->tiles_per_row;
|
||||
u32 bytes_per_pixel = pxl8_bytes_per_pixel(tilesheet->pixel_mode);
|
||||
|
||||
for (u32 py = 0; py < tilesheet->tile_size; py++) {
|
||||
for (u32 px = 0; px < tilesheet->tile_size; px++) {
|
||||
|
|
@ -320,12 +281,7 @@ pxl8_result pxl8_tilesheet_set_tile_pixels(pxl8_tilesheet* tilesheet, u16 tile_i
|
|||
u32 dst_x = tile_x * tilesheet->tile_size + px;
|
||||
u32 dst_y = tile_y * tilesheet->tile_size + py;
|
||||
u32 dst_idx = dst_y * tilesheet->width + dst_x;
|
||||
|
||||
if (bytes_per_pixel == 2) {
|
||||
((u16*)tilesheet->data)[dst_idx] = ((const u16*)pixels)[src_idx];
|
||||
} else {
|
||||
tilesheet->data[dst_idx] = pixels[src_idx];
|
||||
}
|
||||
tilesheet->data[dst_idx] = pixels[src_idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -170,11 +170,7 @@ void pxl8_transition_render(const pxl8_transition* transition, pxl8_gfx* gfx) {
|
|||
i32 block_size = (i32)(max_block_size * progress);
|
||||
if (block_size < 1) block_size = 1;
|
||||
|
||||
pxl8_pixel_mode mode = pxl8_gfx_get_pixel_mode(gfx);
|
||||
bool has_fb = (mode == PXL8_PIXEL_HICOLOR)
|
||||
? (pxl8_gfx_get_framebuffer_hicolor(gfx) != NULL)
|
||||
: (pxl8_gfx_get_framebuffer_indexed(gfx) != NULL);
|
||||
if (!has_fb) break;
|
||||
if (!pxl8_gfx_framebuffer(gfx)) break;
|
||||
|
||||
for (i32 y = 0; y < height; y += block_size) {
|
||||
for (i32 x = 0; x < width; x += block_size) {
|
||||
|
|
|
|||
|
|
@ -125,16 +125,9 @@ static void sdl3_upload_texture(void* platform_data, const void* pixels, u32 w,
|
|||
ctx->rgba_buffer_size = pixel_count;
|
||||
}
|
||||
|
||||
if (bpp == 2) {
|
||||
const u16* pixels16 = (const u16*)pixels;
|
||||
for (u32 i = 0; i < pixel_count; i++) {
|
||||
ctx->rgba_buffer[i] = pxl8_rgb565_to_rgba32(pixels16[i]);
|
||||
}
|
||||
} else {
|
||||
const u8* pixels8 = (const u8*)pixels;
|
||||
for (u32 i = 0; i < pixel_count; i++) {
|
||||
ctx->rgba_buffer[i] = palette[pixels8[i]];
|
||||
}
|
||||
const u8* pixels8 = (const u8*)pixels;
|
||||
for (u32 i = 0; i < pixel_count; i++) {
|
||||
ctx->rgba_buffer[i] = palette[pixels8[i]];
|
||||
}
|
||||
|
||||
SDL_UpdateTexture(ctx->framebuffer, NULL, ctx->rgba_buffer, w * 4);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ function World:init_local_player(x, y, z)
|
|||
C.pxl8_world_init_local_player(self._ptr, x, y, z)
|
||||
end
|
||||
|
||||
function World:set_look(yaw, pitch)
|
||||
C.pxl8_world_set_look(self._ptr, yaw, pitch or 0)
|
||||
end
|
||||
|
||||
function World:local_player()
|
||||
local ptr = C.pxl8_world_local_player(self._ptr)
|
||||
if ptr == nil then return nil end
|
||||
|
|
|
|||
|
|
@ -1214,12 +1214,6 @@ static pxl8_resolution parse_resolution(const char* str) {
|
|||
return PXL8_RESOLUTION_640x360;
|
||||
}
|
||||
|
||||
static pxl8_pixel_mode parse_pixel_mode(const char* str) {
|
||||
if (strcmp(str, "indexed") == 0) return PXL8_PIXEL_INDEXED;
|
||||
if (strcmp(str, "hicolor") == 0) return PXL8_PIXEL_HICOLOR;
|
||||
return PXL8_PIXEL_INDEXED;
|
||||
}
|
||||
|
||||
pxl8_result pxl8_script_load_cart_manifest(pxl8_script* script, pxl8_cart* cart) {
|
||||
if (!script || !script->L || !cart) return PXL8_ERROR_NULL_POINTER;
|
||||
|
||||
|
|
@ -1267,12 +1261,6 @@ pxl8_result pxl8_script_load_cart_manifest(pxl8_script* script, pxl8_cart* cart)
|
|||
}
|
||||
lua_pop(script->L, 1);
|
||||
|
||||
lua_getfield(script->L, -1, "pixel-mode");
|
||||
if (lua_isstring(script->L, -1)) {
|
||||
pxl8_cart_set_pixel_mode(cart, parse_pixel_mode(lua_tostring(script->L, -1)));
|
||||
}
|
||||
lua_pop(script->L, 1);
|
||||
|
||||
lua_getfield(script->L, -1, "window-size");
|
||||
if (lua_istable(script->L, -1)) {
|
||||
lua_rawgeti(script->L, -1, 1);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static const char* pxl8_ffi_cdefs =
|
|||
"f32 pxl8_get_fps(const pxl8* sys);\n"
|
||||
"\n"
|
||||
"u8 pxl8_gfx_find_color(pxl8_gfx* gfx, u32 color);\n"
|
||||
"u8* pxl8_gfx_get_framebuffer_indexed(pxl8_gfx* gfx);\n"
|
||||
"u8* pxl8_gfx_framebuffer(pxl8_gfx* gfx);\n"
|
||||
"i32 pxl8_gfx_get_height(pxl8_gfx* ctx);\n"
|
||||
"u32* pxl8_gfx_get_light_accum(pxl8_gfx* gfx);\n"
|
||||
"const u32* pxl8_gfx_palette_colors(pxl8_gfx* gfx);\n"
|
||||
|
|
@ -437,6 +437,7 @@ static const char* pxl8_ffi_cdefs =
|
|||
"} pxl8_sim_entity;\n"
|
||||
"\n"
|
||||
"void pxl8_world_init_local_player(pxl8_world* world, f32 x, f32 y, f32 z);\n"
|
||||
"void pxl8_world_set_look(pxl8_world* world, f32 yaw, f32 pitch);\n"
|
||||
"pxl8_sim_entity* pxl8_world_local_player(pxl8_world* world);\n"
|
||||
"\n"
|
||||
"typedef struct { i32 cursor_x; i32 cursor_y; bool cursor_down; bool cursor_clicked; u32 hot_id; u32 active_id; } pxl8_gui_state;\n"
|
||||
|
|
|
|||
|
|
@ -316,6 +316,7 @@ void pxl8_world_init_local_player(pxl8_world* world, f32 x, f32 y, f32 z) {
|
|||
world->local_player.flags = PXL8_SIM_FLAG_ALIVE | PXL8_SIM_FLAG_PLAYER | PXL8_SIM_FLAG_GROUNDED;
|
||||
world->local_player.kind = 0;
|
||||
world->client_tick = 0;
|
||||
world->pointer_motion = (pxl8_vec2){0};
|
||||
|
||||
#ifdef PXL8_ASYNC_THREADS
|
||||
world->render_state[0] = world->local_player;
|
||||
|
|
@ -323,6 +324,20 @@ void pxl8_world_init_local_player(pxl8_world* world, f32 x, f32 y, f32 z) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void pxl8_world_set_look(pxl8_world* world, f32 yaw, f32 pitch) {
|
||||
if (!world) return;
|
||||
world->local_player.yaw = yaw;
|
||||
world->local_player.pitch = pitch;
|
||||
world->pointer_motion = (pxl8_vec2){.yaw = yaw, .pitch = pitch};
|
||||
|
||||
#ifdef PXL8_ASYNC_THREADS
|
||||
world->render_state[0].yaw = yaw;
|
||||
world->render_state[0].pitch = pitch;
|
||||
world->render_state[1].yaw = yaw;
|
||||
world->render_state[1].pitch = pitch;
|
||||
#endif
|
||||
}
|
||||
|
||||
pxl8_sim_entity* pxl8_world_local_player(pxl8_world* world) {
|
||||
if (!world) return NULL;
|
||||
#ifdef PXL8_ASYNC_THREADS
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ void pxl8_world_set_bsp_material(pxl8_world* world, u16 material_id, const pxl8_
|
|||
|
||||
void pxl8_world_set_sim_config(pxl8_world* world, const pxl8_sim_config* config);
|
||||
void pxl8_world_init_local_player(pxl8_world* world, f32 x, f32 y, f32 z);
|
||||
void pxl8_world_set_look(pxl8_world* world, f32 yaw, f32 pitch);
|
||||
pxl8_sim_entity* pxl8_world_local_player(pxl8_world* world);
|
||||
pxl8_sim_world pxl8_world_sim_world(const pxl8_world* world, pxl8_vec3 pos);
|
||||
void pxl8_world_predict(pxl8_world* world, pxl8_net* net, const pxl8_input_msg* input, f32 dt);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue