diff --git a/src/asset/pxl8_ase.c b/client/src/asset/pxl8_ase.c similarity index 100% rename from src/asset/pxl8_ase.c rename to client/src/asset/pxl8_ase.c diff --git a/src/asset/pxl8_ase.h b/client/src/asset/pxl8_ase.h similarity index 100% rename from src/asset/pxl8_ase.h rename to client/src/asset/pxl8_ase.h diff --git a/src/asset/pxl8_cart.c b/client/src/asset/pxl8_cart.c similarity index 100% rename from src/asset/pxl8_cart.c rename to client/src/asset/pxl8_cart.c diff --git a/src/asset/pxl8_cart.h b/client/src/asset/pxl8_cart.h similarity index 100% rename from src/asset/pxl8_cart.h rename to client/src/asset/pxl8_cart.h diff --git a/src/asset/pxl8_embed.h b/client/src/asset/pxl8_embed.h similarity index 70% rename from src/asset/pxl8_embed.h rename to client/src/asset/pxl8_embed.h index a3efa98..07791e6 100644 --- a/src/asset/pxl8_embed.h +++ b/client/src/asset/pxl8_embed.h @@ -8,67 +8,55 @@ static const char embed_fennel[] = { , 0 }; static const char embed_pxl8[] = { -#embed "src/lua/pxl8.lua" +#embed "client/src/lua/pxl8.lua" , 0 }; static const char embed_pxl8_anim[] = { -#embed "src/lua/pxl8/anim.lua" -, 0 }; - -static const char embed_pxl8_bytes[] = { -#embed "src/lua/pxl8/bytes.lua" +#embed "client/src/lua/pxl8/anim.lua" , 0 }; static const char embed_pxl8_core[] = { -#embed "src/lua/pxl8/core.lua" -, 0 }; - -static const char embed_pxl8_effects[] = { -#embed "src/lua/pxl8/effects.lua" +#embed "client/src/lua/pxl8/core.lua" , 0 }; static const char embed_pxl8_gfx2d[] = { -#embed "src/lua/pxl8/gfx2d.lua" +#embed "client/src/lua/pxl8/gfx2d.lua" , 0 }; static const char embed_pxl8_gfx3d[] = { -#embed "src/lua/pxl8/gfx3d.lua" +#embed "client/src/lua/pxl8/gfx3d.lua" , 0 }; static const char embed_pxl8_gui[] = { -#embed "src/lua/pxl8/gui.lua" +#embed "client/src/lua/pxl8/gui.lua" , 0 }; static const char embed_pxl8_input[] = { -#embed "src/lua/pxl8/input.lua" +#embed "client/src/lua/pxl8/input.lua" , 0 }; static const char embed_pxl8_math[] = { -#embed "src/lua/pxl8/math.lua" -, 0 }; - -static const char embed_pxl8_net[] = { -#embed "src/lua/pxl8/net.lua" +#embed "client/src/lua/pxl8/math.lua" , 0 }; static const char embed_pxl8_particles[] = { -#embed "src/lua/pxl8/particles.lua" +#embed "client/src/lua/pxl8/particles.lua" , 0 }; static const char embed_pxl8_sfx[] = { -#embed "src/lua/pxl8/sfx.lua" +#embed "client/src/lua/pxl8/sfx.lua" , 0 }; static const char embed_pxl8_tilemap[] = { -#embed "src/lua/pxl8/tilemap.lua" +#embed "client/src/lua/pxl8/tilemap.lua" , 0 }; static const char embed_pxl8_transition[] = { -#embed "src/lua/pxl8/transition.lua" +#embed "client/src/lua/pxl8/transition.lua" , 0 }; static const char embed_pxl8_world[] = { -#embed "src/lua/pxl8/world.lua" +#embed "client/src/lua/pxl8/world.lua" , 0 }; #define PXL8_EMBED_ENTRY(var, name) {name, var, sizeof(var) - 1} @@ -79,15 +67,12 @@ static const pxl8_embed pxl8_embeds[] = { PXL8_EMBED_ENTRY(embed_fennel, "fennel"), PXL8_EMBED_ENTRY(embed_pxl8, "pxl8"), PXL8_EMBED_ENTRY(embed_pxl8_anim, "pxl8.anim"), - PXL8_EMBED_ENTRY(embed_pxl8_bytes, "pxl8.bytes"), PXL8_EMBED_ENTRY(embed_pxl8_core, "pxl8.core"), - PXL8_EMBED_ENTRY(embed_pxl8_effects, "pxl8.effects"), PXL8_EMBED_ENTRY(embed_pxl8_gfx2d, "pxl8.gfx2d"), PXL8_EMBED_ENTRY(embed_pxl8_gfx3d, "pxl8.gfx3d"), PXL8_EMBED_ENTRY(embed_pxl8_gui, "pxl8.gui"), PXL8_EMBED_ENTRY(embed_pxl8_input, "pxl8.input"), PXL8_EMBED_ENTRY(embed_pxl8_math, "pxl8.math"), - PXL8_EMBED_ENTRY(embed_pxl8_net, "pxl8.net"), PXL8_EMBED_ENTRY(embed_pxl8_particles, "pxl8.particles"), PXL8_EMBED_ENTRY(embed_pxl8_sfx, "pxl8.sfx"), PXL8_EMBED_ENTRY(embed_pxl8_tilemap, "pxl8.tilemap"), diff --git a/src/asset/pxl8_save.c b/client/src/asset/pxl8_save.c similarity index 100% rename from src/asset/pxl8_save.c rename to client/src/asset/pxl8_save.c diff --git a/src/asset/pxl8_save.h b/client/src/asset/pxl8_save.h similarity index 100% rename from src/asset/pxl8_save.h rename to client/src/asset/pxl8_save.h diff --git a/src/core/pxl8.c b/client/src/core/pxl8.c similarity index 99% rename from src/core/pxl8.c rename to client/src/core/pxl8.c index 0c7d0d2..8e29af4 100644 --- a/src/core/pxl8.c +++ b/client/src/core/pxl8.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -309,7 +310,7 @@ pxl8_result pxl8_update(pxl8* sys) { if (pxl8_script_load_module(game->script, "pxl8") != PXL8_OK) { const char* err_msg = pxl8_script_get_last_error(game->script); - pxl8_error("failed to load pxl8 global: %s", err_msg); + pxl8_error("failed to setup pxl8 global: %s", err_msg); } sys->repl = pxl8_repl_create(); diff --git a/src/core/pxl8_io.c b/client/src/core/pxl8_io.c similarity index 100% rename from src/core/pxl8_io.c rename to client/src/core/pxl8_io.c diff --git a/client/src/core/pxl8_io.h b/client/src/core/pxl8_io.h new file mode 100644 index 0000000..f4e73bb --- /dev/null +++ b/client/src/core/pxl8_io.h @@ -0,0 +1,126 @@ +#pragma once + +#include +#include +#include + +#include "pxl8_types.h" + +typedef struct { + const u8* bytes; + u32 offset; + u32 size; + bool overflow; +} pxl8_stream; + +static inline pxl8_stream pxl8_stream_create(const u8* bytes, u32 size) { + return (pxl8_stream){ + .bytes = bytes, + .offset = 0, + .size = size, + .overflow = false + }; +} + +static inline bool pxl8_stream_can_read(const pxl8_stream* stream, u32 count) { + return !stream->overflow && stream->offset + count <= stream->size; +} + +static inline bool pxl8_stream_has_overflow(const pxl8_stream* stream) { + return stream->overflow; +} + +static inline void pxl8_stream_seek(pxl8_stream* stream, u32 offset) { + stream->offset = offset; +} + +static inline u32 pxl8_stream_position(const pxl8_stream* stream) { + return stream->offset; +} + +static inline u8 pxl8_read_u8(pxl8_stream* stream) { + if (stream->offset + 1 > stream->size) { stream->overflow = true; return 0; } + return stream->bytes[stream->offset++]; +} + +static inline u16 pxl8_read_u16(pxl8_stream* stream) { + if (stream->offset + 2 > stream->size) { stream->overflow = true; return 0; } + u16 val = (u16)stream->bytes[stream->offset] | ((u16)stream->bytes[stream->offset + 1] << 8); + stream->offset += 2; + return val; +} + +static inline u32 pxl8_read_u32(pxl8_stream* stream) { + if (stream->offset + 4 > stream->size) { stream->overflow = true; return 0; } + u32 val = (u32)stream->bytes[stream->offset] | + ((u32)stream->bytes[stream->offset + 1] << 8) | + ((u32)stream->bytes[stream->offset + 2] << 16) | + ((u32)stream->bytes[stream->offset + 3] << 24); + stream->offset += 4; + return val; +} + +static inline i16 pxl8_read_i16(pxl8_stream* stream) { + return (i16)pxl8_read_u16(stream); +} + +static inline i32 pxl8_read_i32(pxl8_stream* stream) { + return (i32)pxl8_read_u32(stream); +} + +static inline f32 pxl8_read_f32(pxl8_stream* stream) { + u32 val = pxl8_read_u32(stream); + f32 result; + memcpy(&result, &val, sizeof(f32)); + return result; +} + +static inline void pxl8_read_bytes(pxl8_stream* stream, void* dest, u32 count) { + if (stream->offset + count > stream->size) { stream->overflow = true; return; } + for (u32 i = 0; i < count; i++) { + ((u8*)dest)[i] = stream->bytes[stream->offset++]; + } +} + +static inline void pxl8_skip_bytes(pxl8_stream* stream, u32 count) { + if (stream->offset + count > stream->size) { stream->overflow = true; return; } + stream->offset += count; +} + +static inline const u8* pxl8_read_ptr(pxl8_stream* stream, u32 count) { + if (stream->offset + count > stream->size) { stream->overflow = true; return NULL; } + const u8* ptr = &stream->bytes[stream->offset]; + stream->offset += count; + return ptr; +} + +#ifdef __cplusplus +extern "C" { +#endif + +pxl8_result pxl8_io_create_directory(const char* path); +bool pxl8_io_file_exists(const char* path); +void pxl8_io_free_binary_data(u8* data); +void pxl8_io_free_file_content(char* content); +f64 pxl8_io_get_file_modified_time(const char* path); +pxl8_result pxl8_io_read_binary_file(const char* path, u8** data, size_t* size); +pxl8_result pxl8_io_read_file(const char* path, char** content, size_t* size); +pxl8_result pxl8_io_write_binary_file(const char* path, const u8* data, size_t size); +pxl8_result pxl8_io_write_file(const char* path, const char* content, size_t size); + +bool pxl8_key_down(const pxl8_input_state* input, const char* key_name); +bool pxl8_key_pressed(const pxl8_input_state* input, const char* key_name); +bool pxl8_key_released(const pxl8_input_state* input, const char* key_name); + +i32 pxl8_mouse_dx(const pxl8_input_state* input); +i32 pxl8_mouse_dy(const pxl8_input_state* input); +bool pxl8_mouse_pressed(const pxl8_input_state* input, i32 button); +bool pxl8_mouse_released(const pxl8_input_state* input, i32 button); +i32 pxl8_mouse_wheel_x(const pxl8_input_state* input); +i32 pxl8_mouse_wheel_y(const pxl8_input_state* input); +i32 pxl8_mouse_x(const pxl8_input_state* input); +i32 pxl8_mouse_y(const pxl8_input_state* input); + +#ifdef __cplusplus +} +#endif diff --git a/src/core/pxl8_log.c b/client/src/core/pxl8_log.c similarity index 100% rename from src/core/pxl8_log.c rename to client/src/core/pxl8_log.c diff --git a/src/core/pxl8_log.h b/client/src/core/pxl8_log.h similarity index 100% rename from src/core/pxl8_log.h rename to client/src/core/pxl8_log.h diff --git a/src/core/pxl8_macros.h b/client/src/core/pxl8_macros.h similarity index 100% rename from src/core/pxl8_macros.h rename to client/src/core/pxl8_macros.h diff --git a/src/core/pxl8_rng.c b/client/src/core/pxl8_rng.c similarity index 100% rename from src/core/pxl8_rng.c rename to client/src/core/pxl8_rng.c diff --git a/src/core/pxl8_rng.h b/client/src/core/pxl8_rng.h similarity index 100% rename from src/core/pxl8_rng.h rename to client/src/core/pxl8_rng.h diff --git a/src/core/pxl8_sys.h b/client/src/core/pxl8_sys.h similarity index 100% rename from src/core/pxl8_sys.h rename to client/src/core/pxl8_sys.h diff --git a/src/core/pxl8_types.h b/client/src/core/pxl8_types.h similarity index 96% rename from src/core/pxl8_types.h rename to client/src/core/pxl8_types.h index e5e1135..3a90580 100644 --- a/src/core/pxl8_types.h +++ b/client/src/core/pxl8_types.h @@ -29,9 +29,8 @@ typedef __uint128_t u128; #endif typedef enum pxl8_pixel_mode { - PXL8_PIXEL_INDEXED = 1, - PXL8_PIXEL_HICOLOR = 2, - PXL8_PIXEL_RGBA = 4, + PXL8_PIXEL_INDEXED, + PXL8_PIXEL_HICOLOR } pxl8_pixel_mode; typedef enum pxl8_cursor { diff --git a/src/core/pxl8_game.h b/client/src/game/pxl8_game.h similarity index 100% rename from src/core/pxl8_game.h rename to client/src/game/pxl8_game.h diff --git a/src/gui/pxl8_gui.c b/client/src/game/pxl8_gui.c similarity index 72% rename from src/gui/pxl8_gui.c rename to client/src/game/pxl8_gui.c index 72fdc29..6f8bbd3 100644 --- a/src/gui/pxl8_gui.c +++ b/client/src/game/pxl8_gui.c @@ -18,20 +18,18 @@ void pxl8_gui_state_destroy(pxl8_gui_state* state) { free(state); } -void pxl8_gui_begin_frame(pxl8_gui_state* state, pxl8_gfx* gfx) { +void pxl8_gui_begin_frame(pxl8_gui_state* state) { if (!state) return; state->hot_id = 0; - if (gfx) pxl8_gfx_push_target(gfx); } -void pxl8_gui_end_frame(pxl8_gui_state* state, pxl8_gfx* gfx) { +void pxl8_gui_end_frame(pxl8_gui_state* state) { if (!state) return; if (!state->cursor_down) { state->active_id = 0; } state->cursor_clicked = false; - if (gfx) pxl8_gfx_pop_target(gfx); } void pxl8_gui_cursor_move(pxl8_gui_state* state, i32 x, i32 y) { @@ -82,16 +80,16 @@ bool pxl8_gui_button(pxl8_gui_state* state, pxl8_gfx* gfx, u32 id, i32 x, i32 y, i32 offset_y = 0; if (is_active) { - bg_color = pxl8_gfx_ui_color(gfx, PXL8_UI_BG3); - border_color = pxl8_gfx_ui_color(gfx, PXL8_UI_BG2); + bg_color = 4; + border_color = 3; offset_x = 1; offset_y = 1; } else if (is_hot || cursor_over) { - bg_color = pxl8_gfx_ui_color(gfx, PXL8_UI_BG3); - border_color = pxl8_gfx_ui_color(gfx, PXL8_UI_FG0); + bg_color = 4; + border_color = 8; } else { - bg_color = pxl8_gfx_ui_color(gfx, PXL8_UI_BG2); - border_color = pxl8_gfx_ui_color(gfx, PXL8_UI_BG3); + bg_color = 3; + border_color = 4; } pxl8_2d_rect_fill(gfx, x, y, w, h, bg_color); @@ -100,7 +98,7 @@ bool pxl8_gui_button(pxl8_gui_state* state, pxl8_gfx* gfx, u32 id, i32 x, i32 y, i32 text_len = (i32)strlen(label); i32 text_x = x + (w / 2) - ((text_len * 8) / 2) + offset_x; i32 text_y = y + (h / 2) - 5 + offset_y; - pxl8_2d_text(gfx, label, text_x, text_y, pxl8_gfx_ui_color(gfx, PXL8_UI_FG1)); + pxl8_2d_text(gfx, label, text_x, text_y, 6); return clicked; } @@ -108,19 +106,14 @@ bool pxl8_gui_button(pxl8_gui_state* state, pxl8_gfx* gfx, u32 id, i32 x, i32 y, void pxl8_gui_window(pxl8_gfx* gfx, i32 x, i32 y, i32 w, i32 h, const char* title) { if (!gfx || !title) return; - u8 title_bg = pxl8_gfx_ui_color(gfx, PXL8_UI_BG1); - u8 body_bg = pxl8_gfx_ui_color(gfx, PXL8_UI_BG2); - u8 border = pxl8_gfx_ui_color(gfx, PXL8_UI_BG3); - u8 title_fg = pxl8_gfx_ui_color(gfx, PXL8_UI_FG0); - - pxl8_2d_rect_fill(gfx, x, y, w, 28, title_bg); - pxl8_2d_rect_fill(gfx, x, y + 28, w, h - 28, body_bg); - pxl8_2d_rect(gfx, x, y, w, h, border); - pxl8_2d_rect_fill(gfx, x, y + 28, w, 1, border); + pxl8_2d_rect_fill(gfx, x, y, w, 28, 1); + pxl8_2d_rect_fill(gfx, x, y + 28, w, h - 28, 2); + pxl8_2d_rect(gfx, x, y, w, h, 4); + pxl8_2d_rect_fill(gfx, x, y + 28, w, 1, 4); i32 title_x = x + 10; i32 title_y = y + (28 / 2) - 5; - pxl8_2d_text(gfx, title, title_x, title_y, title_fg); + pxl8_2d_text(gfx, title, title_x, title_y, 8); } void pxl8_gui_label(pxl8_gfx* gfx, i32 x, i32 y, const char* text, u8 color) { diff --git a/src/gui/pxl8_gui.h b/client/src/game/pxl8_gui.h similarity index 88% rename from src/gui/pxl8_gui.h rename to client/src/game/pxl8_gui.h index 1d7646a..db1147f 100644 --- a/src/gui/pxl8_gui.h +++ b/client/src/game/pxl8_gui.h @@ -22,8 +22,8 @@ void pxl8_gui_state_destroy(pxl8_gui_state* state); void pxl8_gui_get_cursor_pos(const pxl8_gui_state* state, i32* x, i32* y); bool pxl8_gui_is_hovering(const pxl8_gui_state* state); -void pxl8_gui_begin_frame(pxl8_gui_state* state, pxl8_gfx* gfx); -void pxl8_gui_end_frame(pxl8_gui_state* state, pxl8_gfx* gfx); +void pxl8_gui_begin_frame(pxl8_gui_state* state); +void pxl8_gui_end_frame(pxl8_gui_state* state); void pxl8_gui_cursor_down(pxl8_gui_state* state); void pxl8_gui_cursor_move(pxl8_gui_state* state, i32 x, i32 y); diff --git a/src/core/pxl8_replay.c b/client/src/game/pxl8_replay.c similarity index 100% rename from src/core/pxl8_replay.c rename to client/src/game/pxl8_replay.c diff --git a/src/core/pxl8_replay.h b/client/src/game/pxl8_replay.h similarity index 100% rename from src/core/pxl8_replay.h rename to client/src/game/pxl8_replay.h diff --git a/src/gfx/pxl8_3d_camera.c b/client/src/gfx/pxl8_3d_camera.c similarity index 82% rename from src/gfx/pxl8_3d_camera.c rename to client/src/gfx/pxl8_3d_camera.c index 7f27b20..3cec31d 100644 --- a/src/gfx/pxl8_3d_camera.c +++ b/client/src/gfx/pxl8_3d_camera.c @@ -56,8 +56,8 @@ void pxl8_3d_camera_lookat(pxl8_3d_camera* cam, pxl8_vec3 eye, pxl8_vec3 target, pxl8_vec3 forward = pxl8_vec3_normalize(pxl8_vec3_sub(target, eye)); - cam->pitch = asinf(forward.y); - cam->yaw = atan2f(-forward.x, -forward.z); + cam->pitch = asinf(-forward.y); + cam->yaw = atan2f(forward.x, forward.z); cam->roll = 0; (void)up; @@ -104,9 +104,9 @@ pxl8_vec3 pxl8_3d_camera_get_forward(const pxl8_3d_camera* cam) { f32 sy = sinf(cam->yaw); return (pxl8_vec3){ - -sy * cp, - sp, - -cy * cp + cp * sy, + -sp, + cp * cy }; } @@ -183,8 +183,8 @@ void pxl8_3d_camera_follow(pxl8_3d_camera* cam, pxl8_vec3 target, pxl8_vec3 offs cam->position = pxl8_vec3_lerp(cam->position, desired, t); pxl8_vec3 forward = pxl8_vec3_normalize(pxl8_vec3_sub(target, cam->position)); - cam->pitch = asinf(forward.y); - cam->yaw = atan2f(-forward.x, -forward.z); + cam->pitch = asinf(-forward.y); + cam->yaw = atan2f(forward.x, forward.z); } void pxl8_3d_camera_shake(pxl8_3d_camera* cam, f32 intensity, f32 duration) { @@ -212,30 +212,3 @@ void pxl8_3d_camera_update(pxl8_3d_camera* cam, f32 dt) { } } } - -pxl8_projected_point pxl8_3d_camera_world_to_screen(const pxl8_3d_camera* cam, pxl8_vec3 world_pos, u32 screen_width, u32 screen_height) { - pxl8_projected_point result = {0, 0, 0.0f, false}; - if (!cam) return result; - - pxl8_mat4 view = pxl8_3d_camera_get_view(cam); - pxl8_mat4 proj = pxl8_3d_camera_get_projection(cam); - pxl8_mat4 vp = pxl8_mat4_mul(proj, view); - - pxl8_vec4 clip = pxl8_mat4_mul_vec4(vp, (pxl8_vec4){world_pos.x, world_pos.y, world_pos.z, 1.0f}); - - if (clip.w <= 0.0f) return result; - - f32 inv_w = 1.0f / clip.w; - f32 ndc_x = clip.x * inv_w; - f32 ndc_y = clip.y * inv_w; - f32 ndc_z = clip.z * inv_w; - - if (ndc_x < -1.0f || ndc_x > 1.0f || ndc_y < -1.0f || ndc_y > 1.0f) return result; - - result.x = (i32)((ndc_x + 1.0f) * 0.5f * (f32)screen_width); - result.y = (i32)((1.0f - ndc_y) * 0.5f * (f32)screen_height); - result.depth = ndc_z; - result.visible = true; - - return result; -} diff --git a/src/gfx/pxl8_3d_camera.h b/client/src/gfx/pxl8_3d_camera.h similarity index 91% rename from src/gfx/pxl8_3d_camera.h rename to client/src/gfx/pxl8_3d_camera.h index e3a9fc4..24ee8dd 100644 --- a/src/gfx/pxl8_3d_camera.h +++ b/client/src/gfx/pxl8_3d_camera.h @@ -32,7 +32,6 @@ pxl8_mat4 pxl8_3d_camera_get_view(const pxl8_3d_camera* cam); void pxl8_3d_camera_blend(pxl8_3d_camera* dest, const pxl8_3d_camera* a, const pxl8_3d_camera* b, f32 t); void pxl8_3d_camera_follow(pxl8_3d_camera* cam, pxl8_vec3 target, pxl8_vec3 offset, f32 smoothing, f32 dt); -pxl8_projected_point pxl8_3d_camera_world_to_screen(const pxl8_3d_camera* cam, pxl8_vec3 world_pos, u32 screen_width, u32 screen_height); void pxl8_3d_camera_shake(pxl8_3d_camera* cam, f32 intensity, f32 duration); void pxl8_3d_camera_update(pxl8_3d_camera* cam, f32 dt); diff --git a/src/gfx/pxl8_anim.c b/client/src/gfx/pxl8_anim.c similarity index 100% rename from src/gfx/pxl8_anim.c rename to client/src/gfx/pxl8_anim.c diff --git a/src/gfx/pxl8_anim.h b/client/src/gfx/pxl8_anim.h similarity index 100% rename from src/gfx/pxl8_anim.h rename to client/src/gfx/pxl8_anim.h diff --git a/src/gfx/pxl8_atlas.c b/client/src/gfx/pxl8_atlas.c similarity index 88% rename from src/gfx/pxl8_atlas.c rename to client/src/gfx/pxl8_atlas.c index 0f87389..f752145 100644 --- a/src/gfx/pxl8_atlas.c +++ b/client/src/gfx/pxl8_atlas.c @@ -27,8 +27,6 @@ typedef struct pxl8_skyline { struct pxl8_atlas { u32 height, width; u8* pixels; - u8* pixels_tiled; - u32 tiled_capacity, tiled_size; bool dirty; @@ -197,7 +195,6 @@ void pxl8_atlas_destroy(pxl8_atlas* atlas) { free(atlas->entries); free(atlas->free_list); free(atlas->pixels); - free(atlas->pixels_tiled); free(atlas->skyline.nodes); free(atlas); } @@ -212,13 +209,6 @@ void pxl8_atlas_clear(pxl8_atlas* atlas, u32 preserve_count) { atlas->entry_count = preserve_count; atlas->free_count = 0; - if (preserve_count == 0) { - atlas->tiled_size = 0; - } else { - pxl8_atlas_entry* last = &atlas->entries[preserve_count - 1]; - atlas->tiled_size = last->tiled_base + (u32)(last->w * last->h); - } - atlas->skyline.nodes[0] = (pxl8_skyline_node){0, 0, (i32)atlas->width}; atlas->skyline.count = 1; @@ -344,7 +334,6 @@ u32 pxl8_atlas_add_texture( entry->y = fit.pos.y; entry->w = w; 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++) { @@ -360,30 +349,6 @@ u32 pxl8_atlas_add_texture( } } - u32 tiled_tex_size = w * h; - u32 new_tiled_size = atlas->tiled_size + tiled_tex_size; - if (new_tiled_size > atlas->tiled_capacity) { - u32 new_cap = atlas->tiled_capacity ? atlas->tiled_capacity * 2 : 4096; - while (new_cap < new_tiled_size) new_cap *= 2; - u8* new_tiled = (u8*)realloc(atlas->pixels_tiled, new_cap); - if (!new_tiled) { - entry->active = false; - return UINT32_MAX; - } - atlas->pixels_tiled = new_tiled; - atlas->tiled_capacity = new_cap; - } - - entry->tiled_base = atlas->tiled_size; - u8* tiled_dst = atlas->pixels_tiled + entry->tiled_base; - for (u32 ty = 0; ty < h; ty++) { - for (u32 tx = 0; tx < w; tx++) { - u32 tiled_offset = pxl8_tile_addr(tx, ty, entry->log2_w); - tiled_dst[tiled_offset] = pixels[ty * w + tx]; - } - } - atlas->tiled_size = new_tiled_size; - if (!pxl8_skyline_add_rect(&atlas->skyline, fit.pos, w, h)) { entry->active = false; return UINT32_MAX; @@ -412,10 +377,6 @@ const u8* pxl8_atlas_get_pixels(const pxl8_atlas* atlas) { return atlas ? atlas->pixels : NULL; } -const u8* pxl8_atlas_get_pixels_tiled(const pxl8_atlas* atlas) { - return atlas ? atlas->pixels_tiled : NULL; -} - u32 pxl8_atlas_get_width(const pxl8_atlas* atlas) { return atlas ? atlas->width : 0; } diff --git a/src/gfx/pxl8_atlas.h b/client/src/gfx/pxl8_atlas.h similarity index 70% rename from src/gfx/pxl8_atlas.h rename to client/src/gfx/pxl8_atlas.h index 2a429f9..2f0313b 100644 --- a/src/gfx/pxl8_atlas.h +++ b/client/src/gfx/pxl8_atlas.h @@ -8,42 +8,28 @@ typedef struct pxl8_atlas_entry { bool active; u32 texture_id; i32 x, y, w, h; - u32 tiled_base; - u8 log2_w; } pxl8_atlas_entry; -static inline u32 pxl8_tile_addr(u32 u, u32 v, u8 log2_w) { - u32 tile_y = v >> 3; - u32 tile_x = u >> 3; - u32 local_y = v & 7; - u32 local_x = u & 7; - return (tile_y << (log2_w + 3)) | (tile_x << 6) | (local_y << 3) | local_x; -} - -static inline u8 pxl8_log2(u32 v) { - u8 r = 0; - while (v >>= 1) r++; - return r; -} - #ifdef __cplusplus extern "C" { #endif -u32 pxl8_atlas_add_texture(pxl8_atlas* atlas, const u8* pixels, u32 w, u32 h, pxl8_pixel_mode pixel_mode); -void pxl8_atlas_clear(pxl8_atlas* atlas, u32 preserve_count); pxl8_atlas* pxl8_atlas_create(u32 width, u32 height, pxl8_pixel_mode pixel_mode); void pxl8_atlas_destroy(pxl8_atlas* atlas); -bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_pixel_mode pixel_mode); + 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); const u8* pxl8_atlas_get_pixels(const pxl8_atlas* atlas); -const u8* pxl8_atlas_get_pixels_tiled(const pxl8_atlas* atlas); u32 pxl8_atlas_get_width(const pxl8_atlas* atlas); bool pxl8_atlas_is_dirty(const pxl8_atlas* atlas); + void pxl8_atlas_mark_clean(pxl8_atlas* atlas); +u32 pxl8_atlas_add_texture(pxl8_atlas* atlas, const u8* pixels, u32 w, u32 h, pxl8_pixel_mode pixel_mode); +void pxl8_atlas_clear(pxl8_atlas* atlas, u32 preserve_count); +bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_pixel_mode pixel_mode); + #ifdef __cplusplus } #endif diff --git a/src/gfx/pxl8_backend.h b/client/src/gfx/pxl8_backend.h similarity index 100% rename from src/gfx/pxl8_backend.h rename to client/src/gfx/pxl8_backend.h diff --git a/src/gfx/pxl8_blit.c b/client/src/gfx/pxl8_blit.c similarity index 100% rename from src/gfx/pxl8_blit.c rename to client/src/gfx/pxl8_blit.c diff --git a/src/gfx/pxl8_blit.h b/client/src/gfx/pxl8_blit.h similarity index 100% rename from src/gfx/pxl8_blit.h rename to client/src/gfx/pxl8_blit.h diff --git a/src/gfx/pxl8_color.h b/client/src/gfx/pxl8_color.h similarity index 97% rename from src/gfx/pxl8_color.h rename to client/src/gfx/pxl8_color.h index 285a147..6f6eb55 100644 --- a/src/gfx/pxl8_color.h +++ b/client/src/gfx/pxl8_color.h @@ -3,7 +3,7 @@ #include "pxl8_types.h" static inline i32 pxl8_bytes_per_pixel(pxl8_pixel_mode mode) { - return (i32)mode; + return (mode == PXL8_PIXEL_HICOLOR) ? 2 : 1; } static inline u16 pxl8_rgb565_pack(u8 r, u8 g, u8 b) { diff --git a/client/src/gfx/pxl8_colormap.c b/client/src/gfx/pxl8_colormap.c new file mode 100644 index 0000000..f967751 --- /dev/null +++ b/client/src/gfx/pxl8_colormap.c @@ -0,0 +1,79 @@ +#include "pxl8_colormap.h" +#include + +static u8 find_closest_color(const u32* palette, u8 target_r, u8 target_g, u8 target_b) { + u8 best_idx = 1; + u32 best_dist = 0xFFFFFFFF; + + u8 dynamic_end = PXL8_DYNAMIC_RANGE_START + PXL8_DYNAMIC_RANGE_COUNT; + + for (u32 i = 1; i < PXL8_FULLBRIGHT_START; i++) { + if (i >= PXL8_DYNAMIC_RANGE_START && i < dynamic_end) { + continue; + } + + u32 c = palette[i]; + u8 pr = (c >> 24) & 0xFF; + u8 pg = (c >> 16) & 0xFF; + u8 pb = (c >> 8) & 0xFF; + + i32 dr = (i32)target_r - (i32)pr; + i32 dg = (i32)target_g - (i32)pg; + i32 db = (i32)target_b - (i32)pb; + u32 dist = (u32)(dr * dr + dg * dg + db * db); + + if (dist < best_dist) { + best_dist = dist; + best_idx = (u8)i; + if (dist == 0) break; + } + } + + return best_idx; +} + +void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette, const pxl8_level_tint* tint) { + if (!cm || !palette) return; + + u8 dark_r, dark_g, dark_b; + if (tint && tint->tint_strength > 0.0f) { + f32 t = tint->tint_strength; + f32 inv = 1.0f - t; + dark_r = (u8)(tint->dark_r * inv + tint->tint_r * t); + dark_g = (u8)(tint->dark_g * inv + tint->tint_g * t); + dark_b = (u8)(tint->dark_b * inv + tint->tint_b * t); + } else if (tint) { + dark_r = tint->dark_r; + dark_g = tint->dark_g; + dark_b = tint->dark_b; + } else { + dark_r = dark_g = dark_b = 0; + } + + for (u32 light = 0; light < PXL8_LIGHT_LEVELS; light++) { + f32 brightness = (f32)light / (f32)(PXL8_LIGHT_LEVELS - 1); + + for (u32 pal_idx = 0; pal_idx < 256; pal_idx++) { + u8 result_idx; + + if (pal_idx == PXL8_TRANSPARENT) { + result_idx = PXL8_TRANSPARENT; + } else if (pal_idx >= PXL8_FULLBRIGHT_START) { + result_idx = (u8)pal_idx; + } else { + u32 c = palette[pal_idx]; + u8 r = (c >> 24) & 0xFF; + u8 g = (c >> 16) & 0xFF; + u8 b = (c >> 8) & 0xFF; + + u8 target_r = (u8)(dark_r + (r - dark_r) * brightness); + u8 target_g = (u8)(dark_g + (g - dark_g) * brightness); + u8 target_b = (u8)(dark_b + (b - dark_b) * brightness); + + result_idx = find_closest_color(palette, target_r, target_g, target_b); + } + + cm->table[light * 256 + pal_idx] = result_idx; + } + } +} diff --git a/client/src/gfx/pxl8_colormap.h b/client/src/gfx/pxl8_colormap.h new file mode 100644 index 0000000..6e090a0 --- /dev/null +++ b/client/src/gfx/pxl8_colormap.h @@ -0,0 +1,43 @@ +#pragma once + +#include "pxl8_dither.h" +#include "pxl8_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PXL8_LIGHT_LEVELS 64 +#define PXL8_COLORMAP_SIZE (256 * PXL8_LIGHT_LEVELS) + +#define PXL8_FULLBRIGHT_START 240 +#define PXL8_TRANSPARENT 0 +#define PXL8_DYNAMIC_RANGE_START 144 +#define PXL8_DYNAMIC_RANGE_COUNT 16 + +typedef struct { + u8 table[PXL8_COLORMAP_SIZE]; +} pxl8_colormap; + +typedef struct { + u8 dark_r, dark_g, dark_b; + u8 tint_r, tint_g, tint_b; + f32 tint_strength; +} pxl8_level_tint; + +void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette, const pxl8_level_tint* tint); + +static inline u8 pxl8_colormap_lookup(const pxl8_colormap* cm, u8 pal_idx, u8 light) { + u32 light_idx = light >> 2; + return cm->table[light_idx * 256 + pal_idx]; +} + +static inline u8 pxl8_colormap_lookup_dithered(const pxl8_colormap* cm, u8 pal_idx, u8 light, u32 x, u32 y) { + u8 dithered = pxl8_dither_light(light, x, y); + u32 light_idx = dithered >> 2; + return cm->table[light_idx * 256 + pal_idx]; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/gfx/pxl8_cpu.c b/client/src/gfx/pxl8_cpu.c similarity index 67% rename from src/gfx/pxl8_cpu.c rename to client/src/gfx/pxl8_cpu.c index 6a3b3b4..6881c06 100644 --- a/src/gfx/pxl8_cpu.c +++ b/client/src/gfx/pxl8_cpu.c @@ -1,116 +1,18 @@ #include "pxl8_cpu.h" -#include #include #include +#include "pxl8_simd.h" + struct pxl8_cpu_render_target { u8* framebuffer; u32 height; u32 width; - u16* zbuffer; + f32* zbuffer; u32* light_accum; }; -static inline u16 depth_to_u16(f32 z) { - f32 d = (z + 1.0f) * 32767.5f; - if (d < 0.0f) d = 0.0f; - if (d > 65535.0f) d = 65535.0f; - return (u16)d; -} - -static inline f32 calc_light_intensity(const pxl8_light* light, pxl8_vec3 world_pos, pxl8_vec3 normal) { - pxl8_vec3 to_light = pxl8_vec3_sub(light->position, world_pos); - f32 dist_sq = pxl8_vec3_dot(to_light, to_light); - - if (dist_sq >= light->radius_sq) { - return 0.0f; - } - - f32 intensity_norm = light->intensity * (1.0f / 255.0f); - - if (dist_sq < 0.001f) { - return intensity_norm; - } - - f32 inv_dist = pxl8_fast_inv_sqrt(dist_sq); - pxl8_vec3 light_dir = pxl8_vec3_scale(to_light, inv_dist); - f32 n_dot_l = pxl8_vec3_dot(normal, light_dir); - - if (n_dot_l <= 0.0f) { - return 0.0f; - } - - f32 falloff = 1.0f - dist_sq * light->inv_radius_sq; - return n_dot_l * falloff * intensity_norm; -} - -typedef struct pxl8_light_result { - u8 light; - u32 light_color; -} pxl8_light_result; - -static pxl8_light_result calc_vertex_light( - pxl8_vec3 world_pos, - pxl8_vec3 normal, - const pxl8_3d_frame* frame -) { - f32 intensity = 0.25f + frame->uniforms.ambient * (1.0f / 255.0f); - - f32 accum_r = 0.0f; - f32 accum_g = 0.0f; - f32 accum_b = 0.0f; - f32 total_dynamic = 0.0f; - - f32 celestial_dot = -pxl8_vec3_dot(normal, frame->uniforms.celestial_dir); - if (celestial_dot > 0.0f) { - intensity += celestial_dot * frame->uniforms.celestial_intensity; - } - - f32 sky_factor = normal.y * 0.5f + 0.5f; - if (sky_factor < 0.0f) sky_factor = 0.0f; - intensity += sky_factor * frame->uniforms.celestial_intensity * 0.3f; - - for (u32 i = 0; i < frame->uniforms.num_lights; i++) { - const pxl8_light* light = &frame->uniforms.lights[i]; - f32 contrib = calc_light_intensity(light, world_pos, normal); - if (contrib > 0.0f) { - intensity += contrib; - total_dynamic += contrib; - - accum_r += light->r * contrib; - accum_g += light->g * contrib; - accum_b += light->b * contrib; - } - } - - u32 light_color = 0; - if (total_dynamic > 0.001f) { - f32 inv_total = 1.0f / total_dynamic; - f32 tint_strength = total_dynamic * 1.5f; - if (tint_strength > 1.0f) tint_strength = 1.0f; - - u32 r = (u32)(accum_r * inv_total); - u32 g = (u32)(accum_g * inv_total); - u32 b = (u32)(accum_b * inv_total); - u32 a = (u32)(tint_strength * 255.0f); - - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - - light_color = r | (g << 8) | (b << 16) | (a << 24); - } - - if (intensity < 0.0f) intensity = 0.0f; - if (intensity > 1.0f) intensity = 1.0f; - - return (pxl8_light_result){ - .light = (u8)(intensity * 255.0f), - .light_color = light_color, - }; -} - #define PXL8_MAX_TARGET_STACK 8 struct pxl8_cpu_backend { @@ -118,12 +20,9 @@ struct pxl8_cpu_backend { pxl8_cpu_render_target* target_stack[PXL8_MAX_TARGET_STACK]; u32 target_stack_depth; const pxl8_colormap* colormap; - const pxl8_palette_cube* palette_cube; const u32* palette; pxl8_3d_frame frame; pxl8_mat4 mvp; - u32* output; - u32 output_size; }; static inline void clip_line_2d(i32* x0, i32* y0, i32* x1, i32* y1, i32 w, i32 h, bool* visible) { @@ -191,15 +90,6 @@ pxl8_cpu_backend* pxl8_cpu_create(u32 width, u32 height) { cpu->target_stack[0] = base_target; cpu->target_stack_depth = 1; cpu->current_target = base_target; - - cpu->output_size = width * height; - cpu->output = calloc(cpu->output_size, sizeof(u32)); - if (!cpu->output) { - pxl8_cpu_destroy_render_target(base_target); - free(cpu); - return NULL; - } - return cpu; } @@ -208,7 +98,6 @@ void pxl8_cpu_destroy(pxl8_cpu_backend* cpu) { for (u32 i = 0; i < cpu->target_stack_depth; i++) { pxl8_cpu_destroy_render_target(cpu->target_stack[i]); } - free(cpu->output); free(cpu); } @@ -231,12 +120,11 @@ void pxl8_cpu_clear(pxl8_cpu_backend* cpu, u8 color) { void pxl8_cpu_clear_depth(pxl8_cpu_backend* cpu) { if (!cpu || !cpu->current_target) return; pxl8_cpu_render_target* render_target = cpu->current_target; - u32 count = render_target->width * render_target->height; if (render_target->zbuffer) { - memset(render_target->zbuffer, 0xFF, count * sizeof(u16)); + memset(render_target->zbuffer, 0x7F, render_target->width * render_target->height * sizeof(f32)); } if (render_target->light_accum) { - memset(render_target->light_accum, 0, count * sizeof(u32)); + memset(render_target->light_accum, 0, render_target->width * render_target->height * sizeof(u32)); } } @@ -244,10 +132,6 @@ void pxl8_cpu_set_colormap(pxl8_cpu_backend* cpu, const pxl8_colormap* cm) { if (cpu) cpu->colormap = cm; } -void pxl8_cpu_set_palette_cube(pxl8_cpu_backend* cpu, const pxl8_palette_cube* cube) { - if (cpu) cpu->palette_cube = cube; -} - void pxl8_cpu_set_palette(pxl8_cpu_backend* cpu, const u32* palette) { if (cpu) cpu->palette = palette; } @@ -391,44 +275,8 @@ typedef struct { f32 u, v; u8 color; u8 light; - u32 light_color; } vertex_output; -static inline u32 blend_tri_light_color(u32 lc0, u32 lc1, u32 lc2) { - u32 a0 = (lc0 >> 24) & 0xFF; - u32 a1 = (lc1 >> 24) & 0xFF; - u32 a2 = (lc2 >> 24) & 0xFF; - u32 total_a = a0 + a1 + a2; - if (total_a == 0) return 0; - - u32 r = ((lc0 & 0xFF) * a0 + (lc1 & 0xFF) * a1 + (lc2 & 0xFF) * a2) / total_a; - u32 g = (((lc0 >> 8) & 0xFF) * a0 + ((lc1 >> 8) & 0xFF) * a1 + ((lc2 >> 8) & 0xFF) * a2) / total_a; - u32 b = (((lc0 >> 16) & 0xFF) * a0 + ((lc1 >> 16) & 0xFF) * a1 + ((lc2 >> 16) & 0xFF) * a2) / total_a; - u32 a = total_a / 3; - if (a > 255) a = 255; - - return r | (g << 8) | (b << 16) | (a << 24); -} - -static inline u32 lerp_light_color(u32 a, u32 b, f32 t) { - u32 ar = a & 0xFF; - u32 ag = (a >> 8) & 0xFF; - u32 ab = (a >> 16) & 0xFF; - u32 aa = (a >> 24) & 0xFF; - - u32 br = b & 0xFF; - u32 bg = (b >> 8) & 0xFF; - u32 bb = (b >> 16) & 0xFF; - u32 ba = (b >> 24) & 0xFF; - - u32 or = ar + (u32)((i32)(br - ar) * t); - u32 og = ag + (u32)((i32)(bg - ag) * t); - u32 ob = ab + (u32)((i32)(bb - ab) * t); - u32 oa = aa + (u32)((i32)(ba - aa) * t); - - return or | (og << 8) | (ob << 16) | (oa << 24); -} - static vertex_output lerp_vertex(const vertex_output* a, const vertex_output* b, f32 t) { vertex_output out; out.clip_pos.x = a->clip_pos.x + (b->clip_pos.x - a->clip_pos.x) * t; @@ -445,7 +293,6 @@ static vertex_output lerp_vertex(const vertex_output* a, const vertex_output* b, out.v = a->v + (b->v - a->v) * t; out.color = t < 0.5f ? a->color : b->color; out.light = (u8)(a->light + (b->light - a->light) * t); - out.light_color = lerp_light_color(a->light_color, b->light_color, t); return out; } @@ -501,8 +348,6 @@ typedef struct { f32 w0_recip, w1_recip, w2_recip; f32 u0_w, v0_w, u1_w, v1_w, u2_w, v2_w; f32 l0_w, l1_w, l2_w; - u32 lc0, lc1, lc2; - f32 c0_w, c1_w, c2_w; i32 y_start, y_end, total_height; f32 inv_total; u32 target_width, target_height; @@ -574,14 +419,6 @@ static bool setup_triangle( setup->l1_w = sorted[1]->light * setup->w1_recip; setup->l2_w = sorted[2]->light * setup->w2_recip; - setup->lc0 = sorted[0]->light_color; - setup->lc1 = sorted[1]->light_color; - setup->lc2 = sorted[2]->light_color; - - setup->c0_w = (f32)sorted[0]->color * setup->w0_recip; - setup->c1_w = (f32)sorted[1]->color * setup->w1_recip; - setup->c2_w = (f32)sorted[2]->color * setup->w2_recip; - setup->inv_total = 1.0f / (f32)setup->total_height; setup->target_width = width; setup->target_height = height; @@ -595,8 +432,6 @@ static void rasterize_triangle_opaque( const pxl8_atlas* textures, u32 texture_id, bool dither ) { pxl8_cpu_render_target* render_target = cpu->current_target; - u32* light_accum = render_target->light_accum; - u32 tri_light_color = light_accum ? blend_tri_light_color(setup->lc0, setup->lc1, setup->lc2) : 0; const pxl8_atlas_entry* tex_entry = textures ? pxl8_atlas_get_entry(textures, texture_id) : NULL; u32 atlas_width = textures ? pxl8_atlas_get_width(textures) : 1; f32 tex_w = tex_entry ? (f32)tex_entry->w : 1.0f; @@ -681,7 +516,7 @@ static void rasterize_triangle_opaque( u32 row_start = (u32)y * render_target->width; u8* prow = render_target->framebuffer + row_start; - u16* zrow = render_target->zbuffer + row_start; + f32* zrow = render_target->zbuffer + row_start; const i32 SUBDIV = 32; i32 x = x_start; @@ -701,22 +536,6 @@ static void rasterize_triangle_opaque( f32 v_end = (vw + dvw * steps) * pw_end; f32 l_start = lw * pw_start; f32 l_end = (lw + d_lw * steps) * pw_end; - - f32 fog_density = cpu->frame.uniforms.fog_density; - if (fog_density > 0.0f) { - f32 z_end_fog = z + dz * steps; - f32 t_start = (z + 1.0f) * 0.5f; - f32 t_end = (z_end_fog + 1.0f) * 0.5f; - if (t_start < 0.0f) t_start = 0.0f; - if (t_end < 0.0f) t_end = 0.0f; - f32 fog_start = t_start * t_start * fog_density; - f32 fog_end = t_end * t_end * fog_density; - if (fog_start > 1.0f) fog_start = 1.0f; - if (fog_end > 1.0f) fog_end = 1.0f; - l_start *= (1.0f - fog_start); - l_end *= (1.0f - fog_end); - } - if (l_start > 255.0f) l_start = 255.0f; if (l_end > 255.0f) l_end = 255.0f; @@ -734,8 +553,7 @@ static void rasterize_triangle_opaque( f32 z_a = z; for (i32 px = x; px <= span_end; px++) { - u16 z16 = depth_to_u16(z_a); - if (z16 < zrow[px]) { + if (z_a <= zrow[px]) { i32 tx = (u_fixed >> 16) & tex_mask_w; i32 ty = (v_fixed >> 16) & tex_mask_h; u8 tex_idx = tex_pixels ? tex_pixels[tex_base + (u32)ty * (u32)tex_stride + (u32)tx] : 1; @@ -745,12 +563,9 @@ static void rasterize_triangle_opaque( if (dither) { light = pxl8_dither_light(light, (u32)px, (u32)y); } - u8 pal_idx = cpu->colormap ? pxl8_colormap_lookup(cpu->colormap, tex_idx, PXL8_LIGHT_WHITE, light) : tex_idx; + u8 pal_idx = cpu->colormap ? pxl8_colormap_lookup(cpu->colormap, tex_idx, light) : tex_idx; prow[px] = pal_idx; - zrow[px] = z16; - if (light_accum) { - light_accum[row_start + (u32)px] = tri_light_color; - } + zrow[px] = z_a; } } @@ -772,9 +587,11 @@ static void rasterize_triangle_opaque( static void rasterize_triangle_passthrough( pxl8_cpu_backend* cpu, - const tri_setup* setup + const tri_setup* setup, + const vertex_output* vo0 ) { pxl8_cpu_render_target* render_target = cpu->current_target; + u8 color = vo0->color; for (i32 y = setup->y_start; y <= setup->y_end; y++) { bool second_half = y > setup->y1 || setup->y1 == setup->y0; @@ -786,33 +603,20 @@ static void rasterize_triangle_passthrough( f32 ax = (f32)setup->x0 + (f32)(setup->x2 - setup->x0) * alpha; f32 az = setup->z0 + (setup->z2 - setup->z0) * alpha; - f32 a_wr = setup->w0_recip + (setup->w2_recip - setup->w0_recip) * alpha; - f32 a_cw = setup->c0_w + (setup->c2_w - setup->c0_w) * alpha; - - f32 bx, bz, b_wr, b_cw; + f32 bx, bz; if (second_half) { bx = (f32)setup->x1 + (f32)(setup->x2 - setup->x1) * beta; bz = setup->z1 + (setup->z2 - setup->z1) * beta; - b_wr = setup->w1_recip + (setup->w2_recip - setup->w1_recip) * beta; - b_cw = setup->c1_w + (setup->c2_w - setup->c1_w) * beta; } else { bx = (f32)setup->x0 + (f32)(setup->x1 - setup->x0) * beta; bz = setup->z0 + (setup->z1 - setup->z0) * beta; - b_wr = setup->w0_recip + (setup->w1_recip - setup->w0_recip) * beta; - b_cw = setup->c0_w + (setup->c1_w - setup->c0_w) * beta; } - f32 x_start_f, x_end_f, z_start, z_end, wr_start, wr_end, cw_start, cw_end; + f32 x_start_f, x_end_f, z_start, z_end; if (ax <= bx) { - x_start_f = ax; x_end_f = bx; - z_start = az; z_end = bz; - wr_start = a_wr; wr_end = b_wr; - cw_start = a_cw; cw_end = b_cw; + x_start_f = ax; x_end_f = bx; z_start = az; z_end = bz; } else { - x_start_f = bx; x_end_f = ax; - z_start = bz; z_end = az; - wr_start = b_wr; wr_end = a_wr; - cw_start = b_cw; cw_end = a_cw; + x_start_f = bx; x_end_f = ax; z_start = bz; z_end = az; } i32 x_start_orig = (i32)(x_start_f + 0.5f); @@ -826,30 +630,19 @@ static void rasterize_triangle_passthrough( f32 inv_width = 1.0f / (f32)width_orig; f32 dz = (z_end - z_start) * inv_width; - f32 dwr = (wr_end - wr_start) * inv_width; - f32 dcw = (cw_end - cw_start) * inv_width; - f32 skip = (f32)(x_start - x_start_orig); f32 z = z_start + dz * skip; - f32 wr = wr_start + dwr * skip; - f32 cw = cw_start + dcw * skip; u32 row_start = (u32)y * render_target->width; u8* prow = render_target->framebuffer + row_start; - u16* zrow = render_target->zbuffer + row_start; + f32* zrow = render_target->zbuffer + row_start; for (i32 px = x_start; px <= x_end; px++) { - u16 z16 = depth_to_u16(z); - if (z16 < zrow[px]) { - f32 w = 1.0f / wr; - f32 color_f = cw * w; - u8 color = pxl8_dither_float(color_f, (u32)px, (u32)y); + if (z <= zrow[px]) { prow[px] = color; - zrow[px] = z16; + zrow[px] = z; } z += dz; - wr += dwr; - cw += dcw; } } } @@ -860,8 +653,6 @@ static void rasterize_triangle_alpha( const pxl8_atlas* textures, u32 texture_id, u8 mat_alpha, bool dither ) { pxl8_cpu_render_target* render_target = cpu->current_target; - u32* light_accum = render_target->light_accum; - u32 tri_light_color = light_accum ? blend_tri_light_color(setup->lc0, setup->lc1, setup->lc2) : 0; const pxl8_atlas_entry* tex_entry = textures ? pxl8_atlas_get_entry(textures, texture_id) : NULL; u32 atlas_width = textures ? pxl8_atlas_get_width(textures) : 1; f32 tex_w = tex_entry ? (f32)tex_entry->w : 1.0f; @@ -946,7 +737,7 @@ static void rasterize_triangle_alpha( u32 row_start = (u32)y * render_target->width; u8* prow = render_target->framebuffer + row_start; - u16* zrow = render_target->zbuffer + row_start; + f32* zrow = render_target->zbuffer + row_start; const i32 SUBDIV = 32; i32 x = x_start; @@ -966,22 +757,6 @@ static void rasterize_triangle_alpha( f32 v_end = (vw + dvw * steps) * pw_end; f32 l_start = lw * pw_start; f32 l_end = (lw + d_lw * steps) * pw_end; - - f32 fog_density = cpu->frame.uniforms.fog_density; - if (fog_density > 0.0f) { - f32 z_end_fog = z + dz * steps; - f32 t_start = (z + 1.0f) * 0.5f; - f32 t_end = (z_end_fog + 1.0f) * 0.5f; - if (t_start < 0.0f) t_start = 0.0f; - if (t_end < 0.0f) t_end = 0.0f; - f32 fog_start = t_start * t_start * fog_density; - f32 fog_end = t_end * t_end * fog_density; - if (fog_start > 1.0f) fog_start = 1.0f; - if (fog_end > 1.0f) fog_end = 1.0f; - l_start *= (1.0f - fog_start); - l_end *= (1.0f - fog_end); - } - if (l_start > 255.0f) l_start = 255.0f; if (l_end > 255.0f) l_end = 255.0f; @@ -1008,15 +783,11 @@ static void rasterize_triangle_alpha( if (dither) { light = pxl8_dither_light(light, (u32)px, (u32)y); } - u8 src_idx = cpu->colormap ? pxl8_colormap_lookup(cpu->colormap, tex_idx, PXL8_LIGHT_WHITE, light) : tex_idx; + u8 src_idx = cpu->colormap ? pxl8_colormap_lookup(cpu->colormap, tex_idx, light) : tex_idx; if (mat_alpha >= 128) { prow[px] = src_idx; - u16 z16 = depth_to_u16(z_a); - if (z16 < zrow[px]) zrow[px] = z16; - if (light_accum) { - light_accum[row_start + (u32)px] = tri_light_color; - } + if (z_a <= zrow[px]) zrow[px] = z_a; } } @@ -1036,43 +807,11 @@ static void rasterize_triangle_alpha( } } -static void rasterize_triangle_wireframe( - pxl8_cpu_backend* cpu, - const vertex_output* vo0, const vertex_output* vo1, const vertex_output* vo2, - u8 color, bool double_sided -) { - pxl8_cpu_render_target* render_target = cpu->current_target; - f32 hw = (f32)render_target->width * 0.5f; - f32 hh = (f32)render_target->height * 0.5f; - - i32 x0 = (i32)(hw + vo0->clip_pos.x / vo0->clip_pos.w * hw); - i32 y0 = (i32)(hh - vo0->clip_pos.y / vo0->clip_pos.w * hh); - i32 x1 = (i32)(hw + vo1->clip_pos.x / vo1->clip_pos.w * hw); - i32 y1 = (i32)(hh - vo1->clip_pos.y / vo1->clip_pos.w * hh); - i32 x2 = (i32)(hw + vo2->clip_pos.x / vo2->clip_pos.w * hw); - i32 y2 = (i32)(hh - vo2->clip_pos.y / vo2->clip_pos.w * hh); - - if (!double_sided) { - i32 cross = (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0); - if (cross >= 0) return; - } - - pxl8_cpu_draw_line_2d(cpu, x0, y0, x1, y1, color); - pxl8_cpu_draw_line_2d(cpu, x1, y1, x2, y2, color); - pxl8_cpu_draw_line_2d(cpu, x2, y2, x0, y0, color); -} - static void dispatch_triangle( pxl8_cpu_backend* cpu, const vertex_output* vo0, const vertex_output* vo1, const vertex_output* vo2, - const pxl8_atlas* textures, const pxl8_gfx_material* material + const pxl8_atlas* textures, const pxl8_material* material ) { - if (material->wireframe) { - u8 color = (material->texture_id > 0) ? (u8)material->texture_id : 15; - rasterize_triangle_wireframe(cpu, vo0, vo1, vo2, color, material->double_sided); - return; - } - pxl8_cpu_render_target* render_target = cpu->current_target; tri_setup setup; if (!setup_triangle(&setup, vo0, vo1, vo2, render_target->width, render_target->height, material->double_sided)) { @@ -1085,7 +824,7 @@ static void dispatch_triangle( if (alpha_blend) { rasterize_triangle_alpha(cpu, &setup, textures, material->texture_id, material->alpha, material->dither); } else if (passthrough) { - rasterize_triangle_passthrough(cpu, &setup); + rasterize_triangle_passthrough(cpu, &setup, vo0); } else { rasterize_triangle_opaque(cpu, &setup, textures, material->texture_id, material->dither); } @@ -1094,13 +833,13 @@ static void dispatch_triangle( void pxl8_cpu_draw_mesh( pxl8_cpu_backend* cpu, const pxl8_mesh* mesh, - const pxl8_mat4* model, - const pxl8_gfx_material* material, + pxl8_mat4 model, + pxl8_material material, const pxl8_atlas* textures ) { - if (!cpu || !mesh || !model || !material || mesh->index_count < 3 || !cpu->current_target) return; + if (!cpu || !mesh || mesh->index_count < 3 || !cpu->current_target) return; - pxl8_mat4 mv = pxl8_mat4_mul(cpu->frame.view, *model); + pxl8_mat4 mv = pxl8_mat4_mul(cpu->frame.view, model); pxl8_mat4 mvp = pxl8_mat4_mul(cpu->frame.projection, mv); f32 near = cpu->frame.near_clip > 0.0f ? cpu->frame.near_clip : 0.1f; @@ -1124,9 +863,9 @@ void pxl8_cpu_draw_mesh( vo1.clip_pos = pxl8_mat4_mul_vec4(mvp, p1); vo2.clip_pos = pxl8_mat4_mul_vec4(mvp, p2); - pxl8_vec4 w0 = pxl8_mat4_mul_vec4(*model, p0); - pxl8_vec4 w1 = pxl8_mat4_mul_vec4(*model, p1); - pxl8_vec4 w2 = pxl8_mat4_mul_vec4(*model, p2); + pxl8_vec4 w0 = pxl8_mat4_mul_vec4(model, p0); + pxl8_vec4 w1 = pxl8_mat4_mul_vec4(model, p1); + pxl8_vec4 w2 = pxl8_mat4_mul_vec4(model, p2); vo0.world_pos = (pxl8_vec3){w0.x, w0.y, w0.z}; vo1.world_pos = (pxl8_vec3){w1.x, w1.y, w1.z}; vo2.world_pos = (pxl8_vec3){w2.x, w2.y, w2.z}; @@ -1143,36 +882,15 @@ void pxl8_cpu_draw_mesh( vo1.color = v1->color; vo2.color = v2->color; - if (material->dynamic_lighting) { - pxl8_vec3 n0 = pxl8_vec3_normalize(pxl8_mat4_mul_vec3(*model, v0->normal)); - pxl8_vec3 n1 = pxl8_vec3_normalize(pxl8_mat4_mul_vec3(*model, v1->normal)); - pxl8_vec3 n2 = pxl8_vec3_normalize(pxl8_mat4_mul_vec3(*model, v2->normal)); - - pxl8_light_result lr0 = calc_vertex_light(vo0.world_pos, n0, &cpu->frame); - pxl8_light_result lr1 = calc_vertex_light(vo1.world_pos, n1, &cpu->frame); - pxl8_light_result lr2 = calc_vertex_light(vo2.world_pos, n2, &cpu->frame); - - vo0.light = lr0.light; - vo1.light = lr1.light; - vo2.light = lr2.light; - - vo0.light_color = lr0.light_color; - vo1.light_color = lr1.light_color; - vo2.light_color = lr2.light_color; - } else { - vo0.light = 255; - vo1.light = 255; - vo2.light = 255; - vo0.light_color = 0; - vo1.light_color = 0; - vo2.light_color = 0; - } + vo0.light = material.dynamic_lighting ? v0->light : 255; + vo1.light = material.dynamic_lighting ? v1->light : 255; + vo2.light = material.dynamic_lighting ? v2->light : 255; vertex_output clipped[6]; i32 clipped_count = clip_triangle_near(&vo0, &vo1, &vo2, near, clipped); for (i32 t = 0; t < clipped_count; t += 3) { - dispatch_triangle(cpu, &clipped[t], &clipped[t+1], &clipped[t+2], textures, material); + dispatch_triangle(cpu, &clipped[t], &clipped[t+1], &clipped[t+2], textures, &material); } } } @@ -1246,7 +964,7 @@ pxl8_cpu_render_target* pxl8_cpu_create_render_target(const pxl8_cpu_render_targ } if (desc->with_depth) { - target->zbuffer = calloc(size, sizeof(u16)); + target->zbuffer = calloc(size, sizeof(f32)); if (!target->zbuffer) { free(target->framebuffer); free(target); @@ -1303,12 +1021,10 @@ void pxl8_cpu_blit(pxl8_cpu_backend* cpu, pxl8_cpu_render_target* src, i32 x, i3 for (i32 row = 0; row < copy_h; row++) { u8* src_row = src->framebuffer + (src_y0 + row) * src->width + src_x0; u8* dst_row = dst->framebuffer + (dst_y0 + row) * dst->width + dst_x0; - u32* light_row = dst->light_accum ? dst->light_accum + (dst_y0 + row) * dst->width + dst_x0 : NULL; for (i32 col = 0; col < copy_w; col++) { u8 pixel = src_row[col]; if (pixel != transparent_idx) { dst_row[col] = pixel; - if (light_row) light_row[col] = 0; } } } @@ -1357,194 +1073,3 @@ u32 pxl8_cpu_render_target_get_height(const pxl8_cpu_render_target* target) { u32 pxl8_cpu_render_target_get_width(const pxl8_cpu_render_target* target) { return target ? target->width : 0; } - -u32* pxl8_cpu_render_target_get_light_accum(pxl8_cpu_render_target* target) { - return target ? target->light_accum : NULL; -} - -u32* pxl8_cpu_get_output(pxl8_cpu_backend* cpu) { - return cpu ? cpu->output : NULL; -} - -void pxl8_cpu_render_glows( - pxl8_cpu_backend* cpu, - const pxl8_glow_source* glows, - u32 glow_count -) { - if (!cpu || cpu->target_stack_depth == 0) return; - - pxl8_cpu_render_target* target = cpu->target_stack[cpu->target_stack_depth - 1]; - if (!target || !target->framebuffer) return; - - u32 width = target->width; - u32 height = target->height; - u8* pixels = target->framebuffer; - u16* zbuffer = target->zbuffer; - u32* light_accum = target->light_accum; - - for (u32 gi = 0; gi < glow_count; gi++) { - const pxl8_glow_source* glow = &glows[gi]; - i32 cx = glow->x; - i32 cy = glow->y; - i32 radius = glow->radius; - - if (radius <= 0 || glow->intensity == 0) continue; - - i32 x0 = cx - radius; - i32 y0 = cy - radius; - i32 x1 = cx + radius; - i32 y1 = cy + radius; - - if (x0 < 0) x0 = 0; - if (y0 < 0) y0 = 0; - if (x1 >= (i32)width) x1 = (i32)width - 1; - if (y1 >= (i32)height) y1 = (i32)height - 1; - - if (x0 >= x1 || y0 >= y1) continue; - - u16 glow_depth = glow->depth; - u8 base_color = glow->color; - f32 base_intensity = glow->intensity / 255.0f; - f32 radius_f = (f32)radius; - f32 radius_sq = radius_f * radius_f; - f32 inv_radius_sq = 1.0f / radius_sq; - f32 inv_radius = 1.0f / radius_f; - - for (i32 y = y0; y <= y1; y++) { - u32 row = (u32)y * width; - f32 dy = (f32)(y - cy); - - for (i32 x = x0; x <= x1; x++) { - u32 idx = row + (u32)x; - - if (zbuffer && glow_depth > zbuffer[idx]) continue; - - f32 dx = (f32)(x - cx); - f32 intensity = 0.0f; - - switch (glow->shape) { - case PXL8_GLOW_CIRCLE: { - f32 dist_sq = dx * dx + dy * dy; - if (dist_sq >= radius_sq) continue; - f32 falloff = 1.0f - dist_sq * inv_radius_sq; - intensity = base_intensity * falloff * falloff; - break; - } - case PXL8_GLOW_DIAMOND: { - f32 abs_dx = dx < 0 ? -dx : dx; - f32 abs_dy = dy < 0 ? -dy : dy; - f32 manhattan = abs_dx + abs_dy; - if (manhattan >= radius_f) continue; - f32 falloff = 1.0f - manhattan * inv_radius; - intensity = base_intensity * falloff * falloff; - break; - } - case PXL8_GLOW_SHAFT: { - f32 abs_dx = dx < 0 ? -dx : dx; - f32 abs_dy = dy < 0 ? -dy : dy; - f32 height_f = glow->height > 0 ? (f32)glow->height : radius_f; - if (abs_dx >= radius_f || abs_dy >= height_f) continue; - f32 falloff_x = 1.0f - abs_dx * inv_radius; - f32 falloff_y = 1.0f - abs_dy / height_f; - intensity = base_intensity * falloff_x * falloff_x * falloff_y; - break; - } - } - - if (intensity < 0.02f) continue; - - u8 int_val = intensity < 1.0f ? (u8)(intensity * 255.0f) : 255; - u8 light_level = pxl8_ordered_dither(int_val, (u32)x, (u32)y); - - if (light_level < 8) continue; - - u8 shaded = pxl8_colormap_lookup(cpu->colormap, base_color, PXL8_LIGHT_WHITE, light_level); - - if (cpu->palette_cube) { - u8 sr, sg, sb, dr, dg, db; - pxl8_palette_cube_get_rgb(cpu->palette_cube, shaded, &sr, &sg, &sb); - pxl8_palette_cube_get_rgb(cpu->palette_cube, pixels[idx], &dr, &dg, &db); - u32 r = (u32)sr + (u32)dr; - u32 g = (u32)sg + (u32)dg; - u32 b = (u32)sb + (u32)db; - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - pixels[idx] = pxl8_palette_cube_lookup(cpu->palette_cube, (u8)r, (u8)g, (u8)b); - } else { - pixels[idx] = shaded; - } - - if (light_accum) { - light_accum[idx] = 0; - } - } - } - } -} - -void pxl8_cpu_resolve(pxl8_cpu_backend* cpu) { - if (!cpu || !cpu->palette || cpu->target_stack_depth == 0) return; - - pxl8_cpu_render_target* target = cpu->target_stack[0]; - if (!target || !target->framebuffer) return; - - u32 pixel_count = target->width * target->height; - const u8* pixels = target->framebuffer; - const u32* light_accum = target->light_accum; - const u32* palette = cpu->palette; - u32* output = cpu->output; - - for (u32 i = 0; i < pixel_count; i++) { - u32 base = palette[pixels[i]]; - - if (light_accum && light_accum[i] != 0) { - u32 light_color = light_accum[i]; - u32 tint_alpha = (light_color >> 24) & 0xFF; - - if (tint_alpha > 0) { - u32 lr = light_color & 0xFF; - u32 lg = (light_color >> 8) & 0xFF; - u32 lb = (light_color >> 16) & 0xFF; - - u32 br = base & 0xFF; - u32 bg = (base >> 8) & 0xFF; - u32 bb = (base >> 16) & 0xFF; - u32 ba = (base >> 24) & 0xFF; - - u32 t = (tint_alpha * tint_alpha) / 255; - u32 inv_t = 255 - t; - - u32 lr_norm = (lr * 255) / 240; - u32 lg_norm = (lg * 255) / 240; - u32 lb_norm = (lb * 255) / 220; - - u32 or = ((br * inv_t + (br * lr_norm / 255) * t) / 255); - u32 og = ((bg * inv_t + (bg * lg_norm / 255) * t) / 255); - u32 ob = ((bb * inv_t + (bb * lb_norm / 255) * t) / 255); - - if (or > 255) or = 255; - if (og > 255) og = 255; - if (ob > 255) ob = 255; - - output[i] = or | (og << 8) | (ob << 16) | (ba << 24); - continue; - } - } - - output[i] = base; - } - - for (u32 t = 1; t < cpu->target_stack_depth; t++) { - pxl8_cpu_render_target* overlay = cpu->target_stack[t]; - if (!overlay || !overlay->framebuffer) continue; - - const u8* overlay_pixels = overlay->framebuffer; - for (u32 i = 0; i < pixel_count; i++) { - u8 idx = overlay_pixels[i]; - if (idx != 0) { - output[i] = palette[idx]; - } - } - } -} diff --git a/src/gfx/pxl8_cpu.h b/client/src/gfx/pxl8_cpu.h similarity index 80% rename from src/gfx/pxl8_cpu.h rename to client/src/gfx/pxl8_cpu.h index 319253c..35f99a0 100644 --- a/src/gfx/pxl8_cpu.h +++ b/client/src/gfx/pxl8_cpu.h @@ -2,12 +2,8 @@ #include "pxl8_atlas.h" #include "pxl8_colormap.h" -#include "pxl8_gfx.h" -#include "pxl8_gfx3d.h" -#include "pxl8_lightmap.h" #include "pxl8_math.h" #include "pxl8_mesh.h" -#include "pxl8_palette.h" #include "pxl8_types.h" #ifdef __cplusplus @@ -24,6 +20,19 @@ typedef struct pxl8_cpu_render_target_desc { bool with_lighting; } pxl8_cpu_render_target_desc; +typedef struct pxl8_3d_frame { + u8 ambient_light; + pxl8_vec3 camera_dir; + pxl8_vec3 camera_pos; + f32 far_clip; + u8 fog_color; + f32 fog_density; + f32 near_clip; + pxl8_mat4 projection; + f32 time; + pxl8_mat4 view; +} pxl8_3d_frame; + pxl8_cpu_backend* pxl8_cpu_create(u32 width, u32 height); void pxl8_cpu_destroy(pxl8_cpu_backend* cpu); @@ -35,10 +44,6 @@ void pxl8_cpu_clear_depth(pxl8_cpu_backend* cpu); void pxl8_cpu_set_colormap(pxl8_cpu_backend* cpu, const pxl8_colormap* cm); void pxl8_cpu_set_palette(pxl8_cpu_backend* cpu, const u32* palette); -void pxl8_cpu_set_palette_cube(pxl8_cpu_backend* cpu, const pxl8_palette_cube* cube); - -u32 pxl8_cpu_add_lightmap(pxl8_cpu_backend* cpu, pxl8_lightmap* lm); -pxl8_lightmap* pxl8_cpu_get_lightmap(pxl8_cpu_backend* cpu, u32 id); void pxl8_cpu_draw_pixel(pxl8_cpu_backend* cpu, i32 x, i32 y, u8 color); u8 pxl8_cpu_get_pixel(pxl8_cpu_backend* cpu, i32 x, i32 y); @@ -52,8 +57,8 @@ void pxl8_cpu_draw_line_3d(pxl8_cpu_backend* cpu, pxl8_vec3 v0, pxl8_vec3 v1, u8 void pxl8_cpu_draw_mesh( pxl8_cpu_backend* cpu, const pxl8_mesh* mesh, - const pxl8_mat4* model, - const pxl8_gfx_material* material, + pxl8_mat4 model, + pxl8_material material, const pxl8_atlas* textures ); @@ -65,18 +70,9 @@ void pxl8_cpu_draw_mesh_wireframe( ); u8* pxl8_cpu_get_framebuffer(pxl8_cpu_backend* cpu); -u32* pxl8_cpu_get_output(pxl8_cpu_backend* cpu); u32 pxl8_cpu_get_height(const pxl8_cpu_backend* cpu); u32 pxl8_cpu_get_width(const pxl8_cpu_backend* cpu); -void pxl8_cpu_render_glows( - pxl8_cpu_backend* cpu, - const pxl8_glow_source* glows, - u32 glow_count -); - -void pxl8_cpu_resolve(pxl8_cpu_backend* cpu); - pxl8_cpu_render_target* pxl8_cpu_create_render_target(const pxl8_cpu_render_target_desc* desc); void pxl8_cpu_destroy_render_target(pxl8_cpu_render_target* target); @@ -92,7 +88,6 @@ u32 pxl8_cpu_get_target_depth(const pxl8_cpu_backend* cpu); u8* pxl8_cpu_render_target_get_framebuffer(pxl8_cpu_render_target* target); u32 pxl8_cpu_render_target_get_height(const pxl8_cpu_render_target* target); u32 pxl8_cpu_render_target_get_width(const pxl8_cpu_render_target* target); -u32* pxl8_cpu_render_target_get_light_accum(pxl8_cpu_render_target* target); #ifdef __cplusplus } diff --git a/src/gfx/pxl8_dither.c b/client/src/gfx/pxl8_dither.c similarity index 100% rename from src/gfx/pxl8_dither.c rename to client/src/gfx/pxl8_dither.c diff --git a/src/gfx/pxl8_dither.h b/client/src/gfx/pxl8_dither.h similarity index 100% rename from src/gfx/pxl8_dither.h rename to client/src/gfx/pxl8_dither.h diff --git a/src/gfx/pxl8_font.c b/client/src/gfx/pxl8_font.c similarity index 100% rename from src/gfx/pxl8_font.c rename to client/src/gfx/pxl8_font.c diff --git a/src/gfx/pxl8_font.h b/client/src/gfx/pxl8_font.h similarity index 100% rename from src/gfx/pxl8_font.h rename to client/src/gfx/pxl8_font.h diff --git a/src/gfx/pxl8_gfx.c b/client/src/gfx/pxl8_gfx.c similarity index 79% rename from src/gfx/pxl8_gfx.c rename to client/src/gfx/pxl8_gfx.c index b4f3202..565280b 100644 --- a/src/gfx/pxl8_gfx.c +++ b/client/src/gfx/pxl8_gfx.c @@ -34,7 +34,6 @@ struct pxl8_gfx { const pxl8_hal* hal; bool initialized; pxl8_palette* palette; - pxl8_palette_cube* palette_cube; pxl8_pixel_mode pixel_mode; void* platform_data; pxl8_sprite_cache_entry* sprite_cache; @@ -75,14 +74,10 @@ i32 pxl8_gfx_get_width(const pxl8_gfx* gfx) { return gfx ? gfx->framebuffer_width : 0; } -pxl8_palette* pxl8_gfx_palette(pxl8_gfx* gfx) { +pxl8_palette* pxl8_gfx_get_palette(pxl8_gfx* gfx) { return gfx ? gfx->palette : NULL; } -pxl8_colormap* pxl8_gfx_colormap(pxl8_gfx* gfx) { - return gfx ? gfx->colormap : NULL; -} - u8 pxl8_gfx_find_color(pxl8_gfx* gfx, u32 color) { if (!gfx || !gfx->palette) return 0; if (color <= 0xFFFFFF) color = (color << 8) | 0xFF; @@ -92,24 +87,37 @@ u8 pxl8_gfx_find_color(pxl8_gfx* gfx, u32 color) { return pxl8_palette_find_closest(gfx->palette, r, g, b); } -void pxl8_gfx_set_palette_colors(pxl8_gfx* gfx, const u32* colors, u16 count) { - if (!gfx || !gfx->palette || !colors) return; - pxl8_set_palette(gfx->palette, colors, count); - if (gfx->pixel_mode != PXL8_PIXEL_HICOLOR && gfx->backend.type == PXL8_GFX_BACKEND_CPU) { - pxl8_cpu_set_palette(gfx->backend.cpu, pxl8_palette_colors(gfx->palette)); +void pxl8_gfx_set_palette(pxl8_gfx* gfx, pxl8_palette* pal) { + if (!gfx) return; + if (gfx->palette) { + pxl8_palette_destroy(gfx->palette); + } + gfx->palette = pal; + + if (gfx->palette && gfx->pixel_mode != PXL8_PIXEL_HICOLOR) { + u32* colors = pxl8_palette_colors(gfx->palette); + if (gfx->colormap) { + pxl8_colormap_generate(gfx->colormap, colors, NULL); + } + if (gfx->backend.type == PXL8_GFX_BACKEND_CPU) { + pxl8_cpu_set_palette(gfx->backend.cpu, colors); + } } } 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 (!gfx || !filepath) return -1; + pxl8_palette* pal = gfx->palette; + if (!pal) return -1; + pxl8_result result = pxl8_palette_load_ase(pal, filepath); if (result != PXL8_OK) return (i32)result; if (gfx->pixel_mode != PXL8_PIXEL_HICOLOR) { + u32* colors = pxl8_palette_colors(pal); if (gfx->colormap) { - pxl8_colormap_generate(gfx->colormap, pxl8_palette_colors(gfx->palette)); + pxl8_colormap_generate(gfx->colormap, colors, NULL); } if (gfx->backend.type == PXL8_GFX_BACKEND_CPU) { - pxl8_cpu_set_palette(gfx->backend.cpu, pxl8_palette_colors(gfx->palette)); + pxl8_cpu_set_palette(gfx->backend.cpu, colors); } } return 0; @@ -180,7 +188,6 @@ void pxl8_gfx_destroy(pxl8_gfx* gfx) { pxl8_cpu_destroy(gfx->backend.cpu); } free(gfx->colormap); - pxl8_palette_cube_destroy(gfx->palette_cube); pxl8_palette_destroy(gfx->palette); free(gfx->sprite_cache); @@ -302,30 +309,15 @@ 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->backend.type == PXL8_GFX_BACKEND_CPU && gfx->pixel_mode == PXL8_PIXEL_INDEXED) { - pxl8_cpu_resolve(gfx->backend.cpu); - u32* output = pxl8_cpu_get_output(gfx->backend.cpu); - if (output) { - gfx->hal->upload_texture( - gfx->platform_data, - output, - gfx->framebuffer_width, - gfx->framebuffer_height, - PXL8_PIXEL_RGBA, - NULL - ); - return; - } - } - + u32 bpp = (gfx->pixel_mode == PXL8_PIXEL_HICOLOR) ? 2 : 1; u32* colors = gfx->palette ? pxl8_palette_colors(gfx->palette) : NULL; gfx->hal->upload_texture( gfx->platform_data, gfx->framebuffer, gfx->framebuffer_width, gfx->framebuffer_height, - gfx->pixel_mode, - colors + colors, + bpp ); } @@ -446,7 +438,6 @@ void pxl8_2d_text(pxl8_gfx* gfx, const char* text, i32 x, i32 y, u32 color) { if (!gfx || !text) return; u8* framebuffer = NULL; - u32* light_accum = NULL; i32 fb_width = 0; i32 fb_height = 0; @@ -455,7 +446,6 @@ void pxl8_2d_text(pxl8_gfx* gfx, const char* text, i32 x, i32 y, u32 color) { pxl8_cpu_render_target* render_target = pxl8_cpu_get_target(gfx->backend.cpu); if (!render_target) return; framebuffer = pxl8_cpu_render_target_get_framebuffer(render_target); - light_accum = pxl8_cpu_render_target_get_light_accum(render_target); fb_width = (i32)pxl8_cpu_render_target_get_width(render_target); fb_height = (i32)pxl8_cpu_render_target_get_height(render_target); break; @@ -493,9 +483,7 @@ void pxl8_2d_text(pxl8_gfx* gfx, const char* text, i32 x, i32 y, u32 color) { } if (pixel_bit) { - i32 idx = py * fb_width + px; - framebuffer[idx] = (u8)color; - if (light_accum) light_accum[idx] = 0; + framebuffer[py * fb_width + px] = (u8)color; } } } @@ -509,7 +497,6 @@ void pxl8_2d_sprite(pxl8_gfx* gfx, u32 sprite_id, i32 x, i32 y, i32 w, i32 h, bo if (!gfx || !gfx->atlas) return; u8* framebuffer = NULL; - u32* light_accum = NULL; i32 fb_width = 0; i32 fb_height = 0; @@ -518,7 +505,6 @@ void pxl8_2d_sprite(pxl8_gfx* gfx, u32 sprite_id, i32 x, i32 y, i32 w, i32 h, bo pxl8_cpu_render_target* render_target = pxl8_cpu_get_target(gfx->backend.cpu); if (!render_target) return; framebuffer = pxl8_cpu_render_target_get_framebuffer(render_target); - light_accum = pxl8_cpu_render_target_get_light_accum(render_target); fb_width = (i32)pxl8_cpu_render_target_get_width(render_target); fb_height = (i32)pxl8_cpu_render_target_get_height(render_target); break; @@ -555,11 +541,6 @@ 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); - if (light_accum) { - for (i32 py = 0; py < h; py++) { - memset(light_accum + (y + py) * fb_width + x, 0, w * sizeof(u32)); - } - } } else { for (i32 py = 0; py < draw_height; py++) { for (i32 px = 0; px < draw_width; px++) { @@ -573,7 +554,6 @@ void pxl8_2d_sprite(pxl8_gfx* gfx, u32 sprite_id, i32 x, i32 y, i32 w, i32 h, bo i32 dest_idx = (dest_y + py) * fb_width + (dest_x + px); framebuffer[dest_idx] = pxl8_blend_indexed(atlas_pixels[src_idx], framebuffer[dest_idx]); - if (light_accum) light_accum[dest_idx] = 0; } } } @@ -588,32 +568,30 @@ void pxl8_gfx_update(pxl8_gfx* gfx, f32 dt) { } } -pxl8_3d_frame pxl8_3d_frame_from_camera(const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms) { - pxl8_3d_frame frame = {0}; - if (!camera) return frame; - - frame.view = pxl8_3d_camera_get_view(camera); - frame.projection = pxl8_3d_camera_get_projection(camera); - frame.camera_pos = pxl8_3d_camera_get_position(camera); - frame.camera_dir = pxl8_3d_camera_get_forward(camera); - frame.near_clip = 1.0f; - frame.far_clip = 4096.0f; - - if (uniforms) { - frame.uniforms = *uniforms; - } - - return frame; -} - void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms) { if (!gfx || !camera) return; - pxl8_3d_frame frame = pxl8_3d_frame_from_camera(camera, uniforms); + pxl8_mat4 view = pxl8_3d_camera_get_view(camera); + pxl8_mat4 projection = pxl8_3d_camera_get_projection(camera); + pxl8_vec3 position = pxl8_3d_camera_get_position(camera); + pxl8_vec3 forward = pxl8_3d_camera_get_forward(camera); - pxl8_mat4 vp = pxl8_mat4_mul(frame.projection, frame.view); + pxl8_mat4 vp = pxl8_mat4_mul(projection, view); gfx->frustum = pxl8_frustum_from_matrix(vp); + pxl8_3d_frame frame = { + .ambient_light = uniforms ? uniforms->ambient : 0, + .camera_dir = forward, + .camera_pos = position, + .far_clip = 4096.0f, + .fog_color = uniforms ? uniforms->fog_color : 0, + .fog_density = uniforms ? uniforms->fog_density : 0.0f, + .near_clip = 1.0f, + .projection = projection, + .time = uniforms ? uniforms->time : 0.0f, + .view = view, + }; + switch (gfx->backend.type) { case PXL8_GFX_BACKEND_CPU: pxl8_cpu_begin_frame(gfx->backend.cpu, &frame); @@ -661,8 +639,8 @@ void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color) { } } -void pxl8_3d_draw_mesh(pxl8_gfx* gfx, const pxl8_mesh* mesh, const pxl8_mat4* model, const pxl8_gfx_material* material) { - if (!gfx || !mesh || !model || !material) return; +void pxl8_3d_draw_mesh(pxl8_gfx* gfx, const pxl8_mesh* mesh, pxl8_mat4 model, pxl8_material material) { + if (!gfx || !mesh) return; switch (gfx->backend.type) { case PXL8_GFX_BACKEND_CPU: pxl8_cpu_draw_mesh(gfx->backend.cpu, mesh, model, material, gfx->atlas); @@ -726,67 +704,3 @@ void pxl8_gfx_pop_target(pxl8_gfx* gfx) { break; } } - -void pxl8_gfx_ensure_blend_tables(pxl8_gfx* gfx) { - if (!gfx || !gfx->palette) return; - - if (!gfx->palette_cube) { - gfx->palette_cube = pxl8_palette_cube_create(gfx->palette); - if (gfx->backend.cpu) { - pxl8_cpu_set_palette_cube(gfx->backend.cpu, gfx->palette_cube); - } - } -} - -void pxl8_gfx_blend_tables_update(pxl8_gfx* gfx) { - if (!gfx || !gfx->palette) return; - - pxl8_gfx_ensure_blend_tables(gfx); - - if (gfx->palette_cube) { - pxl8_palette_cube_rebuild(gfx->palette_cube, gfx->palette); - if (gfx->backend.cpu) { - pxl8_cpu_set_palette_cube(gfx->backend.cpu, gfx->palette_cube); - } - } -} - -void pxl8_gfx_colormap_update(pxl8_gfx* gfx) { - if (!gfx || !gfx->palette || !gfx->colormap) return; - u32* colors = pxl8_palette_colors(gfx->palette); - if (colors) { - pxl8_colormap_generate(gfx->colormap, colors); - } -} - -u8 pxl8_gfx_find_closest_color(pxl8_gfx* gfx, u8 r, u8 g, u8 b) { - if (!gfx || !gfx->palette) return 0; - return pxl8_palette_find_closest(gfx->palette, r, g, b); -} - -u8 pxl8_gfx_ui_color(pxl8_gfx* gfx, u8 index) { - if (!gfx || !gfx->palette || index >= PXL8_UI_PALETTE_SIZE) return 0; - u32 abgr = pxl8_ui_palette[index]; - u8 r = (abgr >> 0) & 0xFF; - u8 g = (abgr >> 8) & 0xFF; - u8 b = (abgr >> 16) & 0xFF; - return pxl8_palette_find_closest(gfx->palette, r, g, b); -} - -void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count) { - if (!gfx || !params || count == 0) return; - - switch (effect) { - case PXL8_GFX_EFFECT_GLOWS: { - const pxl8_glow_source* glows = (const pxl8_glow_source*)params; - switch (gfx->backend.type) { - case PXL8_GFX_BACKEND_CPU: - pxl8_cpu_render_glows(gfx->backend.cpu, glows, count); - break; - case PXL8_GFX_BACKEND_GPU: - break; - } - break; - } - } -} diff --git a/client/src/gfx/pxl8_gfx.h b/client/src/gfx/pxl8_gfx.h new file mode 100644 index 0000000..ac3acd4 --- /dev/null +++ b/client/src/gfx/pxl8_gfx.h @@ -0,0 +1,48 @@ +#pragma once + +#include "pxl8_gfx2d.h" +#include "pxl8_gfx3d.h" +#include "pxl8_hal.h" +#include "pxl8_palette.h" +#include "pxl8_types.h" + +typedef struct pxl8_gfx pxl8_gfx; + +#ifdef __cplusplus +extern "C" { +#endif + +pxl8_gfx* pxl8_gfx_create(const pxl8_hal* hal, void* platform_data, pxl8_pixel_mode mode, pxl8_resolution resolution); +void pxl8_gfx_destroy(pxl8_gfx* gfx); + +void pxl8_gfx_present(pxl8_gfx* gfx); +void pxl8_gfx_update(pxl8_gfx* gfx, f32 dt); +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); +i32 pxl8_gfx_get_height(const pxl8_gfx* gfx); +pxl8_palette* pxl8_gfx_get_palette(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); +void pxl8_gfx_project(pxl8_gfx* gfx, f32 left, f32 right, f32 top, f32 bottom); +void pxl8_gfx_set_palette(pxl8_gfx* gfx, pxl8_palette* pal); +void pxl8_gfx_set_viewport(pxl8_gfx* gfx, pxl8_viewport vp); +pxl8_viewport pxl8_gfx_viewport(pxl8_bounds bounds, i32 width, i32 height); + +void pxl8_gfx_clear_textures(pxl8_gfx* gfx); +pxl8_result pxl8_gfx_create_texture(pxl8_gfx* gfx, const u8* pixels, u32 width, u32 height); +pxl8_result pxl8_gfx_load_font_atlas(pxl8_gfx* gfx); +pxl8_result pxl8_gfx_load_sprite(pxl8_gfx* gfx, const char* path); + +bool pxl8_gfx_push_target(pxl8_gfx* gfx); +void pxl8_gfx_pop_target(pxl8_gfx* gfx); + +#ifdef __cplusplus +} +#endif diff --git a/src/gfx/pxl8_gfx2d.h b/client/src/gfx/pxl8_gfx2d.h similarity index 100% rename from src/gfx/pxl8_gfx2d.h rename to client/src/gfx/pxl8_gfx2d.h diff --git a/client/src/gfx/pxl8_gfx3d.h b/client/src/gfx/pxl8_gfx3d.h new file mode 100644 index 0000000..0c4f2df --- /dev/null +++ b/client/src/gfx/pxl8_gfx3d.h @@ -0,0 +1,33 @@ +#pragma once + +#include "pxl8_3d_camera.h" +#include "pxl8_math.h" +#include "pxl8_mesh.h" +#include "pxl8_types.h" + +typedef struct pxl8_gfx pxl8_gfx; + +typedef struct pxl8_3d_uniforms { + u8 ambient; + u8 fog_color; + f32 fog_density; + f32 time; +} pxl8_3d_uniforms; + +#ifdef __cplusplus +extern "C" { +#endif + +void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms); +void pxl8_3d_clear(pxl8_gfx* gfx, u8 color); +void pxl8_3d_clear_depth(pxl8_gfx* gfx); +void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color); +void pxl8_3d_draw_mesh(pxl8_gfx* gfx, const pxl8_mesh* mesh, pxl8_mat4 model, pxl8_material material); +void pxl8_3d_draw_mesh_wireframe(pxl8_gfx* gfx, const pxl8_mesh* mesh, pxl8_mat4 model, u8 color); +void pxl8_3d_end_frame(pxl8_gfx* gfx); +u8* pxl8_3d_get_framebuffer(pxl8_gfx* gfx); +const pxl8_frustum* pxl8_3d_get_frustum(pxl8_gfx* gfx); + +#ifdef __cplusplus +} +#endif diff --git a/src/gfx/pxl8_mesh.c b/client/src/gfx/pxl8_mesh.c similarity index 100% rename from src/gfx/pxl8_mesh.c rename to client/src/gfx/pxl8_mesh.c diff --git a/src/gfx/pxl8_mesh.h b/client/src/gfx/pxl8_mesh.h similarity index 50% rename from src/gfx/pxl8_mesh.h rename to client/src/gfx/pxl8_mesh.h index 803cad4..cbfad5c 100644 --- a/src/gfx/pxl8_mesh.h +++ b/client/src/gfx/pxl8_mesh.h @@ -17,9 +17,8 @@ typedef enum pxl8_blend_mode { PXL8_BLEND_ADDITIVE, } pxl8_blend_mode; -typedef struct pxl8_gfx_material { +typedef struct pxl8_material { u32 texture_id; - u32 lightmap_id; u8 alpha; u8 blend_mode; bool dither; @@ -27,15 +26,13 @@ typedef struct pxl8_gfx_material { bool dynamic_lighting; bool per_pixel; bool vertex_color_passthrough; - bool wireframe; f32 emissive_intensity; -} pxl8_gfx_material; +} pxl8_material; typedef struct pxl8_vertex { pxl8_vec3 position; pxl8_vec3 normal; f32 u, v; - f32 lu, lv; u8 color; u8 light; u8 _pad[2]; @@ -65,6 +62,62 @@ static inline u32 pxl8_mesh_triangle_count(const pxl8_mesh* mesh) { return mesh->index_count / 3; } +static inline pxl8_material pxl8_material_new(u32 texture_id) { + return (pxl8_material){ + .texture_id = texture_id, + .alpha = 255, + .blend_mode = PXL8_BLEND_OPAQUE, + .dither = true, + .double_sided = false, + .dynamic_lighting = false, + .per_pixel = false, + .vertex_color_passthrough = false, + .emissive_intensity = 0.0f, + }; +} + +static inline pxl8_material pxl8_material_with_alpha(pxl8_material m, u8 alpha) { + m.alpha = alpha; + if (alpha < 255 && m.blend_mode == PXL8_BLEND_OPAQUE) { + m.blend_mode = PXL8_BLEND_ALPHA; + } + return m; +} + +static inline pxl8_material pxl8_material_with_blend(pxl8_material m, pxl8_blend_mode mode) { + m.blend_mode = mode; + return m; +} + +static inline pxl8_material pxl8_material_with_double_sided(pxl8_material m) { + m.double_sided = true; + return m; +} + +static inline pxl8_material pxl8_material_with_emissive(pxl8_material m, f32 intensity) { + m.emissive_intensity = intensity; + return m; +} + +static inline pxl8_material pxl8_material_with_lighting(pxl8_material m) { + m.dynamic_lighting = true; + return m; +} + +static inline pxl8_material pxl8_material_with_no_dither(pxl8_material m) { + m.dither = false; + return m; +} + +static inline pxl8_material pxl8_material_with_passthrough(pxl8_material m) { + m.vertex_color_passthrough = true; + return m; +} + +static inline pxl8_material pxl8_material_with_per_pixel(pxl8_material m) { + m.per_pixel = true; + return m; +} #ifdef __cplusplus } diff --git a/src/gfx/pxl8_palette.c b/client/src/gfx/pxl8_palette.c similarity index 79% rename from src/gfx/pxl8_palette.c rename to client/src/gfx/pxl8_palette.c index 93b4eee..9d16390 100644 --- a/src/gfx/pxl8_palette.c +++ b/client/src/gfx/pxl8_palette.c @@ -5,17 +5,10 @@ #include "pxl8_ase.h" #include "pxl8_color.h" -#include "pxl8_colormap.h" #include "pxl8_log.h" #define PXL8_PALETTE_HASH_SIZE 512 -struct pxl8_palette_cube { - u8 colors[PXL8_PALETTE_SIZE * 3]; - u8 table[PXL8_CUBE_ENTRIES]; - u8 stable[PXL8_CUBE_ENTRIES]; -}; - typedef struct { u32 color; i16 index; @@ -339,6 +332,10 @@ void pxl8_palette_get_rgba(const pxl8_palette* pal, u8 idx, u8* r, u8* g, u8* b, unpack_rgba(pal->colors[idx], r, g, b, a); } +void pxl8_palette_set(pxl8_palette* pal, u8 idx, u32 color) { + if (pal) pal->colors[idx] = color; +} + void pxl8_palette_set_rgb(pxl8_palette* pal, u8 idx, u8 r, u8 g, u8 b) { if (pal) pal->colors[idx] = pack_rgb(r, g, b); } @@ -347,17 +344,6 @@ void pxl8_palette_set_rgba(pxl8_palette* pal, u8 idx, u8 r, u8 g, u8 b, u8 a) { if (pal) pal->colors[idx] = pack_rgba(r, g, b, a); } -void pxl8_set_palette(pxl8_palette* pal, const u32* colors, u16 count) { - if (!pal || !colors) return; - for (u16 i = 0; i < count; i++) { - u32 rgb = colors[i]; - u8 r = (rgb >> 16) & 0xFF; - u8 g = (rgb >> 8) & 0xFF; - u8 b = rgb & 0xFF; - pal->colors[i] = pack_rgb(r, g, b); - } -} - void pxl8_palette_fill_gradient(pxl8_palette* pal, u8 start, u8 count, u32 from, u32 to) { if (!pal || count == 0) return; @@ -463,7 +449,7 @@ void pxl8_palette_tick(pxl8_palette* pal, u16 delta_ticks) { } } -pxl8_cycle_range pxl8_cycle_range_create(u8 start, u8 len, u16 period) { +pxl8_cycle_range pxl8_cycle_range_new(u8 start, u8 len, u16 period) { pxl8_cycle_range range = { .easing = PXL8_EASE_LINEAR, .interpolate = true, @@ -486,91 +472,3 @@ pxl8_cycle_range pxl8_cycle_range_disabled(void) { }; return range; } - -static u8 find_closest_stable(const pxl8_palette* pal, u8 r, u8 g, u8 b) { - u8 best_idx = 1; - u32 best_dist = 0xFFFFFFFF; - - u8 dynamic_end = PXL8_DYNAMIC_RANGE_START + PXL8_DYNAMIC_RANGE_COUNT; - - for (u32 i = 1; i < PXL8_FULLBRIGHT_START; i++) { - if (i >= PXL8_DYNAMIC_RANGE_START && i < dynamic_end) { - continue; - } - - u8 pr, pg, pb; - pxl8_palette_get_rgb(pal, (u8)i, &pr, &pg, &pb); - - i32 dr = (i32)r - (i32)pr; - i32 dg = (i32)g - (i32)pg; - i32 db = (i32)b - (i32)pb; - u32 dist = (u32)(dr * dr + dg * dg + db * db); - - if (dist < best_dist) { - best_dist = dist; - best_idx = (u8)i; - if (dist == 0) break; - } - } - - return best_idx; -} - -pxl8_palette_cube* pxl8_palette_cube_create(const pxl8_palette* pal) { - pxl8_palette_cube* cube = calloc(1, sizeof(pxl8_palette_cube)); - if (!cube) return NULL; - pxl8_palette_cube_rebuild(cube, pal); - return cube; -} - -void pxl8_palette_cube_destroy(pxl8_palette_cube* cube) { - free(cube); -} - -void pxl8_palette_cube_rebuild(pxl8_palette_cube* cube, const pxl8_palette* pal) { - if (!cube || !pal) return; - - for (u32 i = 0; i < PXL8_PALETTE_SIZE; i++) { - u8 r, g, b; - pxl8_palette_get_rgb(pal, (u8)i, &r, &g, &b); - cube->colors[i * 3 + 0] = r; - cube->colors[i * 3 + 1] = g; - cube->colors[i * 3 + 2] = b; - } - - for (u32 bi = 0; bi < PXL8_CUBE_SIZE; bi++) { - for (u32 gi = 0; gi < PXL8_CUBE_SIZE; gi++) { - for (u32 ri = 0; ri < PXL8_CUBE_SIZE; ri++) { - u32 idx = (bi * PXL8_CUBE_SIZE * PXL8_CUBE_SIZE) + (gi * PXL8_CUBE_SIZE) + ri; - u8 r8 = (u8)((ri * 255) / (PXL8_CUBE_SIZE - 1)); - u8 g8 = (u8)((gi * 255) / (PXL8_CUBE_SIZE - 1)); - u8 b8 = (u8)((bi * 255) / (PXL8_CUBE_SIZE - 1)); - - cube->table[idx] = pxl8_palette_find_closest(pal, r8, g8, b8); - cube->stable[idx] = find_closest_stable(pal, r8, g8, b8); - } - } - } -} - -u8 pxl8_palette_cube_lookup(const pxl8_palette_cube* cube, u8 r, u8 g, u8 b) { - u32 ri = (r * (PXL8_CUBE_SIZE - 1)) / 255; - u32 gi = (g * (PXL8_CUBE_SIZE - 1)) / 255; - u32 bi = (b * (PXL8_CUBE_SIZE - 1)) / 255; - u32 idx = (bi * PXL8_CUBE_SIZE * PXL8_CUBE_SIZE) + (gi * PXL8_CUBE_SIZE) + ri; - return cube->table[idx]; -} - -u8 pxl8_palette_cube_lookup_stable(const pxl8_palette_cube* cube, u8 r, u8 g, u8 b) { - u32 ri = (r * (PXL8_CUBE_SIZE - 1)) / 255; - u32 gi = (g * (PXL8_CUBE_SIZE - 1)) / 255; - u32 bi = (b * (PXL8_CUBE_SIZE - 1)) / 255; - u32 idx = (bi * PXL8_CUBE_SIZE * PXL8_CUBE_SIZE) + (gi * PXL8_CUBE_SIZE) + ri; - return cube->stable[idx]; -} - -void pxl8_palette_cube_get_rgb(const pxl8_palette_cube* cube, u8 idx, u8* r, u8* g, u8* b) { - *r = cube->colors[idx * 3 + 0]; - *g = cube->colors[idx * 3 + 1]; - *b = cube->colors[idx * 3 + 2]; -} diff --git a/src/gfx/pxl8_palette.h b/client/src/gfx/pxl8_palette.h similarity index 74% rename from src/gfx/pxl8_palette.h rename to client/src/gfx/pxl8_palette.h index 0cfbf9b..69b38db 100644 --- a/src/gfx/pxl8_palette.h +++ b/client/src/gfx/pxl8_palette.h @@ -5,11 +5,8 @@ #define PXL8_PALETTE_SIZE 256 #define PXL8_MAX_CYCLES 8 #define PXL8_MAX_CYCLE_LEN 16 -#define PXL8_CUBE_SIZE 32 -#define PXL8_CUBE_ENTRIES (PXL8_CUBE_SIZE * PXL8_CUBE_SIZE * PXL8_CUBE_SIZE) typedef struct pxl8_palette pxl8_palette; -typedef struct pxl8_palette_cube pxl8_palette_cube; typedef enum pxl8_cycle_mode { PXL8_CYCLE_LOOP, @@ -52,9 +49,9 @@ u32 pxl8_palette_color(const pxl8_palette* pal, u8 idx); i32 pxl8_palette_index(const pxl8_palette* pal, u32 color); void pxl8_palette_get_rgb(const pxl8_palette* pal, u8 idx, u8* r, u8* g, u8* b); void pxl8_palette_get_rgba(const pxl8_palette* pal, u8 idx, u8* r, u8* g, u8* b, u8* a); +void pxl8_palette_set(pxl8_palette* pal, u8 idx, u32 color); void pxl8_palette_set_rgb(pxl8_palette* pal, u8 idx, u8 r, u8 g, u8 b); void pxl8_palette_set_rgba(pxl8_palette* pal, u8 idx, u8 r, u8 g, u8 b, u8 a); -void pxl8_set_palette(pxl8_palette* pal, const u32* colors, u16 count); void pxl8_palette_fill_gradient(pxl8_palette* pal, u8 start, u8 count, u32 from, u32 to); void pxl8_palette_fill_gradient_rgb(pxl8_palette* pal, u8 start, u8 count, u8 r0, u8 g0, u8 b0, u8 r1, u8 g1, u8 b1); @@ -65,16 +62,9 @@ void pxl8_palette_set_cycle_colors(pxl8_palette* pal, u8 slot, const u32* colors void pxl8_palette_set_cycle_phase(pxl8_palette* pal, u8 slot, f32 phase); void pxl8_palette_tick(pxl8_palette* pal, u16 delta_ticks); -pxl8_cycle_range pxl8_cycle_range_create(u8 start, u8 len, u16 period); +pxl8_cycle_range pxl8_cycle_range_new(u8 start, u8 len, u16 period); pxl8_cycle_range pxl8_cycle_range_disabled(void); -pxl8_palette_cube* pxl8_palette_cube_create(const pxl8_palette* pal); -void pxl8_palette_cube_destroy(pxl8_palette_cube* cube); -void pxl8_palette_cube_rebuild(pxl8_palette_cube* cube, const pxl8_palette* pal); -u8 pxl8_palette_cube_lookup(const pxl8_palette_cube* cube, u8 r, u8 g, u8 b); -u8 pxl8_palette_cube_lookup_stable(const pxl8_palette_cube* cube, u8 r, u8 g, u8 b); -void pxl8_palette_cube_get_rgb(const pxl8_palette_cube* cube, u8 idx, u8* r, u8* g, u8* b); - #ifdef __cplusplus } #endif diff --git a/src/gfx/pxl8_particles.c b/client/src/gfx/pxl8_particles.c similarity index 100% rename from src/gfx/pxl8_particles.c rename to client/src/gfx/pxl8_particles.c diff --git a/src/gfx/pxl8_particles.h b/client/src/gfx/pxl8_particles.h similarity index 100% rename from src/gfx/pxl8_particles.h rename to client/src/gfx/pxl8_particles.h diff --git a/src/gfx/pxl8_tilemap.c b/client/src/gfx/pxl8_tilemap.c similarity index 100% rename from src/gfx/pxl8_tilemap.c rename to client/src/gfx/pxl8_tilemap.c diff --git a/src/gfx/pxl8_tilemap.h b/client/src/gfx/pxl8_tilemap.h similarity index 100% rename from src/gfx/pxl8_tilemap.h rename to client/src/gfx/pxl8_tilemap.h diff --git a/src/gfx/pxl8_tilesheet.c b/client/src/gfx/pxl8_tilesheet.c similarity index 100% rename from src/gfx/pxl8_tilesheet.c rename to client/src/gfx/pxl8_tilesheet.c diff --git a/src/gfx/pxl8_tilesheet.h b/client/src/gfx/pxl8_tilesheet.h similarity index 100% rename from src/gfx/pxl8_tilesheet.h rename to client/src/gfx/pxl8_tilesheet.h diff --git a/src/gfx/pxl8_transition.c b/client/src/gfx/pxl8_transition.c similarity index 100% rename from src/gfx/pxl8_transition.c rename to client/src/gfx/pxl8_transition.c diff --git a/src/gfx/pxl8_transition.h b/client/src/gfx/pxl8_transition.h similarity index 100% rename from src/gfx/pxl8_transition.h rename to client/src/gfx/pxl8_transition.h diff --git a/src/hal/pxl8_hal.h b/client/src/hal/pxl8_hal.h similarity index 85% rename from src/hal/pxl8_hal.h rename to client/src/hal/pxl8_hal.h index df504c0..282cc90 100644 --- a/src/hal/pxl8_hal.h +++ b/client/src/hal/pxl8_hal.h @@ -11,8 +11,8 @@ typedef struct pxl8_hal { void (*present)(void* platform_data); void (*set_cursor)(void* platform_data, u32 cursor); void (*set_relative_mouse_mode)(void* platform_data, bool enabled); - void (*upload_texture)(void* platform_data, const void* pixels, u32 w, u32 h, - u32 bpp, const u32* palette); + void (*upload_texture)(void* platform_data, const u8* pixels, u32 w, u32 h, + const u32* palette, u32 bpp); void* (*audio_create)(i32 sample_rate, i32 channels); void (*audio_destroy)(void* audio_handle); diff --git a/src/hal/pxl8_sdl3.c b/client/src/hal/pxl8_sdl3.c similarity index 94% rename from src/hal/pxl8_sdl3.c rename to client/src/hal/pxl8_sdl3.c index 3f2f909..fe93912 100644 --- a/src/hal/pxl8_sdl3.c +++ b/client/src/hal/pxl8_sdl3.c @@ -81,6 +81,7 @@ static u64 sdl3_get_ticks(void) { return SDL_GetTicksNS(); } + static void sdl3_present(void* platform_data) { if (!platform_data) return; @@ -96,34 +97,28 @@ static void sdl3_present(void* platform_data) { SDL_RenderPresent(ctx->renderer); } -static void sdl3_upload_texture(void* platform_data, const void* pixels, u32 w, u32 h, - u32 bpp, const u32* palette) { +static void sdl3_upload_texture(void* platform_data, const u8* pixels, u32 w, u32 h, + const u32* palette, u32 bpp) { if (!platform_data || !pixels) return; pxl8_sdl3_context* ctx = (pxl8_sdl3_context*)platform_data; - size_t pixel_count = w * h; + size_t needed_size = w * h; - if (bpp == 4) { - SDL_UpdateTexture(ctx->framebuffer, NULL, pixels, w * 4); - return; - } - - if (ctx->rgba_buffer_size < pixel_count) { - u32* new_buffer = (u32*)SDL_realloc(ctx->rgba_buffer, pixel_count * 4); + if (ctx->rgba_buffer_size < needed_size) { + u32* new_buffer = (u32*)SDL_realloc(ctx->rgba_buffer, needed_size * 4); if (!new_buffer) return; ctx->rgba_buffer = new_buffer; - ctx->rgba_buffer_size = pixel_count; + ctx->rgba_buffer_size = needed_size; } if (bpp == 2) { const u16* pixels16 = (const u16*)pixels; - for (u32 i = 0; i < pixel_count; i++) { + for (u32 i = 0; i < w * h; 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]]; + for (u32 i = 0; i < w * h; i++) { + ctx->rgba_buffer[i] = palette[pixels[i]]; } } diff --git a/src/hal/pxl8_sdl3.h b/client/src/hal/pxl8_sdl3.h similarity index 100% rename from src/hal/pxl8_sdl3.h rename to client/src/hal/pxl8_sdl3.h diff --git a/src/lua/pxl8.lua b/client/src/lua/pxl8.lua similarity index 58% rename from src/lua/pxl8.lua rename to client/src/lua/pxl8.lua index 3dfa593..5f91f34 100644 --- a/src/lua/pxl8.lua +++ b/client/src/lua/pxl8.lua @@ -1,14 +1,11 @@ local anim = require("pxl8.anim") -local bytes = require("pxl8.bytes") local core = require("pxl8.core") local gfx2d = require("pxl8.gfx2d") local gfx3d = require("pxl8.gfx3d") local gui = require("pxl8.gui") local input = require("pxl8.input") -local math = require("pxl8.math") -local net = require("pxl8.net") +local math3d = require("pxl8.math") local particles = require("pxl8.particles") -local procgen = require("pxl8.procgen") local sfx = require("pxl8.sfx") local tilemap = require("pxl8.tilemap") local transition = require("pxl8.transition") @@ -28,20 +25,15 @@ pxl8.debug = core.debug pxl8.trace = core.trace pxl8.quit = core.quit -pxl8.hash32 = math.hash32 -pxl8.rng_f32 = core.rng_f32 -pxl8.rng_next = core.rng_next -pxl8.rng_range = core.rng_range pxl8.rng_seed = core.rng_seed +pxl8.rng_next = core.rng_next +pxl8.rng_f32 = core.rng_f32 +pxl8.rng_range = core.rng_range pxl8.find_color = core.find_color pxl8.palette_color = core.palette_color pxl8.palette_index = core.palette_index pxl8.ramp_index = core.ramp_index -pxl8.set_colormap = core.set_colormap -pxl8.set_palette = core.set_palette -pxl8.set_palette_rgb = core.set_palette_rgb -pxl8.update_palette_deps = core.update_palette_deps pxl8.clear = gfx2d.clear pxl8.pixel = gfx2d.pixel @@ -79,96 +71,87 @@ pxl8.center_cursor = input.center_cursor pxl8.set_cursor = input.set_cursor pxl8.set_relative_mouse_mode = input.set_relative_mouse_mode -pxl8.Anim = anim.Anim -pxl8.create_anim = anim.Anim.new -pxl8.create_anim_from_ase = anim.Anim.from_ase +pxl8.Particles = particles.Particles +pxl8.create_particles = function(max_count) return particles.Particles.new(max_count) end -pxl8.bounds = math.bounds +pxl8.Tilesheet = tilemap.Tilesheet +pxl8.Tilemap = tilemap.Tilemap +pxl8.create_tilesheet = function(tile_size) return tilemap.Tilesheet.new(tile_size) end +pxl8.create_tilemap = function(w, h, tile_size) return tilemap.Tilemap.new(w, h, tile_size) end +pxl8.TILE_FLIP_X = tilemap.TILE_FLIP_X +pxl8.TILE_FLIP_Y = tilemap.TILE_FLIP_Y +pxl8.TILE_SOLID = tilemap.TILE_SOLID +pxl8.TILE_TRIGGER = tilemap.TILE_TRIGGER pxl8.Camera3D = gfx3d.Camera3D -pxl8.create_camera_3d = gfx3d.Camera3D.new +pxl8.create_camera_3d = function() return gfx3d.Camera3D.new() end pxl8.begin_frame_3d = gfx3d.begin_frame +pxl8.end_frame_3d = gfx3d.end_frame pxl8.clear_3d = gfx3d.clear pxl8.clear_depth = gfx3d.clear_depth pxl8.draw_line_3d = gfx3d.draw_line -pxl8.draw_mesh = gfx3d.draw_mesh -pxl8.end_frame_3d = gfx3d.end_frame pxl8.Mesh = gfx3d.Mesh -pxl8.create_mesh = gfx3d.Mesh.new +pxl8.create_mesh = function(vertices, indices) return gfx3d.Mesh.new(vertices, indices) end +pxl8.draw_mesh = gfx3d.draw_mesh -pxl8.Compressor = sfx.Compressor -pxl8.create_compressor = sfx.Compressor.new -pxl8.Delay = sfx.Delay -pxl8.create_delay = sfx.Delay.new -pxl8.Reverb = sfx.Reverb -pxl8.create_reverb = sfx.Reverb.new +pxl8.mat4_identity = math3d.mat4_identity +pxl8.mat4_multiply = math3d.mat4_multiply +pxl8.mat4_translate = math3d.mat4_translate +pxl8.mat4_rotate_x = math3d.mat4_rotate_x +pxl8.mat4_rotate_y = math3d.mat4_rotate_y +pxl8.mat4_rotate_z = math3d.mat4_rotate_z +pxl8.mat4_scale = math3d.mat4_scale +pxl8.mat4_ortho = math3d.mat4_ortho +pxl8.mat4_perspective = math3d.mat4_perspective +pxl8.mat4_lookat = math3d.mat4_lookat +pxl8.bounds = math3d.bounds pxl8.Gui = gui.Gui -pxl8.create_gui = gui.Gui.new +pxl8.create_gui = function() return gui.Gui.new() end pxl8.gui_label = gui.label pxl8.gui_window = gui.window -pxl8.mat4_identity = math.mat4_identity -pxl8.mat4_lookat = math.mat4_lookat -pxl8.mat4_multiply = math.mat4_multiply -pxl8.mat4_ortho = math.mat4_ortho -pxl8.mat4_perspective = math.mat4_perspective -pxl8.mat4_rotate_x = math.mat4_rotate_x -pxl8.mat4_rotate_y = math.mat4_rotate_y -pxl8.mat4_rotate_z = math.mat4_rotate_z -pxl8.mat4_scale = math.mat4_scale -pxl8.mat4_translate = math.mat4_translate - -pxl8.Net = net.Net -pxl8.create_net = net.Net.new -pxl8.NET_MODE_LOCAL = net.MODE_LOCAL -pxl8.NET_MODE_REMOTE = net.MODE_REMOTE - -pxl8.pack_f32_be = bytes.pack_f32_be -pxl8.pack_f32_le = bytes.pack_f32_le -pxl8.pack_f64_be = bytes.pack_f64_be -pxl8.pack_f64_le = bytes.pack_f64_le -pxl8.pack_i8 = bytes.pack_i8 -pxl8.pack_i16_be = bytes.pack_i16_be -pxl8.pack_i16_le = bytes.pack_i16_le -pxl8.pack_i32_be = bytes.pack_i32_be -pxl8.pack_i32_le = bytes.pack_i32_le -pxl8.pack_i64_be = bytes.pack_i64_be -pxl8.pack_i64_le = bytes.pack_i64_le -pxl8.pack_u8 = bytes.pack_u8 -pxl8.pack_u16_be = bytes.pack_u16_be -pxl8.pack_u16_le = bytes.pack_u16_le -pxl8.pack_u32_be = bytes.pack_u32_be -pxl8.pack_u32_le = bytes.pack_u32_le -pxl8.pack_u64_be = bytes.pack_u64_be -pxl8.pack_u64_le = bytes.pack_u64_le - -pxl8.Particles = particles.Particles -pxl8.create_particles = particles.Particles.new - -pxl8.Graph = procgen.Graph -pxl8.create_graph = procgen.create_graph +pxl8.World = world.World +pxl8.create_world = function() return world.World.new() end +pxl8.procgen_tex = world.procgen_tex pxl8.PROCGEN_ROOMS = world.PROCGEN_ROOMS pxl8.PROCGEN_TERRAIN = world.PROCGEN_TERRAIN +pxl8.Transition = transition.Transition +pxl8.create_transition = function(type_name, duration) return transition.Transition.new(type_name, duration) end +pxl8.TRANSITION_TYPES = transition.TYPES + +pxl8.Anim = anim.Anim +pxl8.create_anim = function(frame_ids, frame_durations) return anim.Anim.new(frame_ids, frame_durations) end +pxl8.create_anim_from_ase = function(filepath) return anim.Anim.from_ase(filepath) end + pxl8.SfxContext = sfx.SfxContext pxl8.SfxNode = sfx.SfxNode -pxl8.create_sfx_context = sfx.SfxContext.new +pxl8.Compressor = sfx.Compressor +pxl8.Delay = sfx.Delay +pxl8.Reverb = sfx.Reverb +pxl8.create_sfx_context = function() return sfx.SfxContext.new() end +pxl8.create_compressor = function(opts) return sfx.Compressor.new(opts) end +pxl8.create_delay = function(opts) return sfx.Delay.new(opts) end +pxl8.create_reverb = function(opts) return sfx.Reverb.new(opts) end pxl8.sfx_get_master_volume = sfx.get_master_volume -pxl8.sfx_note_to_freq = sfx.note_to_freq pxl8.sfx_set_master_volume = sfx.set_master_volume +pxl8.sfx_note_to_freq = sfx.note_to_freq pxl8.sfx_voice_params = sfx.voice_params pxl8.SFX_FILTER_BANDPASS = sfx.FILTER_BANDPASS pxl8.SFX_FILTER_HIGHPASS = sfx.FILTER_HIGHPASS pxl8.SFX_FILTER_LOWPASS = sfx.FILTER_LOWPASS pxl8.SFX_FILTER_NONE = sfx.FILTER_NONE + pxl8.SFX_LFO_AMPLITUDE = sfx.LFO_AMPLITUDE pxl8.SFX_LFO_FILTER = sfx.LFO_FILTER pxl8.SFX_LFO_PITCH = sfx.LFO_PITCH + pxl8.SFX_NODE_COMPRESSOR = sfx.NODE_COMPRESSOR pxl8.SFX_NODE_DELAY = sfx.NODE_DELAY pxl8.SFX_NODE_REVERB = sfx.NODE_REVERB + pxl8.SFX_WAVE_NOISE = sfx.WAVE_NOISE pxl8.SFX_WAVE_PULSE = sfx.WAVE_PULSE pxl8.SFX_WAVE_SAW = sfx.WAVE_SAW @@ -176,39 +159,4 @@ pxl8.SFX_WAVE_SINE = sfx.WAVE_SINE pxl8.SFX_WAVE_SQUARE = sfx.WAVE_SQUARE pxl8.SFX_WAVE_TRIANGLE = sfx.WAVE_TRIANGLE -pxl8.TILE_FLIP_X = tilemap.TILE_FLIP_X -pxl8.TILE_FLIP_Y = tilemap.TILE_FLIP_Y -pxl8.TILE_SOLID = tilemap.TILE_SOLID -pxl8.TILE_TRIGGER = tilemap.TILE_TRIGGER -pxl8.Tilemap = tilemap.Tilemap -pxl8.create_tilemap = tilemap.Tilemap.new -pxl8.Tilesheet = tilemap.Tilesheet -pxl8.create_tilesheet = tilemap.Tilesheet.new - -pxl8.Transition = transition.Transition -pxl8.create_transition = transition.Transition.new -pxl8.TRANSITION_TYPES = transition.TYPES - -pxl8.unpack_f32_be = bytes.unpack_f32_be -pxl8.unpack_f32_le = bytes.unpack_f32_le -pxl8.unpack_f64_be = bytes.unpack_f64_be -pxl8.unpack_f64_le = bytes.unpack_f64_le -pxl8.unpack_i8 = bytes.unpack_i8 -pxl8.unpack_i16_be = bytes.unpack_i16_be -pxl8.unpack_i16_le = bytes.unpack_i16_le -pxl8.unpack_i32_be = bytes.unpack_i32_be -pxl8.unpack_i32_le = bytes.unpack_i32_le -pxl8.unpack_i64_be = bytes.unpack_i64_be -pxl8.unpack_i64_le = bytes.unpack_i64_le -pxl8.unpack_u8 = bytes.unpack_u8 -pxl8.unpack_u16_be = bytes.unpack_u16_be -pxl8.unpack_u16_le = bytes.unpack_u16_le -pxl8.unpack_u32_be = bytes.unpack_u32_be -pxl8.unpack_u32_le = bytes.unpack_u32_le -pxl8.unpack_u64_be = bytes.unpack_u64_be -pxl8.unpack_u64_le = bytes.unpack_u64_le - -pxl8.World = world.World -pxl8.create_world = world.World.new - return pxl8 diff --git a/src/lua/pxl8/anim.lua b/client/src/lua/pxl8/anim.lua similarity index 100% rename from src/lua/pxl8/anim.lua rename to client/src/lua/pxl8/anim.lua diff --git a/src/lua/pxl8/core.lua b/client/src/lua/pxl8/core.lua similarity index 77% rename from src/lua/pxl8/core.lua rename to client/src/lua/pxl8/core.lua index afd5dac..ecee66d 100644 --- a/src/lua/pxl8/core.lua +++ b/client/src/lua/pxl8/core.lua @@ -20,40 +20,19 @@ function core.get_fps() end function core.palette_color(index) - local pal = C.pxl8_gfx_palette(core.gfx) + local pal = C.pxl8_gfx_get_palette(core.gfx) if pal == nil then return 0 end return C.pxl8_palette_color(pal, index) end function core.palette_index(color) - local pal = C.pxl8_gfx_palette(core.gfx) + local pal = C.pxl8_gfx_get_palette(core.gfx) if pal == nil then return -1 end return C.pxl8_palette_index(pal, color) end -function core.set_palette_rgb(index, r, g, b) - local pal = C.pxl8_gfx_palette(core.gfx) - if pal == nil then return end - C.pxl8_palette_set_rgb(pal, index, r, g, b) -end - -function core.set_palette(colors, count) - C.pxl8_gfx_set_palette_colors(core.gfx, colors, count) -end - -function core.set_colormap(data, size) - local cm = C.pxl8_gfx_colormap(core.gfx) - if cm == nil then return end - C.pxl8_set_colormap(cm, data, size) -end - -function core.update_palette_deps() - C.pxl8_gfx_blend_tables_update(core.gfx) - C.pxl8_gfx_colormap_update(core.gfx) -end - function core.ramp_index(position) - local pal = C.pxl8_gfx_palette(core.gfx) + local pal = C.pxl8_gfx_get_palette(core.gfx) if pal == nil then return 0 end return C.pxl8_palette_ramp_index(pal, position) end diff --git a/src/lua/pxl8/gfx2d.lua b/client/src/lua/pxl8/gfx2d.lua similarity index 100% rename from src/lua/pxl8/gfx2d.lua rename to client/src/lua/pxl8/gfx2d.lua diff --git a/src/lua/pxl8/gfx3d.lua b/client/src/lua/pxl8/gfx3d.lua similarity index 63% rename from src/lua/pxl8/gfx3d.lua rename to client/src/lua/pxl8/gfx3d.lua index a08432a..3772263 100644 --- a/src/lua/pxl8/gfx3d.lua +++ b/client/src/lua/pxl8/gfx3d.lua @@ -42,14 +42,6 @@ function Camera3D:get_up() return {v.x, v.y, v.z} end -function Camera3D:get_view() - return C.pxl8_3d_camera_get_view(self._ptr) -end - -function Camera3D:get_projection() - return C.pxl8_3d_camera_get_projection(self._ptr) -end - function Camera3D:lookat(eye, target, up) up = up or {0, 1, 0} local eye_vec = ffi.new("pxl8_vec3", {x = eye[1], y = eye[2], z = eye[3]}) @@ -75,15 +67,6 @@ function Camera3D:update(dt) C.pxl8_3d_camera_update(self._ptr, dt) end -function Camera3D:world_to_screen(x, y, z, width, height) - local pos = ffi.new("pxl8_vec3", {x = x, y = y, z = z}) - local result = C.pxl8_3d_camera_world_to_screen(self._ptr, pos, width, height) - if result.visible then - return {x = result.x, y = result.y, depth = result.depth} - end - return nil -end - gfx3d.Camera3D = Camera3D local Mesh = {} @@ -131,16 +114,8 @@ gfx3d.Mesh = Mesh function gfx3d.draw_mesh(mesh, opts) opts = opts or {} - local model = ffi.new("pxl8_mat4") - local s = opts.scale or 1 - model.m[0] = s - model.m[5] = s - model.m[10] = s - model.m[15] = 1 - if opts.x then model.m[12] = opts.x end - if opts.y then model.m[13] = opts.y end - if opts.z then model.m[14] = opts.z end - local material = ffi.new("pxl8_gfx_material", { + local model = C.pxl8_mat4_identity() + local material = ffi.new("pxl8_material", { texture_id = opts.texture or 0, alpha = opts.alpha or 255, blend_mode = opts.blend_mode or 0, @@ -149,7 +124,6 @@ function gfx3d.draw_mesh(mesh, opts) dynamic_lighting = opts.lighting or false, per_pixel = opts.per_pixel or false, vertex_color_passthrough = opts.passthrough or false, - wireframe = opts.wireframe or false, emissive_intensity = opts.emissive or 0.0, }) C.pxl8_3d_draw_mesh(core.gfx, mesh._ptr, model, material) @@ -157,44 +131,12 @@ end function gfx3d.begin_frame(camera, uniforms) uniforms = uniforms or {} - local u = ffi.new("pxl8_3d_uniforms") - - u.ambient = uniforms.ambient or 0 - u.fog_color = uniforms.fog_color or 0 - u.fog_density = uniforms.fog_density or 0.0 - u.time = uniforms.time or 0.0 - - if uniforms.celestial_dir then - u.celestial_dir.x = uniforms.celestial_dir[1] or 0 - u.celestial_dir.y = uniforms.celestial_dir[2] or -1 - u.celestial_dir.z = uniforms.celestial_dir[3] or 0 - else - u.celestial_dir.x = 0 - u.celestial_dir.y = -1 - u.celestial_dir.z = 0 - end - u.celestial_intensity = uniforms.celestial_intensity or 0.0 - - u.num_lights = 0 - if uniforms.lights then - for i, light in ipairs(uniforms.lights) do - if i > 16 then break end - local idx = i - 1 - u.lights[idx].position.x = light.x or 0 - u.lights[idx].position.y = light.y or 0 - u.lights[idx].position.z = light.z or 0 - u.lights[idx].r = light.r or 255 - u.lights[idx].g = light.g or 255 - u.lights[idx].b = light.b or 255 - u.lights[idx].intensity = light.intensity or 255 - u.lights[idx].radius = light.radius or 100 - local radius_sq = u.lights[idx].radius * u.lights[idx].radius - u.lights[idx].radius_sq = radius_sq - u.lights[idx].inv_radius_sq = radius_sq > 0 and (1.0 / radius_sq) or 0 - u.num_lights = i - end - end - + local u = ffi.new("pxl8_3d_uniforms", { + ambient = uniforms.ambient or 0, + fog_color = uniforms.fog_color or 0, + fog_density = uniforms.fog_density or 0.0, + time = uniforms.time or 0.0, + }) C.pxl8_3d_begin_frame(core.gfx, camera._ptr, u) end diff --git a/src/lua/pxl8/gui.lua b/client/src/lua/pxl8/gui.lua similarity index 93% rename from src/lua/pxl8/gui.lua rename to client/src/lua/pxl8/gui.lua index b1f379c..b8cba94 100644 --- a/src/lua/pxl8/gui.lua +++ b/client/src/lua/pxl8/gui.lua @@ -16,7 +16,7 @@ function Gui.new() end function Gui:begin_frame() - C.pxl8_gui_begin_frame(self._ptr, core.gfx) + C.pxl8_gui_begin_frame(self._ptr) end function Gui:button(id, x, y, w, h, label) @@ -43,7 +43,7 @@ function Gui:destroy() end function Gui:end_frame() - C.pxl8_gui_end_frame(self._ptr, core.gfx) + C.pxl8_gui_end_frame(self._ptr) end function Gui:get_cursor_pos() diff --git a/src/lua/pxl8/input.lua b/client/src/lua/pxl8/input.lua similarity index 100% rename from src/lua/pxl8/input.lua rename to client/src/lua/pxl8/input.lua diff --git a/src/lua/pxl8/math.lua b/client/src/lua/pxl8/math.lua similarity index 62% rename from src/lua/pxl8/math.lua rename to client/src/lua/pxl8/math.lua index b0d8d36..c82ad84 100644 --- a/src/lua/pxl8/math.lua +++ b/client/src/lua/pxl8/math.lua @@ -1,57 +1,53 @@ local ffi = require("ffi") local C = ffi.C -local math = {} +local math3d = {} -function math.hash32(x) - return C.pxl8_hash32(x) -end - -function math.mat4_identity() +function math3d.mat4_identity() return C.pxl8_mat4_identity() end -function math.mat4_mul(a, b) +function math3d.mat4_mul(a, b) return C.pxl8_mat4_mul(a, b) end -function math.mat4_translate(x, y, z) +function math3d.mat4_translate(x, y, z) return C.pxl8_mat4_translate(x, y, z) end -function math.mat4_rotate_x(angle) +function math3d.mat4_rotate_x(angle) return C.pxl8_mat4_rotate_x(angle) end -function math.mat4_rotate_y(angle) +function math3d.mat4_rotate_y(angle) return C.pxl8_mat4_rotate_y(angle) end -function math.mat4_rotate_z(angle) +function math3d.mat4_rotate_z(angle) return C.pxl8_mat4_rotate_z(angle) end -function math.mat4_scale(x, y, z) +function math3d.mat4_scale(x, y, z) return C.pxl8_mat4_scale(x, y, z) end -function math.mat4_ortho(left, right, bottom, top, near, far) +function math3d.mat4_ortho(left, right, bottom, top, near, far) return C.pxl8_mat4_ortho(left, right, bottom, top, near, far) end -function math.mat4_perspective(fov, aspect, near, far) +function math3d.mat4_perspective(fov, aspect, near, far) return C.pxl8_mat4_perspective(fov, aspect, near, far) end -function math.mat4_lookat(eye, center, up) +function math3d.mat4_lookat(eye, center, up) local eye_vec = ffi.new("pxl8_vec3", {x = eye[1], y = eye[2], z = eye[3]}) local center_vec = ffi.new("pxl8_vec3", {x = center[1], y = center[2], z = center[3]}) local up_vec = ffi.new("pxl8_vec3", {x = up[1], y = up[2], z = up[3]}) return C.pxl8_mat4_lookat(eye_vec, center_vec, up_vec) end -function math.bounds(x, y, w, h) +function math3d.bounds(x, y, w, h) return ffi.new("pxl8_bounds", {x = x, y = y, w = w, h = h}) end -return math +return math3d diff --git a/src/lua/pxl8/particles.lua b/client/src/lua/pxl8/particles.lua similarity index 98% rename from src/lua/pxl8/particles.lua rename to client/src/lua/pxl8/particles.lua index a0abfe6..41eacef 100644 --- a/src/lua/pxl8/particles.lua +++ b/client/src/lua/pxl8/particles.lua @@ -12,7 +12,7 @@ function Particles.new(max_count) if ps == nil then return nil end - local pal = C.pxl8_gfx_palette(core.gfx) + local pal = C.pxl8_gfx_get_palette(core.gfx) if pal ~= nil then C.pxl8_particles_set_palette(ps, pal) end diff --git a/src/lua/pxl8/sfx.lua b/client/src/lua/pxl8/sfx.lua similarity index 98% rename from src/lua/pxl8/sfx.lua rename to client/src/lua/pxl8/sfx.lua index ff942a1..3a1faf5 100644 --- a/src/lua/pxl8/sfx.lua +++ b/client/src/lua/pxl8/sfx.lua @@ -200,7 +200,9 @@ function sfx.get_master_volume() return C.pxl8_sfx_mixer_get_master_volume(core.sfx) end -sfx.note_to_freq = C.pxl8_sfx_note_to_freq +function sfx.note_to_freq(note) + return C.pxl8_sfx_note_to_freq(note) +end function sfx.set_master_volume(volume) C.pxl8_sfx_mixer_set_master_volume(core.sfx, volume) diff --git a/src/lua/pxl8/tilemap.lua b/client/src/lua/pxl8/tilemap.lua similarity index 100% rename from src/lua/pxl8/tilemap.lua rename to client/src/lua/pxl8/tilemap.lua diff --git a/src/lua/pxl8/transition.lua b/client/src/lua/pxl8/transition.lua similarity index 100% rename from src/lua/pxl8/transition.lua rename to client/src/lua/pxl8/transition.lua diff --git a/client/src/lua/pxl8/vfx.lua b/client/src/lua/pxl8/vfx.lua new file mode 100644 index 0000000..a4372b4 --- /dev/null +++ b/client/src/lua/pxl8/vfx.lua @@ -0,0 +1,65 @@ +local ffi = require("ffi") +local C = ffi.C +local core = require("pxl8.core") + +local vfx = {} + +function vfx.raster_bars(bars, time) + local c_bars = ffi.new("pxl8_raster_bar[?]", #bars) + for i, bar in ipairs(bars) do + c_bars[i-1].base_y = bar.base_y or 0 + c_bars[i-1].amplitude = bar.amplitude or 10 + c_bars[i-1].height = bar.height or 5 + c_bars[i-1].speed = bar.speed or 1.0 + c_bars[i-1].phase = bar.phase or 0 + c_bars[i-1].color = bar.color or 15 + c_bars[i-1].fade_color = bar.fade_color or bar.color or 15 + end + C.pxl8_vfx_raster_bars(core.gfx, c_bars, #bars, time) +end + +function vfx.plasma(time, scale1, scale2, palette_offset) + C.pxl8_vfx_plasma(core.gfx, time, scale1 or 0.05, scale2 or 0.03, palette_offset or 0) +end + +function vfx.rotozoom(angle, zoom, cx, cy) + local width = C.pxl8_gfx_get_width(core.gfx) + local height = C.pxl8_gfx_get_height(core.gfx) + C.pxl8_vfx_rotozoom(core.gfx, angle, zoom, cx or width/2, cy or height/2) +end + +function vfx.tunnel(time, speed, twist) + C.pxl8_vfx_tunnel(core.gfx, time, speed or 2.0, twist or 0.5) +end + +function vfx.explosion(ps, x, y, color, force) + C.pxl8_vfx_explosion(ps, x, y, color or 15, force or 200.0) +end + +function vfx.fire(ps, x, y, width, palette_start) + C.pxl8_vfx_fire(ps, x, y, width or 50, palette_start or 64) +end + +function vfx.rain(ps, width, wind) + local w = width or C.pxl8_gfx_get_width(core.gfx) + C.pxl8_vfx_rain(ps, w, wind or 0.0) +end + +function vfx.smoke(ps, x, y, color) + C.pxl8_vfx_smoke(ps, x, y, color or 8) +end + +function vfx.snow(ps, width, wind) + local w = width or C.pxl8_gfx_get_width(core.gfx) + C.pxl8_vfx_snow(ps, w, wind or 10.0) +end + +function vfx.sparks(ps, x, y, color) + C.pxl8_vfx_sparks(ps, x, y, color or 15) +end + +function vfx.starfield(ps, speed, spread) + C.pxl8_vfx_starfield(ps, speed or 5.0, spread or 500.0) +end + +return vfx diff --git a/src/lua/pxl8/world.lua b/client/src/lua/pxl8/world.lua similarity index 77% rename from src/lua/pxl8/world.lua rename to client/src/lua/pxl8/world.lua index 6d0d22e..589917e 100644 --- a/src/lua/pxl8/world.lua +++ b/client/src/lua/pxl8/world.lua @@ -85,14 +85,36 @@ function World:resolve_collision(from_x, from_y, from_z, to_x, to_y, to_z, radiu return result.x, result.y, result.z end -function World:set_wireframe(enabled, color) - C.pxl8_world_set_wireframe(self._ptr, enabled, color or 15) -end - function World:unload() C.pxl8_world_unload(self._ptr) end world.World = World +function world.procgen_tex(params) + local width = params.width or 64 + local height = params.height or 64 + local buffer = ffi.new("u8[?]", width * height) + local tex_params = ffi.new("pxl8_procgen_tex_params") + + local name = params.name or "" + ffi.copy(tex_params.name, name, math.min(#name, 15)) + + tex_params.seed = params.seed or 0 + tex_params.width = width + tex_params.height = height + tex_params.scale = params.scale or 1.0 + tex_params.roughness = params.roughness or 0.0 + tex_params.base_color = params.base_color or 0 + tex_params.variation = params.variation or 0 + + C.pxl8_procgen_tex(buffer, tex_params) + + local tex_id = C.pxl8_gfx_create_texture(core.gfx, buffer, width, height) + if tex_id < 0 then + return nil + end + return tex_id +end + return world diff --git a/src/math/pxl8_math.c b/client/src/math/pxl8_math.c similarity index 94% rename from src/math/pxl8_math.c rename to client/src/math/pxl8_math.c index feae87e..92b858f 100644 --- a/src/math/pxl8_math.c +++ b/client/src/math/pxl8_math.c @@ -1,14 +1,5 @@ #include "pxl8_math.h" -u32 pxl8_hash32(u32 x) { - x ^= x >> 16; - x *= 0x85EBCA6Bu; - x ^= x >> 13; - x *= 0xC2B2AE35u; - x ^= x >> 16; - return x; -} - pxl8_vec2 pxl8_vec2_add(pxl8_vec2 a, pxl8_vec2 b) { return (pxl8_vec2){ .x = a.x + b.x, @@ -135,14 +126,6 @@ pxl8_vec4 pxl8_mat4_mul_vec4(pxl8_mat4 m, pxl8_vec4 v) { }; } -pxl8_vec3 pxl8_mat4_mul_vec3(pxl8_mat4 m, pxl8_vec3 v) { - return (pxl8_vec3){ - .x = m.m[0] * v.x + m.m[4] * v.y + m.m[8] * v.z, - .y = m.m[1] * v.x + m.m[5] * v.y + m.m[9] * v.z, - .z = m.m[2] * v.x + m.m[6] * v.y + m.m[10] * v.z, - }; -} - pxl8_mat4 pxl8_mat4_translate(f32 x, f32 y, f32 z) { pxl8_mat4 mat = pxl8_mat4_identity(); diff --git a/src/math/pxl8_math.h b/client/src/math/pxl8_math.h similarity index 58% rename from src/math/pxl8_math.h rename to client/src/math/pxl8_math.h index a5477c0..40ea22f 100644 --- a/src/math/pxl8_math.h +++ b/client/src/math/pxl8_math.h @@ -4,51 +4,9 @@ #include "pxl8_types.h" -#if defined(__x86_64__) || defined(_M_X64) - #include -#elif defined(__aarch64__) || defined(_M_ARM64) - #include -#endif - #define PXL8_PI 3.14159265358979323846f #define PXL8_TAU (PXL8_PI * 2.0f) -static inline f32 pxl8_fast_inv_sqrt(f32 x) { -#if defined(__x86_64__) || defined(_M_X64) - __m128 v = _mm_set_ss(x); - v = _mm_rsqrt_ss(v); - return _mm_cvtss_f32(v); -#elif defined(__aarch64__) || defined(_M_ARM64) - float32x2_t v = vdup_n_f32(x); - float32x2_t est = vrsqrte_f32(v); - est = vmul_f32(est, vrsqrts_f32(vmul_f32(v, est), est)); - return vget_lane_f32(est, 0); -#else - f32 half = 0.5f * x; - i32 i = *(i32*)&x; - i = 0x5f3759df - (i >> 1); - x = *(f32*)&i; - x = x * (1.5f - half * x * x); - return x; -#endif -} - -static inline f32 pxl8_fast_rcp(f32 x) { -#if defined(__x86_64__) || defined(_M_X64) - __m128 v = _mm_set_ss(x); - __m128 rcp = _mm_rcp_ss(v); - rcp = _mm_add_ss(rcp, _mm_mul_ss(rcp, _mm_sub_ss(_mm_set_ss(1.0f), _mm_mul_ss(v, rcp)))); - return _mm_cvtss_f32(rcp); -#elif defined(__aarch64__) || defined(_M_ARM64) - float32x2_t v = vdup_n_f32(x); - float32x2_t est = vrecpe_f32(v); - est = vmul_f32(est, vrecps_f32(v, est)); - return vget_lane_f32(est, 0); -#else - return 1.0f / x; -#endif -} - typedef struct pxl8_vec2 { f32 x, y; } pxl8_vec2; @@ -66,27 +24,18 @@ typedef struct pxl8_mat4 { } pxl8_mat4; typedef struct pxl8_plane { - f32 distance; pxl8_vec3 normal; + f32 distance; } pxl8_plane; typedef struct pxl8_frustum { pxl8_plane planes[6]; } pxl8_frustum; -typedef struct pxl8_projected_point { - f32 depth; - i32 x; - i32 y; - bool visible; -} pxl8_projected_point; - #ifdef __cplusplus extern "C" { #endif -u32 pxl8_hash32(u32 x); - pxl8_vec2 pxl8_vec2_add(pxl8_vec2 a, pxl8_vec2 b); f32 pxl8_vec2_dot(pxl8_vec2 a, pxl8_vec2 b); f32 pxl8_vec2_length(pxl8_vec2 v); @@ -106,7 +55,6 @@ pxl8_vec3 pxl8_vec3_sub(pxl8_vec3 a, pxl8_vec3 b); pxl8_mat4 pxl8_mat4_identity(void); pxl8_mat4 pxl8_mat4_lookat(pxl8_vec3 eye, pxl8_vec3 center, pxl8_vec3 up); pxl8_mat4 pxl8_mat4_mul(pxl8_mat4 a, pxl8_mat4 b); -pxl8_vec3 pxl8_mat4_mul_vec3(pxl8_mat4 m, pxl8_vec3 v); pxl8_vec4 pxl8_mat4_mul_vec4(pxl8_mat4 m, pxl8_vec4 v); pxl8_mat4 pxl8_mat4_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far); pxl8_mat4 pxl8_mat4_perspective(f32 fov, f32 aspect, f32 near, f32 far); diff --git a/client/src/math/pxl8_simd.h b/client/src/math/pxl8_simd.h new file mode 100644 index 0000000..8202b24 --- /dev/null +++ b/client/src/math/pxl8_simd.h @@ -0,0 +1,299 @@ +#pragma once + +#include "pxl8_types.h" + +#if defined(__x86_64__) || defined(_M_X64) + #define PXL8_SIMD_SSE2 1 + #include +#elif defined(__aarch64__) || defined(_M_ARM64) + #define PXL8_SIMD_NEON 1 + #include +#else + #define PXL8_SIMD_SCALAR 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(PXL8_SIMD_SSE2) + +typedef struct { __m128 v; } pxl8_f32x4; +typedef struct { __m128i v; } pxl8_i32x4; +typedef struct { __m128i v; } pxl8_u16x8; + +static inline pxl8_f32x4 pxl8_f32x4_splat(f32 x) { + return (pxl8_f32x4){ _mm_set1_ps(x) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_new(f32 a, f32 b, f32 c, f32 d) { + return (pxl8_f32x4){ _mm_set_ps(d, c, b, a) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_add(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ _mm_add_ps(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_sub(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ _mm_sub_ps(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_mul(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ _mm_mul_ps(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_div(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ _mm_div_ps(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_min(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ _mm_min_ps(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_max(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ _mm_max_ps(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_cmplt(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ _mm_cmplt_ps(a.v, b.v) }; +} + +static inline i32 pxl8_f32x4_movemask(pxl8_f32x4 a) { + return _mm_movemask_ps(a.v); +} + +static inline pxl8_i32x4 pxl8_f32x4_to_i32x4(pxl8_f32x4 a) { + return (pxl8_i32x4){ _mm_cvttps_epi32(a.v) }; +} + +static inline void pxl8_f32x4_store(pxl8_f32x4 a, f32* out) { + _mm_storeu_ps(out, a.v); +} + +static inline pxl8_i32x4 pxl8_i32x4_splat(i32 x) { + return (pxl8_i32x4){ _mm_set1_epi32(x) }; +} + +static inline pxl8_i32x4 pxl8_i32x4_slli(pxl8_i32x4 a, i32 n) { + return (pxl8_i32x4){ _mm_slli_epi32(a.v, n) }; +} + +static inline pxl8_i32x4 pxl8_i32x4_srai(pxl8_i32x4 a, i32 n) { + return (pxl8_i32x4){ _mm_srai_epi32(a.v, n) }; +} + +static inline pxl8_i32x4 pxl8_i32x4_and(pxl8_i32x4 a, pxl8_i32x4 b) { + return (pxl8_i32x4){ _mm_and_si128(a.v, b.v) }; +} + +static inline pxl8_i32x4 pxl8_i32x4_or(pxl8_i32x4 a, pxl8_i32x4 b) { + return (pxl8_i32x4){ _mm_or_si128(a.v, b.v) }; +} + +static inline void pxl8_i32x4_store(pxl8_i32x4 a, i32* out) { + _mm_storeu_si128((__m128i*)out, a.v); +} + +static inline pxl8_u16x8 pxl8_u16x8_cmplt(pxl8_u16x8 a, pxl8_u16x8 b) { + return (pxl8_u16x8){ _mm_cmplt_epi16(a.v, b.v) }; +} + +static inline pxl8_u16x8 pxl8_u16x8_blend(pxl8_u16x8 a, pxl8_u16x8 b, pxl8_u16x8 mask) { + __m128i not_mask = _mm_andnot_si128(mask.v, a.v); + __m128i and_mask = _mm_and_si128(mask.v, b.v); + return (pxl8_u16x8){ _mm_or_si128(not_mask, and_mask) }; +} + +static inline i32 pxl8_u16x8_movemask(pxl8_u16x8 a) { + return _mm_movemask_epi8(a.v); +} + +#elif defined(PXL8_SIMD_NEON) + +typedef struct { float32x4_t v; } pxl8_f32x4; +typedef struct { int32x4_t v; } pxl8_i32x4; +typedef struct { uint16x8_t v; } pxl8_u16x8; + +static inline pxl8_f32x4 pxl8_f32x4_splat(f32 x) { + return (pxl8_f32x4){ vdupq_n_f32(x) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_new(f32 a, f32 b, f32 c, f32 d) { + f32 arr[4] = {a, b, c, d}; + return (pxl8_f32x4){ vld1q_f32(arr) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_add(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ vaddq_f32(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_sub(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ vsubq_f32(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_mul(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ vmulq_f32(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_div(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ vdivq_f32(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_min(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ vminq_f32(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_max(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){ vmaxq_f32(a.v, b.v) }; +} + +static inline pxl8_f32x4 pxl8_f32x4_cmplt(pxl8_f32x4 a, pxl8_f32x4 b) { + uint32x4_t cmp = vcltq_f32(a.v, b.v); + return (pxl8_f32x4){ vreinterpretq_f32_u32(cmp) }; +} + +static inline i32 pxl8_f32x4_movemask(pxl8_f32x4 a) { + uint32x4_t input = vreinterpretq_u32_f32(a.v); + static const i32 shifts[4] = {0, 1, 2, 3}; + uint32x4_t shifted = vshrq_n_u32(input, 31); + return vgetq_lane_u32(shifted, 0) | (vgetq_lane_u32(shifted, 1) << 1) | + (vgetq_lane_u32(shifted, 2) << 2) | (vgetq_lane_u32(shifted, 3) << 3); +} + +static inline pxl8_i32x4 pxl8_f32x4_to_i32x4(pxl8_f32x4 a) { + return (pxl8_i32x4){ vcvtq_s32_f32(a.v) }; +} + +static inline void pxl8_f32x4_store(pxl8_f32x4 a, f32* out) { + vst1q_f32(out, a.v); +} + +static inline pxl8_i32x4 pxl8_i32x4_splat(i32 x) { + return (pxl8_i32x4){ vdupq_n_s32(x) }; +} + +static inline pxl8_i32x4 pxl8_i32x4_slli(pxl8_i32x4 a, i32 n) { + return (pxl8_i32x4){ vshlq_s32(a.v, vdupq_n_s32(n)) }; +} + +static inline pxl8_i32x4 pxl8_i32x4_srai(pxl8_i32x4 a, i32 n) { + return (pxl8_i32x4){ vshlq_s32(a.v, vdupq_n_s32(-n)) }; +} + +static inline pxl8_i32x4 pxl8_i32x4_and(pxl8_i32x4 a, pxl8_i32x4 b) { + return (pxl8_i32x4){ vandq_s32(a.v, b.v) }; +} + +static inline pxl8_i32x4 pxl8_i32x4_or(pxl8_i32x4 a, pxl8_i32x4 b) { + return (pxl8_i32x4){ vorrq_s32(a.v, b.v) }; +} + +static inline void pxl8_i32x4_store(pxl8_i32x4 a, i32* out) { + vst1q_s32(out, a.v); +} + +#else + +typedef struct { f32 v[4]; } pxl8_f32x4; +typedef struct { i32 v[4]; } pxl8_i32x4; +typedef struct { u16 v[8]; } pxl8_u16x8; + +static inline pxl8_f32x4 pxl8_f32x4_splat(f32 x) { + return (pxl8_f32x4){{ x, x, x, x }}; +} + +static inline pxl8_f32x4 pxl8_f32x4_new(f32 a, f32 b, f32 c, f32 d) { + return (pxl8_f32x4){{ a, b, c, d }}; +} + +static inline pxl8_f32x4 pxl8_f32x4_add(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){{ a.v[0]+b.v[0], a.v[1]+b.v[1], a.v[2]+b.v[2], a.v[3]+b.v[3] }}; +} + +static inline pxl8_f32x4 pxl8_f32x4_sub(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){{ a.v[0]-b.v[0], a.v[1]-b.v[1], a.v[2]-b.v[2], a.v[3]-b.v[3] }}; +} + +static inline pxl8_f32x4 pxl8_f32x4_mul(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){{ a.v[0]*b.v[0], a.v[1]*b.v[1], a.v[2]*b.v[2], a.v[3]*b.v[3] }}; +} + +static inline pxl8_f32x4 pxl8_f32x4_div(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){{ a.v[0]/b.v[0], a.v[1]/b.v[1], a.v[2]/b.v[2], a.v[3]/b.v[3] }}; +} + +static inline pxl8_f32x4 pxl8_f32x4_min(pxl8_f32x4 a, pxl8_f32x4 b) { + return (pxl8_f32x4){{ + a.v[0]b.v[0]?a.v[0]:b.v[0], a.v[1]>b.v[1]?a.v[1]:b.v[1], + a.v[2]>b.v[2]?a.v[2]:b.v[2], a.v[3]>b.v[3]?a.v[3]:b.v[3] + }}; +} + +static inline pxl8_f32x4 pxl8_f32x4_cmplt(pxl8_f32x4 a, pxl8_f32x4 b) { + pxl8_f32x4 r; + u32* rv = (u32*)r.v; + rv[0] = a.v[0] < b.v[0] ? 0xFFFFFFFF : 0; + rv[1] = a.v[1] < b.v[1] ? 0xFFFFFFFF : 0; + rv[2] = a.v[2] < b.v[2] ? 0xFFFFFFFF : 0; + rv[3] = a.v[3] < b.v[3] ? 0xFFFFFFFF : 0; + return r; +} + +static inline i32 pxl8_f32x4_movemask(pxl8_f32x4 a) { + u32* av = (u32*)a.v; + return ((av[0] >> 31) & 1) | ((av[1] >> 31) & 1) << 1 | + ((av[2] >> 31) & 1) << 2 | ((av[3] >> 31) & 1) << 3; +} + +static inline pxl8_i32x4 pxl8_f32x4_to_i32x4(pxl8_f32x4 a) { + return (pxl8_i32x4){{ (i32)a.v[0], (i32)a.v[1], (i32)a.v[2], (i32)a.v[3] }}; +} + +static inline void pxl8_f32x4_store(pxl8_f32x4 a, f32* out) { + out[0] = a.v[0]; out[1] = a.v[1]; out[2] = a.v[2]; out[3] = a.v[3]; +} + +static inline pxl8_i32x4 pxl8_i32x4_splat(i32 x) { + return (pxl8_i32x4){{ x, x, x, x }}; +} + +static inline pxl8_i32x4 pxl8_i32x4_slli(pxl8_i32x4 a, i32 n) { + return (pxl8_i32x4){{ a.v[0]<>n, a.v[1]>>n, a.v[2]>>n, a.v[3]>>n }}; +} + +static inline pxl8_i32x4 pxl8_i32x4_and(pxl8_i32x4 a, pxl8_i32x4 b) { + return (pxl8_i32x4){{ a.v[0]&b.v[0], a.v[1]&b.v[1], a.v[2]&b.v[2], a.v[3]&b.v[3] }}; +} + +static inline pxl8_i32x4 pxl8_i32x4_or(pxl8_i32x4 a, pxl8_i32x4 b) { + return (pxl8_i32x4){{ a.v[0]|b.v[0], a.v[1]|b.v[1], a.v[2]|b.v[2], a.v[3]|b.v[3] }}; +} + +static inline void pxl8_i32x4_store(pxl8_i32x4 a, i32* out) { + out[0] = a.v[0]; out[1] = a.v[1]; out[2] = a.v[2]; out[3] = a.v[3]; +} + +#endif + +static inline f32 pxl8_fast_inv_sqrt(f32 x) { + f32 half = 0.5f * x; + i32 i = *(i32*)&x; + i = 0x5f375a86 - (i >> 1); + f32 y = *(f32*)&i; + return y * (1.5f - half * y * y); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/script/pxl8_repl.c b/client/src/script/pxl8_repl.c similarity index 95% rename from src/script/pxl8_repl.c rename to client/src/script/pxl8_repl.c index 7df3ab7..5c0d3e0 100644 --- a/src/script/pxl8_repl.c +++ b/client/src/script/pxl8_repl.c @@ -1,13 +1,14 @@ #include "pxl8_repl.h" #include +#include #include #include #include #include +#include #include -#include #include #define PXL8_MAX_REPL_COMMAND_SIZE 4096 @@ -28,7 +29,7 @@ struct pxl8_repl { atomic_uint log_read_idx; atomic_bool should_quit; - SDL_Thread* thread; + pthread_t thread; char accumulator[PXL8_MAX_REPL_COMMAND_SIZE]; pxl8_repl_command command; }; @@ -104,7 +105,7 @@ static void pxl8_repl_flush_logs(pxl8_repl* repl) { fflush(stdout); } -static int pxl8_repl_thread(void* arg) { +static void* pxl8_repl_thread(void* arg) { pxl8_repl* repl = (pxl8_repl*)arg; printf("[pxl8 REPL] Fennel 1.6.0 - Tab for completion, Ctrl-D to exit\n"); @@ -203,7 +204,8 @@ static int pxl8_repl_thread(void* arg) { lw = atomic_load(&repl->log_write_idx); } fflush(stdout); - SDL_Delay(1); + struct timespec ts = {.tv_sec = 0, .tv_nsec = 1000000}; + nanosleep(&ts, NULL); } atomic_store(&repl->cmd_complete, false); } @@ -212,7 +214,7 @@ static int pxl8_repl_thread(void* arg) { pxl8_repl_flush_logs(repl); - return 0; + return NULL; } pxl8_repl* pxl8_repl_create(void) { @@ -235,8 +237,7 @@ pxl8_repl* pxl8_repl_create(void) { g_repl = repl; - repl->thread = SDL_CreateThread(pxl8_repl_thread, "pxl8-repl", repl); - if (!repl->thread) { + if (pthread_create(&repl->thread, NULL, pxl8_repl_thread, repl) != 0) { free(repl); g_repl = NULL; return NULL; @@ -250,12 +251,13 @@ void pxl8_repl_destroy(pxl8_repl* repl) { atomic_store(&repl->should_quit, true); - SDL_Delay(2); + struct timespec ts = {.tv_sec = 0, .tv_nsec = 2000000}; + nanosleep(&ts, NULL); printf("\r\033[K"); fflush(stdout); - SDL_WaitThread(repl->thread, NULL); + pthread_join(repl->thread, NULL); pxl8_repl_flush_logs(repl); g_repl = NULL; diff --git a/src/script/pxl8_repl.h b/client/src/script/pxl8_repl.h similarity index 100% rename from src/script/pxl8_repl.h rename to client/src/script/pxl8_repl.h diff --git a/src/script/pxl8_script.c b/client/src/script/pxl8_script.c similarity index 100% rename from src/script/pxl8_script.c rename to client/src/script/pxl8_script.c diff --git a/src/script/pxl8_script.h b/client/src/script/pxl8_script.h similarity index 100% rename from src/script/pxl8_script.h rename to client/src/script/pxl8_script.h diff --git a/src/script/pxl8_script_ffi.h b/client/src/script/pxl8_script_ffi.h similarity index 70% rename from src/script/pxl8_script_ffi.h rename to client/src/script/pxl8_script_ffi.h index 63bae74..66e1189 100644 --- a/src/script/pxl8_script_ffi.h +++ b/client/src/script/pxl8_script_ffi.h @@ -27,16 +27,10 @@ static const char* pxl8_ffi_cdefs = "u8 pxl8_gfx_find_color(pxl8_gfx* gfx, u32 color);\n" "i32 pxl8_gfx_get_height(pxl8_gfx* ctx);\n" "typedef struct pxl8_palette pxl8_palette;\n" -"pxl8_palette* pxl8_gfx_palette(pxl8_gfx* gfx);\n" +"pxl8_palette* pxl8_gfx_get_palette(pxl8_gfx* gfx);\n" "u32 pxl8_palette_color(const pxl8_palette* pal, u8 idx);\n" -"void pxl8_palette_set_rgb(pxl8_palette* pal, u8 idx, u8 r, u8 g, u8 b);\n" -"void pxl8_gfx_set_palette_colors(pxl8_gfx* gfx, const u32* colors, u16 count);\n" "i32 pxl8_palette_index(const pxl8_palette* pal, u32 color);\n" "u8 pxl8_palette_ramp_index(const pxl8_palette* pal, u8 position);\n" -"typedef struct pxl8_colormap pxl8_colormap;\n" -"pxl8_colormap* pxl8_gfx_colormap(pxl8_gfx* gfx);\n" -"void pxl8_set_colormap(pxl8_colormap* cm, const u8* data, u32 size);\n" -"void pxl8_gfx_ensure_blend_tables(pxl8_gfx* gfx);\n" "i32 pxl8_gfx_get_width(pxl8_gfx* ctx);\n" "void pxl8_2d_circle(pxl8_gfx* ctx, i32 x, i32 y, i32 r, u32 color);\n" "void pxl8_2d_circle_fill(pxl8_gfx* ctx, i32 x, i32 y, i32 r, u32 color);\n" @@ -195,23 +189,10 @@ static const char* pxl8_ffi_cdefs = "typedef struct { float x, y, z, w; } pxl8_vec4;\n" "typedef struct { float m[16]; } pxl8_mat4;\n" "\n" -"typedef struct pxl8_light {\n" -" pxl8_vec3 position;\n" -" u8 r, g, b;\n" -" u8 intensity;\n" -" f32 radius;\n" -" f32 radius_sq;\n" -" f32 inv_radius_sq;\n" -"} pxl8_light;\n" -"\n" "typedef struct pxl8_3d_uniforms {\n" " u8 ambient;\n" -" pxl8_vec3 celestial_dir;\n" -" f32 celestial_intensity;\n" " u8 fog_color;\n" " f32 fog_density;\n" -" pxl8_light lights[16];\n" -" u32 num_lights;\n" " f32 time;\n" "} pxl8_3d_uniforms;\n" "\n" @@ -229,27 +210,6 @@ static const char* pxl8_ffi_cdefs = "pxl8_mat4 pxl8_3d_camera_get_view(const pxl8_3d_camera* cam);\n" "pxl8_mat4 pxl8_3d_camera_get_projection(const pxl8_3d_camera* cam);\n" "void pxl8_3d_camera_update(pxl8_3d_camera* cam, f32 dt);\n" -"typedef struct pxl8_projected_point { i32 x; i32 y; f32 depth; bool visible; } pxl8_projected_point;\n" -"pxl8_projected_point pxl8_3d_camera_world_to_screen(const pxl8_3d_camera* cam, pxl8_vec3 world_pos, u32 screen_width, u32 screen_height);\n" -"\n" -"typedef enum pxl8_gfx_effect { PXL8_GFX_EFFECT_GLOWS = 0 } pxl8_gfx_effect;\n" -"\n" -"typedef enum pxl8_glow_shape { PXL8_GLOW_CIRCLE = 0, PXL8_GLOW_DIAMOND = 1, PXL8_GLOW_SHAFT = 2 } pxl8_glow_shape;\n" -"\n" -"typedef struct pxl8_glow_source {\n" -" u8 color;\n" -" u16 depth;\n" -" u8 height;\n" -" u16 intensity;\n" -" u8 radius;\n" -" pxl8_glow_shape shape;\n" -" i16 x;\n" -" i16 y;\n" -"} pxl8_glow_source;\n" -"\n" -"void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count);\n" -"void pxl8_gfx_blend_tables_update(pxl8_gfx* gfx);\n" -"void pxl8_gfx_colormap_update(pxl8_gfx* gfx);\n" "\n" "void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms);\n" "void pxl8_3d_clear(pxl8_gfx* gfx, u8 color);\n" @@ -259,9 +219,8 @@ static const char* pxl8_ffi_cdefs = "\n" "typedef enum pxl8_blend_mode { PXL8_BLEND_OPAQUE = 0, PXL8_BLEND_ALPHA_TEST, PXL8_BLEND_ALPHA, PXL8_BLEND_ADDITIVE } pxl8_blend_mode;\n" "\n" -"typedef struct pxl8_gfx_material {\n" +"typedef struct pxl8_material {\n" " u32 texture_id;\n" -" u32 lightmap_id;\n" " u8 alpha;\n" " u8 blend_mode;\n" " bool dither;\n" @@ -269,15 +228,13 @@ static const char* pxl8_ffi_cdefs = " bool dynamic_lighting;\n" " bool per_pixel;\n" " bool vertex_color_passthrough;\n" -" bool wireframe;\n" " f32 emissive_intensity;\n" -"} pxl8_gfx_material;\n" +"} pxl8_material;\n" "\n" "typedef struct pxl8_vertex {\n" " pxl8_vec3 position;\n" " pxl8_vec3 normal;\n" " f32 u, v;\n" -" f32 lu, lv;\n" " u8 color;\n" " u8 light;\n" " u8 _pad[2];\n" @@ -297,10 +254,7 @@ static const char* pxl8_ffi_cdefs = "void pxl8_mesh_clear(pxl8_mesh* mesh);\n" "u16 pxl8_mesh_push_vertex(pxl8_mesh* mesh, pxl8_vertex v);\n" "void pxl8_mesh_push_triangle(pxl8_mesh* mesh, u16 i0, u16 i1, u16 i2);\n" -"void pxl8_3d_draw_mesh(pxl8_gfx* gfx, const pxl8_mesh* mesh, const pxl8_mat4* model, const pxl8_gfx_material* material);\n" -"void pxl8_3d_draw_mesh_wireframe(pxl8_gfx* gfx, const pxl8_mesh* mesh, pxl8_mat4 model, u8 color);\n" -"\n" -"u32 pxl8_hash32(u32 x);\n" +"void pxl8_3d_draw_mesh(pxl8_gfx* gfx, const pxl8_mesh* mesh, pxl8_mat4 model, pxl8_material material);\n" "\n" "pxl8_mat4 pxl8_mat4_identity(void);\n" "pxl8_mat4 pxl8_mat4_lookat(pxl8_vec3 eye, pxl8_vec3 center, pxl8_vec3 up);\n" @@ -329,76 +283,18 @@ static const char* pxl8_ffi_cdefs = " int num_rooms;\n" "} pxl8_procgen_params;\n" "\n" -"typedef enum pxl8_graph_op {\n" -" PXL8_OP_CONST = 0,\n" -" PXL8_OP_INPUT_AGE,\n" -" PXL8_OP_INPUT_SEED,\n" -" PXL8_OP_INPUT_TIME,\n" -" PXL8_OP_INPUT_X,\n" -" PXL8_OP_INPUT_Y,\n" +"typedef struct pxl8_procgen_tex_params {\n" +" char name[16];\n" +" unsigned int seed;\n" +" int width;\n" +" int height;\n" +" float scale;\n" +" float roughness;\n" +" unsigned char base_color;\n" +" unsigned char variation;\n" +"} pxl8_procgen_tex_params;\n" "\n" -" PXL8_OP_ABS,\n" -" PXL8_OP_CEIL,\n" -" PXL8_OP_COS,\n" -" PXL8_OP_FLOOR,\n" -" PXL8_OP_FRACT,\n" -" PXL8_OP_NEGATE,\n" -" PXL8_OP_SIN,\n" -" PXL8_OP_SQRT,\n" -"\n" -" PXL8_OP_ADD,\n" -" PXL8_OP_DIV,\n" -" PXL8_OP_MAX,\n" -" PXL8_OP_MIN,\n" -" PXL8_OP_MOD,\n" -" PXL8_OP_MUL,\n" -" PXL8_OP_POW,\n" -" PXL8_OP_SUB,\n" -"\n" -" PXL8_OP_CLAMP,\n" -" PXL8_OP_LERP,\n" -" PXL8_OP_SELECT,\n" -" PXL8_OP_SMOOTHSTEP,\n" -"\n" -" PXL8_OP_NOISE_FBM,\n" -" PXL8_OP_NOISE_PERLIN,\n" -" PXL8_OP_NOISE_RIDGED,\n" -" PXL8_OP_NOISE_TURBULENCE,\n" -" PXL8_OP_NOISE_VALUE,\n" -"\n" -" PXL8_OP_VORONOI_CELL,\n" -" PXL8_OP_VORONOI_EDGE,\n" -" PXL8_OP_VORONOI_ID,\n" -"\n" -" PXL8_OP_GRADIENT_LINEAR,\n" -" PXL8_OP_GRADIENT_RADIAL,\n" -"\n" -" PXL8_OP_QUANTIZE,\n" -" PXL8_OP_COUNT\n" -"} pxl8_graph_op;\n" -"\n" -"typedef struct pxl8_node {\n" -" u8 in[4];\n" -" u8 op;\n" -" u8 out;\n" -" f32 param;\n" -"} pxl8_node;\n" -"\n" -"typedef struct pxl8_graph {\n" -" u32 capacity;\n" -" u32 count;\n" -" pxl8_node* nodes;\n" -" u8 output_reg;\n" -" u32 seed;\n" -"} pxl8_graph;\n" -"\n" -"pxl8_graph* pxl8_graph_create(u32 capacity);\n" -"void pxl8_graph_destroy(pxl8_graph* graph);\n" -"void pxl8_graph_clear(pxl8_graph* graph);\n" -"u8 pxl8_graph_add_node(pxl8_graph* graph, pxl8_graph_op op, u8 in0, u8 in1, u8 in2, u8 in3, f32 param);\n" -"void pxl8_graph_set_output(pxl8_graph* graph, u8 reg);\n" -"void pxl8_graph_set_seed(pxl8_graph* graph, u32 seed);\n" -"void pxl8_graph_eval_texture(const pxl8_graph* graph, u8* buffer, i32 width, i32 height);\n" +"void pxl8_procgen_tex(u8* buffer, const pxl8_procgen_tex_params* params);\n" "\n" "typedef struct pxl8_bsp pxl8_bsp;\n" "typedef struct pxl8_bsp_face pxl8_bsp_face;\n" @@ -421,13 +317,12 @@ static const char* pxl8_ffi_cdefs = "bool pxl8_world_is_loaded(const pxl8_world* world);\n" "void pxl8_world_render(pxl8_world* world, pxl8_gfx* gfx, pxl8_vec3 camera_pos);\n" "pxl8_vec3 pxl8_world_resolve_collision(const pxl8_world* world, pxl8_vec3 from, pxl8_vec3 to, float radius);\n" -"void pxl8_world_set_wireframe(pxl8_world* world, bool enabled, u8 color);\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" "pxl8_gui_state* pxl8_gui_state_create(void);\n" "void pxl8_gui_state_destroy(pxl8_gui_state* state);\n" -"void pxl8_gui_begin_frame(pxl8_gui_state* state, pxl8_gfx* gfx);\n" -"void pxl8_gui_end_frame(pxl8_gui_state* state, pxl8_gfx* gfx);\n" +"void pxl8_gui_begin_frame(pxl8_gui_state* state);\n" +"void pxl8_gui_end_frame(pxl8_gui_state* state);\n" "void pxl8_gui_cursor_move(pxl8_gui_state* state, i32 x, i32 y);\n" "void pxl8_gui_cursor_down(pxl8_gui_state* state);\n" "void pxl8_gui_cursor_up(pxl8_gui_state* state);\n" @@ -491,107 +386,4 @@ static const char* pxl8_ffi_cdefs = "void pxl8_sfx_reverb_set_mix(pxl8_sfx_node* node, f32 mix);\n" "void pxl8_sfx_reverb_set_room(pxl8_sfx_node* node, f32 room);\n" "void pxl8_sfx_stop_all(pxl8_sfx_context* ctx);\n" -"void pxl8_sfx_stop_voice(pxl8_sfx_context* ctx, u16 voice_id);\n" -"\n" -"typedef struct pxl8_net pxl8_net;\n" -"typedef enum pxl8_net_mode { PXL8_NET_LOCAL = 0, PXL8_NET_REMOTE } pxl8_net_mode;\n" -"typedef struct pxl8_net_config { const char* address; pxl8_net_mode mode; u16 port; } pxl8_net_config;\n" -"typedef enum pxl8_cmd_type { PXL8_CMD_NONE = 0, PXL8_CMD_SPAWN_ENTITY } pxl8_cmd_type;\n" -"\n" -"typedef struct pxl8_command_msg {\n" -" u16 cmd_type;\n" -" u8 payload[64];\n" -" u16 payload_size;\n" -" u64 tick;\n" -"} pxl8_command_msg;\n" -"\n" -"typedef struct pxl8_input_msg {\n" -" u32 buttons;\n" -" f32 look_dx;\n" -" f32 look_dy;\n" -" f32 move_x;\n" -" f32 move_y;\n" -" f32 yaw;\n" -" u64 tick;\n" -" u64 timestamp;\n" -"} pxl8_input_msg;\n" -"\n" -"typedef struct pxl8_entity_state {\n" -" u64 entity_id;\n" -" u8 userdata[56];\n" -"} pxl8_entity_state;\n" -"\n" -"typedef struct pxl8_snapshot_header {\n" -" u16 entity_count;\n" -" u16 event_count;\n" -" u64 player_id;\n" -" u64 tick;\n" -" f32 time;\n" -"} pxl8_snapshot_header;\n" -"\n" -"i32 pxl8_net_connect(pxl8_net* net);\n" -"bool pxl8_net_connected(const pxl8_net* net);\n" -"pxl8_net* pxl8_net_create(const pxl8_net_config* config);\n" -"void pxl8_net_destroy(pxl8_net* net);\n" -"void pxl8_net_disconnect(pxl8_net* net);\n" -"const pxl8_entity_state* pxl8_net_entities(const pxl8_net* net);\n" -"const u8* pxl8_net_entity_prev_userdata(const pxl8_net* net, u64 entity_id);\n" -"const u8* pxl8_net_entity_userdata(const pxl8_net* net, u64 entity_id);\n" -"const pxl8_input_msg* pxl8_net_input_at(const pxl8_net* net, u64 tick);\n" -"u64 pxl8_net_input_oldest_tick(const pxl8_net* net);\n" -"void pxl8_net_input_push(pxl8_net* net, const pxl8_input_msg* input);\n" -"f32 pxl8_net_lerp_alpha(const pxl8_net* net);\n" -"bool pxl8_net_needs_correction(const pxl8_net* net);\n" -"u64 pxl8_net_player_id(const pxl8_net* net);\n" -"bool pxl8_net_poll(pxl8_net* net);\n" -"u8* pxl8_net_predicted_state(pxl8_net* net);\n" -"void pxl8_net_predicted_tick_set(pxl8_net* net, u64 tick);\n" -"i32 pxl8_net_send_command(pxl8_net* net, const pxl8_command_msg* cmd);\n" -"i32 pxl8_net_send_input(pxl8_net* net, const pxl8_input_msg* input);\n" -"const pxl8_snapshot_header* pxl8_net_snapshot(const pxl8_net* net);\n" -"u64 pxl8_net_tick(const pxl8_net* net);\n" -"void pxl8_net_update(pxl8_net* net, f32 dt);\n" -"\n" -"void pxl8_bit_clear(u32* val, u8 bit);\n" -"u32 pxl8_bit_count(u32 val);\n" -"void pxl8_bit_set(u32* val, u8 bit);\n" -"bool pxl8_bit_test(u32 val, u8 bit);\n" -"void pxl8_bit_toggle(u32* val, u8 bit);\n" -"\n" -"void pxl8_pack_u8(u8* buf, size_t offset, u8 val);\n" -"void pxl8_pack_u16_be(u8* buf, size_t offset, u16 val);\n" -"void pxl8_pack_u16_le(u8* buf, size_t offset, u16 val);\n" -"void pxl8_pack_u32_be(u8* buf, size_t offset, u32 val);\n" -"void pxl8_pack_u32_le(u8* buf, size_t offset, u32 val);\n" -"void pxl8_pack_u64_be(u8* buf, size_t offset, u64 val);\n" -"void pxl8_pack_u64_le(u8* buf, size_t offset, u64 val);\n" -"void pxl8_pack_i8(u8* buf, size_t offset, i8 val);\n" -"void pxl8_pack_i16_be(u8* buf, size_t offset, i16 val);\n" -"void pxl8_pack_i16_le(u8* buf, size_t offset, i16 val);\n" -"void pxl8_pack_i32_be(u8* buf, size_t offset, i32 val);\n" -"void pxl8_pack_i32_le(u8* buf, size_t offset, i32 val);\n" -"void pxl8_pack_i64_be(u8* buf, size_t offset, i64 val);\n" -"void pxl8_pack_i64_le(u8* buf, size_t offset, i64 val);\n" -"void pxl8_pack_f32_be(u8* buf, size_t offset, f32 val);\n" -"void pxl8_pack_f32_le(u8* buf, size_t offset, f32 val);\n" -"void pxl8_pack_f64_be(u8* buf, size_t offset, f64 val);\n" -"void pxl8_pack_f64_le(u8* buf, size_t offset, f64 val);\n" -"\n" -"u8 pxl8_unpack_u8(const u8* buf, size_t offset);\n" -"u16 pxl8_unpack_u16_be(const u8* buf, size_t offset);\n" -"u16 pxl8_unpack_u16_le(const u8* buf, size_t offset);\n" -"u32 pxl8_unpack_u32_be(const u8* buf, size_t offset);\n" -"u32 pxl8_unpack_u32_le(const u8* buf, size_t offset);\n" -"u64 pxl8_unpack_u64_be(const u8* buf, size_t offset);\n" -"u64 pxl8_unpack_u64_le(const u8* buf, size_t offset);\n" -"i8 pxl8_unpack_i8(const u8* buf, size_t offset);\n" -"i16 pxl8_unpack_i16_be(const u8* buf, size_t offset);\n" -"i16 pxl8_unpack_i16_le(const u8* buf, size_t offset);\n" -"i32 pxl8_unpack_i32_be(const u8* buf, size_t offset);\n" -"i32 pxl8_unpack_i32_le(const u8* buf, size_t offset);\n" -"i64 pxl8_unpack_i64_be(const u8* buf, size_t offset);\n" -"i64 pxl8_unpack_i64_le(const u8* buf, size_t offset);\n" -"f32 pxl8_unpack_f32_be(const u8* buf, size_t offset);\n" -"f32 pxl8_unpack_f32_le(const u8* buf, size_t offset);\n" -"f64 pxl8_unpack_f64_be(const u8* buf, size_t offset);\n" -"f64 pxl8_unpack_f64_le(const u8* buf, size_t offset);\n"; +"void pxl8_sfx_stop_voice(pxl8_sfx_context* ctx, u16 voice_id);\n"; diff --git a/src/sfx/pxl8_sfx.c b/client/src/sfx/pxl8_sfx.c similarity index 99% rename from src/sfx/pxl8_sfx.c rename to client/src/sfx/pxl8_sfx.c index 75c7937..02357fe 100644 --- a/src/sfx/pxl8_sfx.c +++ b/client/src/sfx/pxl8_sfx.c @@ -9,11 +9,6 @@ #define VOICE_SCALE 0.15f -static inline f32 sanitize_audio(f32 x) { - union { f32 f; u32 u; } conv = { .f = x }; - return ((conv.u & 0x7F800000) == 0x7F800000) ? 0.0f : x; -} - typedef enum envelope_state { ENV_ATTACK = 0, ENV_DECAY, @@ -721,8 +716,8 @@ void pxl8_sfx_mixer_process(pxl8_sfx_mixer* mixer) { left = fmaxf(-1.0f, fminf(1.0f, left)); right = fmaxf(-1.0f, fminf(1.0f, right)); - left = sanitize_audio(left); - right = sanitize_audio(right); + if (!isfinite(left)) left = 0.0f; + if (!isfinite(right)) right = 0.0f; mixer->output_buffer[i * 2] = left; mixer->output_buffer[i * 2 + 1] = right; diff --git a/src/sfx/pxl8_sfx.h b/client/src/sfx/pxl8_sfx.h similarity index 100% rename from src/sfx/pxl8_sfx.h rename to client/src/sfx/pxl8_sfx.h diff --git a/src/world/pxl8_bsp.c b/client/src/world/pxl8_bsp.c similarity index 86% rename from src/world/pxl8_bsp.c rename to client/src/world/pxl8_bsp.c index f3e9485..5beacd2 100644 --- a/src/world/pxl8_bsp.c +++ b/client/src/world/pxl8_bsp.c @@ -345,7 +345,6 @@ void pxl8_bsp_destroy(pxl8_bsp* bsp) { free(bsp->planes); free(bsp->surfedges); free(bsp->texinfo); - free(bsp->vertex_lights); free(bsp->vertices); free(bsp->visdata); @@ -378,24 +377,26 @@ bool pxl8_bsp_is_leaf_visible(const pxl8_bsp* bsp, i32 leaf_from, i32 leaf_to) { u32 target_byte = leaf_to >> 3; u32 target_bit = leaf_to & 7; + u32 pvs_size = (bsp->num_leafs + 7) / 8; u32 pos = (u32)visofs; - u32 out_pos = 0; + u32 current_byte = 0; - while (out_pos <= target_byte && pos < bsp->visdata_size) { + while (current_byte < pvs_size && pos < bsp->visdata_size) { u8 b = bsp->visdata[pos++]; + if (b != 0) { - if (out_pos == target_byte) { + if (current_byte == target_byte) { return (b & (1 << target_bit)) != 0; } - out_pos++; + current_byte++; } else { - if (pos >= bsp->visdata_size) break; + if (pos >= bsp->visdata_size) return false; u32 count = bsp->visdata[pos++]; - if (out_pos + count > target_byte) { + if (target_byte < current_byte + count) { return false; } - out_pos += count; + current_byte += count; } } @@ -545,12 +546,6 @@ static inline bool face_in_frustum(const pxl8_bsp* bsp, u32 face_id, const pxl8_ return pxl8_frustum_test_aabb(frustum, face->aabb_min, face->aabb_max); } -static inline bool leaf_in_frustum(const pxl8_bsp_leaf* leaf, const pxl8_frustum* frustum) { - pxl8_vec3 mins = {(f32)leaf->mins[0], (f32)leaf->mins[1], (f32)leaf->mins[2]}; - pxl8_vec3 maxs = {(f32)leaf->maxs[0], (f32)leaf->maxs[1], (f32)leaf->maxs[2]}; - return pxl8_frustum_test_aabb(frustum, mins, maxs); -} - static void collect_face_to_mesh( const pxl8_bsp* bsp, u32 face_id, @@ -577,12 +572,15 @@ static void collect_face_to_mesh( u16 base_idx = (u16)mesh->vertex_count; u32 num_verts = 0; + static int face_debug = 0; + bool debug_this = (face_debug++ < 3); for (u32 i = 0; i < face->num_edges && num_verts < 64; i++) { i32 surfedge_idx = face->first_edge + i; u32 vert_idx; if (!pxl8_bsp_get_edge_vertex(bsp, surfedge_idx, &vert_idx)) { + if (debug_this) pxl8_debug("face %u: edge %u failed to get vertex (surfedge_idx=%d)", face_id, i, surfedge_idx); continue; } @@ -611,6 +609,11 @@ static void collect_face_to_mesh( num_verts++; } + if (debug_this) { + pxl8_debug("face %u: num_edges=%u, collected %u verts, texinfo_id=%u", + face_id, face->num_edges, num_verts, face->texinfo_id); + } + if (num_verts < 3) return; for (u32 i = 1; i < num_verts - 1; i++) { @@ -627,14 +630,8 @@ void pxl8_bsp_render_face(pxl8_gfx* gfx, const pxl8_bsp* bsp, u32 face_id, u32 t collect_face_to_mesh(bsp, face_id, mesh); if (mesh->index_count > 0) { - pxl8_mat4 identity = pxl8_mat4_identity(); - pxl8_gfx_material mat = { - .texture_id = texture_id, - .alpha = 255, - .dither = true, - .dynamic_lighting = true, - }; - pxl8_3d_draw_mesh(gfx, mesh, &identity, &mat); + pxl8_material mat = pxl8_material_new(texture_id); + pxl8_3d_draw_mesh(gfx, mesh, pxl8_mat4_identity(), mat); } pxl8_mesh_destroy(mesh); @@ -660,32 +657,6 @@ void pxl8_bsp_render_textured(pxl8_gfx* gfx, const pxl8_bsp* bsp, pxl8_vec3 came i32 camera_leaf = pxl8_bsp_find_leaf(bsp, camera_pos); - static u32 debug_counter = 0; - bool do_debug = (debug_counter++ % 300 == 0); - u32 visible_leafs = 0; - u32 visible_faces = 0; - u32 total_faces_in_visible_leafs = 0; - static bool dumped_camera_leaf = false; - if (do_debug) { - bool self_visible = (camera_leaf < 0) || pxl8_bsp_is_leaf_visible(bsp, camera_leaf, camera_leaf); - if (!self_visible) { - pxl8_debug("WARNING: Camera leaf %d is NOT visible from itself!", camera_leaf); - } - if (!dumped_camera_leaf && camera_leaf >= 0) { - const pxl8_bsp_leaf* cl = &bsp->leafs[camera_leaf]; - pxl8_debug("Camera leaf %d: contents=%d, marksurfaces=%u-%u (%u faces)", - camera_leaf, cl->contents, cl->first_marksurface, - cl->first_marksurface + cl->num_marksurfaces, cl->num_marksurfaces); - dumped_camera_leaf = true; - } - for (u32 i = 0; i < bsp->num_leafs; i++) { - if (camera_leaf < 0 || pxl8_bsp_is_leaf_visible(bsp, camera_leaf, i)) { - visible_leafs++; - total_faces_in_visible_leafs += bsp->leafs[i].num_marksurfaces; - } - } - } - static u8* rendered_faces = NULL; static u32 rendered_faces_capacity = 0; @@ -703,25 +674,14 @@ void pxl8_bsp_render_textured(pxl8_gfx* gfx, const pxl8_bsp* bsp, pxl8_vec3 came u32 current_texture = 0xFFFFFFFF; + static int debug_cull = 0; + u32 faces_checked = 0, faces_culled = 0, faces_passed = 0; + for (u32 leaf_id = 0; leaf_id < bsp->num_leafs; leaf_id++) { if (camera_leaf >= 0 && !pxl8_bsp_is_leaf_visible(bsp, camera_leaf, leaf_id)) continue; const pxl8_bsp_leaf* leaf = &bsp->leafs[leaf_id]; - bool is_camera_leaf = ((i32)leaf_id == camera_leaf); - - f32 cx = ((f32)leaf->mins[0] + (f32)leaf->maxs[0]) * 0.5f; - f32 cy = ((f32)leaf->mins[1] + (f32)leaf->maxs[1]) * 0.5f; - f32 cz = ((f32)leaf->mins[2] + (f32)leaf->maxs[2]) * 0.5f; - f32 dx = camera_pos.x - cx; - f32 dy = camera_pos.y - cy; - f32 dz = camera_pos.z - cz; - f32 dist_sq = dx*dx + dy*dy + dz*dz; - bool camera_near_leaf = dist_sq < (512.0f * 512.0f); - - bool skip_frustum = is_camera_leaf || camera_near_leaf; - if (!skip_frustum && !leaf_in_frustum(leaf, frustum)) continue; - for (u32 i = 0; i < leaf->num_marksurfaces; i++) { u32 surf_idx = leaf->first_marksurface + i; if (surf_idx >= bsp->num_marksurfaces) continue; @@ -731,11 +691,13 @@ void pxl8_bsp_render_textured(pxl8_gfx* gfx, const pxl8_bsp* bsp, pxl8_vec3 came if (rendered_faces[face_id]) continue; rendered_faces[face_id] = 1; - if (do_debug) visible_faces++; - if (!skip_frustum && !face_in_frustum(bsp, face_id, frustum)) { + faces_checked++; + if (!face_in_frustum(bsp, face_id, frustum)) { + faces_culled++; continue; } + faces_passed++; const pxl8_bsp_face* face = &bsp->faces[face_id]; u32 texture_id = 0; @@ -744,38 +706,39 @@ void pxl8_bsp_render_textured(pxl8_gfx* gfx, const pxl8_bsp* bsp, pxl8_vec3 came } if (texture_id != current_texture && mesh->index_count > 0) { - pxl8_mat4 identity = pxl8_mat4_identity(); - pxl8_gfx_material mat = { - .texture_id = current_texture, - .alpha = 255, - .dither = true, - .dynamic_lighting = true, - }; - pxl8_3d_draw_mesh(gfx, mesh, &identity, &mat); + pxl8_material mat = pxl8_material_with_double_sided(pxl8_material_new(current_texture)); + pxl8_3d_draw_mesh(gfx, mesh, pxl8_mat4_identity(), mat); pxl8_mesh_clear(mesh); } current_texture = texture_id; + u32 before = mesh->index_count; collect_face_to_mesh(bsp, face_id, mesh); + if (debug_cull < 3 && mesh->index_count > before) { + pxl8_debug("Added face %u: mesh now has %u indices (was %u)", face_id, mesh->index_count, before); + } } } + static int draw_count = 0; + if (debug_cull < 3) { + pxl8_debug("Final mesh: %u indices, %u vertices", mesh->index_count, mesh->vertex_count); + } if (mesh->index_count > 0) { - pxl8_mat4 identity = pxl8_mat4_identity(); - pxl8_gfx_material mat = { - .texture_id = current_texture, - .alpha = 255, - .dither = true, - .dynamic_lighting = true, - }; - pxl8_3d_draw_mesh(gfx, mesh, &identity, &mat); + pxl8_material mat = pxl8_material_with_double_sided(pxl8_material_new(current_texture)); + pxl8_3d_draw_mesh(gfx, mesh, pxl8_mat4_identity(), mat); + if (draw_count++ < 5) { + pxl8_debug("bsp_render_textured: drew mesh with %u indices, camera_leaf=%d", + mesh->index_count, camera_leaf); + } + } else if (draw_count < 5) { + pxl8_debug("bsp_render_textured: mesh is empty, camera_leaf=%d, num_leafs=%u", + camera_leaf, bsp->num_leafs); + draw_count++; } - if (do_debug) { - pxl8_debug("Camera at (%.1f, %.1f, %.1f) -> leaf %d, %u/%u leafs, %u/%u faces (expected %u)", - camera_pos.x, camera_pos.y, camera_pos.z, - camera_leaf, visible_leafs, bsp->num_leafs, - visible_faces, bsp->num_faces, total_faces_in_visible_leafs); + if (debug_cull++ < 5) { + pxl8_debug("bsp_render: checked=%u, culled=%u, passed=%u", faces_checked, faces_culled, faces_passed); } pxl8_mesh_destroy(mesh); diff --git a/src/world/pxl8_bsp.h b/client/src/world/pxl8_bsp.h similarity index 100% rename from src/world/pxl8_bsp.h rename to client/src/world/pxl8_bsp.h diff --git a/client/src/world/pxl8_gen.c b/client/src/world/pxl8_gen.c new file mode 100644 index 0000000..ba80b11 --- /dev/null +++ b/client/src/world/pxl8_gen.c @@ -0,0 +1,504 @@ +#include "pxl8_gen.h" + +#include +#include + +#include "pxl8_log.h" +#include "pxl8_rng.h" + +typedef struct room_grid { + u8* cells; + i32 width; + i32 height; +} room_grid; + +static bool room_grid_init(room_grid* grid, i32 width, i32 height) { + grid->width = width; + grid->height = height; + grid->cells = calloc(width * height, sizeof(u8)); + + return grid->cells != NULL; +} + +static u8 room_grid_get(const room_grid* grid, i32 x, i32 y) { + if (x < 0 || x >= grid->width || y < 0 || y >= grid->height) { + return 1; + } + return grid->cells[y * grid->width + x]; +} + +static void room_grid_set(room_grid* grid, i32 x, i32 y, u8 value) { + if (x < 0 || x >= grid->width || y < 0 || y >= grid->height) { + return; + } + grid->cells[y * grid->width + x] = value; +} + +static inline void compute_face_aabb(pxl8_bsp_face* face, const pxl8_bsp_vertex* verts, u32 vert_idx) { + face->aabb_min = (pxl8_vec3){1e30f, 1e30f, 1e30f}; + face->aabb_max = (pxl8_vec3){-1e30f, -1e30f, -1e30f}; + + for (u32 i = 0; i < 4; i++) { + pxl8_vec3 v = verts[vert_idx + i].position; + if (v.x < face->aabb_min.x) face->aabb_min.x = v.x; + if (v.x > face->aabb_max.x) face->aabb_max.x = v.x; + if (v.y < face->aabb_min.y) face->aabb_min.y = v.y; + if (v.y > face->aabb_max.y) face->aabb_max.y = v.y; + if (v.z < face->aabb_min.z) face->aabb_min.z = v.z; + if (v.z > face->aabb_max.z) face->aabb_max.z = v.z; + } +} + +static void room_grid_fill(room_grid* grid, u8 value) { + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + room_grid_set(grid, x, y, value); + } + } +} + +static pxl8_result grid_to_bsp(pxl8_bsp* bsp, const room_grid* grid) { + i32 vertex_count = 0; + i32 face_count = 0; + i32 floor_ceiling_count = 0; + + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + if (room_grid_get(grid, x, y) == 0) { + if (room_grid_get(grid, x - 1, y) == 1) face_count++; + if (room_grid_get(grid, x + 1, y) == 1) face_count++; + if (room_grid_get(grid, x, y - 1) == 1) face_count++; + if (room_grid_get(grid, x, y + 1) == 1) face_count++; + floor_ceiling_count++; + } + } + } + + face_count += floor_ceiling_count * 2; + vertex_count = face_count * 4; + + pxl8_debug("Cave generation: %dx%d grid -> %d faces, %d vertices", + grid->width, grid->height, face_count, vertex_count); + + bsp->vertices = calloc(vertex_count, sizeof(pxl8_bsp_vertex)); + bsp->faces = calloc(face_count, sizeof(pxl8_bsp_face)); + bsp->planes = calloc(face_count, sizeof(pxl8_bsp_plane)); + bsp->edges = calloc(vertex_count, sizeof(pxl8_bsp_edge)); + bsp->surfedges = calloc(vertex_count, sizeof(i32)); + + if (!bsp->vertices || !bsp->faces || !bsp->planes || !bsp->edges || !bsp->surfedges) { + return PXL8_ERROR_OUT_OF_MEMORY; + } + + bsp->texinfo = NULL; + bsp->num_texinfo = 0; + + i32 vert_idx = 0; + i32 face_idx = 0; + i32 edge_idx = 0; + + const f32 cell_size = 64.0f; + const f32 wall_height = 128.0f; + + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + if (room_grid_get(grid, x, y) == 0) { + f32 fx = (f32)x * cell_size; + f32 fy = (f32)y * cell_size; + + if (room_grid_get(grid, x - 1, y) == 1) { + bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, 0, fy}; + bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx, wall_height, fy}; + bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx, wall_height, fy + cell_size}; + bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx, 0, fy + cell_size}; + + bsp->planes[face_idx].normal = (pxl8_vec3){-1, 0, 0}; + bsp->planes[face_idx].dist = -fx; + + bsp->faces[face_idx].plane_id = face_idx; + bsp->faces[face_idx].num_edges = 4; + bsp->faces[face_idx].first_edge = edge_idx; + bsp->faces[face_idx].texinfo_id = 0; + + for (i32 i = 0; i < 4; i++) { + bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; + bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); + bsp->surfedges[edge_idx + i] = edge_idx + i; + } + + compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); + + vert_idx += 4; + edge_idx += 4; + face_idx++; + } + + if (room_grid_get(grid, x + 1, y) == 1) { + bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx + cell_size, 0, fy}; + bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx + cell_size, 0, fy + cell_size}; + bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, wall_height, fy + cell_size}; + bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx + cell_size, wall_height, fy}; + + bsp->planes[face_idx].normal = (pxl8_vec3){1, 0, 0}; + bsp->planes[face_idx].dist = fx + cell_size; + + bsp->faces[face_idx].plane_id = face_idx; + bsp->faces[face_idx].num_edges = 4; + bsp->faces[face_idx].first_edge = edge_idx; + bsp->faces[face_idx].texinfo_id = 0; + + for (i32 i = 0; i < 4; i++) { + bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; + bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); + bsp->surfedges[edge_idx + i] = edge_idx + i; + } + + compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); + + vert_idx += 4; + edge_idx += 4; + face_idx++; + } + + if (room_grid_get(grid, x, y - 1) == 1) { + bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, 0, fy}; + bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx + cell_size, 0, fy}; + bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, wall_height, fy}; + bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx, wall_height, fy}; + + bsp->planes[face_idx].normal = (pxl8_vec3){0, 0, -1}; + bsp->planes[face_idx].dist = -fy; + + bsp->faces[face_idx].plane_id = face_idx; + bsp->faces[face_idx].num_edges = 4; + bsp->faces[face_idx].first_edge = edge_idx; + bsp->faces[face_idx].texinfo_id = 0; + + for (i32 i = 0; i < 4; i++) { + bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; + bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); + bsp->surfedges[edge_idx + i] = edge_idx + i; + } + + compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); + + vert_idx += 4; + edge_idx += 4; + face_idx++; + } + + if (room_grid_get(grid, x, y + 1) == 1) { + bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, 0, fy + cell_size}; + bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx, wall_height, fy + cell_size}; + bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, wall_height, fy + cell_size}; + bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx + cell_size, 0, fy + cell_size}; + + bsp->planes[face_idx].normal = (pxl8_vec3){0, 0, 1}; + bsp->planes[face_idx].dist = fy + cell_size; + + bsp->faces[face_idx].plane_id = face_idx; + bsp->faces[face_idx].num_edges = 4; + bsp->faces[face_idx].first_edge = edge_idx; + bsp->faces[face_idx].texinfo_id = 0; + + for (i32 i = 0; i < 4; i++) { + bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; + bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); + bsp->surfedges[edge_idx + i] = edge_idx + i; + } + + compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); + + vert_idx += 4; + edge_idx += 4; + face_idx++; + } + } + } + } + + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + if (room_grid_get(grid, x, y) == 0) { + f32 fx = (f32)x * cell_size; + f32 fy = (f32)y * cell_size; + + bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, 0, fy}; + bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx, 0, fy + cell_size}; + bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, 0, fy + cell_size}; + bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx + cell_size, 0, fy}; + + bsp->planes[face_idx].normal = (pxl8_vec3){0, 1, 0}; + bsp->planes[face_idx].dist = 0; + + bsp->faces[face_idx].plane_id = face_idx; + bsp->faces[face_idx].num_edges = 4; + bsp->faces[face_idx].first_edge = edge_idx; + bsp->faces[face_idx].texinfo_id = 0; + + for (i32 i = 0; i < 4; i++) { + bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; + bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); + bsp->surfedges[edge_idx + i] = edge_idx + i; + } + + compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); + + vert_idx += 4; + edge_idx += 4; + face_idx++; + + bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, wall_height, fy}; + bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx + cell_size, wall_height, fy}; + bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, wall_height, fy + cell_size}; + bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx, wall_height, fy + cell_size}; + + bsp->planes[face_idx].normal = (pxl8_vec3){0, -1, 0}; + bsp->planes[face_idx].dist = -wall_height; + + bsp->faces[face_idx].plane_id = face_idx; + bsp->faces[face_idx].num_edges = 4; + bsp->faces[face_idx].first_edge = edge_idx; + bsp->faces[face_idx].texinfo_id = 0; + + for (i32 i = 0; i < 4; i++) { + bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; + bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); + bsp->surfedges[edge_idx + i] = edge_idx + i; + } + + compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); + + vert_idx += 4; + edge_idx += 4; + face_idx++; + } + } + } + + bsp->num_vertices = vertex_count; + bsp->num_faces = face_count; + bsp->num_planes = face_count; + bsp->num_edges = vertex_count; + bsp->num_surfedges = vertex_count; + + bsp->leafs = calloc(1, sizeof(pxl8_bsp_leaf)); + bsp->marksurfaces = calloc(face_count, sizeof(u16)); + + if (!bsp->leafs || !bsp->marksurfaces) { + return PXL8_ERROR_OUT_OF_MEMORY; + } + + bsp->num_leafs = 1; + bsp->num_marksurfaces = face_count; + + bsp->leafs[0].first_marksurface = 0; + bsp->leafs[0].num_marksurfaces = face_count; + bsp->leafs[0].contents = -2; + + for (i32 i = 0; i < face_count; i++) { + bsp->marksurfaces[i] = i; + } + + return PXL8_OK; +} + +static bool bounds_intersects(const pxl8_bounds* a, const pxl8_bounds* b) { + return !(a->x + a->w <= b->x || b->x + b->w <= a->x || + a->y + a->h <= b->y || b->y + b->h <= a->y); +} + +static void carve_corridor_h(room_grid* grid, i32 x1, i32 x2, i32 y) { + i32 start = (x1 < x2) ? x1 : x2; + i32 end = (x1 > x2) ? x1 : x2; + for (i32 x = start; x <= end; x++) { + room_grid_set(grid, x, y, 0); + room_grid_set(grid, x, y - 1, 0); + room_grid_set(grid, x, y + 1, 0); + } +} + +static void carve_corridor_v(room_grid* grid, i32 y1, i32 y2, i32 x) { + i32 start = (y1 < y2) ? y1 : y2; + i32 end = (y1 > y2) ? y1 : y2; + for (i32 y = start; y <= end; y++) { + room_grid_set(grid, x, y, 0); + room_grid_set(grid, x - 1, y, 0); + room_grid_set(grid, x + 1, y, 0); + } +} + +static pxl8_result procgen_rooms(pxl8_bsp* bsp, const pxl8_procgen_params* params) { + pxl8_debug("procgen_rooms called: %dx%d, seed=%u, min=%d, max=%d, num=%d", + params->width, params->height, params->seed, + params->min_room_size, params->max_room_size, params->num_rooms); + + pxl8_rng rng; + pxl8_rng_seed(&rng, params->seed); + + room_grid grid; + if (!room_grid_init(&grid, params->width, params->height)) { + pxl8_error("Failed to allocate room grid"); + return PXL8_ERROR_OUT_OF_MEMORY; + } + + room_grid_fill(&grid, 1); + + pxl8_bounds rooms[256]; + i32 room_count = 0; + i32 max_attempts = params->num_rooms * 10; + + for (i32 attempt = 0; attempt < max_attempts && room_count < params->num_rooms && room_count < 256; attempt++) { + i32 w = params->min_room_size + (pxl8_rng_next(&rng) % (params->max_room_size - params->min_room_size + 1)); + i32 h = params->min_room_size + (pxl8_rng_next(&rng) % (params->max_room_size - params->min_room_size + 1)); + i32 x = 1 + (pxl8_rng_next(&rng) % (params->width - w - 2)); + i32 y = 1 + (pxl8_rng_next(&rng) % (params->height - h - 2)); + + pxl8_bounds new_room = {x, y, w, h}; + + bool overlaps = false; + for (i32 i = 0; i < room_count; i++) { + if (bounds_intersects(&new_room, &rooms[i])) { + overlaps = true; + break; + } + } + + if (!overlaps) { + for (i32 ry = y; ry < y + h; ry++) { + for (i32 rx = x; rx < x + w; rx++) { + room_grid_set(&grid, rx, ry, 0); + } + } + + if (room_count > 0) { + i32 new_cx = x + w / 2; + i32 new_cy = y + h / 2; + i32 prev_cx = rooms[room_count - 1].x + rooms[room_count - 1].w / 2; + i32 prev_cy = rooms[room_count - 1].y + rooms[room_count - 1].h / 2; + + if (pxl8_rng_next(&rng) % 2 == 0) { + carve_corridor_h(&grid, prev_cx, new_cx, prev_cy); + carve_corridor_v(&grid, prev_cy, new_cy, new_cx); + } else { + carve_corridor_v(&grid, prev_cy, new_cy, prev_cx); + carve_corridor_h(&grid, prev_cx, new_cx, new_cy); + } + } + + rooms[room_count++] = new_room; + } + } + + pxl8_debug("Room generation: %dx%d grid -> %d rooms created", + params->width, params->height, room_count); + + pxl8_result result = grid_to_bsp(bsp, &grid); + free(grid.cells); + + return result; +} + +pxl8_result pxl8_procgen(pxl8_bsp* bsp, const pxl8_procgen_params* params) { + if (!bsp || !params) { + return PXL8_ERROR_NULL_POINTER; + } + + switch (params->type) { + case PXL8_PROCGEN_ROOMS: + return procgen_rooms(bsp, params); + + case PXL8_PROCGEN_TERRAIN: + pxl8_error("Terrain generation not yet implemented"); + return PXL8_ERROR_NOT_INITIALIZED; + + default: + pxl8_error("Unknown procgen type: %d", params->type); + return PXL8_ERROR_INVALID_ARGUMENT; + } +} + +static u32 hash2d(i32 x, i32 y) { + u32 h = ((u32)x * 374761393u) + ((u32)y * 668265263u); + h ^= h >> 13; + h ^= h << 17; + h ^= h >> 5; + return h; +} + +void pxl8_procgen_tex(u8* buffer, const pxl8_procgen_tex_params* params) { + if (!buffer || !params) return; + + for (i32 y = 0; y < params->height; y++) { + for (i32 x = 0; x < params->width; x++) { + f32 u = (f32)x / (f32)params->width; + f32 v = (f32)y / (f32)params->height; + + u8 color = params->base_color; + + // Tile-based pattern (floor style) + if (params->seed == 11111) { + i32 tile_x = (i32)floorf(u * 8.0f); + i32 tile_y = (i32)floorf(v * 8.0f); + u32 h = hash2d(tile_x, tile_y); + + f32 pattern = (f32)(h & 0xFF) / 255.0f; + i32 quantized = (pattern < 0.3f) ? 0 : (pattern < 0.7f) ? 1 : 2; + + color = params->base_color + quantized; + + // Checkerboard dither + if (((tile_x + tile_y) & 1) == 0 && (h & 0x100)) { + color = (color < 255) ? color + 1 : color; + } + } + // Large tile pattern (ceiling style) + else if (params->seed == 22222) { + i32 coarse_x = (i32)floorf(u * 2.0f); + i32 coarse_y = (i32)floorf(v * 2.0f); + u32 coarse_h = hash2d(coarse_x, coarse_y); + + i32 subdivision = (coarse_h >> 8) & 0x3; + i32 tile_x, tile_y; + + switch (subdivision) { + case 0: tile_x = (i32)floorf(u * 3.0f); tile_y = (i32)floorf(v * 3.0f); break; + case 1: tile_x = (i32)floorf(u * 5.0f); tile_y = (i32)floorf(v * 5.0f); break; + case 2: tile_x = (i32)floorf(u * 2.0f); tile_y = (i32)floorf(v * 4.0f); break; + default: tile_x = (i32)floorf(u * 4.0f); tile_y = (i32)floorf(v * 2.0f); break; + } + + u32 h = hash2d(tile_x, tile_y); + f32 pattern = (f32)(h & 0xFF) / 255.0f; + + if (pattern < 0.25f) color = params->base_color; + else if (pattern < 0.50f) color = params->base_color + 1; + else if (pattern < 0.75f) color = params->base_color + 2; + else color = params->base_color + 3; + } + // Brick pattern (wall style) + else { + f32 brick_y = floorf(v * 4.0f); + f32 offset = ((i32)brick_y & 1) ? 0.5f : 0.0f; + i32 brick_x = (i32)floorf(u * 4.0f + offset); + brick_y = (i32)brick_y; + + f32 brick_u = fabsf((u * 4.0f + offset) - floorf(u * 4.0f + offset) - 0.5f); + f32 brick_v = fabsf((v * 4.0f) - floorf(v * 4.0f) - 0.5f); + + u32 h = hash2d(brick_x, (i32)brick_y); + f32 noise = (f32)(h & 0xFF) / 255.0f; + + // Mortar lines + if (brick_u > 0.47f || brick_v > 0.47f) { + color = params->base_color - 2; + } else { + i32 shade = (i32)(noise * 3.0f); + color = params->base_color + shade; + } + } + + buffer[y * params->width + x] = color; + } + } +} diff --git a/src/world/pxl8_gen.h b/client/src/world/pxl8_gen.h similarity index 63% rename from src/world/pxl8_gen.h rename to client/src/world/pxl8_gen.h index bef83b0..a887eb1 100644 --- a/src/world/pxl8_gen.h +++ b/client/src/world/pxl8_gen.h @@ -21,11 +21,24 @@ typedef struct pxl8_procgen_params { i32 num_rooms; } pxl8_procgen_params; +typedef struct pxl8_procgen_tex_params { + char name[16]; + u32 seed; + i32 width; + i32 height; + f32 scale; + f32 roughness; + u8 base_color; + u8 variation; + u8 max_color; +} pxl8_procgen_tex_params; + #ifdef __cplusplus extern "C" { #endif pxl8_result pxl8_procgen(pxl8_bsp* bsp, const pxl8_procgen_params* params); +void pxl8_procgen_tex(u8* buffer, const pxl8_procgen_tex_params* params); #ifdef __cplusplus } diff --git a/src/world/pxl8_world.c b/client/src/world/pxl8_world.c similarity index 98% rename from src/world/pxl8_world.c rename to client/src/world/pxl8_world.c index 90fee37..3f96b74 100644 --- a/src/world/pxl8_world.c +++ b/client/src/world/pxl8_world.c @@ -398,15 +398,15 @@ void pxl8_world_render(pxl8_world* world, pxl8_gfx* gfx, pxl8_vec3 camera_pos) { return; } + static int render_count = 0; + if (render_count++ < 5) { + pxl8_debug("world_render: camera_pos=(%.1f, %.1f, %.1f), num_faces=%u", + camera_pos.x, camera_pos.y, camera_pos.z, world->bsp.num_faces); + } + if (world->wireframe) { pxl8_bsp_render_wireframe(gfx, &world->bsp, camera_pos, world->wireframe_color); } else { pxl8_bsp_render_textured(gfx, &world->bsp, camera_pos); } } - -void pxl8_world_set_wireframe(pxl8_world* world, bool enabled, u8 color) { - if (!world) return; - world->wireframe = enabled; - world->wireframe_color = color; -} diff --git a/src/world/pxl8_world.h b/client/src/world/pxl8_world.h similarity index 94% rename from src/world/pxl8_world.h rename to client/src/world/pxl8_world.h index e2a1f1e..5388a12 100644 --- a/src/world/pxl8_world.h +++ b/client/src/world/pxl8_world.h @@ -32,7 +32,6 @@ bool pxl8_world_check_collision(const pxl8_world* world, pxl8_vec3 pos, f32 radi bool pxl8_world_is_loaded(const pxl8_world* world); void pxl8_world_render(pxl8_world* world, pxl8_gfx* gfx, pxl8_vec3 camera_pos); pxl8_vec3 pxl8_world_resolve_collision(const pxl8_world* world, pxl8_vec3 from, pxl8_vec3 to, f32 radius); -void pxl8_world_set_wireframe(pxl8_world* world, bool enabled, u8 color); #ifdef __cplusplus } diff --git a/demo/main.fnl b/demo/main.fnl index 6b9367d..d078be3 100644 --- a/demo/main.fnl +++ b/demo/main.fnl @@ -1,15 +1,16 @@ (local pxl8 (require :pxl8)) (local menu (require :mod.menu)) (local music (require :mod.music)) -(local first_person3d (require :mod.first_person3d)) +(local worldgen (require :mod.worldgen)) (var time 0) (var active-demo :logo) (var particles nil) +(var particles2 nil) (var fire-init? false) (var rain-init? false) (var snow-init? false) -(var first_person3d-init? false) +(var snow-init2? false) (var use-famicube-palette? false) (var logo-x 256) @@ -31,12 +32,15 @@ (pxl8.load_palette "res/sprites/pxl8_logo.ase") (set logo-sprite (pxl8.load_sprite "res/sprites/pxl8_logo.ase")) (set particles (pxl8.create_particles 1000)) - (music.init))) + (set particles2 (pxl8.create_particles 500)) + (music.init) + (music.start) + (worldgen.init))) (global update (fn [dt] (when (pxl8.key_pressed "escape") (menu.toggle) - (when (= active-demo :first_person3d) + (when (= active-demo :worldgen) (pxl8.set_relative_mouse_mode (not (menu.is-paused))))) (when (not (menu.is-paused)) @@ -46,16 +50,15 @@ (transition:update dt) (when (transition:is_complete) (when transition-pending - (when (and (= active-demo :first_person3d) (not= transition-pending :first_person3d)) + (when (and (= active-demo :worldgen) (not= transition-pending :worldgen)) (pxl8.set_relative_mouse_mode false)) - (when (and (not= active-demo :first_person3d) (= transition-pending :first_person3d)) + (when (and (not= active-demo :worldgen) (= transition-pending :worldgen)) (pxl8.set_relative_mouse_mode true)) (set active-demo transition-pending) (set transition-pending nil) (when (= active-demo :fire) (set fire-init? false)) (when (= active-demo :rain) (set rain-init? false)) - (when (= active-demo :snow) (set snow-init? false)) - (when (= active-demo :first_person3d) (set first_person3d-init? false))) + (when (= active-demo :snow) (set snow-init? false) (set snow-init2? false))) (transition:destroy) (set transition nil))) @@ -66,14 +69,12 @@ (when (pxl8.key_pressed "5") (switch-demo :fire)) (when (pxl8.key_pressed "6") (switch-demo :rain)) (when (pxl8.key_pressed "7") (switch-demo :snow)) - (when (pxl8.key_pressed "8") (switch-demo :first_person3d)) + (when (pxl8.key_pressed "8") (switch-demo :worldgen)) (when (pxl8.key_pressed "=") (set use-famicube-palette? (not use-famicube-palette?)) (local palette-path (if use-famicube-palette? "res/palettes/famicube.ase" "res/sprites/pxl8_logo.ase")) (pxl8.load_palette palette-path)) - (music.update dt) - (case active-demo :logo (do (set logo-x (+ logo-x (* logo-dx dt))) @@ -90,14 +91,14 @@ (when (> logo-y 296) (set logo-y 296) (set logo-dy (- (math.abs logo-dy))))) - :first_person3d (do - (when (not first_person3d-init?) - (first_person3d.init) - (set first_person3d-init? true)) - (first_person3d.update dt))) + :worldgen (worldgen.update dt)) + + (music.update dt) (when particles - (particles:update dt))) + (particles:update dt)) + (when particles2 + (particles2:update dt))) (when (menu.is-paused) (menu.update)))) @@ -172,8 +173,7 @@ (set snow-init? true)) (particles:render))) - :first_person3d (first_person3d.frame) - + :worldgen (worldgen.frame) _ (pxl8.clear 0)) diff --git a/demo/mod/blendtable.fnl b/demo/mod/blendtable.fnl deleted file mode 100644 index b210921..0000000 --- a/demo/mod/blendtable.fnl +++ /dev/null @@ -1,4103 +0,0 @@ -(require :pxl8) -(local ffi (require :ffi)) - -(local data (ffi.new "u8[65536]" [ - 143 175 141 47 158 95 2 2 43 43 3 4 4 4 5 5 - 158 158 158 158 1 47 141 141 47 141 141 142 142 142 175 143 - 31 31 94 94 94 45 158 46 46 47 47 47 141 174 142 142 - 26 245 245 172 41 26 246 245 99 23 62 246 245 172 173 174 - 246 171 172 172 172 172 173 78 79 79 79 174 174 142 175 175 - 30 157 157 45 103 158 46 1 1 47 141 141 141 142 142 142 - 63 77 1 47 190 127 142 175 24 91 39 4 5 38 4 244 - 244 187 124 125 126 126 125 126 190 190 127 190 191 191 143 143 - 27 246 139 139 139 172 140 158 140 47 141 141 142 142 175 143 - 41 155 43 93 44 44 44 30 103 45 102 1 159 141 142 175 - 138 171 139 172 172 173 173 173 173 79 174 174 175 175 143 175 - 186 186 186 187 187 188 188 188 189 126 127 127 127 141 191 175 - 41 42 43 43 93 44 31 45 158 158 1 47 159 141 142 175 - 156 206 206 206 156 101 44 6 6 5 152 201 19 19 17 61 - 17 61 62 62 239 239 171 76 76 77 77 77 78 79 174 174 - 171 137 139 189 127 175 141 39 25 26 172 5 3 244 169 129 - 159 47 158 95 94 2 43 3 3 4 4 4 5 5 5 6 - 101 101 245 63 102 103 103 103 103 158 158 1 47 47 159 159 - 43 43 43 93 44 2 31 94 94 45 103 103 158 1 1 1 - 155 24 26 245 40 22 62 62 17 19 21 62 246 245 63 173 - 137 169 170 170 171 171 171 172 172 172 172 173 140 47 141 141 - 42 25 93 101 101 101 30 157 45 45 103 158 46 1 47 173 - 246 245 102 95 189 158 47 79 90 88 4 5 35 5 5 4 - 244 244 187 187 124 124 124 125 126 126 126 127 127 47 159 141 - 42 24 138 138 138 138 94 94 103 103 46 46 1 47 141 141 - 39 41 41 155 155 42 43 43 44 44 30 45 103 158 1 141 - 137 137 170 246 171 171 171 63 172 172 140 140 47 141 141 190 - 185 185 185 186 186 186 187 187 188 188 189 189 158 46 1 141 - 39 41 41 155 42 43 93 44 157 157 45 102 158 1 159 159 - 205 205 204 204 20 155 156 6 33 200 200 200 16 16 60 61 - 61 61 61 61 238 238 169 239 239 239 75 76 77 173 173 173 - 170 136 137 138 95 159 140 38 136 91 245 36 4 39 168 128 - 95 95 2 2 43 3 3 3 4 4 5 5 35 6 33 33 - 42 24 25 26 101 28 44 44 44 31 31 45 45 45 95 95 - 244 3 3 3 3 3 43 43 43 2 2 2 2 94 45 157 - 40 41 155 24 153 20 21 62 83 17 98 19 23 26 101 139 - 136 168 168 169 170 170 170 246 246 246 246 139 94 103 103 103 - 39 41 42 92 42 42 43 43 43 93 2 2 94 94 45 103 - 62 62 101 2 2 2 102 172 86 134 5 35 34 34 35 5 - 4 4 186 186 121 122 124 124 124 124 188 94 45 95 95 46 - 39 41 42 92 92 92 93 93 93 29 94 94 94 45 95 158 - 4 4 4 4 39 39 41 3 3 3 43 44 2 31 45 103 - 89 136 90 137 137 24 246 246 246 246 94 94 45 103 95 189 - 185 184 185 185 185 186 186 187 187 187 2 2 2 94 45 158 - 5 4 39 39 41 155 155 155 43 43 44 30 157 45 102 158 - 202 203 203 203 154 155 41 7 7 199 200 200 55 55 55 60 - 60 60 97 61 61 168 168 168 169 169 170 170 171 139 139 139 - 168 135 136 244 2 102 94 37 134 88 24 6 5 4 88 128 - 31 2 43 3 3 4 4 4 5 5 35 33 6 33 7 7 - 155 41 41 41 155 42 43 43 43 43 43 43 2 2 2 2 - 4 4 4 4 4 39 244 3 3 3 3 3 3 43 43 93 - 37 40 154 21 152 153 18 19 51 83 84 17 99 22 42 26 - 135 135 88 87 90 90 137 137 137 24 25 27 93 93 44 29 - 38 39 41 41 41 39 41 3 3 3 3 43 43 93 2 28 - 87 21 42 3 3 43 44 101 153 37 36 33 32 33 34 35 - 35 5 4 186 185 186 187 186 186 244 244 43 2 2 2 45 - 38 39 39 39 39 41 41 3 3 3 43 43 43 44 2 31 - 5 5 5 5 4 4 4 4 39 39 3 3 43 43 43 93 - 134 85 86 88 89 90 90 91 92 92 25 93 93 29 2 188 - 183 183 184 184 185 185 185 186 244 244 244 244 3 43 2 2 - 36 5 5 5 40 40 40 40 41 155 42 43 43 44 44 157 - 202 203 201 201 152 154 154 7 8 199 199 214 150 55 55 55 - 55 60 96 96 97 98 166 167 167 168 169 169 170 26 27 138 - 135 133 134 4 3 2 27 36 37 40 41 7 6 5 135 128 - 43 3 3 4 4 4 5 5 35 33 34 33 7 7 7 8 - 39 40 40 40 39 39 41 3 3 3 3 3 3 3 3 3 - 5 5 5 5 38 4 4 4 4 4 4 4 4 3 3 3 - 36 153 153 40 150 152 152 17 150 50 82 83 85 154 41 91 - 84 84 85 85 85 86 88 89 89 41 41 42 42 3 3 43 - 5 38 38 4 4 4 4 39 4 39 39 244 3 3 244 42 - 85 18 154 39 244 3 3 42 151 131 33 7 7 32 32 33 - 34 34 5 184 184 185 186 185 186 186 244 244 244 3 3 43 - 5 38 38 38 38 38 4 39 4 39 244 3 244 244 244 43 - 6 6 6 37 5 5 5 5 38 4 4 39 244 3 3 42 - 37 133 84 85 85 85 40 40 41 41 155 3 3 3 43 187 - 33 182 183 183 183 183 5 5 4 4 4 4 4 244 3 43 - 6 36 36 36 152 153 153 153 153 154 154 41 41 3 3 156 - 201 202 201 200 200 152 5 8 8 147 196 214 214 214 49 54 - 54 55 55 51 83 83 84 166 166 167 167 88 136 136 42 137 - 133 132 132 5 4 3 42 149 151 153 40 8 7 6 132 128 - 3 3 4 4 38 5 5 35 34 7 7 7 8 8 8 9 - 5 153 153 153 40 39 39 39 4 39 39 39 4 4 4 3 - 35 35 37 5 5 5 5 38 4 4 4 4 4 4 244 3 - 6 152 152 153 149 151 151 83 49 50 50 152 153 153 40 41 - 132 83 84 84 84 84 85 86 40 40 40 39 39 39 39 244 - 37 37 37 5 5 5 38 4 38 38 4 4 4 4 4 41 - 153 153 4 4 4 4 41 41 150 130 7 8 8 8 7 7 - 33 34 35 35 183 184 185 184 185 4 4 4 4 39 244 3 - 37 37 37 5 5 5 38 4 38 4 4 4 4 244 244 3 - 33 33 33 6 6 36 37 5 5 5 38 4 4 4 39 41 - 151 82 152 152 84 153 153 153 40 39 39 39 39 244 244 244 - 32 33 33 33 33 34 35 35 5 5 5 4 4 4 4 3 - 7 6 6 150 151 152 152 152 153 153 40 4 39 39 3 155 - 196 200 200 201 200 152 6 10 9 145 146 146 147 214 49 49 - 49 54 54 50 81 51 82 84 165 85 85 85 135 40 41 136 - 132 131 131 35 4 3 41 148 150 152 153 8 7 7 131 128 - 4 4 5 5 5 35 6 33 7 7 8 8 8 9 10 9 - 36 151 152 37 5 5 38 38 38 38 4 4 4 4 4 4 - 33 34 6 35 35 35 35 35 35 5 5 5 5 38 4 4 - 149 150 150 152 148 150 150 151 48 49 49 150 151 152 5 40 - 131 82 82 82 82 132 133 153 153 38 39 38 38 38 4 4 - 34 6 6 6 36 37 37 37 35 5 5 5 5 38 4 4 - 152 152 5 5 5 4 4 40 149 129 8 8 9 9 8 7 - 7 33 33 33 34 35 183 35 35 35 5 5 38 4 4 4 - 6 33 6 35 36 35 37 5 5 5 5 38 38 4 4 4 - 7 7 7 7 33 33 6 6 6 35 37 5 5 5 4 38 - 150 50 151 151 151 152 152 37 37 38 38 4 38 4 4 4 - 32 32 32 33 32 33 34 34 35 35 35 5 5 4 4 4 - 8 7 7 149 150 150 151 152 152 152 153 5 5 4 4 39 - 196 197 197 197 199 150 6 9 9 144 145 145 146 147 147 48 - 49 49 49 49 80 80 81 82 83 83 84 133 133 38 38 135 - 131 130 130 34 5 4 40 146 149 151 151 146 8 8 130 128 - 5 5 35 6 34 33 7 7 7 8 8 8 9 10 10 10 - 150 150 150 150 6 36 37 37 5 5 5 5 5 5 5 5 - 7 32 33 33 33 33 33 33 33 34 35 35 35 5 5 5 - 148 148 148 150 146 148 148 149 146 48 148 149 149 150 6 37 - 254 49 49 80 50 50 151 151 152 37 37 5 5 5 5 5 - 7 7 7 33 33 6 34 33 34 6 35 35 5 5 5 5 - 150 150 6 6 35 5 5 5 128 128 9 9 10 9 9 8 - 9 7 32 32 33 33 32 33 35 35 35 5 5 5 5 5 - 7 7 7 33 34 6 34 34 35 35 37 5 5 5 5 5 - 8 8 8 7 7 7 7 7 33 33 34 34 34 35 5 37 - 149 254 254 150 150 150 151 36 36 37 37 5 5 5 5 5 - 9 8 32 32 32 33 32 32 33 33 34 35 35 5 5 5 - 8 8 8 147 147 148 149 150 150 151 151 6 36 5 5 5 - 196 214 196 214 196 199 7 10 10 10 144 144 144 146 146 146 - 48 48 48 48 49 49 49 80 81 81 82 132 132 37 37 37 - 129 129 128 32 35 5 38 253 148 149 149 9 9 8 129 128 - 35 6 34 33 7 7 7 8 8 9 9 10 10 10 11 11 - 7 148 7 7 7 6 6 6 6 33 33 34 34 34 34 6 - 7 7 7 7 7 7 7 7 33 6 33 33 33 33 6 6 - 8 147 147 148 145 146 147 148 146 48 48 147 148 149 6 150 - 128 48 254 49 254 254 254 150 150 150 6 33 6 6 35 5 - 7 7 8 7 7 7 7 8 34 34 34 33 33 33 34 36 - 149 149 7 33 33 34 6 36 128 146 9 10 10 10 10 9 - 8 8 8 8 32 32 32 32 33 34 33 34 34 35 5 35 - 7 7 7 7 7 7 7 8 33 34 34 34 34 6 35 5 - 9 8 9 9 8 8 7 7 8 7 7 33 6 33 34 34 - 147 48 48 148 149 149 149 7 36 6 6 6 35 35 35 35 - 9 8 8 9 8 8 7 8 33 32 33 33 33 33 6 5 - 9 8 8 8 146 146 148 149 149 148 148 6 6 6 6 5 - 195 196 196 195 196 147 147 12 10 11 11 144 144 144 144 147 - 146 48 48 48 48 48 254 49 254 254 130 130 131 36 36 36 - 129 128 128 8 33 6 150 106 253 148 148 10 9 8 253 128 - 33 6 7 8 7 8 9 8 9 10 10 10 11 11 11 11 - 8 8 148 7 7 7 7 8 7 7 7 7 33 33 33 34 - 8 8 9 9 9 8 8 7 7 7 7 7 7 7 33 33 - 9 146 146 146 144 145 145 253 253 144 144 146 147 8 7 36 - 129 48 48 48 48 48 148 149 149 149 7 33 33 34 34 34 - 9 8 8 8 8 8 7 32 8 8 8 7 32 33 33 34 - 147 147 7 7 7 7 33 37 106 106 10 10 11 11 10 10 - 10 10 9 9 8 8 32 32 32 33 7 7 33 33 34 33 - 9 8 8 8 8 8 7 7 7 7 8 7 33 6 34 33 - 9 10 10 9 8 8 9 8 8 7 7 8 8 7 34 34 - 147 48 48 147 148 148 148 148 8 7 7 33 34 6 34 33 - 9 10 10 9 9 9 9 8 9 8 7 7 8 32 34 33 - 10 9 9 9 146 146 146 146 146 148 7 7 7 7 33 6 - 194 195 195 194 194 145 146 11 12 11 11 252 144 144 144 144 - 144 144 253 48 48 253 48 254 48 48 254 254 129 7 33 34 - 128 128 128 8 32 7 149 144 144 253 147 10 11 10 128 128 - 7 7 8 8 8 9 9 10 10 10 11 11 11 12 12 12 - 9 9 9 9 8 8 8 7 7 8 8 7 7 7 7 7 - 10 10 9 8 8 8 8 8 9 8 8 8 7 7 7 7 - 9 9 9 9 10 144 144 253 106 144 144 144 145 9 8 7 - 106 106 253 253 128 128 128 147 148 148 7 8 8 7 7 7 - 10 9 9 8 9 9 9 9 8 8 8 8 8 7 7 8 - 146 145 9 8 8 7 7 8 106 106 11 11 12 12 11 10 - 10 10 10 9 9 9 9 9 8 8 7 7 7 7 32 8 - 10 9 9 8 8 8 9 9 9 8 8 7 7 7 7 7 - 11 10 9 9 10 10 9 8 9 8 9 8 8 8 7 7 - 106 144 253 253 146 146 146 8 7 7 7 7 7 7 7 32 - 10 110 10 10 10 10 9 9 8 9 9 8 7 7 7 8 - 10 10 10 10 9 9 9 9 8 8 8 8 7 7 7 7 - 194 194 193 193 194 145 9 13 13 107 107 107 252 106 106 106 - 144 106 144 253 106 106 106 253 48 48 128 128 128 8 8 7 - 106 253 11 9 8 7 7 252 106 144 144 11 11 10 106 128 - 7 8 8 8 9 10 9 10 11 11 11 12 12 12 12 13 - 10 9 9 9 9 8 8 8 8 9 9 8 8 8 8 8 - 9 9 9 9 9 10 10 9 9 9 9 8 8 9 8 9 - 10 10 10 10 11 106 106 144 252 106 144 144 144 9 8 8 - 144 106 106 106 144 253 253 146 146 8 8 8 8 8 8 8 - 9 10 10 10 10 9 9 10 8 8 9 9 8 8 8 8 - 144 145 9 8 8 9 8 8 106 106 11 12 12 12 12 11 - 11 11 10 10 112 112 9 9 9 8 9 8 8 8 7 7 - 9 9 9 10 10 10 9 9 8 8 8 9 9 9 8 7 - 11 10 11 11 10 10 9 10 10 10 10 8 8 8 8 8 - 144 144 144 144 144 253 9 8 9 8 8 8 8 8 8 32 - 11 110 110 11 10 10 10 10 9 9 9 8 8 9 9 8 - 11 11 11 11 10 10 9 9 9 9 9 8 8 9 8 7 - 193 193 192 192 192 144 10 14 13 107 107 252 107 251 107 252 - 252 106 106 144 253 253 253 106 106 253 253 253 253 8 8 8 - 106 253 10 8 8 9 9 107 106 144 144 13 11 11 106 128 - 9 8 9 10 10 10 11 11 11 12 12 12 12 13 13 13 - 10 10 10 9 9 9 10 10 9 10 9 9 9 9 9 8 - 10 11 11 11 11 10 10 9 10 9 10 10 9 9 9 9 - 11 10 10 11 107 107 252 106 252 252 252 106 144 10 9 8 - 253 106 106 106 106 106 106 144 10 9 9 8 8 8 9 9 - 11 11 11 10 10 10 9 10 10 10 9 9 9 9 9 8 - 10 10 10 10 10 9 9 8 107 107 12 13 13 13 108 108 - 12 109 110 110 110 111 111 112 10 9 9 9 9 9 8 8 - 11 11 11 11 10 10 10 9 10 10 9 9 9 8 8 9 - 11 12 12 11 10 11 11 10 11 9 9 10 10 9 8 9 - 106 106 106 144 144 10 10 9 10 9 9 9 9 9 8 8 - 12 109 109 109 11 11 10 11 11 10 9 10 10 9 9 9 - 12 11 11 11 11 11 10 10 11 10 9 10 9 9 9 8 - 11 192 192 192 11 11 11 14 14 14 251 107 252 252 107 107 - 252 252 252 252 252 106 253 253 106 106 106 144 253 9 9 8 - 106 253 11 9 9 10 9 107 107 252 144 12 13 12 106 128 - 9 9 10 10 11 11 11 11 12 12 12 13 13 13 14 14 - 10 10 11 11 11 10 10 10 10 10 10 9 9 9 9 9 - 12 12 11 11 10 11 11 10 11 10 10 10 10 10 9 9 - 12 11 11 11 12 107 107 252 251 251 107 252 11 10 10 9 - 107 252 106 106 144 106 106 106 10 10 10 10 10 10 9 9 - 12 11 11 10 10 11 11 11 10 10 10 10 10 10 9 9 - 10 10 11 10 10 9 9 10 107 251 13 13 14 14 13 108 - 109 109 109 110 110 110 110 110 10 10 10 9 9 9 9 10 - 12 11 11 11 10 10 11 11 11 10 10 9 9 9 9 10 - 13 12 11 11 12 12 11 10 11 10 10 10 10 10 9 9 - 107 252 252 106 106 11 11 11 10 10 9 9 9 10 10 10 - 108 108 108 109 109 12 12 11 11 11 11 11 10 9 9 10 - 13 12 12 12 11 12 11 11 11 10 11 10 10 9 9 10 - 11 10 10 11 11 11 11 15 215 215 215 251 251 252 252 251 - 251 251 107 252 252 252 252 252 253 106 106 106 10 10 10 9 - 252 107 13 10 9 9 9 251 251 107 106 14 13 12 252 128 - 10 11 10 11 12 12 11 12 13 13 13 14 14 14 15 15 - 12 12 11 11 11 11 11 11 11 11 11 11 11 11 11 11 - 11 11 12 12 12 12 12 12 11 10 11 10 10 11 11 11 - 13 12 12 12 13 107 107 252 251 251 107 107 107 11 10 10 - 107 252 252 252 252 252 252 106 10 10 10 11 11 11 10 10 - 12 12 12 12 12 12 11 11 11 11 11 10 10 10 10 10 - 107 11 10 110 11 11 11 10 107 251 13 14 15 15 14 108 - 108 108 108 109 109 110 110 110 10 10 11 11 11 11 10 9 - 12 12 12 12 12 12 11 11 11 11 11 11 11 11 10 9 - 13 13 13 13 13 12 11 12 11 12 12 11 10 11 10 10 - 107 107 107 107 107 107 11 10 11 11 11 11 10 10 10 9 - 108 108 108 108 12 12 12 12 12 12 11 10 11 11 11 9 - 13 13 13 13 13 12 12 12 12 11 11 10 11 11 11 9 - 11 11 11 12 11 12 12 15 15 215 216 216 216 216 251 251 - 251 251 251 251 107 252 252 252 252 252 252 252 252 11 10 10 - 107 251 107 10 11 11 10 14 251 107 107 215 13 13 251 128 - 11 10 11 12 12 12 13 12 13 13 14 14 15 15 15 215 - 12 12 12 12 12 12 11 11 12 12 11 11 11 11 11 10 - 13 13 13 13 13 12 12 11 11 11 12 12 12 12 11 10 - 13 13 13 13 14 251 251 251 251 251 251 107 107 107 107 11 - 107 252 252 252 107 251 107 252 107 252 11 10 10 11 11 11 - 13 13 13 12 12 12 12 12 11 12 12 12 11 11 11 10 - 107 107 12 12 12 11 11 10 251 251 215 215 15 15 15 14 - 14 108 108 108 109 109 109 12 12 12 11 11 10 11 10 11 - 13 13 13 13 12 107 107 107 12 12 12 11 11 10 10 11 - 14 14 14 13 13 13 13 13 13 107 11 107 107 11 11 11 - 251 251 251 107 107 107 107 107 107 107 11 11 11 10 11 11 - 14 108 108 14 13 13 13 13 13 12 11 12 12 11 11 11 - 14 14 14 13 13 13 13 13 12 11 12 12 11 11 10 11 - 13 12 12 13 12 12 12 215 215 215 216 216 216 216 216 216 - 216 251 251 251 251 252 252 251 252 252 252 252 252 106 11 106 - 252 251 251 12 12 11 11 215 251 251 107 215 215 14 251 128 - 21 99 154 40 153 153 152 152 151 150 150 149 148 148 146 145 - 152 153 16 16 153 17 18 18 19 19 154 20 20 20 20 20 - 151 152 152 152 153 153 153 153 85 18 40 18 40 154 154 20 - 151 51 83 83 49 50 51 96 49 54 55 96 97 16 17 98 - 96 96 96 96 96 97 97 97 98 98 98 19 88 88 88 20 - 152 152 152 152 152 153 16 17 17 17 18 18 18 19 20 20 - 84 16 16 18 18 19 20 20 82 49 149 147 146 147 148 7 - 7 6 36 5 5 5 4 4 4 39 41 41 41 41 155 23 - 151 152 152 152 152 152 16 16 16 17 18 19 20 99 21 21 - 149 150 150 150 151 151 152 152 152 152 16 18 19 19 20 20 - 51 51 83 97 97 97 97 17 98 98 86 19 20 99 21 155 - 6 6 6 6 6 36 37 5 37 153 153 40 86 86 20 99 - 149 149 150 151 151 83 83 83 16 16 18 19 19 20 20 21 - 196 197 198 200 200 200 152 145 147 146 48 53 53 53 58 54 - 54 54 54 54 55 96 96 96 96 165 165 97 98 87 87 87 - 164 163 132 134 39 154 21 49 50 50 97 48 254 254 81 48 - 23 21 20 19 18 16 84 83 82 151 150 150 149 148 147 146 - 16 17 17 17 17 19 19 19 19 20 20 21 21 21 23 23 - 152 84 84 84 84 85 85 18 18 19 19 20 20 20 21 21 - 51 96 97 97 54 55 96 60 54 59 55 96 97 17 19 61 - 96 60 60 60 61 61 61 61 61 61 61 90 90 21 21 21 - 83 83 16 16 16 16 17 17 19 19 19 19 20 21 21 62 - 16 17 17 19 20 21 21 62 51 80 49 148 147 148 148 199 - 150 36 152 153 153 4 39 39 39 154 155 22 22 21 23 62 - 152 83 83 16 16 16 17 17 17 19 19 20 21 21 23 62 - 150 50 50 51 51 83 83 83 16 16 17 19 19 20 21 62 - 55 96 16 97 97 61 61 61 61 61 168 21 21 21 62 100 - 6 35 37 37 37 5 38 38 153 40 86 19 20 99 21 21 - 150 50 50 51 51 96 96 97 17 17 98 19 20 20 21 23 - 201 201 201 201 201 201 153 145 147 48 53 54 58 58 59 58 - 58 59 59 59 60 60 60 96 165 165 166 166 61 61 90 168 - 165 164 133 135 40 99 21 49 55 55 97 48 49 80 82 104 - 62 23 21 20 19 18 84 84 152 151 150 150 149 148 148 146 - 17 17 17 19 19 19 19 20 21 21 21 21 21 23 23 23 - 153 153 84 84 84 85 18 19 19 19 20 20 21 21 21 23 - 51 96 16 16 55 55 60 60 54 55 55 96 97 61 19 61 - 60 60 60 61 61 61 61 61 61 61 168 21 21 23 23 62 - 16 16 16 17 17 17 17 17 19 19 20 21 21 21 23 62 - 17 17 98 19 20 21 21 62 83 80 50 49 148 148 149 199 - 36 152 5 38 39 39 39 154 41 41 155 23 23 23 23 62 - 152 16 16 17 17 17 17 17 19 20 21 21 21 23 62 62 - 50 151 151 83 83 83 16 16 16 17 18 19 20 20 21 62 - 96 96 97 61 61 61 61 61 61 61 21 21 21 23 62 24 - 36 35 5 5 5 5 38 38 40 40 88 99 99 22 23 62 - 150 151 83 83 83 83 16 16 17 61 98 19 20 21 23 23 - 202 202 202 202 202 201 153 146 147 48 48 54 59 59 59 59 - 58 59 59 60 60 60 60 96 165 166 61 61 168 168 168 168 - 165 164 134 135 88 99 62 49 55 96 17 48 49 80 82 48 - 62 23 22 99 88 18 85 153 152 151 150 150 149 148 148 146 - 17 17 19 19 19 19 20 20 21 21 21 21 22 23 23 22 - 153 153 153 153 85 85 86 19 19 20 99 21 21 22 23 62 - 83 16 16 17 55 55 97 97 55 55 55 96 97 61 21 62 - 97 60 97 61 61 61 61 61 61 21 21 21 62 23 23 62 - 16 16 17 17 17 17 18 19 19 19 20 21 21 23 23 62 - 17 17 19 19 20 21 21 62 83 50 50 149 148 149 149 6 - 36 37 5 38 39 39 41 41 155 155 155 42 100 24 24 62 - 84 16 17 17 17 17 18 19 20 20 21 21 23 23 62 62 - 151 151 152 83 84 84 84 17 17 18 19 20 20 21 23 62 - 97 97 97 61 61 61 61 61 61 21 21 21 23 23 62 26 - 36 35 37 5 5 5 38 39 40 40 41 99 22 23 23 23 - 150 151 83 83 16 16 16 17 61 98 19 20 21 23 23 24 - 201 201 201 201 202 202 202 146 146 48 48 54 58 58 59 59 - 59 59 59 60 60 60 60 165 165 166 237 168 168 168 62 169 - 165 164 133 135 41 22 62 50 55 96 17 48 49 50 83 48 - 246 246 23 21 99 19 85 153 153 152 151 150 149 149 148 147 - 19 19 20 20 20 21 21 21 21 21 23 23 23 62 62 246 - 153 153 40 40 86 86 20 20 99 21 22 23 23 23 62 62 - 16 16 17 17 51 96 97 61 55 60 96 97 17 19 21 62 - 61 61 61 61 61 61 61 168 169 62 62 62 62 62 246 62 - 17 17 17 17 17 19 19 20 20 21 21 23 62 62 62 62 - 98 19 20 21 21 23 62 62 84 50 50 149 148 149 150 6 - 36 37 5 39 39 41 3 3 3 155 42 100 26 26 246 246 - 85 17 17 17 18 19 19 20 20 21 21 23 23 23 246 246 - 151 152 152 152 153 84 85 85 85 86 87 99 21 22 23 62 - 97 97 61 61 61 61 61 21 21 21 62 62 62 62 246 246 - 37 35 5 5 5 38 4 39 39 41 41 91 23 100 24 246 - 150 151 152 16 16 16 17 19 19 19 20 21 62 62 24 246 - 202 202 202 201 201 202 202 147 146 48 54 54 54 58 58 59 - 59 59 60 60 60 60 165 166 166 237 237 238 169 169 62 169 - 166 165 134 135 136 23 62 50 96 97 61 254 50 82 83 48 - 245 246 24 23 22 99 40 85 153 152 151 151 150 149 148 148 - 20 20 21 21 21 21 23 23 62 23 62 62 62 246 246 246 - 153 40 40 154 41 99 99 21 21 22 23 23 23 24 246 62 - 16 17 18 19 55 16 17 61 55 60 97 97 61 21 23 62 - 98 61 61 61 61 168 62 62 62 62 62 62 62 246 246 246 - 18 18 19 19 19 19 21 21 21 21 23 62 62 62 246 62 - 20 20 21 21 23 62 62 62 85 82 50 150 149 150 6 37 - 5 5 38 39 41 3 3 3 3 43 43 156 101 246 245 246 - 85 18 18 18 19 20 21 62 21 23 62 62 62 246 246 246 - 152 152 153 153 153 85 85 85 86 99 90 22 23 100 26 62 - 98 61 61 61 61 61 21 21 62 62 62 62 246 246 246 246 - 35 5 5 38 38 4 39 39 39 41 155 42 92 24 26 246 - 152 152 153 17 17 17 19 19 19 20 21 62 62 62 246 246 - 203 203 202 202 202 202 154 147 147 49 54 54 54 59 59 59 - 60 60 60 60 60 60 166 237 237 237 72 238 238 62 62 169 - 166 166 135 136 91 24 62 50 96 97 61 254 50 83 97 254 - 245 246 26 24 91 22 154 40 153 152 151 151 150 149 149 148 - 20 21 21 21 23 23 62 62 62 246 246 246 246 246 246 246 - 40 40 154 41 41 99 22 22 22 23 23 24 24 246 246 246 - 17 18 19 19 83 16 17 61 55 60 97 98 61 21 23 62 - 98 61 61 168 168 169 169 62 62 62 62 246 246 246 245 245 - 86 19 19 99 99 21 21 23 23 23 62 62 246 246 246 246 - 21 21 22 23 23 246 246 246 86 83 82 150 149 6 36 5 - 5 38 39 39 3 3 3 3 43 43 43 93 28 157 245 63 - 85 86 86 20 99 21 62 62 23 62 62 246 246 246 245 245 - 153 153 153 153 40 86 86 86 88 90 91 23 24 246 246 245 - 98 167 61 168 168 168 62 62 23 62 246 246 246 245 245 245 - 37 5 5 4 4 4 39 41 41 41 42 92 25 26 101 246 - 152 153 153 18 18 19 19 19 20 21 23 62 23 246 246 245 - 202 202 203 203 203 203 154 147 148 150 49 54 54 59 59 60 - 60 60 60 60 60 165 166 237 71 72 238 238 239 170 170 170 - 167 166 135 136 92 26 245 50 16 17 21 254 50 84 97 48 - 245 245 246 24 92 41 154 40 40 153 152 152 151 150 199 148 - 21 21 23 62 62 62 62 246 246 246 246 246 245 245 245 245 - 41 41 41 41 41 155 23 23 24 26 246 246 246 246 246 245 - 18 19 20 20 16 16 19 61 55 60 97 98 19 21 24 246 - 167 167 168 168 238 238 62 169 62 62 246 246 246 245 245 245 - 86 88 87 21 21 23 23 23 62 62 246 246 246 246 245 245 - 22 62 62 24 246 246 245 171 86 83 132 131 150 36 36 5 - 5 38 4 3 3 3 43 43 43 43 44 44 28 157 245 63 - 40 86 89 99 90 90 22 23 23 62 246 246 246 245 245 63 - 152 153 153 40 40 86 89 99 99 22 23 24 24 246 245 171 - 167 167 168 168 168 90 62 62 62 246 246 245 245 245 63 139 - 5 5 38 38 4 4 3 3 3 42 43 26 101 101 157 245 - 152 153 153 40 19 20 20 20 21 62 62 62 246 246 245 207 - 203 203 203 203 203 202 20 148 148 149 49 54 55 60 60 60 - 55 60 60 61 61 165 166 237 71 168 238 238 239 239 171 171 - 167 166 135 136 27 246 63 152 16 98 21 49 82 84 97 48 - 172 245 28 26 92 155 41 40 40 40 38 37 6 6 7 149 - 23 23 23 23 62 246 246 246 246 246 246 245 245 245 63 63 - 41 41 41 41 155 155 92 24 24 246 246 246 246 245 245 245 - 18 20 20 21 16 18 19 62 55 16 17 19 21 62 246 171 - 98 168 238 238 238 238 239 170 171 171 246 246 245 245 245 245 - 99 99 22 22 22 23 23 62 24 246 246 246 246 245 245 63 - 23 62 24 26 246 246 245 63 86 84 132 131 150 6 5 5 - 4 4 39 3 3 3 43 43 43 2 2 31 94 139 172 172 - 40 88 99 22 22 23 23 23 24 26 246 246 246 245 63 63 - 152 153 40 40 40 20 99 99 22 91 100 26 246 246 245 245 - 88 167 168 168 168 169 62 246 24 26 246 246 245 63 63 103 - 5 5 38 4 4 39 3 3 3 42 43 93 101 157 245 102 - 152 153 153 40 40 20 20 20 22 23 62 246 246 245 245 207 - 203 202 202 203 203 203 20 148 149 149 50 55 60 60 60 60 - 55 60 60 60 97 167 237 168 238 238 238 239 239 239 171 171 - 167 166 136 136 25 101 63 152 16 61 21 150 132 84 167 48 - 140 172 157 101 25 42 41 41 39 39 38 5 36 6 33 7 - 23 23 23 24 246 246 246 246 246 246 245 245 245 63 63 103 - 41 3 3 3 155 42 92 25 26 246 246 101 246 245 245 63 - 19 21 99 23 16 19 20 62 16 16 98 19 21 62 246 171 - 167 168 238 238 238 239 239 239 171 171 171 171 171 245 245 245 - 99 90 22 22 23 23 24 24 246 246 246 246 246 245 245 63 - 23 23 24 26 246 246 245 63 89 134 132 36 6 6 37 5 - 4 4 39 3 3 3 43 43 2 2 94 45 45 103 172 172 - 40 88 90 91 23 23 24 24 246 246 246 245 245 63 172 140 - 153 153 40 154 154 41 99 22 22 23 24 26 246 245 245 63 - 87 168 168 168 169 169 62 246 246 246 246 245 245 63 172 158 - 5 5 4 4 4 39 3 3 3 43 93 101 101 157 102 102 - 153 153 40 154 41 21 22 21 23 24 246 246 246 245 63 63 - 203 203 203 203 203 203 20 148 149 150 50 55 60 60 55 55 - 55 60 60 97 61 61 168 238 238 238 238 239 239 171 171 171 - 168 166 136 136 138 245 63 152 16 61 21 150 132 84 167 48 - 140 103 157 28 93 43 3 41 39 39 38 5 5 36 6 6 - 100 23 24 246 246 246 245 245 245 245 245 63 63 172 172 158 - 3 3 3 3 3 43 25 26 26 101 157 157 245 63 139 63 - 20 21 21 23 16 19 20 62 16 61 19 87 21 62 245 245 - 168 168 238 238 238 239 239 239 75 171 171 171 171 63 172 172 - 90 22 91 23 23 100 26 26 246 246 246 245 245 63 172 172 - 23 24 26 246 246 245 172 172 88 134 132 36 36 36 5 5 - 4 4 244 244 244 43 2 2 2 2 94 45 103 103 158 172 - 41 90 91 23 24 24 26 26 246 246 245 139 139 139 158 1 - 40 153 153 154 21 41 41 23 23 100 26 246 245 245 63 63 - 90 168 169 169 169 169 170 246 246 245 245 245 63 172 140 46 - 4 4 4 4 4 244 3 3 43 43 44 30 157 102 102 158 - 38 40 154 154 41 22 23 23 24 246 246 246 245 63 172 207 - 203 203 203 203 203 203 155 148 149 150 51 55 60 55 55 55 - 60 60 61 61 61 168 168 238 238 238 238 239 239 171 171 171 - 168 166 136 136 29 103 63 152 17 21 23 150 132 84 167 128 - 1 158 45 30 93 43 3 3 41 39 4 5 5 5 6 6 - 24 246 246 246 246 245 245 245 245 63 63 172 172 158 140 1 - 3 3 3 43 43 43 93 101 27 101 157 157 139 103 158 172 - 99 23 23 62 16 20 21 62 16 61 61 21 62 246 245 171 - 168 168 238 238 239 239 239 239 171 171 172 172 172 172 172 172 - 91 91 91 24 24 26 246 246 246 245 245 245 63 63 172 172 - 24 246 246 246 245 63 172 172 88 134 132 36 36 36 5 4 - 4 4 244 3 43 2 188 188 188 188 45 95 103 158 140 140 - 41 91 23 24 26 26 246 246 246 246 139 139 139 158 1 1 - 40 40 154 41 155 155 155 42 24 26 26 101 245 63 63 172 - 90 169 169 169 169 170 170 246 171 245 63 63 158 1 1 1 - 4 185 185 186 244 244 244 3 43 43 44 31 45 102 158 1 - 38 39 154 154 41 155 23 23 246 246 245 245 245 63 173 173 - 204 204 204 204 204 204 155 149 149 150 151 55 55 55 55 60 - 60 60 61 61 168 168 168 238 238 238 239 239 239 171 172 77 - 168 167 136 137 94 103 173 153 19 62 62 151 133 85 87 128 - 141 1 102 157 2 44 43 3 3 39 4 38 5 5 35 6 - 26 246 246 245 245 245 63 63 63 139 172 158 140 140 140 1 - 3 3 3 43 43 93 44 30 28 157 157 45 103 158 46 140 - 22 23 23 246 17 21 21 62 17 61 87 90 62 245 63 172 - 169 238 238 239 239 239 239 76 76 77 77 172 172 172 172 173 - 91 92 24 26 26 246 246 246 245 245 245 63 139 172 140 173 - 26 246 246 245 63 172 140 173 91 135 134 37 36 37 5 4 - 4 39 244 43 2 188 188 188 125 95 95 158 46 47 141 141 - 91 91 24 26 246 246 246 246 139 139 139 140 140 1 141 141 - 40 154 41 41 41 155 100 42 25 26 101 157 63 63 140 173 - 23 169 170 170 170 170 171 171 171 171 172 172 140 1 159 159 - 186 186 186 186 186 244 244 187 43 2 2 94 45 102 46 159 - 4 154 41 41 155 23 100 24 246 245 245 245 63 63 173 173 - 204 204 204 204 204 204 156 150 150 150 151 55 55 55 60 60 - 61 61 61 61 238 238 238 238 238 238 239 75 76 77 173 77 - 169 167 137 137 94 103 173 153 99 62 62 132 133 135 87 128 - 141 47 158 45 31 44 43 3 3 39 4 38 5 5 35 6 - 26 246 245 245 245 245 63 172 172 172 158 140 140 140 1 47 - 3 3 43 43 44 44 29 31 30 45 103 103 103 158 1 1 - 22 24 24 246 18 21 23 62 61 61 62 62 62 245 63 172 - 169 238 239 239 239 239 171 76 77 77 173 173 173 173 173 173 - 92 24 26 26 246 246 246 245 245 63 63 172 172 140 140 173 - 246 246 245 63 172 140 173 173 91 135 134 37 37 5 4 4 - 4 3 3 2 188 188 188 188 189 189 189 46 47 159 141 79 - 92 24 26 246 246 246 246 171 139 139 172 140 140 47 159 174 - 39 41 155 41 41 42 24 24 93 101 30 157 103 158 1 173 - 23 62 170 170 170 171 171 171 171 172 172 140 1 159 159 159 - 185 186 186 186 186 187 187 187 188 188 94 45 103 158 1 47 - 39 154 155 155 155 42 24 26 246 245 63 63 63 173 173 159 - 205 204 204 204 204 204 156 6 150 151 151 55 60 60 60 61 - 61 61 97 61 238 238 238 238 74 74 75 75 76 77 173 78 - 169 168 137 137 103 1 173 153 19 22 23 131 133 135 87 128 - 174 159 158 45 31 44 43 3 3 244 4 4 5 5 35 36 - 101 245 245 63 63 63 172 140 140 140 140 140 1 47 47 47 - 43 43 43 2 2 2 31 31 157 103 102 102 158 1 47 159 - 22 24 24 245 18 21 62 62 61 61 62 62 62 245 172 173 - 170 238 239 239 239 239 171 77 77 77 173 173 173 173 173 173 - 24 26 26 246 246 246 245 245 63 63 172 140 140 1 141 79 - 246 245 63 172 140 140 173 173 91 135 134 37 37 5 4 4 - 4 3 3 2 188 188 189 189 189 126 126 46 47 141 141 79 - 92 24 26 246 246 246 246 139 139 139 172 140 140 159 159 174 - 154 41 155 155 155 42 43 43 93 28 94 103 103 46 1 173 - 100 23 170 170 170 171 171 171 172 172 172 173 173 159 159 127 - 185 185 186 186 187 187 187 188 188 188 188 189 95 46 47 141 - 4 41 155 155 155 100 26 101 101 245 63 63 1 159 159 159 - 205 204 204 204 204 204 101 6 151 151 151 55 60 60 61 61 - 61 61 97 61 238 238 238 74 75 75 75 76 76 77 78 78 - 170 168 170 138 103 1 79 153 20 23 23 36 134 135 90 128 - 142 159 1 102 45 2 2 43 244 244 4 4 38 5 35 35 - 28 245 139 139 139 103 140 140 140 1 1 1 47 47 141 141 - 43 43 2 2 2 2 2 94 45 103 158 158 158 1 47 47 - 155 24 26 245 19 23 62 62 17 61 62 62 246 245 140 173 - 170 238 239 239 75 75 76 78 173 173 173 173 141 141 141 141 - 25 26 27 28 28 28 157 139 172 172 140 140 140 47 141 141 - 245 245 139 158 140 140 173 173 137 41 134 38 37 5 4 4 - 4 244 244 187 188 188 125 189 126 126 126 127 159 141 174 174 - 92 25 27 138 138 138 138 139 139 172 140 140 47 141 141 142 - 3 39 41 3 43 3 43 43 44 29 94 45 103 46 1 141 - 24 246 246 246 171 171 172 172 172 172 140 173 141 159 141 190 - 185 185 186 186 186 187 187 187 188 188 189 189 189 1 47 141 - 4 41 3 42 42 43 101 101 101 245 158 1 1 159 159 159 - 204 204 205 205 205 205 101 6 6 151 151 16 16 16 97 61 - 61 61 61 61 238 238 238 75 239 75 75 76 77 77 78 78 - 170 168 170 137 189 1 79 85 23 62 246 37 40 136 169 129 - 38 5 5 35 35 34 33 33 32 32 8 9 8 9 10 9 - 34 34 35 35 37 37 37 5 37 5 5 5 5 5 38 38 - 32 32 33 33 33 34 34 35 35 35 5 5 5 5 5 5 - 7 7 6 36 147 148 149 50 48 48 149 149 150 36 37 37 - 130 130 131 131 132 132 132 37 37 37 5 5 5 5 5 38 - 34 34 33 33 34 34 35 35 37 37 37 37 37 5 5 5 - 34 36 37 37 37 5 5 38 7 7 9 8 10 8 9 9 - 32 32 32 32 182 183 183 183 184 184 5 5 5 5 38 4 - 33 33 33 34 34 34 34 34 35 37 37 37 5 5 38 4 - 8 7 7 8 7 7 33 33 33 34 35 35 35 5 5 38 - 129 131 131 131 36 37 37 37 37 37 5 5 5 38 4 4 - 181 181 181 181 181 32 32 32 34 34 35 35 35 5 5 5 - 7 7 7 8 7 33 6 6 33 6 37 5 5 5 5 4 - 196 196 198 197 198 199 6 10 9 9 144 144 145 48 48 48 - 48 48 48 49 80 254 130 131 131 132 132 132 132 37 38 38 - 131 129 130 34 35 5 37 146 147 150 150 10 8 7 129 128 - 4 38 5 35 35 34 33 33 32 32 8 8 9 9 9 10 - 35 35 35 35 35 37 5 5 5 5 5 5 38 38 38 38 - 33 33 33 34 34 34 35 35 35 35 5 5 5 5 5 38 - 7 33 6 36 8 148 149 151 147 149 149 150 131 37 37 38 - 130 162 131 132 132 132 133 37 38 38 38 38 5 38 4 4 - 33 33 33 34 34 35 35 35 35 35 37 5 5 5 5 38 - 36 36 37 37 5 5 38 38 7 7 8 9 9 9 8 8 - 32 32 32 182 182 183 183 183 183 183 5 38 38 4 4 4 - 33 33 33 34 34 35 35 35 35 37 5 5 5 38 4 4 - 7 7 32 32 33 33 33 33 34 34 35 35 5 5 5 38 - 7 131 131 131 36 37 37 37 37 5 5 5 38 4 4 4 - 181 181 181 181 32 32 33 33 35 35 35 35 5 5 38 4 - 32 8 8 32 33 6 34 33 35 35 5 5 5 5 38 39 - 197 214 198 197 198 199 6 10 10 10 144 145 146 147 48 48 - 48 48 49 49 254 130 131 131 132 132 132 133 133 38 38 38 - 131 129 130 34 35 5 38 128 148 150 131 9 8 7 129 128 - 4 4 5 5 35 35 34 33 33 8 8 8 9 8 8 10 - 5 37 37 37 5 5 5 5 5 5 38 4 4 4 4 4 - 34 34 34 34 35 35 35 35 5 5 5 5 5 5 38 4 - 33 6 6 36 148 149 150 151 148 149 150 150 151 37 38 38 - 131 163 132 132 132 133 133 37 38 38 38 38 38 4 4 4 - 33 33 34 35 35 5 5 5 37 5 5 5 38 38 4 4 - 36 37 5 5 5 38 4 39 33 7 8 9 9 9 8 8 - 32 32 32 182 183 183 183 184 183 183 5 4 4 4 4 4 - 34 34 34 34 35 35 35 37 37 5 5 38 38 4 4 4 - 7 8 7 33 34 33 33 34 35 35 5 5 5 5 38 4 - 131 132 132 131 36 37 37 37 38 38 38 38 38 4 4 4 - 32 181 181 32 32 32 33 34 35 35 37 5 5 5 4 4 - 7 8 7 33 6 6 33 33 5 5 5 5 38 4 4 154 - 197 213 200 197 200 199 6 9 10 9 145 146 146 48 48 48 - 48 49 49 49 49 131 131 131 132 132 133 133 134 38 38 38 - 131 130 131 35 5 4 40 128 254 150 36 9 8 7 130 128 - 39 4 38 5 5 35 34 34 33 32 32 8 8 8 8 9 - 5 37 37 5 5 5 38 38 4 4 4 4 4 4 39 4 - 34 34 35 35 35 35 35 5 5 5 5 38 4 4 4 4 - 6 6 36 37 149 149 151 152 149 49 150 151 152 37 38 134 - 131 163 132 132 133 133 133 133 38 38 38 4 4 4 4 4 - 34 35 35 35 5 5 5 5 5 5 5 38 4 4 4 4 - 37 37 38 38 38 4 39 39 33 7 7 8 9 8 8 32 - 32 33 33 182 183 183 183 184 184 184 38 4 4 4 4 4 - 34 34 35 35 35 35 35 37 5 5 38 4 4 4 4 4 - 8 7 33 6 34 33 34 35 35 5 5 5 5 38 4 39 - 131 132 132 132 132 37 37 37 38 38 38 4 4 4 39 4 - 32 32 32 32 32 33 34 35 35 35 5 5 5 38 4 4 - 8 7 33 6 6 33 6 6 5 5 5 38 4 4 4 154 - 196 198 200 198 200 150 6 9 9 9 145 146 147 48 48 48 - 49 49 49 49 80 81 82 131 132 133 133 134 134 40 39 39 - 131 130 131 35 5 4 40 128 254 150 36 8 8 7 130 128 - 39 4 4 5 5 5 35 34 33 33 32 8 7 8 9 8 - 37 37 5 5 38 38 4 4 4 4 4 4 4 4 39 4 - 35 35 35 35 35 37 5 5 5 5 38 4 4 4 4 39 - 6 36 37 37 149 150 151 83 49 49 150 151 152 153 38 135 - 132 132 132 133 133 134 134 134 40 40 39 39 39 39 39 41 - 35 35 37 5 5 5 5 5 5 38 38 4 4 4 4 39 - 37 38 38 38 38 39 39 39 34 7 8 8 9 8 8 32 - 32 33 33 182 183 184 184 184 185 185 4 4 4 4 4 244 - 35 35 35 37 5 5 37 5 38 38 4 4 4 4 39 3 - 7 33 6 6 33 6 35 5 35 5 5 38 38 4 4 39 - 132 132 132 132 132 133 37 38 38 38 39 39 39 39 39 244 - 32 32 33 33 34 34 35 35 37 5 5 38 38 4 4 4 - 7 6 6 6 6 6 37 5 37 5 5 4 4 4 39 41 - 196 200 200 200 200 151 6 9 9 9 146 147 48 48 48 49 - 54 49 49 80 81 82 82 164 165 133 134 134 135 40 39 41 - 132 130 131 35 5 4 40 128 150 151 37 8 8 7 130 128 - 3 244 4 4 5 5 35 35 33 33 32 8 7 8 9 8 - 5 38 38 38 4 4 4 4 4 4 4 4 39 3 41 39 - 35 35 35 37 5 5 5 5 38 4 4 4 4 4 39 3 - 6 36 37 37 149 150 152 84 49 49 50 152 153 153 39 136 - 132 164 133 133 134 135 135 135 88 40 154 41 41 41 41 3 - 37 37 5 5 5 5 5 38 38 4 4 4 4 39 39 41 - 38 153 38 38 39 39 41 41 36 33 7 8 8 8 32 33 - 33 33 34 183 184 184 184 184 184 184 4 4 39 3 3 3 - 5 35 37 37 37 5 38 38 4 4 4 39 39 3 3 3 - 33 6 6 33 6 5 5 5 5 5 38 4 4 4 4 41 - 132 132 132 132 133 133 133 38 40 39 39 39 41 41 3 244 - 32 33 33 34 34 35 35 5 5 5 38 38 4 4 4 3 - 33 6 6 6 6 37 5 37 5 38 38 4 4 39 3 156 - 198 201 200 200 200 151 36 9 9 145 146 147 48 49 49 54 - 54 49 49 54 51 82 83 165 165 165 85 135 135 40 41 136 - 132 131 132 35 4 244 41 128 150 151 37 8 7 33 131 128 - 3 3 244 4 4 5 5 35 35 34 32 7 7 8 8 8 - 38 38 40 40 39 39 39 39 39 39 244 3 3 3 3 3 - 5 5 5 5 5 38 38 4 4 4 4 39 39 3 3 3 - 36 37 37 153 150 151 83 16 50 50 82 84 153 40 40 136 - 133 133 134 134 135 135 86 86 89 41 41 41 155 155 42 3 - 37 5 5 38 38 38 4 4 4 39 39 39 3 3 3 3 - 40 40 40 40 39 41 42 155 37 34 7 7 8 8 33 33 - 33 34 35 183 184 184 184 184 185 185 4 3 3 3 3 3 - 5 37 37 5 5 38 38 38 4 39 41 3 3 3 3 3 - 6 6 6 6 37 5 5 5 5 38 4 4 39 41 3 42 - 132 133 133 84 85 85 85 40 40 41 41 41 3 3 3 244 - 33 33 34 34 35 35 5 5 5 38 4 4 39 244 3 3 - 6 6 6 36 36 37 5 153 153 39 39 39 39 41 3 156 - 201 201 201 201 200 152 37 9 9 146 147 147 49 54 54 54 - 54 54 54 55 51 83 165 166 165 166 135 86 88 41 41 136 - 133 132 132 37 4 3 91 129 150 152 38 8 7 6 132 128 - 43 3 3 39 4 4 5 5 5 6 6 33 7 7 7 8 - 38 40 40 40 154 41 41 3 3 3 3 3 3 3 3 3 - 5 5 38 38 38 4 4 4 4 4 41 3 3 3 3 3 - 37 37 153 153 151 152 84 16 50 51 83 84 85 40 41 91 - 134 165 134 135 135 86 86 88 91 91 91 42 92 92 43 43 - 5 38 38 4 4 4 4 39 39 39 41 41 3 3 3 43 - 40 154 154 41 41 42 92 42 37 34 34 8 7 8 33 33 - 34 35 5 184 185 185 185 185 186 244 244 3 3 43 43 43 - 5 5 38 38 4 39 39 4 39 39 3 3 43 43 43 43 - 6 6 36 5 5 5 5 4 38 4 39 41 3 3 3 92 - 133 84 84 85 86 88 86 99 41 41 155 42 42 43 43 43 - 35 183 183 183 35 5 5 4 4 4 39 41 3 3 43 43 - 6 151 152 153 153 152 153 154 40 154 154 155 3 3 3 156 - 202 202 201 202 152 153 38 8 8 147 147 147 214 54 54 54 - 54 55 60 96 51 96 165 166 166 167 167 136 136 91 42 137 - 133 132 133 38 4 3 92 254 151 152 40 7 7 36 133 128 - 44 43 3 3 4 4 5 5 35 5 6 33 33 7 8 7 - 154 41 41 41 41 41 3 3 3 3 3 3 3 3 43 43 - 38 38 38 38 4 4 39 39 39 41 3 3 3 3 3 43 - 37 153 40 40 151 152 17 17 50 51 83 84 18 89 91 137 - 134 134 135 135 88 89 90 90 90 91 91 92 92 25 25 43 - 38 4 4 39 4 39 39 41 3 3 3 3 3 43 43 93 - 40 154 41 41 41 42 25 25 37 36 36 8 7 32 33 33 - 35 35 5 184 185 185 185 186 186 244 244 3 43 43 2 2 - 5 38 38 38 39 39 39 39 41 3 3 3 43 43 44 44 - 36 36 37 37 5 38 4 4 4 4 39 3 3 3 43 43 - 153 84 85 86 86 86 99 41 41 41 155 3 3 43 43 2 - 183 182 183 184 183 184 184 5 4 4 4 3 3 3 43 44 - 36 151 152 152 153 153 40 40 154 154 41 155 3 43 43 101 - 201 201 202 201 201 153 38 8 8 147 148 214 214 54 54 54 - 60 55 55 55 96 97 166 167 166 167 168 168 90 137 92 137 - 134 132 133 38 244 3 25 130 132 153 40 7 6 36 133 128 - 2 43 3 3 244 4 4 5 5 5 35 34 34 33 7 7 - 41 99 155 155 155 155 42 3 43 43 43 43 43 43 43 2 - 4 4 4 4 4 39 41 3 3 3 3 3 43 43 43 43 - 5 40 154 40 151 84 18 98 51 83 16 17 19 21 92 26 - 135 135 167 136 168 90 169 137 91 100 24 25 26 26 27 101 - 38 4 39 39 39 39 41 41 3 3 3 43 43 43 44 28 - 41 99 91 42 92 25 27 28 38 37 34 33 7 33 33 35 - 35 5 184 185 186 186 186 186 186 244 43 43 44 2 2 2 - 38 38 39 39 39 39 41 41 3 3 43 43 43 44 2 2 - 37 37 5 5 38 4 4 4 4 39 3 3 3 43 43 44 - 40 86 86 20 99 99 22 23 23 100 156 93 44 2 2 188 - 183 183 184 184 184 184 185 185 185 4 244 3 3 43 44 157 - 152 152 152 153 153 40 154 154 154 41 155 155 43 43 44 157 - 202 202 202 201 201 154 4 8 8 148 199 214 214 54 55 55 - 60 60 60 60 97 97 166 167 167 167 168 168 137 26 27 138 - 135 133 134 38 244 43 27 150 84 85 40 7 6 37 133 128 - 31 2 43 3 3 244 4 4 38 5 35 35 34 33 32 7 - 41 22 23 23 42 42 43 43 43 43 43 2 2 2 2 2 - 4 4 39 39 39 3 3 3 3 3 43 43 43 43 2 44 - 38 40 154 20 152 84 18 19 83 83 16 19 99 23 26 246 - 135 167 168 168 169 169 169 24 26 26 26 101 28 101 28 30 - 39 39 154 41 41 41 3 3 3 3 43 43 43 2 2 30 - 155 22 91 92 92 43 27 28 38 37 36 36 7 33 33 5 - 35 5 184 185 186 186 186 187 187 187 2 2 2 31 31 31 - 38 39 39 39 41 41 155 155 42 43 43 93 2 2 31 31 - 5 5 38 38 4 39 4 4 39 3 3 43 43 93 2 30 - 40 86 88 99 90 22 23 23 24 25 101 44 2 31 31 188 - 184 183 184 184 184 185 185 185 186 244 244 3 43 44 30 157 - 5 153 153 153 40 154 154 154 41 155 155 156 43 44 30 157 - 202 202 203 202 201 154 154 7 8 199 199 214 214 55 55 55 - 55 60 60 61 61 61 166 167 167 168 168 169 137 138 138 138 - 135 133 135 39 187 2 28 131 84 85 41 7 6 37 134 128 - 45 2 44 43 3 3 4 4 4 5 5 35 34 33 33 7 - 155 22 23 100 92 156 43 43 44 44 2 2 2 31 31 31 - 4 39 39 41 3 3 3 3 43 43 43 43 43 2 2 31 - 40 40 41 41 152 84 19 87 83 16 17 20 21 23 26 246 - 135 136 168 169 169 169 169 170 246 246 246 101 28 157 157 157 - 39 154 41 155 3 3 3 3 3 43 43 44 2 2 2 31 - 42 91 92 92 43 93 28 28 38 37 37 34 34 33 34 5 - 5 5 185 185 186 186 186 187 187 2 2 31 31 31 94 45 - 39 40 41 41 41 42 42 42 92 43 93 2 2 31 45 45 - 5 5 38 39 39 39 39 39 41 3 3 43 43 44 2 94 - 40 86 88 99 22 23 23 24 26 26 101 30 31 31 31 188 - 184 183 184 184 184 185 185 186 186 244 244 43 43 44 31 102 - 5 5 153 153 40 154 41 41 155 155 156 156 44 44 31 102 - 202 203 204 202 202 154 154 7 7 199 199 214 50 55 55 55 - 55 60 60 61 61 61 167 167 168 168 169 169 170 138 138 138 - 135 134 136 244 187 2 28 36 84 86 41 33 37 5 134 128 - 95 45 2 43 43 3 39 4 4 5 5 5 6 34 33 7 - 42 23 100 24 25 156 101 44 2 2 2 31 94 45 45 45 - 39 41 3 3 3 3 3 3 43 43 43 2 2 2 2 45 - 40 154 41 22 153 85 87 21 83 16 18 20 22 24 101 246 - 136 136 169 169 169 170 170 171 246 246 246 157 94 157 45 45 - 41 41 155 155 3 3 43 43 43 43 44 2 2 31 45 102 - 24 24 26 27 28 29 94 139 38 38 38 34 34 34 35 5 - 5 4 185 186 186 187 186 187 188 188 2 31 45 95 95 158 - 39 41 41 41 42 92 92 25 93 93 44 31 94 45 95 158 - 5 38 39 39 39 41 41 3 3 3 43 43 2 2 31 45 - 41 89 90 91 91 24 246 246 246 101 157 157 45 95 158 126 - 184 184 184 184 185 185 185 186 187 187 187 43 2 2 45 102 - 5 153 153 40 154 41 155 155 156 156 156 44 30 31 45 102 - 203 202 202 202 203 155 41 7 7 199 200 200 55 55 96 55 - 55 60 60 61 61 167 167 168 169 169 169 170 170 138 139 139 - 136 135 136 244 188 2 94 132 85 89 91 6 5 38 135 128 - 47 158 45 2 43 3 3 3 4 4 38 5 35 35 34 33 - 24 24 26 26 101 101 30 157 94 45 45 95 95 95 158 158 - 3 3 3 3 3 43 43 43 2 2 2 2 2 94 45 95 - 41 41 23 23 153 86 21 62 84 17 19 21 23 246 245 139 - 90 169 169 169 170 170 171 171 171 245 139 139 103 103 158 158 - 3 155 155 155 3 43 43 44 44 2 31 31 45 95 95 158 - 26 26 28 28 31 45 103 140 39 39 38 36 33 5 35 5 - 4 185 186 186 187 187 187 187 125 189 45 95 95 158 46 47 - 41 41 91 91 92 25 27 27 28 29 94 45 95 158 158 1 - 38 39 154 41 41 41 3 3 3 43 93 2 2 94 95 103 - 136 136 91 137 137 246 246 246 246 245 245 157 45 158 46 190 - 184 185 185 185 186 186 186 187 187 187 188 188 188 45 95 158 - 38 4 39 154 155 155 155 42 156 101 30 157 45 45 102 1 - 203 203 203 203 20 155 155 7 7 199 200 200 55 16 96 96 - 60 60 61 61 61 168 168 169 238 239 239 170 171 139 139 172 - 136 135 137 244 188 95 172 37 86 90 92 6 5 4 135 128 - 159 1 95 31 2 43 3 3 39 4 4 5 5 35 34 34 - 27 246 246 101 157 157 45 103 45 95 95 95 158 46 46 1 - 3 3 3 43 43 43 2 2 2 2 31 95 95 95 95 158 - 41 155 100 24 40 88 22 62 16 17 20 21 24 246 245 172 - 137 169 169 169 170 170 171 171 172 172 172 172 140 1 1 1 - 3 42 42 43 43 93 2 31 2 31 94 95 95 95 158 1 - 27 27 28 30 94 103 140 140 41 39 38 37 6 5 5 5 - 4 186 186 122 123 123 123 124 125 189 95 95 46 46 127 47 - 41 91 137 137 24 138 138 28 94 94 45 158 158 46 127 159 - 39 154 41 41 41 155 3 3 43 43 2 31 45 95 95 46 - 136 137 137 137 170 170 246 171 171 245 63 103 103 46 46 126 - 185 185 185 185 186 186 186 187 187 188 188 188 188 189 189 46 - 4 39 39 41 155 42 156 156 44 30 157 45 102 158 46 159 - 204 203 204 204 20 155 42 6 7 199 200 201 16 16 96 96 - 61 61 61 61 61 168 238 238 239 239 239 171 171 172 140 140 - 169 135 137 244 125 126 140 153 86 22 92 6 5 39 135 128 - 141 140 103 157 28 93 43 42 39 41 39 5 38 37 6 36 - 246 246 246 245 245 245 63 172 139 103 103 158 158 140 140 140 - 42 92 25 93 93 93 28 29 29 94 45 103 103 103 158 1 - 155 22 23 24 18 19 62 62 97 17 61 62 62 245 63 63 - 169 169 169 170 239 76 76 76 63 63 172 172 173 173 173 173 - 91 100 24 26 26 101 101 157 30 157 45 103 103 158 1 173 - 246 246 245 245 139 172 173 173 91 40 40 37 5 5 5 4 - 4 3 3 187 124 124 124 125 188 95 102 158 1 1 47 173 - 91 91 137 24 26 246 246 246 245 139 172 140 140 1 47 141 - 40 154 41 41 41 155 42 24 25 26 157 45 103 103 46 140 - 137 137 170 170 170 171 171 171 171 63 172 173 173 140 140 47 - 185 185 185 185 187 187 244 187 188 188 188 94 45 103 46 140 - 40 40 154 41 155 23 100 24 101 101 245 63 63 140 140 159 - 205 204 204 204 204 23 156 6 6 150 150 55 60 60 60 60 - 61 61 61 61 61 72 73 238 238 74 239 239 171 172 173 173 - 169 167 136 244 45 158 173 84 86 22 246 36 40 41 88 128 - 152 152 151 150 149 149 148 148 146 146 253 145 144 10 10 144 - 254 254 49 49 150 150 150 150 131 131 131 151 151 132 36 151 - 128 128 148 254 149 254 149 149 130 150 150 150 36 36 36 151 - 147 48 254 254 253 146 48 49 48 48 48 48 49 49 149 82 - 254 104 104 104 49 80 80 80 50 50 150 150 151 151 132 151 - 48 254 254 254 254 254 254 254 254 150 150 150 131 151 132 151 - 254 149 149 150 150 151 151 151 146 146 144 144 10 10 10 9 - 9 146 8 7 7 7 7 7 6 6 36 36 151 151 152 152 - 48 128 254 254 254 49 49 149 150 150 150 151 151 151 152 153 - 147 147 146 146 147 148 148 147 254 149 149 149 150 131 36 151 - 128 48 254 254 254 254 49 50 49 50 151 151 151 151 132 37 - 9 9 9 8 8 7 8 8 7 7 7 130 36 36 36 151 - 253 146 147 146 146 147 148 149 149 150 150 150 150 151 151 152 - 195 196 214 214 196 147 147 11 10 144 144 106 52 52 53 53 - 53 53 53 52 53 104 104 104 104 161 162 80 80 130 151 133 - 255 129 129 33 34 36 132 144 48 48 49 106 144 146 128 128 - 84 84 84 82 50 50 49 49 147 148 147 146 144 253 144 144 - 50 50 50 51 51 51 82 82 83 83 83 84 84 84 84 84 - 49 49 49 50 50 50 50 82 82 151 82 152 152 153 153 85 - 49 49 49 80 48 49 54 54 53 53 49 49 54 51 83 83 - 80 162 162 54 81 96 96 55 51 51 83 83 84 84 84 84 - 254 49 49 80 50 50 82 82 50 82 83 83 83 84 84 84 - 50 51 82 82 83 84 84 97 49 48 146 145 145 145 145 147 - 147 148 149 150 151 151 151 152 5 152 153 153 153 153 85 18 - 49 49 80 80 50 50 50 50 82 82 83 84 84 84 84 84 - 146 48 49 49 49 49 50 50 50 50 50 151 82 152 84 84 - 49 49 80 50 50 50 51 51 51 83 83 16 84 84 85 40 - 7 7 8 8 7 33 6 36 150 150 151 152 152 84 84 84 - 48 48 49 49 49 49 50 50 50 51 82 83 83 84 17 19 - 196 213 214 214 214 149 149 10 144 144 53 52 53 53 53 53 - 52 53 59 59 58 249 249 249 249 250 250 165 96 83 83 84 - 162 255 130 131 132 152 85 253 48 49 50 253 48 48 254 128 - 98 98 16 83 83 82 151 150 149 149 148 148 146 146 144 144 - 83 83 83 83 83 16 16 16 16 16 16 17 17 18 18 17 - 51 51 82 82 51 50 82 83 16 16 16 16 16 17 18 18 - 49 50 50 50 49 54 55 54 53 54 54 54 55 96 16 97 - 250 250 250 250 55 55 96 96 97 16 16 16 17 17 17 17 - 50 50 50 50 51 83 83 83 83 16 17 17 16 17 17 17 - 51 83 83 83 16 16 16 16 49 49 48 146 146 146 146 147 - 148 149 150 151 152 152 5 5 5 37 153 153 40 40 40 18 - 50 50 50 50 82 82 83 83 84 84 84 85 85 85 85 19 - 49 49 49 49 48 49 49 50 51 83 83 83 16 17 18 17 - 50 50 50 51 55 96 96 16 16 16 16 17 17 19 19 20 - 7 7 7 6 6 36 150 150 151 152 153 153 16 16 17 18 - 48 49 49 49 49 50 50 50 51 83 16 16 16 17 17 203 - 214 213 213 213 200 150 151 144 144 253 53 53 53 57 58 53 - 58 58 58 58 58 59 59 68 68 68 250 250 96 97 17 98 - 163 162 131 132 37 153 17 48 54 55 50 253 48 48 80 48 - 61 61 17 16 16 83 83 51 50 49 148 149 147 146 253 146 - 96 96 96 16 16 16 16 16 61 17 17 17 19 19 19 19 - 50 50 51 83 83 16 16 17 16 16 17 17 17 19 19 61 - 51 55 96 55 53 54 55 60 54 59 54 55 60 60 16 61 - 250 250 250 250 60 61 61 61 61 61 61 61 61 61 61 61 - 55 96 96 55 55 96 96 16 16 16 17 17 17 19 19 61 - 16 16 16 16 17 61 61 61 54 49 48 48 146 147 148 148 - 149 150 151 152 153 153 153 153 40 40 40 20 21 21 21 21 - 51 51 82 83 83 83 16 16 16 16 17 18 19 19 19 21 - 49 49 49 50 51 96 96 55 96 96 16 16 16 17 19 61 - 55 55 55 55 60 60 60 60 60 16 61 61 61 61 61 20 - 150 6 6 36 151 152 152 153 152 153 16 17 17 17 19 61 - 49 54 54 51 55 55 96 96 96 16 16 16 17 61 61 203 - 214 213 213 213 55 55 50 144 253 48 53 53 57 57 58 58 - 59 58 59 59 59 60 60 236 250 250 60 60 61 61 61 61 - 96 163 132 133 85 19 61 48 54 55 96 48 49 49 80 104 - 49 49 48 48 48 48 253 253 144 253 253 106 252 252 252 252 - 48 53 53 53 48 48 48 48 49 49 49 49 49 49 49 49 - 48 48 48 48 48 253 253 253 253 48 48 48 49 49 49 49 - 52 52 53 53 52 52 52 53 52 52 52 52 53 53 48 54 - 52 248 248 52 52 53 53 53 54 54 49 49 49 49 49 49 - 48 53 53 48 48 48 48 48 48 48 48 48 49 49 49 49 - 52 52 53 53 48 48 49 54 105 105 106 252 252 252 144 144 - 144 144 145 146 146 147 147 147 147 146 147 48 49 49 49 49 - 253 105 48 48 48 48 48 48 48 48 48 49 80 49 49 49 - 106 106 106 144 105 48 48 253 48 48 48 48 48 48 49 49 - 53 53 53 53 53 53 53 53 53 53 49 49 49 49 49 49 - 144 144 144 106 106 144 253 146 146 48 48 48 48 49 49 49 - 106 106 106 144 52 52 53 53 53 53 48 48 49 54 49 214 - 195 212 214 214 53 53 48 252 252 252 247 247 247 247 247 56 - 56 56 56 52 52 52 52 52 53 53 53 53 54 54 54 54 - 105 105 105 253 146 48 49 247 52 52 53 252 252 247 105 160 - 51 51 81 49 49 48 48 48 48 48 48 105 105 106 106 106 - 54 54 54 54 54 54 49 49 55 55 55 55 55 55 55 55 - 48 48 48 48 49 49 49 49 49 49 80 54 51 51 51 55 - 53 53 53 54 53 53 53 58 52 52 53 53 53 54 54 54 - 249 249 249 249 249 54 54 54 54 54 54 55 55 55 51 55 - 53 53 54 54 54 54 54 54 54 49 49 54 55 55 55 55 - 54 54 54 54 54 55 55 55 53 52 105 105 106 144 253 253 - 146 146 48 148 49 149 149 149 50 50 50 51 51 55 55 55 - 53 53 53 54 54 54 54 54 54 54 54 55 55 55 55 55 - 48 48 48 48 53 53 53 49 49 54 49 49 54 54 55 55 - 53 53 54 54 54 54 54 54 54 54 55 55 55 55 55 51 - 253 253 128 48 254 48 48 48 49 49 49 80 50 51 55 55 - 48 53 53 53 53 53 54 54 54 54 53 54 55 55 55 55 - 195 212 214 214 53 53 48 252 106 247 247 52 56 56 56 56 - 56 56 57 57 57 57 58 58 58 59 59 54 54 55 55 55 - 249 160 255 130 50 96 55 53 52 52 54 105 52 53 105 160 - 97 97 96 51 50 50 49 49 49 48 48 253 253 106 106 105 - 55 55 55 55 55 55 55 55 96 96 96 97 97 97 97 97 - 49 49 49 50 50 50 50 50 83 96 96 96 96 96 96 96 - 53 54 54 54 53 53 54 59 53 58 58 54 59 55 55 60 - 249 249 249 249 250 250 250 60 55 55 60 60 97 96 96 96 - 49 54 54 54 54 55 55 55 55 55 55 96 96 97 97 60 - 55 55 55 55 55 96 96 96 53 48 48 48 253 253 146 146 - 148 148 149 150 151 151 151 151 152 152 83 16 97 97 97 60 - 53 54 54 54 55 55 55 55 55 55 55 60 60 60 16 61 - 48 48 49 54 49 49 49 54 54 55 55 55 55 96 97 97 - 49 54 54 54 55 55 55 55 55 55 60 60 97 97 97 97 - 48 128 148 254 254 254 49 49 50 51 51 83 83 97 97 97 - 48 48 48 49 49 54 54 54 55 55 55 55 96 96 96 16 - 196 213 213 214 54 54 54 144 144 144 52 52 57 57 57 57 - 57 57 58 58 58 58 58 59 59 59 250 60 60 60 60 96 - 250 104 131 131 82 97 96 53 54 54 49 105 53 53 160 160 - 61 61 61 60 60 55 55 54 54 54 80 48 49 48 48 105 - 60 60 60 60 60 60 60 61 60 60 61 61 61 61 61 61 - 51 51 51 55 55 55 55 96 61 60 60 60 60 61 61 61 - 59 59 60 59 58 59 59 60 58 58 59 59 60 60 60 61 - 60 67 250 60 68 60 60 60 61 61 61 61 61 61 61 61 - 59 55 60 60 60 60 60 60 60 60 60 61 61 61 61 61 - 60 60 60 60 60 61 61 61 55 53 53 53 105 48 49 49 - 49 49 50 51 16 16 16 16 61 61 61 61 61 61 61 61 - 55 55 60 60 60 60 60 60 60 60 60 61 61 61 61 61 - 54 54 54 54 54 54 55 60 55 60 60 60 60 61 61 61 - 60 59 59 59 60 60 60 60 60 60 60 61 61 61 61 61 - 49 49 50 50 50 51 51 83 96 97 97 97 97 61 61 61 - 54 54 54 54 55 55 60 60 60 60 60 60 61 61 61 204 - 213 213 213 54 59 59 55 52 52 53 53 58 57 58 57 57 - 229 58 58 58 59 59 59 60 60 60 236 60 60 60 61 70 - 68 249 164 164 97 61 61 54 59 59 55 53 53 54 54 104 - 59 58 53 53 53 53 52 52 247 52 52 247 247 247 247 247 - 53 58 58 57 58 58 58 53 53 53 53 53 53 53 58 59 - 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 - 52 52 52 52 56 56 56 56 56 56 56 56 56 57 58 53 - 52 52 52 52 57 58 58 53 53 53 53 53 53 53 53 58 - 52 52 52 52 53 58 53 58 53 53 53 53 53 53 58 58 - 58 57 57 53 53 53 58 58 52 52 52 52 52 247 247 247 - 106 144 52 53 48 48 53 53 53 53 53 53 54 59 59 58 - 52 52 52 52 53 53 53 53 53 53 53 53 53 58 59 59 - 247 52 52 52 52 52 52 52 52 53 53 53 53 53 58 58 - 52 52 52 52 57 58 57 58 58 58 53 53 53 58 59 54 - 247 247 52 52 53 53 53 53 53 53 53 53 53 53 53 58 - 52 52 52 52 52 52 52 52 58 58 53 53 53 53 53 59 - 212 212 52 52 52 52 52 247 247 52 56 56 219 225 225 225 - 225 56 56 56 56 56 56 56 56 57 58 58 53 53 58 58 - 248 248 248 53 53 53 53 52 56 52 52 247 52 52 52 58 - 59 59 59 58 58 53 53 53 53 52 52 247 52 247 247 52 - 57 57 58 58 58 58 59 59 59 59 58 58 58 58 59 59 - 53 53 53 53 53 53 58 58 58 59 59 59 59 59 58 58 - 57 58 58 58 56 57 57 57 56 56 56 57 58 58 58 59 - 58 58 58 57 57 58 58 58 58 58 59 59 58 58 58 59 - 57 58 58 58 58 57 58 58 59 58 59 59 59 58 58 58 - 57 58 58 59 59 58 58 58 52 52 52 247 247 247 52 52 - 52 53 53 53 48 49 49 54 54 54 54 54 59 59 59 58 - 53 58 58 57 57 53 58 58 58 58 58 59 59 59 59 59 - 53 53 53 52 52 52 53 53 53 58 58 59 59 59 59 58 - 57 58 58 58 58 58 58 58 58 58 59 59 59 59 59 59 - 52 52 52 52 53 53 53 53 53 53 58 58 59 59 59 59 - 52 52 57 57 57 58 58 57 57 58 59 59 58 58 59 59 - 212 212 58 58 58 57 57 247 52 52 56 225 225 225 225 225 - 56 56 56 56 56 57 58 58 58 57 57 58 58 59 59 58 - 227 227 53 249 59 59 59 52 56 57 58 52 52 52 52 58 - 60 60 55 54 54 54 54 54 53 53 53 53 53 52 247 52 - 59 59 59 59 59 59 59 59 60 60 59 60 60 60 60 55 - 54 49 54 54 54 54 54 54 54 54 54 55 55 60 60 60 - 53 58 58 58 53 57 58 58 57 57 57 58 58 59 59 59 - 53 58 58 58 58 58 59 59 59 59 59 60 60 60 250 60 - 58 58 58 58 59 59 59 59 59 54 59 59 60 60 60 60 - 59 59 59 59 59 59 60 60 53 53 52 52 52 52 48 48 - 48 48 48 49 49 50 50 50 51 51 55 55 55 55 55 55 - 53 58 59 59 59 58 58 59 59 59 59 55 60 60 55 55 - 53 53 53 53 53 53 54 59 54 54 54 54 59 55 60 60 - 53 58 58 58 58 58 58 59 59 59 59 60 60 55 55 60 - 48 48 48 48 48 48 48 49 49 54 54 54 55 55 55 60 - 53 53 53 53 53 58 59 59 59 59 59 59 55 60 60 55 - 214 213 213 58 58 58 58 52 247 52 52 56 56 56 56 56 - 56 56 57 58 58 58 58 58 58 58 58 59 59 59 60 59 - 249 64 161 162 55 55 60 52 53 58 58 52 52 53 53 53 - 61 16 55 55 55 55 54 49 54 48 48 48 48 48 253 144 - 55 60 55 55 55 55 55 55 60 55 55 60 60 60 60 60 - 49 49 50 51 55 55 55 55 55 55 55 55 96 96 96 60 - 54 54 54 54 53 58 59 59 53 58 58 59 54 55 60 55 - 54 59 59 59 250 60 60 250 55 250 250 60 60 60 60 60 - 54 54 54 54 55 60 55 55 55 55 55 55 60 60 60 60 - 55 60 55 55 55 60 60 60 54 53 53 53 48 48 48 48 - 48 148 149 150 151 151 152 152 152 83 16 16 16 97 61 61 - 54 54 54 54 59 60 60 60 55 55 60 60 60 61 61 61 - 49 54 49 49 49 49 49 49 54 55 55 55 55 55 60 60 - 54 59 59 59 59 60 55 60 55 55 60 60 60 60 61 61 - 48 48 49 49 49 49 50 50 50 51 51 51 96 16 16 61 - 48 53 54 54 54 54 54 54 60 55 55 55 60 55 60 61 - 214 213 214 214 54 54 54 144 144 52 52 52 56 56 57 57 - 58 57 57 58 58 58 58 59 249 250 250 250 250 96 60 60 - 249 249 162 162 51 96 60 53 58 59 54 52 53 54 54 48 - 61 61 17 97 97 96 51 50 80 50 49 48 48 48 48 48 - 55 55 60 60 60 60 61 61 97 61 61 61 61 61 61 61 - 82 82 82 82 83 83 97 97 97 97 97 97 97 17 98 61 - 55 55 55 55 54 59 59 59 59 58 59 60 60 60 61 61 - 60 60 250 250 60 60 60 60 97 97 97 61 61 61 61 61 - 55 55 55 55 96 60 96 97 61 97 97 97 97 61 61 61 - 96 60 61 61 61 61 61 61 54 49 48 48 48 48 48 148 - 149 150 151 152 153 153 16 17 17 17 18 98 61 61 61 61 - 55 55 54 55 60 60 60 60 61 61 61 61 61 61 61 61 - 49 49 80 51 51 55 96 96 51 96 61 61 97 97 17 61 - 55 60 250 60 60 60 60 60 61 97 61 61 61 61 61 61 - 254 130 131 50 50 82 82 82 83 84 97 97 16 17 61 61 - 49 49 54 55 55 55 55 55 96 60 97 61 61 97 17 204 - 214 198 200 55 55 55 55 144 48 53 53 53 58 57 58 53 - 59 59 58 58 59 60 60 250 250 250 165 165 165 61 61 166 - 250 250 163 132 84 97 61 53 54 55 60 48 48 49 81 104 - 169 62 90 19 98 17 84 83 82 82 80 49 50 80 48 146 - 97 61 61 61 61 61 61 61 168 168 169 62 169 169 62 62 - 85 85 85 85 84 16 17 17 98 98 98 19 87 21 62 62 - 51 97 97 97 55 60 60 60 59 60 250 96 61 61 61 238 - 60 60 60 60 165 166 61 61 168 61 168 169 62 62 62 62 - 83 97 17 97 97 97 17 61 17 61 61 61 168 168 62 62 - 61 61 61 61 61 168 238 238 96 51 80 49 48 148 149 150 - 151 152 153 153 40 154 41 21 99 21 22 23 21 62 62 62 - 96 97 97 61 61 61 61 61 61 61 61 62 62 62 62 62 - 50 51 82 83 83 83 97 97 97 17 98 98 98 21 62 62 - 97 61 61 61 61 61 61 61 168 61 168 168 169 169 169 169 - 132 132 132 152 133 153 84 84 85 19 87 20 99 21 21 62 - 51 51 51 83 96 96 97 61 97 61 61 61 62 62 62 21 - 201 201 202 201 16 16 16 146 48 48 54 59 59 58 59 58 - 58 59 59 60 60 60 60 60 165 166 166 167 168 169 169 168 - 165 164 133 134 88 21 62 54 55 60 61 48 49 81 164 128 - 63 245 246 23 23 23 99 18 85 85 153 151 151 149 149 150 - 20 21 62 62 62 62 62 62 62 62 62 62 246 246 245 245 - 40 40 99 22 23 23 62 62 62 62 62 62 62 246 246 62 - 16 19 61 61 16 16 61 61 55 61 61 97 61 62 62 62 - 166 237 72 72 238 238 238 238 239 62 239 239 63 63 63 207 - 19 20 19 19 21 62 21 21 23 62 62 62 62 62 246 62 - 61 61 62 62 62 62 239 75 98 97 82 150 149 150 151 152 - 5 38 39 39 3 3 43 43 43 43 101 101 245 245 63 63 - 18 20 19 98 19 87 168 62 168 62 62 62 246 245 63 63 - 153 84 85 18 17 18 19 19 19 20 21 23 62 246 245 239 - 97 61 61 61 61 168 168 62 168 169 169 62 171 63 63 63 - 38 38 38 39 39 41 41 41 41 23 24 24 246 246 246 63 - 151 83 16 17 19 19 19 19 19 62 62 62 62 62 245 207 - 203 203 203 202 202 17 20 148 49 49 54 54 58 59 59 60 - 60 55 60 60 60 60 61 237 237 71 238 238 238 239 239 75 - 167 166 135 136 24 246 62 51 97 61 61 49 51 97 166 128 - 77 77 171 170 170 169 169 90 87 98 84 84 84 82 50 50 - 62 62 239 239 239 239 75 75 76 76 76 76 76 77 77 77 - 90 90 90 90 169 62 62 239 239 239 239 75 76 76 77 76 - 61 62 62 62 97 61 61 73 61 60 237 73 73 238 75 74 - 71 71 72 72 72 73 74 74 75 75 75 75 75 76 76 77 - 21 62 62 21 62 62 62 62 239 239 75 75 76 76 77 77 - 238 238 74 75 75 75 75 76 167 98 84 83 82 152 153 40 - 40 39 41 92 27 29 29 29 138 139 139 172 172 77 77 77 - 87 169 169 62 239 239 169 169 75 75 171 171 76 77 77 77 - 84 98 88 87 168 168 168 168 169 62 239 239 239 171 76 76 - 237 71 71 71 73 73 74 75 75 75 75 75 75 76 77 77 - 40 39 41 41 136 91 91 91 246 246 246 246 171 76 77 77 - 97 98 61 98 61 168 62 62 239 62 62 239 76 76 76 77 - 204 204 204 204 204 61 20 49 80 54 54 60 59 60 59 59 - 60 236 70 236 70 71 71 71 73 72 73 74 75 75 76 76 - 238 167 136 137 171 63 76 96 61 237 238 81 96 165 167 160 - 166 165 165 164 163 163 162 162 161 104 160 160 160 160 105 247 - 163 163 163 164 164 164 164 164 165 165 165 165 165 165 165 165 - 162 162 162 163 163 163 163 163 164 164 164 164 165 165 165 165 - 161 162 163 163 160 161 162 250 104 64 64 249 250 250 250 250 - 249 65 65 66 66 66 67 67 68 68 68 165 165 165 165 165 - 162 162 162 163 163 163 163 163 164 164 164 164 165 165 165 165 - 163 250 250 163 164 164 165 165 162 161 160 105 105 105 128 129 - 129 129 130 131 132 132 132 133 133 133 84 165 165 166 166 166 - 162 162 162 162 162 163 163 163 164 164 164 165 165 165 166 166 - 161 104 104 104 161 162 162 162 162 163 163 164 164 165 165 165 - 64 64 65 65 66 66 66 67 250 250 165 165 165 165 166 167 - 129 129 129 130 130 130 131 81 81 163 164 164 165 165 165 166 - 104 104 104 104 161 162 163 163 250 96 96 96 165 165 165 61 - 214 55 214 54 54 54 162 105 105 248 52 52 52 57 57 57 - 227 231 229 230 232 65 65 65 65 66 66 67 67 68 165 68 - 66 64 163 133 83 165 165 248 64 64 65 105 160 160 161 160 - 166 166 165 164 164 163 162 162 64 64 160 160 160 248 248 248 - 250 250 250 250 164 164 164 164 165 165 165 166 166 166 166 166 - 162 162 162 163 250 250 250 250 250 250 164 165 165 166 166 69 - 249 249 250 250 104 249 65 66 64 64 65 66 67 68 68 69 - 65 65 66 66 66 235 234 234 68 69 69 69 69 69 69 69 - 162 162 163 250 250 250 250 164 165 164 164 165 165 166 166 236 - 66 67 67 67 164 69 69 69 64 64 160 160 105 160 160 255 - 255 255 162 163 164 164 164 165 165 165 165 166 166 166 70 70 - 162 162 163 163 163 250 250 250 164 165 165 165 166 166 70 70 - 161 64 64 64 64 64 162 163 163 250 164 164 165 165 166 69 - 65 65 66 66 66 235 235 235 235 68 69 69 69 69 70 166 - 255 255 255 255 162 162 162 163 164 164 164 165 165 69 236 70 - 104 64 64 64 249 250 250 250 250 250 165 165 165 236 236 61 - 54 60 54 54 54 249 250 247 247 248 248 57 57 58 57 57 - 228 229 229 230 232 232 233 66 66 66 235 235 68 69 69 69 - 66 64 163 165 165 166 236 160 64 65 66 248 160 104 249 160 - 237 166 166 165 164 164 163 162 162 162 161 160 160 160 160 248 - 250 164 164 165 165 165 165 165 165 166 166 166 70 70 237 70 - 163 163 250 250 250 250 68 68 68 68 165 165 166 70 166 70 - 162 250 250 250 161 249 66 66 64 249 65 67 68 68 69 69 - 66 66 66 235 235 234 234 69 69 236 236 70 70 70 70 70 - 250 250 250 250 250 250 164 164 165 165 165 166 166 166 70 70 - 67 68 68 68 69 69 70 70 64 64 160 160 160 160 160 255 - 162 162 163 164 164 133 165 165 165 166 166 166 167 237 237 70 - 162 163 250 250 250 250 164 164 165 165 166 70 70 70 237 70 - 161 64 162 65 162 162 250 250 250 164 164 165 165 166 166 236 - 66 66 66 235 235 235 234 68 69 236 236 70 70 70 70 237 - 255 130 130 162 162 163 163 164 164 164 165 165 166 166 70 70 - 104 64 249 249 250 250 250 250 250 250 165 166 166 70 70 237 - 49 60 60 60 60 250 250 247 248 248 52 57 57 57 57 57 - 229 229 229 232 232 233 233 233 66 235 235 234 69 236 70 70 - 66 64 163 165 166 167 70 64 64 65 235 248 104 161 162 160 - 237 237 166 166 165 164 164 163 162 162 162 161 160 160 160 160 - 165 165 165 165 165 166 166 166 166 70 237 237 237 237 237 237 - 164 164 164 164 164 165 69 69 69 69 236 70 70 70 237 70 - 250 250 250 250 162 250 250 67 249 65 66 67 68 69 69 236 - 66 235 235 234 234 234 69 236 236 70 70 70 70 237 237 237 - 250 250 250 164 165 165 165 165 165 166 70 70 70 70 237 237 - 68 69 69 69 69 70 70 70 163 249 161 160 160 104 255 255 - 130 131 132 133 165 165 166 166 166 166 167 167 237 237 237 237 - 163 250 250 250 164 165 69 165 165 166 70 237 237 237 237 237 - 162 162 162 163 250 250 250 250 164 165 165 166 166 166 166 70 - 66 66 235 235 235 68 69 236 236 236 70 70 237 237 237 237 - 255 130 162 163 163 163 164 164 164 165 165 166 166 70 70 237 - 162 249 250 250 250 250 250 250 250 165 166 166 70 237 237 237 - 55 16 55 55 55 60 250 105 248 248 53 53 57 58 58 58 - 229 229 230 232 233 233 234 235 235 234 234 69 236 70 70 70 - 235 65 164 165 166 167 70 64 65 66 68 160 104 162 250 160 - 72 71 237 237 166 165 165 164 163 163 162 162 161 160 160 160 - 165 166 166 166 237 237 237 237 237 237 237 237 237 237 168 71 - 164 164 165 165 165 165 166 236 70 70 237 237 237 237 237 237 - 250 250 68 69 162 250 67 68 66 66 67 68 69 236 70 237 - 68 234 234 69 69 236 236 70 70 70 70 70 237 71 71 71 - 165 165 165 69 69 166 166 70 70 70 237 237 237 237 237 71 - 236 236 70 70 237 237 237 71 250 163 162 104 104 255 255 80 - 131 132 133 134 135 135 167 167 167 167 168 168 168 238 72 72 - 164 164 164 165 165 69 166 166 70 237 237 237 237 71 72 73 - 250 250 250 250 250 250 165 165 165 166 70 70 166 237 237 237 - 68 68 68 69 69 236 236 70 70 70 70 237 71 72 72 73 - 163 132 163 164 164 164 165 165 165 166 166 167 237 237 237 71 - 163 250 250 250 250 250 250 165 166 166 237 237 237 237 237 238 - 16 16 55 55 55 60 96 160 160 53 53 53 58 58 58 59 - 230 230 230 233 233 234 234 235 234 69 69 236 70 70 71 71 - 68 66 165 166 167 168 237 64 66 66 69 160 161 162 250 160 - 73 73 71 237 237 166 165 165 164 163 162 162 255 255 255 160 - 166 166 237 237 237 237 237 237 237 237 72 238 238 238 238 238 - 165 165 165 165 166 166 166 237 237 237 237 237 237 71 72 72 - 164 165 69 236 250 250 68 69 250 67 67 69 236 70 237 71 - 69 69 69 236 236 70 70 70 71 71 71 71 71 72 72 72 - 165 165 165 236 70 70 70 237 237 237 237 237 237 71 72 73 - 70 70 237 237 237 71 72 72 164 163 162 104 255 255 81 81 - 132 133 134 135 86 88 87 88 168 168 169 169 238 238 238 73 - 165 165 165 69 166 70 70 166 237 237 237 237 72 73 73 74 - 164 250 250 164 165 165 166 166 165 166 237 237 237 237 71 71 - 68 68 69 236 236 70 70 70 70 70 237 71 72 73 73 74 - 163 132 164 164 165 165 165 166 166 167 167 168 168 71 238 73 - 163 250 250 96 96 165 165 166 237 237 237 237 237 237 238 74 - 16 16 16 61 60 97 96 160 160 53 59 58 58 59 58 58 - 230 230 233 234 234 234 234 68 69 236 236 70 70 71 71 72 - 69 67 165 166 168 169 71 249 66 67 236 160 161 163 165 160 - 74 73 238 168 168 167 166 165 165 164 163 162 162 255 255 255 - 167 237 237 237 237 168 168 168 168 238 238 238 238 238 74 74 - 166 166 166 166 166 167 167 237 237 237 71 238 238 238 238 73 - 165 166 70 70 250 250 69 70 250 250 250 69 70 71 71 72 - 236 236 236 70 70 70 70 71 71 71 72 72 73 73 73 73 - 166 166 166 70 237 237 237 237 237 237 71 72 72 238 73 74 - 237 237 237 71 72 238 73 73 165 163 163 161 255 255 131 132 - 132 134 135 88 136 90 137 90 169 169 169 239 238 238 74 74 - 165 166 166 166 70 237 237 167 237 237 72 238 238 73 74 74 - 96 96 96 165 165 166 166 166 166 237 237 168 168 238 238 73 - 69 69 236 70 70 70 237 71 71 71 71 73 73 73 74 74 - 164 133 133 165 165 166 166 167 167 167 168 168 168 238 238 74 - 163 96 96 96 165 166 61 61 167 237 72 238 238 238 238 75 - 19 202 16 16 60 61 165 255 104 104 59 59 59 59 58 58 - 230 233 234 234 234 234 69 69 236 70 70 70 71 71 73 73 - 69 69 166 167 169 239 72 250 67 68 237 161 162 164 165 160 - 75 74 74 238 168 168 167 166 165 165 164 164 82 130 254 129 - 168 168 168 238 238 238 238 238 238 74 74 74 74 74 75 75 - 167 166 166 167 167 168 168 168 238 238 238 238 238 238 74 74 - 166 237 237 237 164 96 236 237 250 250 68 70 71 73 73 73 - 70 70 70 70 71 71 71 71 72 73 73 73 74 74 74 74 - 237 237 237 237 237 237 72 238 238 238 238 238 238 74 74 75 - 71 71 71 238 238 238 74 75 166 165 164 162 81 130 132 132 - 132 134 135 88 136 137 137 137 137 170 239 239 239 75 75 75 - 166 166 237 237 237 237 237 237 238 238 238 74 74 74 75 75 - 96 96 97 166 166 166 61 61 61 168 238 238 238 238 74 74 - 166 70 70 237 237 71 71 72 72 73 73 74 74 74 74 75 - 84 133 134 135 135 166 167 167 168 168 169 169 169 238 239 74 - 96 96 97 97 61 61 61 61 61 168 238 238 74 74 74 75 - 153 202 203 61 17 61 97 49 80 53 54 59 59 59 59 59 - 67 234 234 234 234 69 236 236 70 70 71 71 72 73 74 74 - 70 69 166 167 170 239 238 250 68 69 71 162 163 165 166 160 - 76 75 75 239 169 168 168 167 166 166 84 83 82 81 80 254 - 238 238 238 238 238 74 238 238 238 74 75 75 75 75 75 75 - 167 167 168 168 168 168 168 169 238 239 239 239 239 239 75 75 - 166 167 237 238 165 165 237 72 250 250 250 237 71 71 74 74 - 237 70 70 71 71 71 72 73 73 73 74 74 74 75 75 75 - 167 168 72 238 238 238 238 238 238 238 238 74 74 75 75 75 - 72 72 238 238 239 75 75 75 166 166 164 163 80 131 132 132 - 134 134 88 136 91 24 138 246 246 246 170 171 75 76 76 75 - 167 167 237 237 237 238 238 238 238 238 74 75 75 75 75 75 - 97 97 97 61 61 61 61 61 168 168 238 239 239 239 239 75 - 167 237 237 237 71 72 73 73 73 74 74 74 75 75 75 75 - 134 135 135 135 135 136 168 168 168 169 169 170 239 239 75 75 - 96 97 97 61 61 61 61 61 238 238 169 239 75 75 75 76 - 20 202 203 61 61 17 61 49 49 49 54 54 59 59 60 250 - 67 68 67 236 69 236 70 70 70 71 72 73 73 74 74 74 - 237 70 167 169 170 239 75 163 69 237 71 80 164 166 166 160 - 76 75 75 239 169 168 168 167 86 85 84 83 82 82 50 80 - 169 238 238 238 238 239 239 238 239 239 75 75 75 75 76 76 - 168 136 168 168 168 168 169 169 169 239 239 239 239 239 75 75 - 166 167 168 238 97 97 61 72 96 60 165 71 73 238 75 75 - 237 237 71 71 72 72 73 73 74 74 74 75 75 75 75 75 - 167 168 168 168 238 238 238 238 239 239 239 239 75 75 75 75 - 238 238 238 238 239 75 75 75 166 166 164 81 131 131 132 37 - 134 40 41 91 92 25 138 246 246 246 171 171 76 76 76 76 - 167 167 168 168 168 238 238 238 238 239 239 75 75 76 76 76 - 97 97 97 98 61 61 61 61 168 168 169 239 239 239 75 75 - 167 237 237 237 71 72 73 73 74 74 75 75 75 75 75 76 - 134 134 135 135 88 136 136 136 137 169 170 170 170 171 76 76 - 97 97 97 61 61 61 168 168 62 169 169 239 75 75 76 77 - 20 203 203 204 61 61 61 49 49 49 54 54 59 60 60 250 - 250 68 68 70 236 70 70 70 71 71 72 73 74 74 75 75 - 237 167 167 137 170 171 75 164 165 237 238 80 84 166 166 160 - 77 76 76 171 169 169 169 87 86 85 84 83 83 82 50 50 - 169 169 239 239 239 239 239 239 75 75 76 76 76 76 76 76 - 136 136 137 137 169 169 169 170 170 239 239 171 171 76 76 76 - 98 61 168 238 97 61 61 73 60 60 166 72 238 238 75 75 - 237 71 71 73 73 73 74 74 74 75 75 75 75 76 76 76 - 167 168 168 169 169 169 239 239 239 239 239 239 75 76 76 76 - 238 238 238 239 239 75 76 76 167 166 84 82 131 132 37 38 - 40 39 41 42 92 93 28 29 29 94 245 63 172 77 77 77 - 167 168 168 169 169 238 238 169 239 239 239 75 76 76 76 77 - 84 17 17 98 19 21 21 90 90 169 62 239 239 171 76 76 - 168 237 237 238 238 238 74 74 75 75 75 75 76 76 76 77 - 134 38 135 135 136 136 137 137 137 170 170 170 171 171 76 77 - 84 17 98 19 19 21 21 62 62 62 62 239 76 76 76 77 - 21 203 203 203 20 20 21 49 49 80 55 60 60 60 55 250 - 250 68 68 70 70 70 70 71 71 72 73 74 74 75 75 75 - 237 167 168 137 171 171 76 164 166 237 238 80 83 98 167 160 - 77 77 172 171 170 169 23 90 87 86 85 84 152 152 151 50 - 169 169 239 239 239 239 75 75 76 76 76 76 76 77 77 77 - 137 137 137 137 137 170 170 170 170 170 171 171 171 172 172 77 - 87 168 169 62 98 61 168 238 97 97 61 238 238 239 75 76 - 168 71 73 73 74 74 74 75 75 75 75 76 76 76 77 77 - 90 169 169 169 62 170 239 171 239 171 171 171 76 77 77 77 - 239 239 239 239 171 76 76 77 168 167 84 132 132 37 38 38 - 39 39 155 92 43 44 29 29 94 139 139 172 172 173 77 77 - 168 168 169 169 169 239 239 170 239 239 75 76 76 77 77 77 - 85 18 19 20 99 21 22 23 62 62 170 171 171 63 77 77 - 168 168 238 238 238 238 239 239 75 75 76 76 76 77 77 77 - 38 38 39 41 136 136 137 138 138 246 246 171 171 172 172 77 - 85 18 19 19 20 21 62 62 62 62 170 171 76 77 77 77 - 23 204 204 204 204 21 62 149 50 50 55 60 60 55 55 60 - 60 60 68 71 237 71 71 71 73 73 74 74 75 75 76 76 - 168 167 136 137 139 171 76 165 166 168 169 50 84 98 167 104 - 78 172 172 63 246 26 100 22 99 88 40 153 153 152 151 150 - 169 170 171 171 171 171 76 171 76 76 77 77 77 77 77 77 - 137 137 137 26 26 246 246 246 246 171 171 171 172 172 172 173 - 87 90 169 62 98 19 62 62 97 97 61 238 169 239 76 76 - 168 238 238 74 74 74 75 75 76 76 76 76 77 77 77 77 - 22 62 62 62 62 170 246 171 171 171 171 172 172 77 77 77 - 239 239 239 171 171 77 77 77 87 88 134 132 132 37 38 4 - 39 41 3 43 44 2 2 31 45 103 103 140 173 173 173 78 - 90 169 169 169 169 170 239 239 171 171 76 76 77 77 77 77 - 86 86 20 99 21 22 23 23 24 246 246 245 63 172 77 77 - 169 169 238 238 238 239 239 239 75 76 76 77 77 77 77 78 - 4 4 4 244 244 244 92 138 138 138 139 139 139 172 173 78 - 85 19 20 21 21 21 62 62 62 246 245 63 172 77 77 173 - 204 204 204 204 204 23 62 149 150 150 51 55 60 55 60 60 - 60 61 165 71 71 71 71 73 73 74 74 75 75 76 76 76 - 238 167 137 137 139 139 76 165 167 168 239 82 84 86 168 48 - 78 173 172 172 246 26 24 91 41 41 40 40 38 37 36 150 - 246 171 171 171 171 171 63 63 63 172 77 173 173 173 78 173 - 92 25 26 27 138 246 246 246 246 171 172 172 172 140 173 173 - 90 62 62 62 19 21 62 62 97 97 168 62 62 171 63 77 - 169 238 238 74 75 75 75 76 76 76 77 77 77 173 78 78 - 23 62 62 62 246 246 246 245 245 63 63 172 173 173 173 78 - 239 239 171 171 77 77 77 78 136 88 134 132 37 37 38 4 - 39 3 3 43 2 2 31 94 95 95 158 140 173 173 79 78 - 169 169 169 169 170 170 171 171 171 171 172 77 77 77 78 78 - 88 99 99 21 22 23 23 100 26 246 246 245 63 172 173 77 - 169 169 238 238 239 239 239 239 76 76 77 77 77 78 78 173 - 4 4 244 244 244 244 43 93 29 94 139 139 172 172 173 78 - 86 20 99 21 22 23 24 246 246 245 63 63 172 173 173 173 - 205 205 204 204 204 23 23 149 150 50 51 55 55 55 60 61 - 61 61 166 72 71 71 72 73 74 74 75 75 76 76 77 76 - 238 167 170 137 139 172 77 165 167 169 239 152 84 88 168 48 - 79 173 173 172 245 101 27 92 42 41 39 39 38 37 37 36 - 246 245 171 171 171 63 63 63 172 173 173 173 78 78 79 79 - 25 27 27 28 246 246 246 139 139 172 172 172 172 140 173 173 - 23 62 62 62 20 21 62 62 17 17 62 62 62 171 172 77 - 170 238 238 239 75 76 76 76 76 77 77 77 78 78 79 79 - 23 246 246 246 246 246 245 245 245 63 172 172 173 173 173 78 - 171 239 171 172 77 173 78 78 90 88 134 133 37 38 4 4 - 3 3 43 2 2 95 95 95 95 158 1 47 141 79 79 79 - 137 169 170 170 170 171 171 171 172 172 172 173 78 78 78 79 - 41 41 22 22 91 23 24 26 246 246 245 63 63 172 173 78 - 169 169 239 239 239 239 75 76 76 77 77 173 173 78 78 174 - 244 186 186 244 244 187 2 93 29 94 139 140 173 173 78 79 - 20 99 22 23 23 26 246 246 245 63 63 63 172 173 78 79 - 205 205 205 204 204 23 24 150 151 152 83 96 60 60 60 61 - 61 61 61 73 72 72 73 73 74 74 75 76 77 77 77 77 - 239 167 170 137 139 172 77 166 167 169 171 152 153 87 169 48 - 174 78 173 172 63 245 246 26 92 155 41 40 38 38 37 37 - 245 63 63 63 63 63 63 63 172 173 78 79 79 79 79 79 - 26 26 246 246 245 245 245 63 63 172 172 172 173 173 173 79 - 22 62 62 62 19 21 62 62 61 61 62 239 239 77 77 78 - 170 169 169 239 75 76 76 76 76 77 77 78 78 78 79 79 - 24 246 246 245 245 245 63 63 245 63 172 172 173 78 78 78 - 171 76 76 77 77 173 78 78 90 87 85 153 38 38 4 4 - 3 3 43 2 95 95 126 95 158 46 1 141 141 79 174 79 - 170 170 170 170 171 171 171 171 77 77 173 173 78 78 79 79 - 99 22 22 23 23 24 246 246 246 245 63 63 63 173 173 78 - 170 239 239 75 75 76 76 77 77 77 77 78 78 78 79 174 - 244 187 187 187 187 188 2 93 29 94 103 140 173 78 79 79 - 99 21 22 23 246 246 246 246 245 63 63 63 63 173 79 79 - 205 205 205 205 205 205 246 151 151 152 16 60 60 60 61 61 - 61 61 61 73 73 73 73 73 74 74 75 76 77 77 78 77 - 75 167 171 137 140 173 78 98 167 169 76 153 153 90 169 48 - 85 153 152 152 151 150 149 149 148 147 147 146 145 144 144 144 - 150 50 50 151 82 152 151 152 153 152 152 153 153 153 153 153 - 149 149 150 150 150 150 150 150 151 151 152 152 152 153 153 153 - 149 80 150 50 48 49 49 50 48 49 49 49 50 50 151 133 - 130 130 131 131 81 82 82 82 83 83 83 84 152 153 153 153 - 149 150 150 150 150 151 151 151 151 152 152 152 152 133 153 84 - 50 50 151 152 152 133 84 84 254 128 146 253 144 9 8 8 - 8 7 7 7 34 6 35 37 5 37 37 37 37 38 153 153 - 254 49 130 130 131 50 50 151 151 152 152 153 153 153 153 153 - 147 148 254 254 254 254 49 49 131 131 131 151 152 152 153 84 - 254 80 80 80 50 50 82 82 151 152 152 153 153 153 134 38 - 7 8 8 8 32 32 33 6 34 6 36 36 152 153 153 85 - 147 148 148 148 149 149 150 150 151 151 151 151 152 153 153 153 - 196 214 200 198 214 149 150 144 144 144 253 53 53 53 53 53 - 53 53 54 249 104 104 162 162 163 163 164 164 164 133 133 133 - 130 255 130 131 37 37 84 253 48 49 49 106 146 128 254 48 - 86 85 153 152 152 151 150 150 149 148 148 147 146 145 145 144 - 82 83 83 83 83 83 83 84 84 84 84 84 85 85 85 85 - 150 50 50 50 50 82 82 83 83 84 84 84 153 153 153 85 - 49 50 50 82 48 49 80 51 49 54 49 80 51 51 83 85 - 130 131 131 132 164 84 84 84 97 85 85 85 85 153 153 85 - 130 50 50 50 50 82 82 82 152 83 84 84 84 84 85 85 - 82 83 83 152 153 153 84 85 80 254 48 146 146 8 8 8 - 7 7 33 6 35 35 37 5 5 5 38 38 38 40 40 86 - 150 50 50 50 50 82 83 82 152 84 153 153 153 85 86 86 - 147 254 254 49 49 80 50 50 50 82 83 83 84 153 85 85 - 81 81 81 82 82 83 83 84 152 153 153 85 85 85 86 40 - 7 32 32 33 33 34 34 35 37 37 37 37 153 85 85 18 - 148 148 149 149 149 150 150 50 82 82 152 84 153 85 85 18 - 214 213 213 213 198 200 151 144 144 253 253 53 53 53 53 53 - 53 58 249 249 104 249 250 250 250 250 164 164 164 84 134 134 - 131 130 131 132 37 134 85 48 49 50 50 144 48 48 49 48 - 88 86 85 153 152 152 151 150 149 148 148 148 146 146 145 144 - 152 83 83 83 84 84 84 84 84 84 153 85 85 86 86 86 - 150 150 151 151 151 83 83 83 84 84 84 84 153 153 85 85 - 49 50 50 83 48 80 50 51 54 54 49 51 51 83 84 85 - 131 131 132 132 164 84 84 84 84 85 85 85 85 85 40 86 - 131 50 82 82 82 83 83 83 152 84 84 84 85 85 85 86 - 83 83 83 153 153 153 85 85 50 254 48 147 146 8 8 7 - 7 33 6 35 5 5 5 5 38 38 38 38 40 154 41 99 - 150 50 50 50 82 83 83 83 84 84 153 85 85 86 86 20 - 148 149 254 149 80 50 50 50 50 82 84 84 153 153 85 86 - 82 81 82 82 82 83 83 84 84 84 85 85 86 86 86 41 - 7 32 33 34 34 35 35 35 37 37 37 153 153 85 85 18 - 148 148 149 149 150 150 151 151 82 83 84 84 153 85 86 20 - 197 214 213 200 200 200 151 144 144 253 48 53 53 53 53 53 - 58 59 59 53 249 250 250 250 250 164 164 165 165 85 135 134 - 131 131 131 132 133 134 86 48 49 50 50 253 48 254 80 104 - 99 88 85 153 153 152 151 151 150 149 148 148 147 146 146 145 - 152 83 83 83 84 84 84 85 85 134 134 85 86 86 86 86 - 151 151 151 151 152 152 83 84 84 84 84 85 85 85 85 86 - 150 82 82 83 49 50 50 51 54 54 54 51 51 83 17 85 - 132 132 132 164 133 84 97 84 84 85 85 85 86 86 86 88 - 151 82 82 82 83 83 84 84 84 84 85 85 85 85 86 86 - 83 83 84 153 153 85 86 86 50 254 254 147 146 8 8 7 - 7 33 6 35 5 5 5 5 38 38 4 39 40 154 41 99 - 150 50 82 82 82 83 84 84 84 153 85 85 85 86 20 99 - 149 149 150 150 150 50 50 50 82 83 84 153 153 85 86 86 - 132 131 132 132 132 83 133 84 85 85 85 86 86 88 89 41 - 7 32 33 34 34 34 35 5 37 37 38 38 153 40 86 20 - 148 149 149 150 150 151 151 152 83 84 85 85 85 85 86 20 - 196 198 200 200 200 200 151 144 253 253 48 53 53 53 53 58 - 58 59 58 53 250 250 250 250 250 164 165 165 166 86 135 135 - 163 162 132 132 133 134 19 254 49 50 82 253 254 254 80 104 - 22 99 86 85 153 153 152 151 150 149 149 148 147 147 146 145 - 152 84 84 84 85 85 85 86 86 40 40 40 88 89 89 89 - 37 37 37 152 133 133 84 84 84 85 85 85 86 86 88 87 - 50 82 82 84 49 50 51 96 54 54 55 96 55 16 20 86 - 132 164 164 165 165 166 98 98 87 19 88 19 89 99 99 99 - 151 83 83 83 83 84 84 84 85 85 85 86 86 88 89 99 - 83 84 84 85 86 88 89 87 82 49 254 147 146 148 7 7 - 33 6 6 35 5 38 5 4 4 39 39 154 41 41 22 22 - 151 82 83 83 83 84 84 84 85 85 86 86 88 99 99 99 - 149 150 150 151 151 151 151 152 84 153 153 153 40 154 99 89 - 132 132 133 133 133 84 85 85 85 86 86 88 89 90 90 41 - 34 33 33 34 35 35 35 5 5 5 38 38 40 40 88 99 - 149 149 150 151 151 152 152 152 84 84 85 85 86 89 99 21 - 197 200 201 201 200 200 152 145 253 146 48 53 53 53 59 59 - 58 59 58 59 250 250 250 250 164 165 166 166 167 87 89 88 - 164 163 132 133 134 40 90 49 50 51 84 146 254 49 81 48 - 22 99 88 86 153 153 152 152 151 150 149 149 148 147 147 146 - 153 85 85 85 86 85 135 88 88 88 88 41 89 90 90 41 - 37 37 37 133 133 153 153 134 85 85 86 86 86 88 89 87 - 151 83 152 84 49 51 82 96 49 54 96 96 16 17 20 88 - 83 164 165 165 166 167 167 98 87 19 88 20 99 21 99 90 - 152 83 84 84 84 84 85 85 85 85 86 86 88 89 99 90 - 84 17 18 86 88 88 89 90 82 80 49 147 146 7 7 33 - 6 6 35 5 38 4 4 4 4 39 41 41 41 41 155 23 - 151 83 83 84 84 84 85 85 86 86 88 99 99 99 22 22 - 149 150 150 151 151 152 152 152 153 153 153 85 86 99 21 90 - 132 133 133 133 134 135 86 86 86 86 86 88 99 90 91 91 - 34 34 34 35 35 35 35 5 38 38 39 39 40 41 41 22 - 149 150 150 151 151 152 153 84 84 85 85 86 88 90 90 21 - 201 201 201 200 200 201 152 145 253 146 48 53 53 59 59 58 - 58 59 59 59 60 250 250 250 165 165 166 166 167 90 90 136 - 164 164 133 134 135 88 90 49 50 83 16 48 254 80 82 48 - 23 22 99 154 40 153 153 152 151 150 150 149 148 148 147 146 - 153 85 85 85 86 86 86 89 89 89 89 41 91 91 91 91 - 37 38 38 38 38 153 153 134 86 86 88 88 89 89 90 90 - 152 84 133 84 49 51 83 97 54 55 96 96 16 61 20 90 - 133 165 165 165 166 167 167 87 19 19 88 99 21 22 91 23 - 152 84 84 84 84 85 85 85 86 86 88 88 89 99 91 22 - 17 17 18 88 88 99 90 90 83 80 254 148 128 7 7 33 - 6 35 35 5 4 4 4 4 4 39 3 155 155 155 42 100 - 152 83 84 84 84 85 85 85 86 88 89 99 99 91 23 100 - 150 150 151 152 152 152 153 153 153 85 85 86 88 99 22 90 - 133 133 133 134 135 135 86 86 88 88 88 99 22 91 91 92 - 34 34 35 35 35 37 5 5 38 4 39 39 41 41 41 42 - 150 150 151 151 152 152 153 153 85 85 85 86 99 22 91 23 - 202 201 201 201 201 201 153 145 146 146 48 54 54 59 54 59 - 59 59 59 60 60 60 60 165 166 166 166 167 167 90 90 136 - 165 164 133 134 135 136 22 49 50 51 16 48 254 50 83 104 - 26 100 91 99 154 40 153 153 152 151 150 150 149 7 148 147 - 18 86 86 86 87 99 89 90 90 91 91 91 91 24 24 24 - 38 38 38 38 40 40 40 40 88 88 89 90 90 22 91 23 - 152 84 84 85 50 83 84 97 55 60 96 97 61 61 20 23 - 84 165 166 166 166 167 167 87 62 169 22 23 23 23 100 23 - 153 84 85 85 85 86 86 86 88 88 99 22 91 91 91 23 - 85 18 19 99 90 91 91 23 84 131 130 254 148 7 7 6 - 6 35 5 38 4 4 4 4 4 3 3 42 42 24 26 246 - 153 84 85 85 85 86 86 86 99 99 99 22 91 100 26 246 - 151 151 152 152 152 153 153 153 153 85 88 99 99 22 91 137 - 134 165 134 135 135 88 88 87 90 90 90 22 23 24 26 26 - 35 35 35 37 35 5 38 4 38 4 41 41 155 42 92 26 - 150 151 152 152 153 153 153 85 85 86 88 99 90 23 23 24 - 201 201 202 202 201 201 153 146 146 146 48 54 54 54 54 59 - 59 59 60 60 250 60 70 165 70 70 167 167 168 90 137 137 - 166 164 133 134 136 91 62 49 51 83 17 48 254 50 83 104 - 26 24 23 22 41 40 40 153 152 152 36 6 7 7 7 148 - 20 20 20 99 99 90 22 91 22 91 100 100 24 24 24 26 - 38 38 39 39 40 154 41 99 99 99 22 22 22 23 23 24 - 84 85 85 88 151 16 84 17 55 55 96 97 17 20 21 62 - 84 166 167 167 166 167 168 168 169 23 23 23 23 24 26 26 - 153 85 85 86 86 86 88 88 89 99 90 91 92 24 26 246 - 86 19 99 90 91 92 24 170 84 132 131 254 148 33 34 34 - 35 5 5 38 4 4 244 3 244 3 3 43 43 156 26 246 - 153 84 85 85 85 86 88 88 90 91 91 100 24 24 26 246 - 151 151 152 152 153 153 153 85 85 86 88 99 90 91 100 137 - 135 166 166 135 167 87 90 90 90 22 23 23 24 246 246 26 - 36 35 35 37 5 38 4 4 4 39 41 41 42 92 26 26 - 36 152 152 152 153 153 40 40 20 99 99 22 91 23 24 246 - 202 202 202 201 201 201 153 146 146 148 50 54 54 54 53 59 - 60 59 59 60 60 60 96 70 70 237 237 168 168 169 137 137 - 166 164 135 135 136 137 62 50 83 16 18 254 49 82 97 48 - 246 246 24 42 41 154 40 40 38 5 37 6 6 7 7 148 - 20 20 99 21 21 22 23 23 100 24 24 26 26 26 246 246 - 39 39 39 39 154 41 41 22 22 22 23 23 100 24 26 246 - 153 85 85 88 151 16 16 98 55 55 96 16 19 20 23 62 - 166 166 167 167 167 168 168 168 169 23 62 246 246 246 246 246 - 85 85 86 86 88 89 99 99 91 91 91 100 24 26 26 246 - 87 99 90 22 92 24 26 246 85 132 131 254 7 34 34 6 - 5 5 38 4 4 4 244 244 3 3 43 43 43 93 101 246 - 153 85 85 86 86 88 99 99 91 23 100 24 26 26 246 245 - 152 152 152 153 153 153 40 40 86 88 89 90 91 100 24 170 - 135 166 166 167 167 87 90 90 23 23 23 246 246 246 245 101 - 37 37 5 5 5 5 4 4 39 41 3 3 42 25 101 101 - 36 37 153 153 153 40 40 154 99 99 22 23 23 24 246 246 - 202 202 202 201 201 201 153 147 147 148 49 49 54 54 54 59 - 60 60 60 60 60 60 165 237 237 237 237 168 169 169 170 170 - 166 165 135 135 137 92 62 50 83 16 19 254 150 82 97 48 - 245 101 26 24 42 41 154 39 38 38 5 36 6 33 7 7 - 99 21 21 23 23 23 100 24 26 26 246 246 246 245 245 245 - 39 39 39 41 41 41 155 42 23 23 24 26 246 246 246 246 - 153 86 86 99 152 16 17 61 96 60 97 98 61 21 24 246 - 167 166 167 167 168 169 169 90 169 62 246 246 246 246 246 246 - 40 86 88 99 99 22 91 91 100 24 24 26 26 246 246 246 - 21 21 23 24 26 27 246 171 85 132 132 150 7 6 35 35 - 5 38 4 4 244 244 244 244 3 43 44 2 2 30 157 245 - 40 86 88 89 89 90 91 91 92 24 26 26 246 157 245 245 - 152 153 153 153 40 40 86 88 89 90 91 91 24 26 246 246 - 88 167 167 167 168 168 169 23 62 62 246 246 245 245 245 245 - 37 5 5 38 38 4 4 3 3 3 3 43 43 101 157 157 - 37 5 153 153 40 154 99 99 21 22 23 24 26 246 246 245 - 202 203 203 203 202 202 41 148 148 149 49 49 54 55 55 60 - 59 60 60 60 60 165 166 237 237 71 238 169 169 170 246 170 - 167 165 136 136 137 26 246 151 16 18 99 149 151 83 97 48 - 172 245 28 26 92 42 41 39 38 38 5 37 36 6 33 7 - 22 23 23 23 100 24 246 246 246 246 245 245 245 245 63 245 - 41 3 3 3 155 155 42 92 24 26 26 101 101 245 245 245 - 86 89 99 22 152 17 19 61 96 16 17 19 21 62 246 246 - 167 167 167 168 169 239 170 170 170 170 246 246 245 245 245 245 - 88 99 90 22 22 23 100 24 26 26 26 246 246 245 245 245 - 23 23 24 26 101 28 245 63 88 153 152 131 34 36 35 5 - 5 38 4 244 244 244 244 244 43 2 2 31 45 45 103 172 - 88 88 89 22 91 91 100 26 24 26 246 246 245 245 63 63 - 153 153 153 40 40 154 41 41 90 91 91 24 26 246 245 171 - 87 168 168 168 168 169 169 62 62 246 246 245 245 63 63 103 - 5 5 4 4 4 4 244 3 3 43 43 93 44 157 157 102 - 37 5 153 40 154 41 22 22 23 23 24 246 246 245 245 63 - 202 203 203 203 202 202 155 7 148 149 150 55 55 60 55 60 - 55 60 60 60 166 166 237 71 71 72 238 238 239 171 171 171 - 168 166 136 136 138 138 245 152 18 19 23 150 132 84 98 48 - 140 102 30 28 43 43 3 41 39 4 38 5 37 35 6 6 - 23 23 24 26 246 246 246 245 246 245 245 245 63 63 63 103 - 3 3 3 3 3 42 43 25 26 101 101 157 157 157 103 63 - 154 21 22 23 16 19 20 62 96 16 98 19 21 62 246 246 - 167 168 168 169 239 239 239 171 171 171 171 63 63 63 172 172 - 99 22 22 91 91 100 24 26 26 26 246 157 245 63 172 172 - 23 62 246 101 101 157 139 172 99 153 133 36 36 37 5 5 - 5 4 4 3 244 43 187 2 2 2 2 45 102 158 158 140 - 41 90 91 91 91 24 26 246 26 246 246 139 139 172 140 140 - 153 153 40 154 154 41 41 91 91 91 24 26 101 245 139 63 - 90 168 168 169 169 169 170 170 246 246 246 245 63 63 140 140 - 4 185 185 185 4 4 244 244 3 43 43 2 31 157 103 158 - 5 38 39 154 41 155 23 23 100 24 246 246 245 63 63 207 - 203 203 203 203 203 203 155 7 148 150 150 55 60 60 55 55 - 60 60 60 61 61 237 72 238 238 238 238 239 239 171 172 171 - 168 166 136 136 138 94 63 152 19 21 23 150 152 85 98 48 - 159 158 45 30 44 43 3 3 41 4 38 5 5 35 34 34 - 26 246 246 246 246 245 245 245 139 139 139 172 172 140 140 1 - 3 3 3 43 43 43 93 44 28 30 157 45 45 103 102 140 - 20 22 22 24 16 20 21 62 16 61 87 90 62 246 245 171 - 168 169 169 239 239 239 239 171 76 63 63 172 172 172 140 173 - 91 91 23 100 24 26 246 246 246 246 245 245 63 172 140 173 - 246 246 246 157 157 103 172 172 91 85 153 37 36 5 5 5 - 4 39 3 43 2 2 188 188 188 94 45 95 46 1 1 173 - 91 91 91 24 24 26 246 246 246 245 139 139 172 140 173 173 - 40 154 154 154 41 155 155 42 92 24 26 101 157 102 158 140 - 90 90 169 169 170 170 170 246 171 245 245 63 172 140 140 47 - 185 185 186 186 186 244 244 244 43 2 2 31 45 103 158 1 - 38 39 154 41 41 42 100 23 26 246 245 245 63 63 140 173 - 205 204 204 204 204 204 156 199 149 151 150 55 60 55 55 55 - 60 61 61 61 168 238 238 238 238 238 239 239 171 172 172 172 - 169 167 137 136 138 139 172 153 19 21 23 151 152 85 88 48 - 141 1 102 45 94 44 43 3 244 4 4 38 5 35 35 34 - 246 246 245 245 245 245 139 172 172 172 140 140 1 1 173 47 - 43 43 43 43 2 2 2 94 94 45 103 158 158 158 1 47 - 99 23 24 246 17 21 62 62 17 61 169 169 62 63 172 172 - 169 169 239 239 239 239 239 76 77 172 172 172 173 173 173 173 - 24 24 26 26 246 246 246 245 245 63 63 172 140 173 173 173 - 246 245 245 63 103 158 140 173 24 40 153 37 37 5 5 4 - 4 3 3 2 2 188 188 189 189 95 95 46 47 159 141 141 - 92 24 24 26 246 246 246 245 245 63 172 140 140 173 141 141 - 154 154 155 155 155 42 156 25 26 101 157 102 102 158 1 173 - 91 169 170 170 170 171 171 171 172 172 172 172 140 140 141 190 - 185 185 186 186 187 187 187 188 188 188 94 95 95 158 46 159 - 4 154 41 155 42 24 26 26 246 245 63 63 172 173 173 159 - 205 204 204 204 204 204 156 6 150 151 151 55 60 60 60 60 - 61 61 61 61 168 238 238 238 74 75 75 75 76 173 173 173 - 169 168 137 137 139 103 173 153 99 23 246 151 153 88 168 254 - 174 79 140 63 63 245 27 25 42 41 39 39 38 38 37 37 - 246 171 171 63 63 63 77 172 172 173 173 173 173 173 79 79 - 43 43 93 44 28 157 157 63 139 63 172 140 140 173 173 79 - 21 62 62 245 19 62 62 239 61 61 62 62 62 76 77 77 - 239 74 74 75 75 75 76 76 76 77 77 78 78 78 78 78 - 62 246 246 246 246 245 63 63 63 63 172 173 173 173 78 78 - 171 171 63 63 172 173 173 78 62 86 85 133 37 38 38 4 - 41 3 43 44 94 45 95 158 46 46 46 1 141 79 79 79 - 24 170 170 170 246 171 171 171 63 77 77 173 78 78 79 79 - 41 155 155 23 23 24 246 246 245 245 63 63 63 173 173 173 - 62 169 239 239 75 76 76 76 77 77 77 173 173 78 79 174 - 186 186 186 244 187 187 188 2 94 94 103 103 140 140 141 79 - 40 154 155 23 100 246 246 246 245 245 63 173 173 173 173 79 - 204 204 205 205 204 204 205 151 150 152 51 60 60 60 61 61 - 61 61 61 61 238 238 238 74 74 75 75 75 76 77 78 78 - 239 169 170 138 139 140 78 85 168 62 239 132 85 87 168 254 - 23 21 20 19 17 84 83 82 151 150 254 254 254 147 146 48 - 97 97 97 97 98 98 98 98 87 87 87 87 87 87 87 99 - 152 152 152 153 153 153 153 16 85 18 18 19 20 87 99 21 - 51 51 96 97 54 55 96 60 54 54 55 96 97 97 98 167 - 164 250 164 164 165 166 166 166 167 167 167 167 87 87 87 88 - 83 83 83 84 84 97 97 98 85 98 98 86 86 88 87 168 - 97 97 97 98 98 86 88 167 82 80 254 48 128 128 254 149 - 150 151 152 37 153 38 40 40 40 40 88 99 21 22 23 169 - 83 83 83 84 97 97 97 97 98 98 98 98 87 87 90 21 - 150 150 151 151 82 82 83 83 16 16 16 17 19 20 21 21 - 96 96 96 96 165 165 166 166 166 98 167 88 88 87 169 137 - 34 34 35 35 36 37 37 37 134 134 86 88 88 88 88 87 - 150 150 151 151 82 83 83 83 16 17 18 18 18 20 99 21 - 201 201 201 201 200 152 16 146 48 253 53 53 53 53 58 59 - 59 54 54 54 250 250 164 163 166 166 166 166 166 168 168 168 - 164 163 133 134 135 87 167 104 163 250 165 48 254 80 81 48 - 62 62 21 19 19 17 84 83 83 50 80 49 49 48 48 48 - 61 61 61 61 61 61 61 61 61 61 61 168 168 169 62 62 - 84 84 16 17 17 17 17 18 18 19 19 87 168 168 168 168 - 96 96 97 97 55 55 60 61 54 59 60 60 61 61 61 168 - 165 165 165 165 166 237 237 237 166 167 167 168 168 169 62 62 - 83 97 97 97 97 97 61 61 61 61 167 168 168 168 168 169 - 97 61 61 61 61 168 168 169 83 81 49 254 48 254 150 150 - 151 151 152 153 153 40 40 41 89 99 99 21 23 62 62 62 - 83 164 165 165 165 97 166 61 167 61 61 168 168 168 62 62 - 50 50 51 83 83 83 83 16 17 17 98 19 61 21 62 62 - 96 96 165 165 165 166 61 61 167 167 167 168 168 168 169 169 - 36 36 37 37 37 37 133 134 85 85 88 87 90 90 169 62 - 50 50 51 83 83 16 16 16 17 17 19 19 21 21 62 62 - 201 201 202 202 16 16 16 146 48 48 53 59 59 59 58 58 - 58 59 250 60 250 250 250 250 236 70 70 237 237 168 168 168 - 165 164 134 135 88 90 168 104 250 250 165 48 49 81 81 104 - 62 62 23 21 20 19 17 84 84 83 50 150 150 149 148 148 - 19 61 61 61 61 61 168 21 21 21 21 23 62 62 62 246 - 153 85 85 18 18 19 19 19 99 99 21 90 169 169 169 62 - 97 97 97 61 55 96 60 61 55 55 60 61 61 61 168 169 - 166 166 166 237 237 237 168 168 238 169 169 169 169 169 23 62 - 16 16 17 17 17 61 61 61 61 61 168 62 62 62 62 62 - 61 61 61 61 62 62 62 62 97 82 50 49 149 149 150 151 - 36 37 5 40 39 41 41 155 155 42 92 24 24 246 246 62 - 84 97 98 98 98 167 167 87 168 87 90 169 62 62 62 62 - 82 82 83 83 84 84 84 17 98 18 19 20 21 22 62 62 - 97 61 61 61 61 61 61 61 61 62 62 62 62 62 62 246 - 37 37 37 5 38 38 40 40 40 86 99 21 23 62 62 62 - 50 51 83 97 97 97 17 61 17 61 61 61 62 62 62 62 - 202 202 202 202 16 16 17 48 48 48 54 59 59 59 58 59 - 59 59 250 60 60 250 68 236 70 70 237 237 72 238 238 238 - 165 164 134 135 41 24 62 81 96 97 61 48 50 82 83 48 - 245 246 62 23 22 87 86 18 153 152 151 151 150 149 148 148 - 20 20 21 21 21 62 62 62 62 62 24 246 246 246 246 246 - 40 40 40 86 86 99 99 21 22 23 23 23 62 62 170 62 - 84 16 98 61 83 96 61 61 55 60 60 61 61 168 169 169 - 166 167 167 168 168 168 238 238 169 169 170 62 62 246 246 246 - 18 19 19 19 19 20 21 21 21 62 62 62 62 62 246 62 - 61 61 62 62 62 62 62 62 18 83 50 150 150 150 151 36 - 5 5 4 39 3 3 3 43 3 43 43 27 101 101 246 246 - 85 86 88 87 168 90 90 90 90 22 23 23 62 246 246 245 - 152 84 84 85 85 85 18 86 86 88 87 90 22 62 62 62 - 97 61 61 61 61 61 62 62 62 62 62 62 62 246 245 245 - 37 37 5 38 38 39 154 41 41 41 22 23 23 24 246 246 - 83 83 16 16 17 17 61 61 61 61 62 62 62 62 62 62 - 203 202 202 202 16 16 18 148 48 49 54 54 54 59 59 60 - 60 60 60 60 60 60 236 237 70 237 71 72 238 238 238 238 - 166 165 135 41 42 101 62 51 97 61 19 149 151 84 97 254 - 63 245 246 24 91 90 88 86 40 153 152 152 151 150 149 149 - 21 21 22 23 62 62 62 246 246 246 246 246 246 245 245 245 - 41 41 41 99 90 91 91 100 23 24 26 246 246 246 246 246 - 85 19 19 20 83 97 61 61 96 97 61 61 168 169 62 170 - 167 167 168 168 168 238 238 238 169 170 239 171 171 245 63 63 - 20 20 20 21 21 21 23 23 23 24 246 246 101 245 157 245 - 22 62 62 62 246 246 245 245 86 152 151 151 150 36 5 5 - 5 4 4 3 3 3 3 43 43 2 44 29 157 45 139 245 - 85 86 88 90 90 90 90 90 62 246 246 246 245 245 63 63 - 153 153 85 86 86 86 88 99 99 90 91 24 246 246 246 171 - 88 168 168 168 168 168 169 62 62 246 246 245 245 245 245 245 - 5 5 38 4 4 39 41 155 92 24 24 26 26 246 245 63 - 152 153 85 18 18 19 20 21 23 62 62 62 246 246 245 63 - 203 202 203 203 203 203 20 148 148 49 49 54 55 60 55 55 - 55 60 60 60 165 166 237 237 237 238 238 238 239 239 239 170 - 167 166 136 136 93 157 245 82 16 61 21 150 152 84 98 48 - 172 139 246 138 25 92 41 41 41 39 38 5 37 36 6 6 - 23 62 62 62 246 246 246 245 245 245 245 245 63 63 172 172 - 155 42 42 42 92 24 25 26 26 26 246 245 245 139 139 172 - 20 21 23 62 16 17 61 61 97 97 61 61 169 62 245 171 - 168 168 238 238 238 239 239 239 76 76 76 63 63 63 245 245 - 21 22 22 23 23 100 24 26 26 246 246 157 157 45 103 172 - 23 23 246 246 246 245 172 172 89 134 37 36 36 36 5 5 - 4 4 3 3 3 43 2 2 2 2 94 45 103 158 140 172 - 88 87 90 169 169 169 169 170 246 246 245 245 63 172 140 140 - 153 40 40 154 41 41 22 23 91 24 26 101 246 245 139 172 - 90 168 169 168 90 169 170 246 246 245 245 63 139 103 158 158 - 4 4 4 4 39 3 3 3 43 43 93 28 30 45 103 140 - 153 153 40 154 41 21 23 23 24 246 246 246 246 63 172 173 - 203 203 203 203 203 203 155 149 149 149 50 55 60 60 55 60 - 60 60 61 61 61 168 238 168 238 238 239 170 170 171 171 171 - 167 166 136 137 29 102 63 16 17 21 23 151 152 85 168 48 - 190 46 189 94 2 43 244 244 244 4 4 5 5 5 35 6 - 246 246 246 245 245 245 63 63 63 63 63 172 173 173 173 173 - 156 156 156 156 156 101 101 157 157 157 45 102 102 158 46 1 - 21 23 62 62 18 20 62 62 17 61 61 62 62 245 63 77 - 169 238 238 74 239 75 75 76 76 76 77 77 77 173 173 173 - 91 91 137 137 170 170 246 246 246 171 171 139 139 172 140 140 - 26 246 246 245 139 172 173 173 137 86 134 37 37 5 5 5 - 4 3 3 43 2 2 31 95 95 95 95 158 1 159 141 79 - 90 169 169 170 170 170 246 171 245 63 63 172 140 1 47 159 - 154 154 154 155 155 155 156 156 156 101 157 157 45 102 158 173 - 90 169 169 169 170 170 171 171 172 172 172 140 140 1 141 141 - 185 185 186 186 244 244 187 187 187 188 188 94 94 95 46 140 - 38 40 154 41 155 100 24 26 246 246 245 245 63 172 140 173 - 204 204 204 204 203 204 156 150 150 150 51 60 55 55 60 61 - 61 61 97 61 168 238 238 238 238 239 239 239 171 76 77 76 - 168 167 137 27 45 1 173 17 61 62 62 152 153 86 168 48 - 141 141 140 139 94 29 93 92 3 41 39 39 38 38 37 37 - 171 171 75 171 76 76 77 77 77 77 77 77 77 78 78 78 - 26 101 101 101 101 245 245 63 63 63 172 140 140 140 173 173 - 90 62 62 62 98 168 62 74 61 61 238 238 239 76 77 77 - 238 73 74 74 74 75 75 76 76 76 76 77 78 78 78 77 - 169 169 169 170 170 239 239 171 76 76 77 77 77 173 78 78 - 239 239 171 76 77 77 77 78 169 86 134 133 133 38 4 4 - 39 155 43 44 94 45 103 158 140 140 140 140 173 78 79 78 - 169 169 169 239 239 239 239 239 76 77 77 77 173 78 79 79 - 41 21 21 23 23 100 24 26 246 245 63 63 172 173 173 78 - 169 169 238 239 239 75 76 76 77 77 77 77 78 78 78 79 - 244 244 244 244 244 93 93 138 29 94 139 139 140 140 140 173 - 40 154 22 23 23 24 246 246 245 63 63 77 77 173 78 173 - 204 204 205 205 205 205 205 151 152 50 55 60 60 60 61 61 - 61 61 61 72 72 72 73 74 74 75 75 75 76 77 77 77 - 238 169 170 138 139 173 77 97 168 74 239 83 85 167 238 160 - 84 82 50 50 80 254 254 254 49 48 253 105 106 106 105 105 - 255 255 255 162 162 162 255 162 162 162 81 81 163 82 132 132 - 129 129 129 129 129 254 254 130 130 131 131 131 131 131 131 131 - 128 255 255 255 105 160 104 161 105 160 160 160 104 162 81 163 - 161 160 104 161 161 161 162 162 162 162 163 163 163 163 163 164 - 255 255 80 80 255 255 80 81 81 81 80 80 81 82 132 82 - 104 162 162 162 162 163 163 163 160 105 105 105 106 106 106 106 - 128 128 128 129 130 130 130 130 131 131 131 131 131 132 133 164 - 105 160 104 104 255 255 255 255 162 162 81 81 131 131 132 133 - 253 253 253 128 129 254 254 254 254 129 129 131 131 131 131 132 - 160 104 161 104 104 162 162 161 162 162 162 163 163 164 164 83 - 129 129 129 129 129 129 129 129 129 130 131 131 131 81 81 82 - 253 146 146 146 146 254 49 254 50 50 50 50 50 82 83 83 - 147 214 214 214 214 148 148 252 253 144 247 247 247 52 52 52 - 52 52 53 53 64 104 104 64 249 162 162 162 162 163 163 163 - 162 105 130 131 131 130 163 105 160 160 255 106 105 105 160 160 - 81 80 80 254 253 48 48 105 105 106 106 106 252 252 252 252 - 105 105 48 160 255 255 255 255 160 255 255 255 255 255 255 130 - 128 128 128 128 128 128 128 128 128 128 129 129 129 129 130 130 - 105 105 105 105 106 105 105 105 105 105 105 105 160 104 255 104 - 160 160 160 160 105 160 104 161 160 104 255 255 255 255 255 80 - 48 105 105 105 105 48 48 255 255 255 254 254 254 254 254 80 - 160 104 255 255 255 255 255 104 105 247 106 106 252 252 106 106 - 106 106 253 253 128 128 128 128 128 128 128 129 254 130 130 255 - 105 105 160 160 160 160 104 255 255 160 129 129 130 130 130 130 - 106 106 105 106 106 106 253 253 253 128 128 128 129 129 130 130 - 160 160 160 160 105 160 160 161 104 104 255 255 255 161 80 80 - 106 106 106 106 106 253 128 129 128 128 128 254 254 80 80 80 - 106 253 144 144 144 253 48 48 253 48 254 254 254 49 49 49 - 146 145 145 145 147 147 147 107 252 252 247 247 247 247 247 247 - 247 247 248 248 248 248 248 248 160 160 104 104 104 255 255 255 - 105 105 128 128 129 129 160 247 105 105 105 252 106 106 247 160 - 128 129 128 253 253 253 106 106 106 252 252 252 251 107 107 251 - 106 106 106 106 253 253 253 128 128 128 128 129 128 128 128 128 - 10 10 10 10 106 106 106 106 253 253 253 128 128 128 128 128 - 106 106 106 105 252 106 105 105 252 247 105 105 106 106 253 254 - 106 106 105 105 106 105 253 253 128 128 128 128 128 128 128 128 - 106 106 106 253 253 106 106 106 253 253 253 128 128 128 129 128 - 106 106 253 253 128 128 254 254 106 252 252 251 107 107 107 107 - 11 10 10 9 9 9 9 8 8 8 8 8 8 128 148 128 - 106 106 106 106 106 106 106 106 253 253 128 254 129 128 128 128 - 252 106 106 144 106 106 106 144 106 253 253 253 253 128 128 128 - 106 106 106 105 105 106 105 253 128 128 128 128 128 128 128 128 - 11 10 10 11 11 10 10 10 10 9 9 8 8 128 128 128 - 252 106 106 106 144 144 144 106 144 253 146 146 128 48 48 147 - 144 144 144 144 144 144 144 251 251 251 252 252 247 247 247 247 - 247 247 247 247 247 247 248 248 105 105 105 160 160 160 160 128 - 253 253 10 9 8 128 128 252 106 106 253 107 252 252 106 160 - 8 10 9 9 11 11 11 107 11 107 13 13 14 13 251 14 - 10 144 144 10 10 144 144 144 10 10 10 10 10 10 9 10 - 10 10 11 11 11 11 10 10 106 10 144 144 9 10 10 144 - 107 252 252 106 251 252 252 106 252 252 252 252 106 253 106 106 - 252 252 106 253 106 106 253 144 144 144 144 144 144 144 144 144 - 252 252 106 106 144 144 144 106 106 144 144 144 10 10 10 10 - 253 106 106 10 10 10 106 106 106 107 251 251 13 13 13 108 - 12 11 11 11 110 10 10 10 9 10 9 9 9 9 8 8 - 252 252 252 252 106 144 144 144 106 144 10 10 10 10 9 148 - 107 107 107 107 107 107 11 106 252 106 106 10 10 144 253 253 - 252 252 252 106 253 106 106 106 106 106 144 144 144 253 253 9 - 12 109 109 109 109 110 110 110 11 11 10 10 10 10 9 8 - 107 107 107 107 107 252 106 106 106 106 10 10 10 144 253 145 - 11 10 192 11 11 11 11 15 215 251 251 251 251 252 252 252 - 247 252 252 252 252 252 247 247 105 105 105 105 106 106 106 106 - 106 11 12 9 10 10 253 251 252 106 106 14 251 251 252 128 - 9 9 10 11 11 11 12 12 13 13 13 13 14 15 14 15 - 11 11 10 10 10 10 11 11 10 10 10 10 10 9 9 9 - 12 12 12 12 12 11 11 11 10 10 10 10 11 10 10 10 - 107 107 107 252 251 107 107 252 251 251 252 252 252 252 11 10 - 107 107 252 106 11 11 10 11 11 11 11 10 10 10 10 9 - 12 12 12 12 12 11 11 11 11 11 11 11 11 10 10 9 - 11 11 11 10 10 10 10 9 13 13 14 14 15 14 14 108 - 108 108 109 109 110 110 110 110 110 110 110 111 10 10 9 9 - 12 107 107 107 11 11 10 11 11 11 10 10 10 10 9 9 - 13 13 13 12 12 107 107 107 107 11 10 10 10 11 10 10 - 107 107 107 107 11 11 11 11 11 11 11 11 10 10 9 9 - 108 108 109 109 109 109 109 109 110 110 110 110 11 11 10 9 - 13 13 12 12 12 11 12 12 11 10 10 11 11 10 10 10 - 11 11 11 12 11 11 12 15 15 15 215 215 216 251 251 251 - 252 251 251 251 251 251 252 252 252 252 106 106 106 10 10 10 - 107 107 13 9 110 11 10 251 251 107 11 15 14 251 252 128 - 9 10 9 10 11 11 10 109 109 109 109 108 108 108 14 14 - 11 11 10 10 10 9 9 9 9 10 10 10 9 9 9 9 - 11 110 110 110 11 11 10 10 10 10 10 10 10 10 9 9 - 11 11 11 10 12 11 11 10 251 107 252 252 11 10 10 9 - 11 11 10 10 10 10 9 9 9 9 9 9 9 9 9 9 - 10 10 10 10 11 11 11 11 9 9 9 9 10 10 10 10 - 11 10 10 10 10 10 10 9 12 12 13 13 14 108 108 109 - 109 109 109 110 111 111 111 111 111 111 111 111 111 112 112 9 - 11 11 10 10 11 11 11 11 9 9 9 10 10 9 9 9 - 12 11 12 12 12 11 11 10 11 11 10 10 10 10 10 9 - 11 10 10 11 11 10 10 10 9 9 10 10 9 9 9 9 - 109 109 109 110 110 109 109 109 110 110 110 111 10 10 10 10 - 11 12 12 12 12 11 11 10 11 10 10 9 9 9 9 9 - 10 192 192 192 10 10 110 14 14 14 14 14 251 107 107 251 - 251 252 252 252 252 252 106 106 106 106 9 9 10 10 10 10 - 107 10 11 10 112 10 10 12 107 11 11 14 12 12 252 128 - 8 8 9 9 112 112 111 110 110 110 109 109 109 109 108 108 - 9 9 10 10 10 10 9 9 9 8 8 8 8 8 9 9 - 111 111 111 111 111 10 10 10 10 9 9 8 8 8 8 8 - 11 10 10 10 12 11 10 9 107 11 11 10 9 9 9 8 - 10 10 10 9 10 9 9 9 9 8 8 8 8 9 9 9 - 11 10 10 10 9 9 9 10 10 9 9 9 8 8 8 8 - 10 10 9 9 9 8 8 8 11 11 12 13 108 108 109 109 - 110 110 110 111 111 111 111 111 113 112 112 112 112 112 113 8 - 11 10 10 10 10 10 9 9 10 9 8 8 8 9 9 8 - 12 11 11 11 11 11 11 11 9 10 10 9 9 8 8 8 - 11 10 9 10 10 10 10 10 9 9 9 9 9 8 8 8 - 110 110 109 110 110 111 111 111 111 111 111 112 112 8 8 8 - 12 12 11 11 10 10 10 10 10 10 9 9 8 8 8 8 - 11 192 192 192 192 11 10 14 14 13 13 107 107 107 107 107 - 252 252 252 106 106 106 106 253 144 144 9 9 9 8 8 8 - 106 9 10 10 112 9 9 12 11 10 9 108 12 12 252 128 - 32 8 8 8 112 112 112 111 111 111 110 110 110 109 108 109 - 9 9 9 8 8 9 9 8 9 8 8 32 8 8 32 32 - 111 111 111 111 112 112 8 9 9 9 9 9 9 8 8 32 - 10 9 10 9 11 9 9 10 11 11 10 10 9 8 8 8 - 10 9 9 8 9 9 8 8 9 8 8 32 32 8 8 32 - 9 9 9 9 9 8 8 9 8 8 8 8 8 8 32 32 - 8 8 9 9 8 8 7 8 10 11 11 109 109 109 110 110 - 110 110 111 111 111 113 113 112 113 113 113 114 113 114 114 32 - 10 10 10 9 9 8 8 9 8 8 9 8 8 32 32 32 - 110 110 111 111 111 112 10 10 9 9 8 9 9 8 8 32 - 10 9 9 9 8 8 8 9 9 8 8 8 32 32 32 32 - 110 111 111 111 111 111 111 111 113 112 112 112 112 113 8 32 - 11 11 10 10 10 10 10 10 8 8 9 8 8 8 7 7 - 144 193 193 193 193 9 9 108 108 12 11 11 11 252 11 252 - 106 144 144 144 144 144 106 253 146 9 8 8 8 8 32 8 - 10 106 10 9 112 113 32 11 11 9 8 108 109 11 106 128 - 32 32 181 114 113 113 113 113 111 111 111 111 110 110 110 109 - 112 8 8 32 8 8 32 32 32 32 32 32 32 32 32 33 - 113 113 113 113 113 112 113 8 32 32 32 32 32 32 32 32 - 10 9 8 8 10 9 9 8 10 144 9 8 8 8 8 32 - 8 9 9 8 8 32 32 32 32 32 32 32 32 32 32 32 - 8 8 9 9 9 9 8 8 32 8 8 32 32 32 32 33 - 8 8 7 8 32 32 32 33 10 10 10 110 110 110 110 110 - 111 111 112 113 113 113 114 114 114 114 114 114 114 114 114 182 - 9 8 9 9 9 8 8 32 32 32 32 32 32 32 32 32 - 111 111 111 111 111 112 113 8 9 9 8 8 32 32 32 33 - 9 8 8 9 8 8 32 8 8 32 32 32 32 32 32 32 - 111 111 111 112 113 113 113 113 113 113 114 114 181 180 181 32 - 111 112 112 112 9 8 8 9 8 8 7 7 32 32 32 33 - 9 195 194 193 8 113 113 108 109 12 11 11 192 192 192 144 - 144 144 144 145 145 145 9 8 8 8 7 7 32 32 32 32 - 128 9 8 8 181 114 32 11 9 9 8 109 110 10 253 128 - 183 182 182 114 114 114 113 113 112 113 111 111 111 110 110 110 - 32 32 32 32 32 32 32 33 32 33 182 182 182 182 182 182 - 114 114 114 114 114 113 114 181 32 32 32 32 32 182 182 183 - 8 8 32 32 9 8 8 7 9 145 8 8 7 32 32 34 - 32 7 7 7 32 33 33 33 32 32 33 33 33 33 182 182 - 8 8 32 32 32 33 32 32 32 32 32 33 182 182 182 182 - 32 32 32 32 32 33 33 35 8 9 112 111 110 111 111 111 - 113 113 113 113 114 113 114 114 114 115 115 115 115 115 115 183 - 9 8 8 32 32 32 32 32 32 32 33 182 182 182 183 183 - 112 113 113 113 113 113 113 113 32 113 32 32 32 33 33 35 - 8 8 32 32 32 32 32 32 32 33 33 33 32 182 182 183 - 113 113 113 113 113 113 113 114 114 114 114 114 182 182 182 182 - 112 113 112 112 113 113 32 32 33 33 32 32 33 33 34 5 - 112 7 114 114 114 114 114 110 110 11 11 10 144 144 144 144 - 145 145 145 146 147 8 8 7 7 7 33 33 32 33 182 182 - 8 8 32 180 114 114 182 10 9 8 32 110 111 9 128 128 - 184 184 183 115 114 114 114 114 113 113 113 113 111 111 111 111 - 32 33 33 33 33 33 182 183 183 183 183 183 183 183 184 116 - 114 114 114 114 114 114 114 182 182 182 182 183 183 183 183 184 - 32 32 32 32 8 7 7 33 8 8 7 7 33 33 183 183 - 33 33 33 33 34 34 34 34 35 35 183 183 183 183 183 184 - 32 32 32 32 32 33 33 32 182 182 182 183 183 183 183 184 - 32 33 33 33 183 183 184 184 8 8 112 111 111 111 112 111 - 113 113 114 114 114 115 115 115 115 115 115 116 116 116 116 184 - 32 32 32 32 33 33 32 32 182 183 183 183 183 184 184 116 - 113 113 114 114 113 114 114 114 114 114 114 115 115 183 184 184 - 32 32 32 33 33 33 33 34 182 183 183 183 183 183 184 117 - 113 113 113 113 114 114 114 114 115 114 114 115 115 116 116 116 - 113 113 113 113 114 114 114 114 114 114 182 182 183 183 183 184 - 112 114 114 114 114 113 114 110 111 10 10 144 144 194 195 195 - 147 146 147 148 7 7 7 33 33 34 34 34 35 183 183 183 - 32 8 32 181 115 116 183 9 8 7 6 10 112 8 129 128 - 117 117 117 116 115 115 115 115 114 113 114 114 113 113 113 111 - 183 183 183 183 183 183 184 184 185 185 120 118 117 117 117 118 - 115 115 115 115 115 115 115 116 116 116 116 117 117 117 117 117 - 32 33 33 34 32 7 33 6 8 7 34 33 6 35 184 184 - 34 34 35 35 35 35 183 183 185 185 185 185 184 185 117 120 - 182 33 33 33 182 183 183 184 183 183 184 184 117 117 117 120 - 183 183 183 183 184 185 185 185 33 32 113 113 113 113 113 113 - 113 114 115 114 115 116 116 116 116 116 116 117 117 117 117 120 - 182 33 33 182 183 183 184 184 184 184 184 117 117 117 117 118 - 113 114 114 114 114 114 115 115 115 115 116 116 116 117 117 118 - 182 34 35 35 35 35 183 183 183 184 185 185 185 117 117 118 - 113 114 114 114 115 115 115 115 115 115 116 116 116 116 117 117 - 113 114 114 114 115 115 115 114 115 115 116 116 117 117 117 118 - 115 115 115 115 115 115 115 111 111 10 10 145 145 195 195 195 - 148 148 148 199 6 6 6 35 35 35 5 5 184 184 184 185 - 35 32 33 182 116 117 185 113 32 33 5 112 113 8 33 128 - 119 118 117 117 116 116 116 115 114 115 114 114 114 113 113 112 - 184 184 185 185 185 185 185 120 117 118 118 118 118 118 118 118 - 116 116 116 116 116 116 116 117 117 117 117 118 118 118 118 118 - 183 184 184 184 33 6 35 5 7 6 5 35 5 184 185 185 - 35 5 5 5 184 185 185 185 186 186 186 121 120 120 119 120 - 183 183 183 184 184 185 185 184 185 185 118 118 118 118 118 118 - 185 185 184 184 185 118 118 120 183 33 32 114 114 113 114 115 - 115 115 115 116 116 116 116 117 117 117 117 118 118 118 119 120 - 183 183 183 184 184 184 184 184 184 185 120 120 118 119 119 119 - 115 115 114 114 115 115 115 116 116 116 117 117 117 117 118 118 - 183 184 184 184 184 184 185 185 185 185 185 120 118 120 119 119 - 115 115 115 115 115 116 116 116 116 116 117 118 117 117 118 119 - 115 115 115 114 115 116 116 116 117 117 117 117 118 118 118 119 - 116 115 115 115 115 115 116 111 112 9 8 196 196 197 197 199 - 150 150 150 36 37 5 5 38 5 38 4 185 185 186 121 186 - 183 34 184 183 117 117 120 32 6 5 4 112 114 32 35 128 - 119 119 118 118 117 117 116 115 115 115 115 114 113 114 114 113 - 185 184 185 185 185 185 185 120 118 118 119 119 119 119 119 119 - 116 116 116 116 116 117 117 117 118 117 118 118 118 118 119 119 - 183 184 185 184 34 35 5 4 33 36 5 5 4 185 121 186 - 5 5 38 4 185 185 186 186 186 186 186 121 121 119 119 119 - 184 184 184 184 184 184 184 184 120 118 118 118 119 119 119 119 - 184 185 185 185 118 118 119 121 182 32 32 114 114 113 114 115 - 115 115 116 116 117 116 116 117 117 118 118 119 119 119 119 121 - 184 184 184 184 184 184 184 184 185 120 120 119 119 119 119 119 - 115 115 115 115 115 116 116 116 117 117 117 117 117 118 119 119 - 183 184 185 184 185 185 186 185 186 120 120 120 119 119 119 119 - 115 115 115 115 115 116 116 116 117 117 117 117 118 119 119 119 - 115 115 115 115 115 116 117 117 117 117 117 117 118 118 119 119 - 116 116 116 116 116 116 116 113 112 8 8 196 196 196 197 199 - 150 150 151 37 5 5 4 4 4 4 185 186 186 121 121 121 - 184 183 184 184 118 119 121 114 6 5 185 113 114 182 37 128 - 119 119 119 119 117 117 117 116 115 114 115 114 113 114 114 113 - 186 185 185 186 186 121 121 121 121 119 119 119 119 119 119 119 - 116 116 117 117 117 117 118 118 118 118 118 118 119 119 119 119 - 183 184 184 184 6 35 5 4 6 37 5 5 4 186 121 187 - 184 5 38 4 185 186 186 186 186 186 186 121 123 123 119 123 - 184 184 184 184 184 185 185 121 120 120 120 119 119 119 119 119 - 184 185 185 120 119 119 119 123 183 182 33 114 114 114 114 115 - 115 116 116 116 117 118 118 117 118 118 119 119 119 119 119 123 - 184 184 184 184 184 185 185 186 186 121 121 119 119 119 119 119 - 115 182 115 183 116 116 117 116 117 117 117 117 118 119 119 119 - 183 184 184 185 185 185 186 185 186 120 121 121 123 123 119 119 - 115 115 116 116 116 116 116 116 117 117 117 118 119 119 119 119 - 114 115 115 115 116 117 117 117 117 118 119 119 119 119 119 119 - 117 116 117 117 116 116 116 112 113 7 7 197 197 198 198 198 - 150 151 151 37 5 38 4 4 4 4 185 186 186 121 122 123 - 185 183 184 117 119 119 123 114 6 5 185 32 182 183 134 128 - 123 119 119 119 118 118 118 116 116 116 115 115 114 114 113 113 - 186 186 185 186 186 122 122 123 123 123 119 119 119 119 119 119 - 116 117 117 117 117 118 118 118 119 119 119 119 119 119 119 119 - 183 184 185 185 5 5 5 4 36 5 5 4 4 186 122 123 - 4 4 4 4 244 244 244 187 186 186 187 123 123 123 123 123 - 184 185 185 185 185 185 185 185 121 121 122 123 119 119 119 123 - 185 186 186 121 123 123 119 123 183 183 33 32 114 114 115 115 - 115 116 116 117 117 117 117 118 118 119 119 119 119 119 123 123 - 184 184 184 185 185 185 185 185 186 121 121 123 123 119 119 123 - 183 183 184 184 184 184 184 184 120 120 120 119 119 119 119 119 - 184 184 184 185 186 186 186 187 122 122 121 121 121 123 123 123 - 115 115 116 116 116 116 117 117 117 118 119 119 119 119 119 123 - 6 5 5 183 183 184 185 120 120 120 120 119 123 123 123 123 - 119 117 118 118 116 116 184 112 32 7 199 199 197 198 198 198 - 151 152 152 153 38 39 39 39 39 39 244 244 187 122 123 124 - 185 184 185 120 119 119 123 33 5 4 185 32 182 184 134 128 - 123 123 119 119 119 120 118 117 184 184 183 183 182 114 114 113 - 186 186 186 186 122 122 123 123 123 123 123 123 123 123 124 124 - 117 117 118 118 118 120 119 119 119 119 119 119 119 119 119 123 - 184 4 185 244 5 4 4 244 37 153 38 4 3 3 122 124 - 4 4 3 244 244 244 244 187 188 187 187 124 124 124 124 124 - 185 185 186 186 186 186 186 186 121 122 123 123 123 123 123 124 - 186 244 187 122 123 123 124 124 184 35 35 32 114 114 115 115 - 116 116 117 117 117 118 119 119 119 119 119 119 119 123 124 124 - 185 185 185 185 186 186 186 186 186 186 122 123 123 124 124 124 - 182 183 184 185 185 185 185 185 185 120 121 121 121 123 123 123 - 184 4 185 186 186 186 187 187 122 123 124 123 124 124 124 123 - 116 116 116 116 116 117 117 117 118 119 119 119 119 123 123 124 - 5 5 5 4 4 185 185 186 121 122 123 124 124 124 124 124 - 119 120 120 120 185 185 185 8 8 7 199 199 200 200 200 200 - 151 152 153 153 40 40 41 39 3 3 244 244 187 124 124 124 - 185 184 185 120 119 119 124 34 5 4 185 32 182 183 134 128 - 124 124 123 123 121 121 120 185 184 184 184 183 182 114 114 114 - 186 244 244 186 187 123 124 124 124 124 124 124 124 124 124 124 - 185 185 185 120 120 121 121 121 123 123 123 124 124 124 124 124 - 4 4 4 244 5 4 4 3 153 40 4 39 3 3 123 125 - 3 3 3 3 3 43 43 2 188 187 188 188 125 124 124 125 - 186 186 186 186 186 186 186 187 122 122 123 124 124 124 125 125 - 3 3 187 187 124 124 125 125 4 35 35 33 114 115 115 115 - 116 116 117 118 119 119 119 119 119 119 123 123 124 124 125 125 - 185 185 186 186 186 186 187 187 187 187 124 124 124 124 125 125 - 5 5 184 184 185 185 186 186 186 186 122 123 123 123 123 124 - 185 4 244 244 244 244 187 187 124 124 124 124 124 125 125 125 - 116 116 116 117 117 117 118 118 119 119 123 123 123 124 124 125 - 5 5 38 4 4 4 186 186 186 122 123 124 124 124 125 125 - 121 121 4 4 4 4 185 32 7 7 199 198 200 200 200 201 - 152 16 17 18 40 41 41 91 92 92 43 43 188 125 125 125 - 244 4 185 121 123 123 124 35 4 39 244 33 182 35 135 128 - 125 125 124 123 123 122 186 186 185 185 184 183 183 182 32 32 - 244 3 187 187 124 124 124 125 125 125 125 125 125 125 125 125 - 186 186 186 186 186 122 122 123 124 124 124 124 124 124 125 125 - 4 3 244 3 5 39 41 92 153 40 154 41 43 43 124 125 - 3 3 43 43 43 44 2 2 2 2 188 188 125 125 125 126 - 186 186 186 186 186 187 187 187 187 187 124 125 125 125 125 126 - 43 43 93 2 125 125 126 126 4 5 37 34 182 183 183 116 - 117 117 118 119 119 119 119 119 123 123 124 124 124 125 125 125 - 186 186 186 186 186 187 187 187 188 188 188 125 125 125 125 126 - 4 38 38 38 4 244 244 244 186 122 124 124 124 124 124 125 - 3 3 3 3 3 43 43 187 188 188 125 125 125 126 126 126 - 184 184 184 185 120 120 120 120 121 123 123 124 124 124 125 126 - 5 38 4 4 4 244 244 244 186 122 124 124 125 125 125 126 - 4 4 4 4 154 3 3 33 33 198 200 200 200 201 201 201 - 16 16 18 19 19 99 91 91 24 26 138 29 2 125 125 126 - 244 4 244 121 124 124 125 5 4 41 244 34 35 5 135 128 - 126 125 125 124 124 187 187 186 186 185 184 184 35 34 33 33 - 43 2 2 2 2 2 125 125 125 126 126 126 126 126 126 126 - 186 186 187 187 187 187 187 124 124 124 125 125 125 125 126 126 - 3 3 3 43 38 41 155 26 153 19 41 155 156 157 31 126 - 42 25 93 101 44 30 157 45 94 45 45 189 189 126 126 127 - 244 244 244 244 244 187 187 2 188 188 125 125 126 126 126 127 - 44 101 29 94 126 126 127 127 3 38 38 35 35 184 184 184 - 118 118 119 119 119 123 123 123 124 124 125 125 125 125 126 126 - 186 244 244 244 244 187 188 188 188 188 189 126 126 126 126 127 - 4 4 4 39 3 3 3 3 3 187 124 125 125 125 125 126 - 3 3 3 43 93 44 2 94 2 2 189 126 126 126 127 126 - 184 184 185 185 186 186 121 121 123 123 124 124 124 125 125 126 - 4 4 4 244 244 244 244 187 187 187 124 125 125 126 126 127 - 154 203 154 154 155 156 43 33 6 200 200 200 201 201 201 16 - 16 17 19 19 20 21 22 23 170 246 245 139 45 95 126 127 - 244 39 244 186 124 125 126 5 39 41 92 34 5 38 136 128 - 190 127 126 125 125 124 187 187 244 244 4 5 5 35 35 34 - 2 157 31 31 45 95 95 95 126 126 126 127 127 190 190 190 - 187 187 187 187 187 188 188 188 125 125 126 126 126 126 127 127 - 3 43 43 28 40 155 92 246 18 20 22 92 101 157 95 47 - 25 26 246 157 157 157 103 103 103 140 140 46 158 46 127 127 - 3 43 43 2 2 2 2 94 94 95 95 126 126 127 127 127 - 157 157 94 103 95 126 127 159 3 39 38 5 35 184 184 184 - 185 121 121 123 123 123 124 124 125 125 125 126 126 126 127 127 - 244 3 3 43 2 2 2 2 45 189 189 126 126 127 127 127 - 4 39 3 3 3 3 43 3 43 2 125 125 125 126 126 127 - 3 43 93 28 28 94 94 103 94 95 46 46 127 127 127 190 - 185 185 185 186 186 186 186 187 124 124 125 125 126 126 126 127 - 4 4 3 3 3 3 43 2 2 188 125 126 126 126 127 127 - 155 204 204 204 156 156 43 33 6 6 200 201 201 202 16 17 - 17 61 61 21 21 62 62 170 239 171 172 172 140 1 127 190 - 137 136 244 244 125 125 126 38 41 24 28 37 5 4 136 128 - 191 127 126 126 125 188 187 187 244 244 4 38 5 5 5 35 - 44 45 45 31 95 158 158 1 158 46 127 127 127 127 190 190 - 187 187 187 188 188 188 188 95 189 95 126 126 127 127 127 127 - 3 43 93 157 154 23 92 246 19 21 22 24 245 102 158 47 - 138 170 171 171 139 172 140 140 140 140 47 1 1 47 159 142 - 43 44 2 29 31 94 45 45 45 45 158 158 46 127 127 159 - 157 157 139 103 158 127 127 159 42 39 39 5 5 5 184 185 - 186 122 123 124 124 124 125 125 125 125 126 126 127 127 127 191 - 3 43 93 44 2 94 45 94 95 158 46 127 127 127 127 191 - 39 3 3 3 3 43 43 2 2 31 95 126 126 126 127 127 - 43 27 246 246 138 94 139 139 140 140 1 1 127 127 191 191 - 185 185 186 186 186 187 187 187 188 125 125 126 127 127 127 127 - 4 4 3 3 43 43 44 44 31 45 95 126 126 126 127 142 - 205 205 204 204 23 156 43 6 6 6 200 201 202 16 16 17 - 61 61 61 62 62 62 239 239 239 76 77 172 140 47 127 141 - 138 136 138 2 126 126 190 38 22 26 157 5 4 41 169 128 - 191 127 127 126 126 125 2 187 244 244 4 4 4 5 5 5 - 157 172 103 103 158 1 1 47 47 47 127 127 190 190 191 191 - 187 187 188 188 188 2 94 45 95 158 46 46 127 127 127 191 - 43 101 29 103 41 100 26 246 20 21 23 246 245 63 46 141 - 170 170 171 171 172 172 140 173 173 141 141 141 141 142 142 142 - 44 44 30 94 94 94 103 103 158 158 1 47 47 159 191 191 - 102 102 172 140 46 127 191 142 43 154 154 4 5 5 4 186 - 186 187 124 124 125 125 125 126 126 126 127 127 127 127 191 191 - 93 138 29 29 94 103 95 95 1 127 127 127 127 191 191 175 - 3 3 3 43 43 43 44 29 94 45 95 126 126 127 127 191 - 28 246 171 172 139 139 172 172 140 141 47 47 159 191 175 191 - 186 186 186 186 187 187 188 188 188 189 189 126 127 127 190 191 - 244 3 3 43 43 101 157 157 102 102 1 1 1 159 142 142 - 205 205 205 204 156 156 2 6 6 6 152 201 16 17 17 61 - 61 61 61 62 62 239 239 239 75 75 76 77 173 141 141 174 - 139 137 138 2 126 127 141 39 22 26 245 5 4 3 169 48 - 175 142 174 47 46 103 94 44 43 92 41 39 39 38 5 37 - 172 173 172 172 173 140 140 173 141 141 141 141 141 174 174 142 - 29 29 29 94 139 139 139 172 140 140 140 141 141 141 142 142 - 26 245 246 172 99 24 246 171 61 62 62 170 63 63 140 78 - 170 239 75 76 76 77 77 173 78 79 79 79 79 174 142 174 - 246 245 139 139 139 172 172 172 172 173 173 141 141 174 142 175 - 103 172 172 140 173 174 174 175 26 90 41 40 5 38 4 244 - 244 187 187 125 125 126 126 126 127 127 127 191 191 175 143 175 - 138 246 246 246 139 172 140 140 173 47 141 141 174 142 175 175 - 41 42 92 25 26 28 138 138 139 139 172 140 140 141 174 142 - 246 171 171 172 77 77 77 173 173 78 79 174 142 175 175 175 - 244 186 187 187 187 188 188 189 94 189 140 140 140 140 174 175 - 155 155 42 25 101 245 245 245 63 173 173 173 79 79 174 175 - 206 206 206 206 206 101 44 6 36 152 152 16 61 61 61 61 - 61 61 72 73 74 74 74 75 75 75 76 77 78 79 174 79 - 171 169 171 94 127 190 174 135 62 171 63 38 41 92 169 48 - 133 133 132 131 131 130 129 129 128 128 128 253 253 106 10 10 - 130 131 131 131 131 132 132 132 132 132 133 133 133 132 132 133 - 129 129 130 130 130 130 131 131 132 132 132 132 132 133 133 133 - 254 130 129 130 253 129 254 80 105 53 80 80 80 81 132 132 - 161 161 161 162 162 81 163 132 133 133 133 133 133 133 133 133 - 129 130 130 130 130 131 131 131 132 132 132 132 132 133 133 133 - 131 131 131 132 132 132 132 132 254 254 128 106 10 9 8 8 - 8 8 32 33 33 6 6 35 35 5 5 37 37 37 38 134 - 129 130 130 130 130 131 131 131 131 132 132 133 133 133 133 134 - 128 128 128 128 148 254 254 254 254 130 131 132 132 132 132 133 - 129 130 130 130 130 131 131 131 132 132 132 133 133 133 134 134 - 8 8 8 8 8 32 33 33 34 131 131 132 132 132 132 133 - 128 147 147 148 254 254 149 149 150 151 151 151 151 37 37 153 - 196 197 214 196 149 149 149 106 106 144 144 48 53 53 53 53 - 52 53 53 104 104 104 161 161 162 162 163 163 163 132 133 133 - 255 255 130 131 35 37 132 128 254 80 130 106 128 128 255 160 - 135 134 133 132 132 132 130 254 254 128 128 128 253 144 106 106 - 131 163 132 132 132 164 133 133 132 133 133 133 134 134 134 165 - 255 255 162 162 162 81 163 132 131 132 132 132 133 133 134 84 - 254 80 130 130 128 254 80 81 53 54 54 54 81 82 133 165 - 162 162 162 163 163 163 164 164 164 133 133 133 133 133 133 134 - 130 130 130 131 131 131 163 163 132 132 132 133 133 133 134 134 - 131 131 163 132 133 133 84 84 160 160 128 253 10 9 8 8 - 8 32 32 34 35 35 35 35 5 5 5 37 38 134 135 135 - 130 130 130 130 131 131 163 163 132 164 133 165 84 165 165 85 - 48 254 254 254 254 49 49 80 50 82 82 83 83 133 84 134 - 130 130 130 131 131 163 163 132 164 133 133 133 133 134 134 135 - 8 7 32 32 32 33 34 34 132 131 132 133 133 133 133 165 - 48 48 254 254 254 130 150 150 50 82 83 152 152 133 134 153 - 196 198 214 214 150 150 49 106 106 253 105 53 53 53 53 53 - 53 58 249 249 64 249 249 162 162 163 163 164 164 164 133 165 - 162 255 131 131 132 133 133 160 104 162 131 106 128 129 255 160 - 135 135 133 133 133 83 131 130 254 254 128 129 128 253 144 106 - 132 164 164 164 132 133 133 133 134 134 134 134 135 135 135 166 - 130 81 163 81 81 82 132 132 132 133 133 134 134 135 135 135 - 80 81 131 132 129 130 81 164 104 54 104 80 96 83 133 166 - 162 162 163 163 164 164 164 165 165 165 134 134 135 135 135 166 - 131 131 163 163 163 163 132 164 164 164 133 133 134 135 135 135 - 132 132 164 164 133 134 135 166 255 255 129 128 8 8 8 8 - 7 32 33 34 35 35 5 5 5 5 38 38 38 135 135 88 - 130 130 131 131 163 132 164 164 164 133 133 165 135 135 135 86 - 254 254 254 49 80 50 50 50 50 83 83 83 133 84 135 85 - 130 131 131 163 163 164 164 164 133 133 134 134 134 135 135 135 - 7 32 33 33 33 34 34 35 132 132 132 133 84 134 165 166 - 254 254 254 49 130 130 50 50 82 83 84 84 84 85 134 40 - 197 200 200 214 151 150 150 106 106 253 48 53 53 53 53 52 - 58 249 249 64 249 249 65 162 250 250 164 164 165 165 166 166 - 162 162 131 132 133 133 134 255 255 162 82 253 128 129 255 160 - 88 86 84 84 133 83 82 80 254 49 254 48 48 148 146 144 - 83 164 164 164 133 133 165 134 166 166 166 135 135 166 166 166 - 131 163 82 82 82 132 132 133 133 133 133 133 134 134 135 85 - 80 81 131 132 129 130 131 163 49 54 54 80 96 84 133 166 - 162 250 250 250 164 164 165 165 165 165 135 135 135 135 167 167 - 131 163 132 132 164 164 164 133 133 133 165 134 135 135 135 135 - 133 133 164 164 134 135 86 167 255 255 129 128 8 8 8 7 - 7 33 34 35 35 37 5 5 5 38 4 39 40 135 135 88 - 131 131 163 163 132 164 164 164 133 133 165 135 135 167 167 88 - 254 254 49 150 50 50 50 151 82 83 83 133 84 85 86 135 - 131 131 163 132 164 164 164 165 133 134 165 135 135 135 135 135 - 7 33 34 34 34 34 35 35 37 132 133 84 84 166 135 167 - 254 49 49 80 131 131 82 82 83 83 84 84 84 85 135 20 - 199 200 200 200 151 151 150 106 106 253 48 53 53 53 53 53 - 59 249 249 249 249 250 250 163 250 250 165 165 165 166 166 166 - 163 162 132 132 133 134 166 255 255 163 83 253 128 254 162 160 - 90 87 88 85 84 84 83 82 49 80 49 48 48 254 48 253 - 84 165 165 165 165 135 166 166 166 135 135 135 167 167 167 168 - 132 132 132 133 133 133 133 133 134 134 135 135 135 135 86 86 - 131 132 132 133 254 131 81 164 104 54 81 81 96 166 135 166 - 163 250 67 164 165 165 165 166 166 166 167 167 167 88 167 167 - 132 132 164 164 133 133 165 165 165 165 166 135 135 135 167 167 - 134 134 165 165 135 135 167 167 162 255 129 128 8 8 8 7 - 33 34 35 37 5 38 38 38 4 4 39 41 41 89 136 168 - 132 163 164 164 164 164 165 165 165 166 135 167 167 136 168 168 - 254 149 150 150 50 151 151 152 83 83 84 85 85 86 88 87 - 132 132 164 164 133 133 165 165 165 166 135 167 167 136 136 136 - 33 33 34 34 34 35 35 37 37 134 134 85 135 167 167 167 - 49 80 50 50 50 82 83 83 83 84 84 85 85 86 89 99 - 198 200 200 200 151 151 151 253 253 253 48 52 53 53 58 58 - 59 58 249 249 250 250 250 250 67 68 165 166 166 166 167 167 - 164 163 132 132 134 135 166 255 162 163 84 128 129 130 163 160 - 169 169 90 86 85 84 84 83 82 50 49 49 254 148 147 254 - 84 165 166 166 166 167 167 167 167 167 167 168 136 168 168 169 - 132 132 133 133 84 134 85 85 135 86 86 86 88 90 90 169 - 82 133 133 134 130 82 133 165 104 54 96 96 165 167 136 167 - 164 67 68 165 165 166 166 166 167 167 167 167 136 136 136 168 - 132 133 133 165 165 165 166 166 166 166 135 167 167 136 168 168 - 134 166 166 166 167 136 168 168 163 162 130 129 128 8 7 33 - 34 35 37 5 38 38 4 4 4 39 41 41 136 90 137 169 - 164 164 164 164 165 165 165 165 166 135 167 167 168 168 169 169 - 130 150 50 151 151 152 83 84 84 84 85 86 88 88 87 169 - 133 164 164 165 165 165 166 166 166 167 167 167 136 168 169 137 - 34 34 34 35 35 35 37 38 38 134 135 86 88 87 168 168 - 80 50 50 82 82 83 83 84 84 85 18 86 88 90 90 23 - 200 201 201 201 152 152 84 253 253 146 48 53 53 58 59 59 - 58 249 249 250 250 250 250 68 69 69 166 166 167 167 167 168 - 164 163 132 133 135 136 167 255 163 164 85 128 254 131 163 160 - 169 169 90 88 85 84 84 83 83 50 150 150 149 147 147 254 - 85 166 135 135 166 167 167 167 168 168 168 168 168 168 168 169 - 132 132 133 134 134 135 135 135 134 135 135 88 88 136 136 90 - 82 83 133 134 254 82 83 165 54 55 96 96 165 167 136 168 - 164 68 69 69 166 166 167 167 168 168 168 168 136 136 137 169 - 133 133 134 134 135 166 166 167 135 167 167 136 136 168 169 169 - 135 135 166 167 136 136 169 169 163 162 130 129 128 8 7 33 - 34 35 37 38 38 4 4 4 4 39 41 42 91 91 137 169 - 133 133 165 165 165 166 166 166 135 167 136 136 136 136 137 137 - 131 50 151 83 152 84 84 84 84 85 85 86 88 87 90 169 - 133 133 165 165 166 166 166 167 167 167 136 136 136 137 137 137 - 35 34 35 35 35 35 5 38 38 135 135 135 88 90 169 169 - 50 50 50 82 83 84 84 84 85 18 19 87 87 91 137 24 - 201 201 201 201 152 16 85 146 253 48 48 54 54 59 58 58 - 58 59 250 250 250 250 68 69 69 70 70 237 168 168 168 168 - 164 163 133 133 135 137 168 130 163 164 166 128 130 81 164 160 - 170 137 90 88 86 85 84 152 152 151 150 150 149 148 148 147 - 86 167 167 135 167 167 168 169 136 136 136 136 169 170 169 169 - 133 134 134 134 135 86 135 86 135 88 136 90 137 137 137 169 - 133 85 134 85 50 83 84 166 55 55 96 96 98 167 136 169 - 165 69 69 70 70 237 167 168 168 168 168 136 136 137 137 169 - 134 84 134 135 135 135 135 135 167 136 136 136 136 136 169 169 - 135 135 167 167 136 136 137 169 164 163 130 129 128 7 33 34 - 35 37 5 38 4 4 4 4 244 3 3 42 137 137 137 170 - 133 133 165 165 165 166 167 167 135 136 136 136 136 137 137 170 - 131 50 152 83 84 84 84 84 84 86 86 86 88 90 169 169 - 134 134 135 166 166 166 167 167 167 136 168 169 137 137 137 137 - 35 34 35 5 5 5 5 38 38 39 40 88 136 137 170 170 - 50 50 82 152 84 84 84 84 85 18 19 87 87 91 137 24 - 201 201 202 202 201 153 85 146 147 48 48 54 54 59 58 59 - 59 250 60 250 250 165 69 165 69 70 237 168 168 168 169 169 - 165 164 133 134 136 137 168 130 164 165 86 128 130 132 164 160 - 138 137 137 136 89 86 85 153 153 152 151 151 150 149 148 128 - 88 88 89 136 136 90 169 169 137 137 137 137 137 170 170 170 - 134 40 40 40 40 40 88 89 136 136 137 137 137 137 170 170 - 84 85 86 87 50 83 97 61 55 60 97 166 61 168 90 169 - 166 236 70 237 237 237 168 168 169 169 169 169 137 137 170 170 - 135 135 135 86 88 88 136 168 136 136 136 137 137 137 170 170 - 88 168 168 168 137 137 137 170 134 133 131 130 7 33 34 35 - 35 5 38 4 4 4 244 244 244 3 43 43 27 138 246 170 - 134 135 135 135 135 167 167 136 136 136 137 137 137 137 138 246 - 132 83 83 84 84 84 85 85 86 86 87 90 91 137 170 170 - 134 135 135 167 167 167 167 136 168 136 137 137 170 170 138 138 - 35 35 5 5 5 5 38 4 39 41 42 137 137 170 170 246 - 152 83 84 84 84 85 86 87 19 20 21 23 23 24 26 246 - 202 202 201 201 16 17 18 147 147 149 49 54 54 59 59 59 - 59 60 60 250 166 236 165 70 70 237 237 168 169 169 169 170 - 166 164 135 135 137 137 170 81 164 166 88 129 131 132 165 160 - 139 138 138 137 91 41 40 40 38 153 37 36 36 150 7 129 - 90 90 90 169 169 169 169 170 170 170 170 170 170 246 246 171 - 40 40 40 40 41 41 41 91 91 137 137 246 138 246 246 246 - 84 86 86 90 82 97 97 61 60 60 61 61 61 169 169 170 - 166 70 237 237 237 238 238 169 239 170 170 170 170 170 171 171 - 135 86 86 88 88 89 136 137 137 137 137 170 170 170 246 171 - 136 169 169 169 170 246 246 171 134 133 131 130 33 6 35 35 - 5 38 4 4 244 244 244 244 244 43 44 44 29 139 171 171 - 135 135 135 167 167 168 136 136 169 137 137 138 138 246 171 171 - 132 133 84 84 85 85 86 86 88 89 91 91 137 170 246 170 - 135 167 167 136 168 168 168 169 169 170 170 246 246 171 171 139 - 35 183 5 5 5 4 4 244 39 41 42 92 25 26 246 171 - 152 152 153 85 85 40 88 99 21 21 23 62 246 246 246 245 - 202 202 203 203 202 17 20 148 148 149 49 54 54 59 59 60 - 55 60 60 250 166 166 166 237 237 237 238 238 169 170 170 170 - 167 165 135 135 137 137 170 81 165 166 88 129 131 132 165 160 - 139 139 138 27 92 42 41 39 39 38 38 37 36 34 33 7 - 90 91 137 137 137 137 170 246 246 246 138 246 246 171 139 139 - 41 41 41 41 41 155 42 92 25 27 138 246 138 246 246 171 - 85 87 88 21 83 98 61 61 60 61 61 61 168 62 246 171 - 167 237 237 168 238 238 238 239 239 239 171 171 171 171 139 139 - 86 88 89 90 90 90 137 137 137 137 137 138 138 246 139 172 - 91 137 169 169 246 246 246 171 135 134 132 131 6 36 37 5 - 38 38 4 4 244 244 187 43 2 2 2 31 45 139 172 172 - 88 88 136 136 136 169 137 137 137 137 138 138 138 139 139 172 - 133 84 85 85 86 86 89 99 90 91 91 24 246 246 246 171 - 88 88 168 168 168 169 169 169 170 170 246 171 139 139 172 103 - 184 184 184 185 4 4 244 244 244 3 43 93 138 138 245 63 - 152 153 40 40 88 41 99 99 23 23 24 246 246 246 139 63 - 154 202 203 203 203 20 21 148 148 149 49 54 55 55 55 60 - 60 60 60 96 166 237 167 237 237 238 238 238 239 171 171 171 - 167 166 136 136 138 138 171 132 85 86 90 130 131 133 166 160 - 140 139 94 138 93 42 3 41 39 4 38 5 37 35 34 33 - 137 24 24 246 246 246 246 246 246 171 139 139 139 139 172 172 - 3 3 3 3 42 43 93 28 27 28 29 94 139 139 139 172 - 88 21 22 62 16 61 21 62 97 61 61 87 21 62 246 171 - 168 168 168 238 238 239 239 239 171 171 171 172 172 172 172 172 - 90 90 91 100 137 137 137 246 138 138 138 139 139 139 139 172 - 92 170 137 170 171 139 139 172 88 135 133 132 36 5 5 5 - 4 4 4 244 187 2 2 188 188 188 31 95 103 140 140 172 - 136 136 137 137 137 170 170 137 138 138 138 139 139 172 140 140 - 134 40 40 88 88 41 22 91 91 92 24 27 246 246 139 172 - 136 136 136 169 169 169 170 170 170 171 171 139 172 172 172 140 - 185 185 185 185 244 244 244 244 3 43 2 29 94 139 172 172 - 153 40 40 41 41 41 91 23 24 26 246 245 245 245 172 63 - 204 203 203 203 204 21 155 148 149 150 50 55 55 60 55 60 - 60 60 60 166 237 237 237 72 238 238 238 239 239 171 171 171 - 168 166 136 136 29 139 172 133 98 88 91 131 37 134 167 160 - 173 140 103 94 44 43 43 3 41 4 4 38 5 37 35 34 - 26 246 246 246 245 245 245 63 139 172 140 140 140 140 140 47 - 43 3 3 43 43 43 28 94 29 94 94 139 103 103 140 140 - 41 23 23 246 17 20 62 62 61 61 61 169 62 246 63 172 - 169 169 169 239 239 239 75 76 76 77 77 172 172 173 140 140 - 91 23 24 26 246 246 246 246 171 139 139 172 140 140 140 173 - 26 246 246 246 172 140 140 173 136 135 133 37 37 5 5 5 - 4 4 244 2 188 188 188 125 125 125 126 126 47 47 141 173 - 91 137 137 137 170 170 170 246 171 139 139 172 140 140 140 141 - 40 40 41 41 41 155 42 24 25 26 28 30 139 103 140 140 - 137 169 169 170 170 170 171 171 171 139 172 172 140 140 173 47 - 185 185 185 186 244 244 43 2 2 188 188 94 45 103 140 173 - 40 40 154 41 41 42 92 24 101 245 245 63 63 140 140 159 - 204 204 204 204 204 21 100 150 149 151 151 51 55 60 60 60 - 61 61 61 61 168 238 238 238 238 74 75 75 76 172 172 77 - 169 167 137 137 45 140 78 85 88 87 24 36 37 86 167 128 - 141 141 140 103 94 2 43 3 3 39 4 38 5 5 35 35 - 28 245 245 245 245 63 63 172 172 140 140 1 140 47 47 141 - 43 43 43 93 44 44 2 45 94 45 103 103 140 140 47 173 - 155 24 26 245 18 21 62 239 61 61 168 169 62 245 172 173 - 170 170 239 239 239 75 76 76 77 77 173 173 173 173 173 141 - 24 26 26 246 246 246 246 245 139 139 139 140 140 140 140 141 - 101 245 245 245 140 1 1 141 136 88 134 37 37 5 5 4 - 4 244 187 188 188 188 125 125 126 126 126 127 127 159 141 79 - 92 24 246 246 246 246 171 171 139 172 140 140 140 141 141 141 - 39 41 41 155 42 42 156 101 101 101 157 45 103 46 1 141 - 137 169 170 170 171 171 171 172 172 172 140 173 141 141 141 190 - 185 185 186 186 187 187 2 2 188 188 189 189 95 46 141 79 - 40 154 41 41 155 42 43 101 245 63 63 1 173 159 141 159 - 205 205 205 204 204 23 156 6 150 151 152 55 60 60 60 61 - 61 61 61 168 168 238 238 238 74 75 75 76 77 173 173 78 - 239 168 137 93 45 140 78 85 90 90 246 37 38 88 168 128 - 174 174 47 46 102 31 2 43 3 3 4 4 38 5 35 35 - 157 245 63 63 63 63 140 173 173 159 159 47 159 141 141 142 - 2 2 2 2 94 94 45 95 95 158 158 46 47 141 141 141 - 92 101 101 245 20 62 62 239 61 61 169 170 246 63 140 173 - 170 239 239 239 76 76 77 77 77 77 78 78 173 79 79 174 - 101 101 101 245 245 245 63 172 172 103 158 1 47 47 141 174 - 245 63 63 172 173 159 159 174 137 136 135 38 5 5 4 4 - 244 244 187 188 125 125 125 126 126 126 127 127 127 142 142 174 - 26 246 246 246 246 139 139 139 172 140 140 140 141 141 141 142 - 41 155 42 156 156 156 101 157 157 157 102 102 158 47 159 174 - 137 170 170 171 171 171 172 172 173 173 173 141 141 174 174 191 - 186 186 186 187 187 2 2 188 188 189 189 189 46 47 141 142 - 41 41 155 42 43 43 101 157 102 63 1 1 173 159 141 142 - 206 205 204 205 205 206 101 6 36 152 152 16 16 61 61 61 - 61 61 61 238 238 238 239 239 75 75 76 77 77 78 79 78 - 239 168 138 138 46 1 78 85 169 23 245 38 40 90 169 128 - 175 142 174 159 1 102 157 157 43 43 3 39 4 38 5 37 - 63 63 1 173 173 173 79 79 174 174 174 174 174 142 175 143 - 31 31 157 102 102 102 158 1 1 1 47 159 141 174 174 174 - 101 245 245 63 21 62 62 239 61 62 62 246 245 63 173 79 - 171 75 76 76 76 77 77 78 78 78 79 79 174 142 142 175 - 245 245 245 63 63 63 63 173 173 173 141 174 174 174 142 142 - 63 173 173 173 79 174 142 175 24 91 88 40 38 5 4 244 - 187 187 188 188 189 126 126 127 127 127 127 191 142 175 175 175 - 246 245 245 245 245 172 140 173 173 173 141 174 174 142 175 143 - 155 42 156 156 156 101 157 157 102 102 158 1 159 159 142 142 - 246 171 171 76 77 77 77 78 78 79 79 174 142 142 175 143 - 186 186 187 187 187 188 94 95 189 189 127 47 159 174 142 175 - 155 155 156 101 101 101 157 63 1 173 173 173 159 174 142 175 - 206 206 206 206 206 205 206 152 152 152 152 16 61 61 61 61 - 61 61 72 73 74 74 75 75 75 76 77 77 78 79 174 79 - 239 169 171 94 141 174 79 86 62 62 63 40 154 23 170 129 - 7 148 148 147 146 146 145 9 10 10 10 10 10 11 11 12 - 145 146 147 147 147 147 148 148 148 148 148 148 148 149 149 149 - 9 9 9 145 146 146 146 147 147 147 147 148 148 148 148 148 - 144 145 145 146 144 144 145 146 144 144 145 146 147 148 148 148 - 146 146 146 146 48 48 48 48 148 148 147 148 148 149 199 199 - 145 145 146 146 146 146 146 147 147 147 148 148 148 148 148 149 - 146 147 147 147 148 148 148 149 144 144 106 11 11 11 11 11 - 10 10 9 9 8 8 32 32 7 7 7 7 7 7 7 149 - 145 145 145 145 146 146 147 147 147 148 148 148 148 149 149 149 - 10 144 144 144 144 145 145 145 146 146 146 147 147 148 148 148 - 146 146 146 146 146 147 147 147 148 148 148 148 148 149 149 7 - 9 10 10 10 9 9 8 8 9 8 8 8 8 148 149 199 - 144 144 144 144 145 145 145 146 146 146 147 148 148 148 148 199 - 196 195 194 194 144 145 145 11 107 11 192 144 106 247 52 52 - 247 247 52 52 53 48 48 48 253 48 48 48 254 149 149 254 - 128 128 128 8 8 7 149 144 144 145 146 252 10 144 253 48 - 150 149 148 148 147 147 146 146 145 144 10 10 10 10 11 11 - 147 147 148 148 148 148 148 148 199 149 149 149 149 149 149 150 - 146 146 146 146 147 147 147 147 148 148 148 148 148 149 149 199 - 145 146 146 146 144 145 146 147 144 145 146 147 147 147 148 150 - 146 48 48 48 48 48 254 149 149 149 149 149 149 150 199 199 - 146 146 146 147 147 147 147 147 148 148 148 149 149 149 150 150 - 147 148 148 148 148 149 150 150 145 145 144 10 11 10 10 10 - 10 9 9 8 8 8 8 8 7 7 7 7 33 150 150 150 - 146 146 146 146 147 147 148 148 148 148 149 199 199 199 150 150 - 144 145 145 145 145 146 146 146 146 147 147 148 148 149 149 149 - 146 48 48 48 48 48 148 148 149 149 149 149 150 150 150 150 - 10 10 10 9 8 8 8 9 8 7 7 148 148 149 150 150 - 144 144 145 145 145 146 146 146 147 147 148 149 149 149 150 200 - 212 212 194 194 145 146 145 252 11 192 192 144 106 247 52 52 - 52 52 52 53 53 53 48 48 48 48 254 254 49 149 150 149 - 128 128 128 128 8 7 149 144 145 146 147 252 10 144 253 48 - 151 150 150 149 148 148 147 146 146 145 144 144 10 10 10 10 - 148 148 148 148 149 149 199 199 150 150 150 150 150 150 150 150 - 147 147 147 147 148 148 148 148 148 149 149 150 150 150 150 150 - 146 147 147 148 145 146 146 147 146 146 48 147 147 148 149 151 - 147 48 48 254 254 49 49 49 150 150 150 150 150 150 151 151 - 147 147 147 147 148 148 148 148 149 149 149 149 150 150 150 150 - 148 148 149 149 149 150 150 151 146 145 144 10 10 10 10 10 - 9 9 8 8 7 7 7 7 33 33 33 6 6 151 151 151 - 147 147 147 147 148 148 148 148 149 149 199 150 150 150 151 151 - 145 145 145 146 146 146 147 147 148 148 148 149 149 149 150 150 - 147 48 48 48 48 149 149 149 149 149 150 150 150 151 151 151 - 9 9 8 8 9 9 8 7 7 7 7 7 149 150 151 151 - 145 145 145 146 146 147 147 147 148 148 149 199 150 150 150 201 - 212 212 195 195 194 195 146 11 192 192 192 144 144 247 52 52 - 52 53 53 53 53 53 48 48 49 49 49 49 150 150 150 150 - 128 128 128 32 7 33 150 144 146 48 148 144 144 145 253 48 - 152 151 150 150 149 148 148 147 146 146 145 144 10 10 10 10 - 149 149 149 149 150 150 150 150 150 150 151 151 151 151 151 151 - 147 147 147 148 148 148 149 149 199 150 150 151 151 151 151 151 - 147 148 148 148 146 147 147 148 48 48 48 48 149 150 150 151 - 148 254 49 49 49 49 49 150 50 151 151 151 151 151 151 152 - 148 148 148 148 149 149 149 149 149 149 149 150 150 151 151 151 - 149 149 150 150 150 150 151 152 147 146 144 10 10 10 10 9 - 8 8 8 7 7 32 33 33 6 6 6 6 36 36 151 151 - 147 148 148 148 148 149 149 149 149 150 150 150 151 151 152 152 - 145 146 146 146 147 147 147 148 148 148 149 149 150 150 151 151 - 147 254 49 254 49 49 150 150 150 150 150 151 151 151 152 152 - 8 8 9 8 8 7 7 7 7 7 33 6 150 151 152 152 - 145 146 146 146 147 147 148 148 149 199 150 150 150 151 151 201 - 212 212 196 196 195 196 147 144 192 192 192 144 144 52 52 57 - 53 53 53 53 53 53 49 49 49 49 49 150 50 151 151 151 - 129 129 129 33 33 6 150 144 48 148 149 144 144 145 48 48 - 152 152 151 150 150 149 148 148 147 146 146 145 144 10 10 10 - 149 150 150 150 150 150 151 151 151 151 151 152 152 151 152 152 - 148 148 148 148 149 149 149 199 150 150 151 151 151 151 152 152 - 147 148 148 149 146 147 48 49 146 48 48 49 149 150 151 151 - 149 49 49 49 80 50 50 50 50 151 151 152 152 152 152 152 - 148 148 149 149 149 149 149 150 150 150 151 151 151 151 152 152 - 150 150 150 151 151 151 152 152 148 146 145 144 10 9 9 9 - 9 8 8 7 33 33 33 33 6 6 6 36 36 152 152 153 - 148 148 149 149 149 149 150 150 150 150 151 151 151 152 152 152 - 146 146 147 147 147 148 148 148 149 149 149 150 150 151 151 152 - 148 254 49 49 49 150 50 151 151 151 151 152 152 152 152 5 - 8 9 8 8 7 7 7 8 33 6 6 6 36 151 152 152 - 145 146 146 147 148 148 148 149 150 150 150 151 151 152 152 201 - 195 213 214 196 195 196 148 144 192 192 192 144 145 52 53 58 - 53 53 53 53 53 54 54 54 80 80 80 50 50 151 152 132 - 129 129 129 33 6 36 151 145 48 148 149 144 145 146 48 48 - 153 152 152 151 150 150 149 148 147 147 146 145 145 144 10 10 - 150 150 151 150 150 150 151 152 152 152 152 152 152 152 152 152 - 148 149 149 149 149 150 150 150 150 151 151 151 152 152 152 152 - 148 149 149 149 146 148 49 49 146 48 49 49 49 150 151 152 - 49 49 49 80 50 50 82 82 82 152 152 152 152 152 152 152 - 148 149 149 149 149 149 150 150 150 151 152 152 152 152 152 153 - 150 150 151 151 151 151 152 153 148 147 146 144 9 9 9 8 - 8 8 7 7 33 33 6 6 6 36 37 5 5 5 153 153 - 148 149 149 149 150 150 150 150 151 151 151 152 152 152 153 153 - 146 147 147 148 148 148 148 149 199 150 150 151 151 152 152 152 - 149 49 49 49 80 50 50 151 151 152 152 152 152 153 153 153 - 9 8 7 7 8 8 7 33 6 6 6 36 36 36 152 153 - 146 146 147 148 148 149 149 150 150 150 151 151 152 152 153 201 - 196 213 214 214 196 197 148 144 144 192 144 145 48 53 53 53 - 53 53 53 54 54 54 49 49 50 50 50 50 151 152 152 133 - 129 129 129 34 6 5 152 146 48 149 150 144 145 147 48 48 - 153 153 152 152 151 150 199 149 148 148 147 146 146 145 144 144 - 151 151 151 151 151 151 152 152 152 152 152 153 153 153 153 153 - 7 149 149 150 150 151 151 151 152 152 152 152 152 153 153 153 - 148 150 150 150 147 149 49 50 48 49 49 50 150 151 152 85 - 49 49 80 50 82 82 82 83 84 152 153 153 153 153 153 153 - 149 149 150 150 150 150 151 151 151 152 152 152 152 153 153 153 - 150 151 151 152 152 152 153 153 149 148 146 145 9 9 8 8 - 7 7 7 33 34 6 35 5 5 5 5 38 38 153 153 153 - 149 150 150 150 150 151 151 151 152 152 152 153 153 153 153 40 - 147 147 148 148 149 149 149 199 150 151 151 152 152 152 153 153 - 149 49 50 50 50 151 82 152 152 152 152 153 153 153 153 40 - 7 7 7 7 7 33 34 6 6 6 6 37 37 37 153 40 - 147 148 148 148 149 199 150 150 150 151 151 152 152 153 153 202 - 214 213 214 214 197 198 199 144 144 144 194 145 48 53 53 52 - 53 53 53 54 54 54 54 54 51 51 51 82 83 84 153 134 - 130 130 130 34 35 5 153 48 48 150 151 144 145 148 254 48 - 154 40 153 152 152 151 150 199 149 148 148 147 146 145 145 144 - 151 151 151 152 152 153 153 153 153 5 153 153 40 40 40 40 - 6 6 6 6 151 151 152 152 153 153 153 153 153 153 153 154 - 149 150 151 150 147 149 50 51 49 49 49 49 50 83 84 85 - 80 50 50 82 83 83 83 83 84 84 153 153 40 40 40 40 - 150 150 150 151 151 151 151 151 152 153 153 153 153 40 40 153 - 151 152 152 152 37 153 153 40 149 148 147 145 9 9 8 8 - 8 7 33 35 5 5 5 5 5 5 5 38 38 40 40 154 - 150 50 151 151 151 151 152 152 153 153 153 153 153 40 40 154 - 148 148 149 199 150 150 150 150 151 151 152 152 153 153 153 40 - 150 50 50 50 82 83 152 152 152 153 153 153 153 40 40 39 - 7 7 32 33 33 33 6 6 5 5 5 5 5 5 153 154 - 148 148 149 149 199 150 150 150 151 152 152 153 153 40 40 202 - 197 213 214 198 198 200 199 144 144 145 194 145 53 53 53 53 - 53 53 54 54 54 54 55 55 55 51 83 83 84 84 153 134 - 131 131 130 35 35 5 153 48 49 151 152 145 146 148 254 254 - 154 154 153 5 37 36 36 150 149 148 148 147 8 8 9 9 - 152 152 152 152 153 153 153 153 154 40 40 40 39 39 39 39 - 6 6 36 36 6 36 37 153 153 153 153 153 40 40 154 154 - 150 150 151 152 148 49 50 51 49 49 50 50 51 83 84 85 - 82 82 82 82 83 84 84 85 85 85 85 40 40 40 40 40 - 150 151 151 151 152 152 152 153 153 153 153 153 40 40 40 40 - 152 152 153 153 153 38 40 40 150 149 148 146 9 8 8 7 - 7 33 34 6 35 5 5 5 5 4 4 39 39 39 40 154 - 151 50 82 82 152 152 152 152 153 153 153 40 154 154 154 41 - 148 149 149 149 150 150 150 151 151 152 152 153 153 153 40 154 - 150 50 82 82 83 83 84 153 153 153 40 40 40 154 154 154 - 33 33 33 33 33 6 35 5 5 5 5 38 4 39 39 154 - 148 149 199 150 150 150 151 152 152 152 153 153 153 40 154 203 - 196 214 214 198 200 200 200 145 144 145 194 146 48 53 53 58 - 53 54 54 54 54 55 55 55 55 83 83 84 85 85 40 135 - 131 131 131 37 5 4 40 148 49 150 152 145 147 149 80 48 - 155 41 39 4 5 5 37 36 6 33 7 7 7 8 8 8 - 153 153 153 153 153 40 40 40 40 39 39 154 41 41 155 41 - 37 5 5 5 5 5 153 40 40 40 40 154 154 154 154 154 - 151 151 152 153 149 150 51 97 49 50 51 51 83 85 86 87 - 82 83 83 83 84 84 84 85 86 86 88 88 41 41 41 41 - 151 152 152 152 153 153 153 153 153 40 40 39 154 41 41 41 - 153 84 85 40 40 40 154 41 151 150 148 146 8 8 7 7 - 33 6 6 35 5 4 5 4 4 4 39 41 39 41 41 155 - 151 83 83 83 84 153 153 153 40 40 40 154 41 41 155 155 - 149 150 150 150 151 151 151 152 152 153 153 40 39 154 41 41 - 151 82 83 84 84 84 85 85 85 40 154 41 41 41 155 155 - 33 33 34 34 35 35 5 5 5 5 4 4 39 154 41 41 - 149 150 150 151 151 152 152 153 153 153 40 40 154 154 41 155 - 197 198 200 201 200 200 200 144 145 145 195 214 49 54 54 54 - 54 54 54 55 60 55 55 96 96 97 97 98 86 86 41 88 - 133 132 132 38 5 3 41 149 50 152 153 146 148 150 50 254 - 43 3 3 39 4 4 5 5 36 6 6 33 7 7 8 8 - 40 40 40 154 154 41 41 155 41 41 41 155 155 42 42 3 - 5 38 4 4 38 38 39 39 154 154 41 41 155 155 155 155 - 152 152 153 153 151 82 16 17 50 51 83 16 16 18 99 90 - 84 85 85 85 86 86 86 87 90 90 22 91 91 91 91 23 - 152 153 153 153 40 40 40 154 154 154 41 41 155 155 3 42 - 85 86 88 41 41 41 91 91 152 151 149 148 7 7 7 32 - 6 37 5 5 4 4 4 4 4 244 3 3 3 3 43 25 - 152 84 84 84 85 86 86 40 41 41 41 155 155 155 156 156 - 150 151 151 152 152 152 153 153 153 153 39 154 41 155 155 42 - 153 84 84 85 85 86 86 88 89 41 22 42 42 42 156 43 - 34 34 35 35 35 5 5 5 4 4 39 3 3 3 3 156 - 150 151 151 152 152 153 153 153 40 154 154 41 155 155 156 156 - 201 201 202 202 201 201 201 146 147 146 196 214 49 54 54 54 - 54 55 60 55 55 55 97 61 61 98 98 87 90 90 91 137 - 134 133 133 38 4 3 22 150 152 84 18 147 199 150 82 254 - 44 43 3 3 41 39 4 38 5 36 6 6 33 7 7 8 - 40 88 41 41 41 155 155 42 156 42 43 43 43 43 43 43 - 38 4 4 39 4 39 39 41 41 155 3 3 43 43 43 93 - 153 153 40 18 151 83 17 61 51 83 16 17 18 20 22 91 - 85 88 88 88 87 90 90 90 91 23 100 24 24 26 26 26 - 153 154 154 154 154 41 41 155 41 155 155 42 43 43 43 26 - 20 99 22 91 42 92 92 26 153 152 150 7 7 33 33 34 - 35 5 5 5 4 244 4 244 244 244 3 43 43 43 44 101 - 153 85 85 86 86 99 99 99 91 155 42 24 43 43 44 157 - 151 152 152 152 153 153 153 40 39 39 154 41 3 3 43 156 - 153 85 86 86 88 89 90 90 91 91 92 25 26 93 101 2 - 35 35 35 5 5 5 5 4 4 4 3 3 3 43 43 44 - 36 152 152 5 153 153 40 40 154 41 155 155 42 43 93 101 - 202 202 202 201 201 201 153 147 147 147 196 214 49 54 54 54 - 55 60 55 55 60 61 61 61 167 167 168 168 91 91 24 26 - 135 133 134 38 3 43 24 150 83 17 19 148 199 151 83 48 - 157 2 43 3 3 3 39 4 4 5 37 6 6 33 7 7 - 41 22 91 91 91 42 92 24 43 43 43 93 44 2 2 44 - 4 4 4 3 3 3 3 3 3 3 43 43 43 44 44 157 - 153 40 154 99 152 84 98 61 51 83 16 17 20 23 26 246 - 88 167 88 88 90 169 90 91 24 24 26 26 101 101 157 245 - 40 41 41 154 41 155 155 42 42 156 43 43 44 44 30 157 - 21 22 91 92 25 93 27 101 153 152 151 150 33 33 6 35 - 5 5 4 4 244 244 244 244 244 187 2 2 2 2 31 103 - 40 86 86 88 99 22 91 91 24 24 25 101 44 44 157 102 - 152 153 153 153 153 40 40 154 41 41 3 3 43 43 2 30 - 40 86 88 89 90 90 91 91 92 24 26 28 101 30 157 94 - 35 183 184 184 184 184 4 4 244 244 3 43 43 44 2 157 - 5 5 153 153 40 154 154 154 41 155 3 43 43 44 30 157 - 203 203 203 203 203 203 154 7 148 148 199 214 54 55 55 60 - 55 55 55 60 61 61 97 166 167 167 168 169 169 26 26 246 - 88 134 135 39 3 2 246 151 84 19 99 149 6 152 85 48 - 158 102 2 44 43 3 3 39 4 4 5 5 35 6 33 33 - 92 23 24 26 26 26 101 101 101 101 30 157 45 45 45 45 - 4 4 244 3 3 3 43 43 43 44 2 2 2 31 31 45 - 40 41 22 22 153 85 19 61 83 16 19 20 22 26 246 245 - 90 168 168 87 169 170 170 170 246 246 246 245 245 63 63 63 - 41 155 155 155 100 24 24 25 156 93 101 101 157 157 45 103 - 23 23 24 26 28 94 94 139 40 153 152 36 6 6 35 5 - 5 4 4 244 187 187 187 187 187 188 188 188 94 95 95 158 - 154 99 99 22 91 100 24 24 246 27 28 157 45 45 102 158 - 153 40 40 40 154 154 154 155 3 3 43 43 44 2 31 45 - 41 89 90 91 91 24 26 246 26 246 28 157 45 102 102 95 - 184 184 185 185 185 185 186 244 244 244 43 2 2 31 45 102 - 5 153 40 39 154 41 155 155 3 43 44 44 30 45 102 102 - 202 202 203 202 202 202 154 7 7 149 199 200 55 60 96 55 - 55 60 61 61 61 61 61 238 168 169 169 170 170 171 245 172 - 168 135 136 244 2 95 63 152 84 87 22 150 152 153 86 48 - 159 1 102 157 2 43 3 3 244 4 4 5 5 35 34 6 - 26 246 246 245 245 245 245 63 158 103 103 158 158 46 158 158 - 244 244 244 3 3 43 44 44 31 31 45 45 45 102 158 158 - 41 42 24 100 85 19 62 62 17 19 21 62 62 245 63 63 - 169 169 169 169 239 171 171 171 63 63 172 172 172 140 140 173 - 42 24 24 100 26 101 101 101 101 30 157 45 102 158 158 1 - 246 246 246 245 139 103 140 140 41 40 153 37 37 37 5 4 - 4 4 244 187 188 188 188 125 125 125 189 126 126 46 47 159 - 42 23 24 24 26 246 246 246 245 94 139 158 158 46 1 159 - 39 154 154 41 155 155 155 43 43 43 44 2 31 45 95 46 - 91 23 24 26 246 246 246 245 245 245 139 158 1 1 1 47 - 185 185 186 186 186 186 187 187 187 2 2 94 45 95 46 1 - 4 39 154 41 155 155 3 43 44 30 31 45 102 158 1 159 - 156 204 204 204 203 204 156 6 33 150 200 151 55 60 96 55 - 61 61 61 60 61 73 74 238 239 239 239 171 172 172 173 173 - 169 135 137 244 188 95 140 153 85 22 24 36 5 40 90 128 - 79 173 173 139 139 138 25 92 41 41 39 39 38 37 36 36 - 170 239 239 171 171 76 76 77 77 172 172 173 173 78 78 173 - 137 137 93 27 138 138 138 94 94 139 139 172 140 140 173 173 - 90 169 170 170 98 168 238 74 97 61 61 62 62 171 77 77 - 169 238 239 239 75 76 76 76 77 77 77 77 77 77 78 78 - 169 170 170 62 170 171 246 171 171 63 63 172 173 173 78 78 - 171 239 171 171 172 173 77 77 90 88 84 84 37 38 38 39 - 39 3 3 93 94 94 94 47 189 189 46 140 140 141 141 79 - 169 62 170 170 170 171 171 171 171 171 172 173 173 173 173 79 - 41 22 22 41 91 91 91 25 27 138 94 139 139 140 140 173 - 169 169 170 239 239 239 75 76 76 76 77 77 173 78 78 79 - 244 244 244 244 244 244 93 138 138 94 139 139 140 140 173 79 - 40 41 155 23 23 100 26 246 245 63 63 63 172 173 78 78 - 23 204 205 205 205 23 100 150 149 151 152 16 60 60 61 61 - 61 61 61 237 72 72 72 73 73 74 74 75 76 76 77 77 - 169 167 170 137 95 140 78 85 167 169 170 152 40 88 168 160 - 85 84 133 132 131 131 130 129 129 129 129 128 253 106 253 105 - 162 163 163 163 163 163 164 164 164 164 164 164 165 165 165 165 - 130 130 130 130 130 131 131 131 132 132 132 132 133 133 133 133 - 255 161 162 162 160 104 161 249 53 104 54 104 162 164 164 164 - 161 162 162 162 162 163 163 163 164 164 164 164 164 165 165 165 - 161 162 162 162 162 162 163 163 163 163 164 164 164 164 165 166 - 163 163 163 163 164 164 165 165 104 160 105 105 106 144 253 128 - 128 129 129 130 131 131 131 132 132 132 132 133 134 134 134 165 - 255 161 162 162 162 163 163 163 163 164 164 164 84 84 85 85 - 128 129 254 254 254 129 130 130 131 131 131 131 132 132 133 133 - 255 161 162 162 162 162 163 163 163 164 164 164 165 165 165 165 - 129 129 129 129 129 129 130 130 131 131 132 132 132 133 133 134 - 128 48 254 254 254 49 49 50 50 51 97 83 84 83 165 98 - 147 214 214 54 49 80 49 106 105 105 52 52 52 52 53 53 - 53 53 58 53 64 64 65 64 65 65 250 163 164 164 165 165 - 162 255 131 132 133 133 164 160 160 161 162 105 253 128 161 160 - 166 166 165 164 163 163 131 130 255 255 255 104 48 105 105 105 - 250 250 250 250 250 250 250 164 165 165 165 165 165 166 166 165 - 162 131 131 131 131 132 132 132 132 132 133 133 133 134 134 165 - 161 162 162 163 160 104 249 250 104 104 249 249 250 250 164 69 - 162 162 163 250 250 250 250 164 164 165 165 165 165 165 165 69 - 161 64 65 65 162 163 250 250 250 250 164 164 165 165 165 166 - 163 250 250 164 164 165 165 165 161 160 160 105 105 253 48 128 - 129 254 130 131 82 132 132 133 133 133 133 134 165 166 166 166 - 161 64 249 249 249 250 250 250 250 164 164 165 165 165 166 166 - 255 254 255 255 130 130 131 131 131 131 132 164 133 133 134 165 - 162 64 65 65 65 66 250 250 67 68 165 165 165 166 166 166 - 255 129 255 255 255 255 130 131 131 132 132 133 133 133 134 135 - 128 254 49 49 49 80 50 51 51 55 96 96 165 165 166 61 - 49 214 214 54 49 54 80 105 105 105 52 53 57 57 57 57 - 53 58 249 249 64 65 65 65 65 66 66 67 67 165 165 165 - 162 255 131 132 133 165 165 160 160 64 162 105 160 160 162 160 - 167 166 165 164 164 164 132 131 255 255 255 255 104 48 105 105 - 163 250 250 250 164 165 165 165 166 165 166 166 166 166 166 166 - 163 131 163 163 163 164 164 164 165 165 84 165 166 166 166 166 - 162 162 250 250 104 249 250 250 249 104 249 250 250 250 164 70 - 163 250 250 250 250 164 68 165 165 165 166 166 166 166 166 166 - 162 162 250 250 250 250 250 164 165 165 165 165 166 166 166 166 - 164 164 164 165 165 165 166 166 162 161 104 160 48 48 254 254 - 254 130 131 81 83 133 133 133 134 134 135 166 166 167 167 167 - 162 249 250 250 250 250 250 250 165 165 165 166 166 166 167 167 - 255 254 255 130 130 131 163 132 132 132 133 165 165 166 166 166 - 162 163 250 250 250 250 250 68 68 165 165 166 166 166 167 167 - 255 129 130 130 130 131 131 163 132 133 133 165 134 134 135 167 - 254 254 49 80 50 51 51 55 55 96 97 96 166 165 166 61 - 49 214 55 55 55 55 96 105 105 105 53 53 57 57 57 58 - 58 58 249 66 64 66 65 66 66 66 235 68 68 69 166 166 - 163 162 131 132 134 166 166 160 64 65 163 105 104 255 162 160 - 168 167 166 165 165 133 132 131 131 130 255 255 104 48 48 105 - 164 164 165 165 165 165 166 166 166 166 166 166 166 166 167 167 - 163 163 163 164 164 164 165 165 165 165 166 166 166 166 166 166 - 162 250 250 250 161 249 250 68 64 249 250 250 250 165 166 70 - 163 250 250 250 164 164 165 165 69 166 166 70 70 70 70 166 - 163 250 250 250 250 165 165 165 166 165 166 166 166 166 167 167 - 165 165 69 69 166 166 166 70 162 161 104 104 48 48 254 254 - 254 80 131 82 133 133 133 134 135 135 135 167 167 167 168 168 - 163 250 250 250 250 250 68 165 165 166 166 166 167 167 167 168 - 254 254 80 81 81 81 82 82 164 133 165 165 166 166 167 167 - 163 250 250 250 250 164 68 165 165 166 166 166 166 167 167 168 - 255 130 131 131 131 131 132 164 133 133 165 165 135 166 167 167 - 254 49 80 50 51 51 55 96 96 97 61 97 166 166 167 61 - 150 214 201 55 60 51 82 106 48 53 52 53 53 57 58 58 - 58 58 249 249 66 235 66 235 235 235 68 69 69 70 70 237 - 164 162 132 133 135 167 166 104 64 250 164 105 255 255 162 160 - 169 167 166 166 165 133 133 132 132 131 130 130 254 48 48 48 - 166 166 166 166 166 166 166 166 166 167 167 237 168 168 168 168 - 164 164 164 165 165 165 165 166 166 166 167 167 167 167 167 167 - 163 250 250 68 162 250 250 68 104 250 250 250 250 166 70 70 - 250 250 164 165 69 69 166 166 70 70 237 237 237 237 237 237 - 164 164 164 165 165 165 165 165 166 166 166 166 167 237 237 237 - 166 69 69 70 166 237 237 237 163 162 161 104 48 254 254 254 - 130 131 132 83 84 84 134 135 135 86 88 167 167 168 168 238 - 163 164 164 164 164 165 165 165 166 166 237 237 237 237 168 238 - 49 80 81 82 82 82 83 133 165 165 165 166 166 167 167 168 - 164 164 164 165 165 69 69 166 166 70 237 237 168 168 168 168 - 130 130 131 132 132 132 132 133 165 165 166 166 167 167 167 168 - 254 80 50 51 51 51 96 96 97 61 61 61 61 167 168 168 - 201 200 201 55 55 51 83 105 48 48 53 53 58 58 58 59 - 59 58 249 66 235 66 234 234 234 69 69 236 70 70 237 237 - 164 163 133 134 135 167 167 161 249 250 165 160 255 162 163 160 - 169 169 167 167 135 135 133 133 132 131 131 80 254 254 48 48 - 166 166 166 166 166 167 237 167 167 167 168 168 168 238 238 238 - 164 165 165 165 165 165 166 167 166 167 167 167 167 167 168 168 - 164 165 165 69 250 250 250 68 249 250 250 250 165 165 166 237 - 164 165 165 69 236 70 70 237 237 237 237 237 237 71 72 238 - 165 165 165 165 166 166 166 166 166 167 167 167 168 168 238 238 - 166 70 70 70 237 237 238 72 164 162 161 255 254 254 130 130 - 131 132 133 84 85 85 135 86 88 89 90 168 168 168 169 238 - 164 164 165 165 165 166 166 70 70 237 237 237 237 238 238 238 - 80 50 82 82 82 83 84 165 165 166 166 166 167 167 168 238 - 164 164 165 165 166 166 70 70 237 237 237 168 238 238 238 238 - 131 131 132 132 133 133 133 134 135 166 167 167 167 168 168 169 - 49 50 51 83 83 96 97 97 61 61 61 61 168 168 238 238 - 202 201 202 16 16 16 97 48 48 48 53 58 58 58 58 59 - 58 249 67 67 234 66 234 234 69 236 70 70 70 237 237 71 - 164 164 134 135 135 168 237 162 249 250 166 104 130 81 164 160 - 170 169 168 168 167 135 134 134 133 132 82 81 130 254 254 48 - 166 166 166 166 167 168 168 168 168 168 238 238 238 238 238 169 - 165 165 166 166 166 166 167 167 167 167 168 168 168 168 169 169 - 96 165 166 166 250 250 250 236 250 250 60 165 70 237 237 238 - 165 165 236 70 70 237 237 237 237 237 237 238 238 238 238 238 - 165 166 166 166 166 166 167 167 167 167 168 168 238 238 238 238 - 166 237 70 237 237 238 238 73 164 163 162 80 254 254 130 131 - 132 133 84 85 86 88 88 89 90 90 169 169 169 169 170 238 - 165 165 165 166 166 166 237 237 237 237 237 238 238 238 238 74 - 82 82 82 83 83 84 84 85 166 167 167 167 167 168 169 238 - 165 165 165 166 70 237 237 237 237 237 168 238 238 238 239 239 - 132 132 132 133 133 134 135 135 166 167 167 168 168 169 169 239 - 50 51 83 83 16 16 17 61 61 61 168 61 238 168 238 239 - 201 201 201 202 16 16 97 48 48 48 54 54 59 59 59 58 - 59 59 68 68 68 235 234 69 236 70 70 71 71 71 72 73 - 166 165 166 135 136 169 238 162 250 165 166 255 130 82 165 160 - 170 169 168 168 168 86 135 85 84 133 83 82 80 130 254 48 - 167 61 167 167 168 168 238 238 238 238 238 238 238 238 238 239 - 166 166 167 167 167 167 167 168 168 168 169 169 169 169 169 239 - 165 166 61 237 96 165 166 70 250 60 60 96 166 72 238 238 - 166 166 70 237 237 237 237 71 238 238 238 238 238 238 238 238 - 166 166 167 167 167 167 167 167 167 168 238 238 238 238 238 238 - 167 237 237 237 238 238 238 74 165 163 162 80 254 254 130 131 - 37 153 40 40 41 41 41 91 91 91 137 170 170 170 170 239 - 165 165 166 166 167 167 237 237 237 238 238 238 238 238 238 239 - 83 83 83 84 98 98 98 85 98 167 168 168 168 168 169 239 - 166 166 166 237 237 237 237 237 168 238 238 238 238 239 239 239 - 132 132 133 133 134 135 135 135 135 167 168 168 169 169 169 239 - 82 83 83 83 16 17 61 61 61 61 62 168 169 169 239 239 - 202 203 202 202 16 17 84 48 48 49 54 54 59 59 59 58 - 59 60 250 68 67 69 69 236 70 70 71 71 71 72 238 73 - 70 165 167 88 136 169 238 162 164 165 167 254 131 133 165 160 - 239 239 170 169 169 90 88 85 84 133 132 131 131 130 254 254 - 98 168 168 169 238 238 238 238 239 239 238 238 239 239 239 239 - 135 86 88 87 136 168 136 168 136 169 169 169 169 170 170 239 - 97 61 61 61 96 165 61 237 96 60 60 166 61 168 238 238 - 166 166 237 237 237 237 238 238 238 238 238 238 239 239 239 239 - 167 167 167 167 167 168 168 168 169 169 169 239 239 239 239 239 - 168 168 238 238 169 239 239 239 165 164 163 80 130 130 131 36 - 37 38 40 41 42 42 42 92 25 26 246 246 246 171 171 239 - 166 166 166 167 168 168 168 168 238 238 238 238 239 239 239 75 - 84 84 84 85 98 98 98 88 88 87 168 168 169 169 239 239 - 166 166 237 237 237 237 237 168 238 238 238 239 239 239 239 171 - 133 133 38 134 134 135 135 88 136 136 169 169 169 170 170 239 - 82 83 16 16 16 17 19 61 61 62 62 169 62 239 239 76 - 202 202 203 203 19 19 18 48 48 49 54 54 59 59 59 59 - 250 60 250 68 69 236 69 71 70 70 71 72 73 74 74 74 - 237 165 167 135 137 169 74 163 165 166 168 130 131 133 166 160 - 76 171 170 170 169 90 87 86 85 84 132 132 131 130 130 254 - 90 168 169 169 169 169 239 239 239 239 239 239 239 75 75 239 - 135 88 136 136 136 90 90 137 137 169 170 170 170 171 171 171 - 97 61 61 168 96 97 61 237 96 60 61 61 168 238 239 239 - 167 237 237 168 168 238 238 238 238 239 239 239 239 239 75 75 - 87 87 87 87 168 168 168 168 169 62 239 239 239 239 171 75 - 169 238 238 238 239 239 239 75 166 165 164 81 131 131 132 37 - 38 38 39 155 42 42 43 43 93 27 246 246 171 171 171 76 - 167 167 167 168 168 169 169 169 169 238 239 239 239 75 76 76 - 84 153 85 18 86 18 86 87 90 90 169 169 170 170 171 75 - 167 167 167 237 237 238 238 238 238 238 239 239 239 239 171 171 - 37 38 38 38 135 135 136 136 137 137 137 170 170 170 171 76 - 83 16 16 17 18 19 20 21 21 62 62 62 170 171 171 77 - 202 203 203 203 19 19 19 48 49 49 49 54 59 59 59 60 - 59 60 60 68 70 70 70 70 237 71 72 73 74 74 75 75 - 237 166 167 136 170 170 75 164 166 166 168 130 132 84 166 160 - 77 77 171 246 170 23 90 89 86 85 133 152 132 151 150 149 - 169 62 62 62 62 239 239 75 239 239 171 171 76 76 76 171 - 88 136 136 91 137 137 137 137 170 246 246 246 171 171 171 171 - 98 87 169 62 97 61 61 72 96 61 61 61 168 239 239 75 - 168 168 238 238 238 238 239 239 239 239 239 75 171 76 76 76 - 90 90 90 90 90 169 169 62 170 170 171 171 171 171 171 76 - 169 239 239 239 239 171 76 76 167 165 83 132 132 37 37 37 - 38 4 41 3 43 43 44 2 44 29 94 139 172 172 173 77 - 136 168 168 168 169 169 169 170 170 239 239 171 76 76 77 77 - 85 40 18 19 88 20 87 90 22 23 62 170 171 171 63 76 - 168 168 168 168 238 238 238 239 239 239 239 75 171 76 77 172 - 38 38 38 4 39 41 136 136 137 137 138 246 171 171 171 172 - 153 17 18 19 20 20 21 21 23 62 62 246 245 63 63 77 - 20 203 203 203 20 20 21 254 149 50 54 55 60 60 60 60 - 55 60 70 250 70 237 71 71 71 72 73 74 74 75 75 75 - 237 166 168 136 171 171 75 164 166 166 169 131 132 84 167 160 - 78 173 172 245 246 26 100 91 41 40 40 153 37 37 36 150 - 62 62 62 170 170 170 171 76 171 171 171 172 77 77 77 172 - 136 91 91 92 137 26 138 246 246 246 171 171 139 172 172 172 - 99 21 62 62 17 98 168 238 97 61 61 61 62 239 171 76 - 168 238 238 238 238 239 239 75 76 76 76 76 77 77 77 77 - 91 22 23 23 62 62 246 246 246 171 171 171 172 172 172 77 - 170 239 239 239 171 172 172 77 167 85 133 132 37 37 38 38 - 4 39 3 3 43 2 2 31 31 94 103 103 140 173 173 78 - 136 136 169 169 169 169 170 171 171 171 171 172 172 77 173 78 - 40 154 41 99 99 21 22 23 23 24 246 246 245 63 172 77 - 168 168 169 238 238 238 239 239 239 75 76 76 77 77 77 173 - 4 4 4 244 244 244 244 137 27 138 138 139 139 139 172 173 - 85 18 20 20 21 21 23 23 23 246 246 245 63 172 172 173 - 204 204 203 203 204 21 23 150 149 50 55 55 60 60 55 55 - 60 60 61 166 237 71 72 71 73 73 74 75 75 76 76 76 - 238 167 169 137 139 171 76 165 166 167 169 131 133 85 167 128 - 79 173 172 139 157 101 26 92 41 41 39 38 38 37 36 36 - 26 246 246 245 245 171 63 172 172 172 172 173 173 173 173 173 - 42 92 92 26 27 28 138 157 139 139 139 139 172 172 140 172 - 22 23 62 62 18 87 62 62 97 61 61 62 62 171 77 77 - 169 238 238 239 239 239 75 76 76 77 77 77 173 173 173 173 - 91 23 24 246 246 246 246 246 245 171 63 172 172 173 173 78 - 171 171 171 171 172 172 173 173 136 86 133 132 37 5 38 4 - 4 244 244 43 2 188 125 125 95 95 158 46 1 173 141 79 - 137 137 137 137 170 170 171 171 171 172 172 172 173 173 173 79 - 40 41 41 22 22 23 23 24 24 246 246 245 63 172 140 173 - 169 169 169 239 239 239 239 239 76 76 77 77 173 173 173 141 - 244 186 186 244 244 244 43 93 93 29 94 139 139 140 140 173 - 40 154 99 21 22 23 100 24 246 245 245 63 172 140 173 79 - 205 204 204 204 204 205 24 150 150 152 83 55 55 55 60 60 - 61 61 61 71 71 72 72 73 73 74 75 75 76 76 77 77 - 238 167 137 137 139 139 77 85 167 168 170 132 133 86 168 128 - 174 141 140 103 45 157 28 43 3 41 39 39 38 38 37 36 - 101 245 63 63 63 63 172 172 172 173 173 173 173 173 79 79 - 25 93 28 28 28 30 157 103 103 103 158 158 140 173 173 173 - 23 24 246 246 19 90 62 239 98 61 62 62 239 63 77 78 - 169 239 239 75 75 75 76 76 77 77 173 173 78 78 79 79 - 24 26 246 246 246 245 245 245 63 63 172 172 173 173 173 79 - 171 171 76 172 172 173 173 79 137 136 135 37 37 5 4 4 - 244 244 187 188 188 125 126 126 126 126 127 127 159 141 141 79 - 137 137 137 246 246 171 171 172 172 173 173 173 173 141 174 174 - 41 41 155 42 100 24 26 26 246 246 245 63 172 140 173 79 - 170 170 170 239 239 171 76 77 77 77 173 78 79 79 174 174 - 244 186 187 187 187 187 188 188 29 94 103 140 140 140 141 174 - 41 41 22 23 100 26 246 246 245 63 63 63 173 173 173 142 - 205 205 204 204 204 205 26 151 150 152 16 96 60 60 60 61 - 61 61 61 73 72 73 73 73 74 75 75 76 77 77 78 78 - 239 168 170 93 189 140 78 86 167 169 171 37 153 89 168 128 - 142 142 141 46 103 45 29 93 3 3 39 4 4 5 5 37 - 245 63 63 140 140 173 173 173 173 173 141 79 79 174 174 142 - 44 44 30 31 157 45 103 158 158 1 1 1 141 141 141 141 - 25 101 245 245 99 23 62 239 19 62 62 62 63 77 173 78 - 239 239 75 75 76 76 77 77 78 78 78 79 79 174 174 174 - 246 246 246 245 139 63 63 172 172 173 173 173 173 79 79 79 - 172 63 77 77 173 79 174 174 137 136 135 38 5 5 4 4 - 244 244 188 188 125 126 126 126 126 127 127 127 141 142 142 174 - 138 138 138 246 171 172 172 172 173 173 173 141 174 142 142 175 - 41 42 92 92 24 26 101 101 245 63 172 140 140 141 174 174 - 170 239 171 171 171 76 77 77 77 173 79 79 174 174 142 175 - 187 186 187 187 187 188 188 188 94 189 46 1 1 47 142 175 - 41 155 42 24 26 101 245 245 63 140 63 1 141 141 174 175 - 205 205 205 205 205 205 101 151 150 152 16 16 61 61 61 61 - 61 61 61 74 73 74 74 74 75 75 76 77 78 78 79 78 - 239 169 138 29 190 47 79 86 90 62 63 153 40 91 169 128 - 191 191 190 190 189 189 188 187 186 186 185 185 184 184 5 5 - 189 158 189 46 46 46 190 190 190 190 190 190 190 190 191 191 - 188 188 188 188 188 189 189 189 189 189 190 190 190 190 190 190 - 187 2 94 94 41 92 246 63 20 23 62 246 245 172 140 79 - 171 171 171 172 172 172 173 173 141 141 141 141 141 191 191 191 - 2 188 94 94 189 189 189 189 189 189 190 190 190 190 191 191 - 139 139 139 140 190 190 191 175 244 244 39 38 5 184 185 185 - 186 187 187 188 125 126 126 126 126 190 190 190 190 191 191 191 - 188 188 188 188 188 189 189 189 189 190 190 190 190 191 191 191 - 244 244 244 244 187 188 188 188 188 189 189 189 189 190 190 191 - 138 138 139 139 139 140 140 140 140 141 141 191 191 191 191 191 - 186 186 186 187 187 187 188 188 188 189 189 126 126 190 190 191 - 3 3 3 43 43 2 94 94 189 189 189 189 190 190 190 143 - 2 157 206 205 101 156 157 36 37 37 152 16 17 61 17 61 - 61 61 62 238 239 239 76 239 76 76 77 173 141 141 191 174 - 170 137 188 188 189 190 174 40 23 246 140 38 4 3 137 128 - 181 181 181 180 179 179 179 178 178 177 177 176 109 109 109 108 - 179 180 180 180 180 180 180 180 181 181 181 181 181 181 181 181 - 178 178 179 179 179 179 179 179 180 180 180 180 180 180 181 181 - 178 179 179 180 110 10 9 7 10 9 9 9 9 32 180 182 - 8 8 9 8 32 32 32 181 181 181 181 181 181 181 181 181 - 179 179 179 179 179 179 179 180 180 180 180 180 181 181 181 181 - 181 180 180 180 180 180 181 182 112 9 112 110 109 177 176 176 - 177 177 178 178 179 179 179 180 180 180 180 181 181 181 181 181 - 179 179 179 179 179 179 179 180 180 180 180 180 181 181 181 182 - 111 110 110 111 178 179 179 179 179 179 179 180 181 181 181 181 - 179 179 179 180 180 180 180 180 181 181 181 181 181 181 181 181 - 177 177 177 177 178 178 178 179 179 179 179 180 180 181 181 181 - 111 111 111 110 111 112 113 180 180 180 180 181 181 181 181 114 - 113 113 113 113 113 113 113 108 108 12 12 11 10 10 106 106 - 144 144 144 253 253 8 9 9 9 8 32 32 181 181 181 181 - 32 9 179 181 178 180 182 11 9 8 32 109 110 111 8 128 - 181 181 181 180 179 179 179 178 178 176 177 177 177 110 110 110 - 180 180 180 180 180 180 181 180 180 180 180 181 181 181 181 181 - 178 178 179 179 179 179 179 179 179 180 180 180 180 181 181 181 - 179 179 179 180 111 112 8 32 9 9 9 9 8 181 181 182 - 112 8 8 8 181 181 181 181 181 181 181 181 181 182 182 182 - 179 179 179 179 180 180 180 180 180 180 180 180 181 181 181 181 - 180 180 180 180 180 181 181 182 113 112 111 110 109 176 176 176 - 177 178 178 178 179 179 179 180 180 180 180 181 181 181 181 181 - 179 178 178 179 179 180 180 179 180 180 180 181 181 181 182 182 - 110 111 178 179 179 178 178 178 179 179 179 180 180 181 181 181 - 179 179 179 180 180 180 181 181 181 180 181 181 181 181 182 182 - 177 177 177 177 178 178 178 179 179 179 179 180 180 181 181 181 - 110 111 111 112 113 113 179 180 180 180 180 180 181 181 181 181 - 113 113 113 112 111 112 113 109 109 109 11 11 10 10 10 10 - 106 106 9 9 9 9 9 9 8 32 181 181 181 181 181 182 - 32 9 179 181 179 180 182 11 9 8 32 109 110 111 8 128 - 182 181 181 181 180 180 179 178 178 178 177 178 176 111 110 109 - 181 180 180 180 181 181 181 181 181 181 181 182 182 182 182 182 - 179 179 179 179 179 180 180 180 180 180 181 181 181 181 181 182 - 179 180 180 181 112 112 8 32 9 9 8 9 32 180 182 182 - 8 32 32 32 32 181 181 181 182 182 181 181 181 182 182 182 - 180 180 180 180 180 180 180 180 181 181 181 181 181 182 182 182 - 180 180 180 181 181 181 182 182 113 112 111 110 176 176 177 177 - 177 178 178 179 180 180 180 180 180 181 181 181 181 182 182 182 - 179 179 180 180 180 180 180 181 181 181 181 181 182 182 182 182 - 111 113 180 180 179 179 179 180 180 180 180 181 181 181 182 182 - 180 180 180 180 180 181 181 181 182 181 181 181 182 182 182 182 - 177 177 178 178 178 179 179 179 180 180 180 181 181 181 182 182 - 111 112 112 113 113 180 181 180 181 180 180 181 181 182 182 182 - 114 113 113 113 113 113 113 110 109 110 10 10 10 10 10 144 - 144 253 253 128 8 8 8 8 32 32 32 181 181 182 182 182 - 32 8 179 180 180 181 182 10 9 8 32 110 111 112 8 128 - 183 182 182 181 180 180 180 179 178 179 178 178 176 111 110 110 - 181 181 181 181 181 182 182 182 182 182 182 182 182 182 182 182 - 180 180 180 180 180 181 181 181 181 181 182 182 182 182 182 182 - 179 180 181 181 112 9 8 33 8 8 8 8 32 181 182 182 - 32 32 32 32 32 32 181 182 182 182 182 182 182 182 182 182 - 181 181 180 180 180 181 181 181 181 182 182 182 182 182 182 182 - 181 181 181 181 182 182 182 182 113 112 112 111 111 176 177 178 - 178 179 179 180 180 181 180 181 181 181 182 182 182 182 182 183 - 180 180 181 181 180 180 181 182 182 181 182 182 182 182 183 183 - 112 113 180 180 180 180 181 181 180 181 181 181 182 182 182 182 - 181 181 181 181 181 181 181 181 182 182 182 182 182 182 183 183 - 178 178 178 179 179 179 180 180 180 181 181 181 182 182 182 183 - 113 113 112 113 113 181 181 181 180 180 181 181 182 182 182 182 - 114 114 114 113 113 114 114 110 110 110 10 10 10 144 144 145 - 253 146 128 129 128 128 7 7 33 33 33 33 182 182 182 183 - 32 8 179 180 181 182 183 9 8 8 32 110 111 113 129 128 - 183 183 182 182 181 181 181 180 180 178 179 179 180 110 110 111 - 32 181 181 182 182 183 183 182 182 182 183 183 183 183 183 183 - 180 180 181 181 181 181 181 182 182 182 182 182 182 182 183 183 - 32 32 32 32 8 7 32 33 8 7 8 32 32 182 183 183 - 32 33 32 32 33 34 182 183 182 183 183 183 183 183 183 183 - 181 181 180 181 181 181 182 182 182 182 182 183 183 183 183 183 - 33 33 182 182 183 183 183 183 8 9 9 110 110 176 178 178 - 179 180 180 180 181 181 181 182 182 182 182 182 183 183 183 183 - 181 180 180 181 181 182 182 182 182 182 182 183 183 183 183 184 - 112 113 181 181 181 181 181 180 181 182 182 182 182 183 183 183 - 180 32 32 32 32 33 182 182 182 182 183 183 183 183 183 184 - 179 178 179 179 180 180 180 181 181 181 182 182 182 183 183 183 - 112 112 8 8 32 32 32 32 32 181 182 182 183 183 183 183 - 114 114 113 114 114 114 114 110 110 10 10 9 144 145 145 145 - 48 48 254 254 129 129 130 130 131 34 34 34 183 183 183 183 - 129 128 179 179 182 182 183 9 8 7 33 110 112 8 129 128 - 183 183 183 182 182 182 182 181 181 179 180 180 180 111 111 111 - 33 33 33 182 183 183 183 183 183 183 183 183 183 183 183 184 - 181 181 181 181 182 182 182 182 182 182 182 182 183 183 183 184 - 32 33 32 33 8 7 33 34 8 7 8 33 33 35 183 184 - 33 33 33 33 35 35 34 35 183 183 183 183 183 183 183 183 - 32 32 32 33 182 182 183 183 183 183 183 183 183 183 183 184 - 34 34 182 183 183 183 184 184 32 8 9 111 111 178 179 178 - 180 180 181 181 181 182 182 182 182 183 183 183 183 183 183 184 - 181 181 32 32 182 182 183 183 183 183 183 183 183 183 184 184 - 113 32 32 32 32 32 181 181 181 182 183 183 183 183 183 183 - 32 32 33 33 34 34 35 35 182 183 184 184 183 183 184 184 - 179 179 180 180 180 181 181 181 182 182 182 182 183 183 183 184 - 112 8 32 32 32 32 32 32 33 34 183 183 183 183 183 184 - 114 114 114 114 114 32 32 110 10 10 9 9 145 146 146 146 - 48 48 48 254 254 130 130 131 131 131 34 34 35 183 184 184 - 130 129 180 181 183 183 183 9 8 33 35 10 112 8 129 128 - 184 184 183 183 183 182 182 181 180 181 180 180 112 112 112 110 - 34 35 35 35 183 184 184 184 184 184 184 184 184 184 184 184 - 182 182 182 182 182 182 183 183 183 183 183 183 183 184 184 184 - 32 34 34 35 8 7 33 35 148 7 33 34 35 35 183 184 - 34 35 35 35 35 35 35 35 5 184 184 184 184 184 184 184 - 33 34 34 34 34 34 183 183 183 183 183 184 184 184 184 184 - 34 35 183 183 184 184 184 185 33 32 8 112 112 179 179 179 - 180 181 181 181 182 182 182 183 183 183 184 184 184 184 184 185 - 32 33 34 34 33 34 183 183 183 183 183 184 184 184 184 185 - 32 32 32 32 32 32 32 33 32 183 183 183 183 183 184 184 - 33 34 34 35 35 35 35 35 183 184 184 184 184 184 184 184 - 180 180 180 181 181 181 182 182 182 182 183 183 183 184 184 184 - 32 32 33 33 32 32 33 34 34 35 183 184 184 184 184 184 - 6 6 33 33 33 33 34 10 10 9 9 145 145 146 147 147 - 48 48 254 254 130 131 131 132 132 132 36 35 35 184 184 185 - 131 130 33 182 184 184 184 8 32 33 35 9 8 32 130 128 - 186 185 184 184 183 183 182 181 180 180 181 32 112 112 9 112 - 35 35 35 35 5 184 185 185 184 184 184 185 184 185 185 185 - 182 182 182 182 182 183 183 183 184 184 184 184 184 184 184 185 - 33 6 34 37 7 6 35 35 7 148 36 34 37 5 5 185 - 34 35 35 35 37 5 5 4 5 5 184 184 185 185 185 185 - 34 35 35 35 34 35 183 184 184 184 184 184 184 185 185 185 - 35 5 5 184 185 185 185 185 34 32 8 8 112 180 180 181 - 181 181 182 182 183 183 183 183 183 184 184 184 185 185 185 185 - 34 34 34 34 35 35 35 35 184 184 184 184 185 185 185 185 - 33 32 32 33 33 33 33 34 34 183 184 184 184 184 185 185 - 33 34 35 37 37 5 5 5 5 184 184 184 185 185 185 185 - 180 180 181 181 181 182 182 182 183 183 183 184 184 184 184 185 - 32 32 32 33 34 35 35 34 35 35 5 184 184 185 185 185 - 33 6 6 33 33 33 34 10 9 8 8 146 146 147 148 148 - 49 49 49 80 81 132 132 132 132 132 133 37 38 185 185 185 - 131 131 34 182 184 184 185 8 32 34 37 9 7 33 130 128 - 186 186 185 184 184 184 183 183 181 32 32 32 32 8 9 9 - 5 38 38 38 5 185 185 185 185 185 186 185 185 185 185 185 - 182 183 183 183 183 183 184 184 184 184 184 184 184 185 185 186 - 35 35 35 5 33 36 35 37 149 130 34 36 37 38 4 244 - 35 37 37 38 38 38 38 38 4 4 4 185 185 186 185 185 - 35 35 35 35 5 5 184 185 184 185 185 185 185 185 185 186 - 5 5 38 184 185 186 186 186 34 33 32 8 113 181 181 180 - 181 182 182 183 183 183 184 184 184 184 185 185 185 185 185 186 - 34 35 35 5 5 5 4 185 184 185 185 185 185 185 186 186 - 32 33 33 34 34 35 35 35 35 5 184 184 185 185 185 185 - 34 36 37 37 5 38 38 4 38 185 185 185 186 186 186 186 - 181 181 181 182 182 182 182 183 183 183 184 184 184 185 185 186 - 32 33 33 34 35 35 5 5 5 5 5 185 185 185 185 186 - 6 200 6 36 6 35 35 9 8 8 8 146 147 149 149 149 - 49 80 50 82 82 132 132 133 133 134 134 38 38 185 186 244 - 37 131 5 183 185 185 185 32 33 35 37 8 33 33 131 128 - 187 186 185 185 185 184 184 183 34 33 33 33 32 32 8 8 - 5 38 4 4 4 4 185 185 186 186 186 186 186 186 186 186 - 183 183 184 184 184 184 184 185 185 185 185 185 186 186 186 186 - 35 37 5 5 34 36 37 38 130 131 36 37 38 39 39 244 - 38 38 38 38 38 39 39 41 41 3 244 244 244 186 186 187 - 5 38 38 5 5 38 4 185 185 185 185 186 186 186 186 186 - 38 4 4 4 185 186 186 244 35 34 33 32 8 181 181 181 - 182 182 183 183 184 184 184 185 185 185 186 186 186 186 186 187 - 35 5 5 5 5 38 4 4 185 185 186 186 186 186 186 187 - 33 34 34 35 35 35 5 5 5 5 185 185 185 186 186 186 - 5 5 38 38 38 4 4 4 4 185 185 186 186 187 187 186 - 182 182 182 182 183 183 183 184 184 184 185 185 185 186 186 186 - 33 33 35 35 5 5 5 5 38 4 4 244 186 186 186 187 - 152 201 200 153 37 5 5 9 8 8 8 147 147 149 149 49 - 50 50 50 82 133 133 133 133 134 135 135 39 39 244 186 244 - 134 132 38 184 186 122 187 34 34 5 38 8 33 6 132 128 - 188 187 186 186 185 185 184 184 35 34 34 33 33 32 32 8 - 4 39 39 4 4 244 244 186 186 186 187 187 187 187 187 187 - 184 184 184 185 185 185 185 185 186 186 186 186 186 187 187 187 - 5 5 38 4 36 37 38 135 131 151 37 38 40 41 3 43 - 135 135 135 135 88 41 91 42 42 42 3 244 187 187 187 187 - 38 38 38 4 4 4 4 185 185 185 186 187 187 187 187 187 - 4 39 39 244 244 187 187 187 5 34 34 32 32 181 181 182 - 183 183 183 184 184 185 185 186 186 186 186 186 187 187 187 188 - 5 38 38 4 4 4 4 4 185 186 186 187 187 187 187 187 - 34 35 35 5 5 5 5 38 4 4 185 186 186 186 186 187 - 38 38 39 39 39 39 41 244 244 244 186 186 187 187 187 187 - 182 183 183 183 183 183 183 184 184 185 185 186 186 186 187 187 - 34 35 35 5 5 38 4 4 4 4 244 244 244 186 187 2 - 201 202 201 153 153 4 4 8 8 8 148 148 148 149 150 50 - 50 50 82 84 165 166 166 134 135 136 136 137 244 244 187 2 - 134 132 38 184 185 122 187 33 35 38 38 7 6 35 133 128 - 188 188 187 187 186 186 185 184 5 35 35 34 33 33 32 32 - 41 3 3 244 244 244 244 244 244 187 187 187 187 187 187 187 - 185 185 185 185 185 186 186 186 186 186 187 187 187 187 187 187 - 38 4 4 4 37 38 39 136 152 83 134 40 41 155 43 93 - 135 135 136 136 91 137 137 92 92 92 43 93 2 188 188 188 - 38 4 39 39 39 244 244 244 244 244 244 187 187 187 188 188 - 3 155 244 244 244 187 188 188 38 35 35 34 32 32 181 183 - 183 184 184 184 185 185 186 186 186 186 186 187 187 188 188 188 - 38 38 4 39 39 41 3 244 244 244 187 187 187 187 188 188 - 35 5 5 5 38 4 4 4 4 4 244 244 244 187 187 188 - 38 39 39 41 41 41 42 92 244 244 187 187 188 188 188 188 - 183 183 183 183 184 184 184 185 185 185 186 186 187 187 187 188 - 35 5 5 38 4 4 4 39 41 3 3 3 244 187 187 31 - 202 202 202 202 153 154 39 8 7 7 149 149 150 150 50 51 - 51 51 83 97 166 166 166 167 168 168 137 137 27 93 2 29 - 135 133 4 184 122 124 2 34 37 38 136 7 6 5 134 128 - 189 94 188 187 187 186 185 4 4 38 5 37 35 34 33 32 - 244 42 42 3 43 43 43 43 2 2 188 188 188 188 188 188 - 186 185 185 185 186 186 244 244 244 187 187 188 188 188 188 188 - 4 39 39 41 37 40 41 90 84 16 86 89 22 24 44 94 - 88 88 136 137 137 137 170 246 138 138 138 29 94 94 94 94 - 41 41 3 3 3 3 3 3 43 43 187 188 188 188 188 189 - 92 92 92 43 93 2 94 94 4 37 37 34 33 33 34 183 - 184 184 185 185 186 186 122 187 187 187 187 188 188 188 189 189 - 38 39 41 41 155 42 92 43 244 43 188 188 188 188 188 189 - 5 5 4 4 4 4 39 41 3 3 3 187 187 188 188 189 - 39 41 136 91 91 137 26 138 137 93 29 188 188 188 189 189 - 184 184 184 184 185 185 185 186 186 186 187 187 187 188 188 189 - 5 38 38 4 4 39 41 3 3 3 43 43 2 2 94 102 - 203 203 202 203 154 155 155 7 7 149 149 150 151 51 55 55 - 96 96 97 97 166 167 167 168 168 169 169 170 138 29 94 139 - 135 133 244 185 124 125 95 37 38 40 136 33 5 5 135 128 - 158 45 94 188 187 187 244 4 4 4 38 5 35 35 33 33 - 43 25 93 43 93 44 2 2 31 45 45 95 95 189 189 126 - 244 244 244 244 244 244 244 187 187 2 188 188 188 189 189 95 - 41 155 3 42 153 154 22 23 16 17 88 90 23 101 94 139 - 136 136 169 169 169 170 246 171 139 139 139 139 103 103 103 158 - 3 3 3 43 43 43 43 43 2 2 2 2 94 45 189 46 - 27 26 27 28 94 94 103 140 39 38 38 35 34 35 35 184 - 185 185 186 186 122 187 187 124 124 188 188 189 189 189 46 140 - 39 41 42 92 92 25 26 93 28 29 94 94 189 189 189 46 - 4 4 4 39 39 41 3 3 3 43 43 2 2 188 189 158 - 136 136 137 137 137 26 138 138 138 138 94 45 189 189 158 189 - 184 184 185 185 185 186 186 187 187 187 187 188 188 188 189 189 - 38 4 39 39 41 3 3 3 43 43 44 2 45 103 103 158 - 203 203 202 203 154 155 155 7 6 150 150 151 51 55 96 60 - 97 97 97 61 167 167 168 169 169 169 170 170 246 139 140 172 - 136 134 136 244 188 125 102 37 40 88 137 34 5 4 88 128 - 141 1 189 188 188 188 3 3 39 39 39 38 5 35 34 33 - 93 28 30 30 157 103 102 102 102 102 158 46 1 1 47 159 - 3 43 43 43 43 2 2 2 2 94 45 45 95 158 46 46 - 155 100 26 101 20 20 23 62 16 19 90 91 24 157 45 139 - 170 169 169 170 170 171 171 172 172 172 172 140 140 140 140 141 - 3 43 43 93 93 44 30 31 31 45 45 103 103 158 1 47 - 101 246 245 103 103 103 140 141 42 39 38 37 37 5 5 4 - 185 186 186 187 123 124 125 125 125 126 126 126 46 47 47 141 - 42 92 27 27 101 101 101 157 45 103 103 46 46 47 47 159 - 39 41 3 3 3 3 43 43 43 44 2 94 45 95 46 47 - 137 137 137 170 170 246 171 171 139 139 139 140 140 47 141 190 - 185 185 185 186 186 186 186 187 187 188 188 188 189 189 46 47 - 39 154 41 155 155 42 43 43 44 30 157 102 158 1 1 159 - 204 204 203 204 41 156 156 6 6 150 151 152 16 60 60 60 - 61 61 61 61 168 168 238 238 239 239 239 171 172 172 173 78 - 170 167 138 187 189 127 1 153 99 91 170 36 5 39 136 128 - 174 174 159 46 95 45 2 43 156 42 155 39 38 5 5 5 - 157 63 63 63 63 1 1 1 159 159 159 159 159 174 174 142 - 43 44 157 157 157 157 102 102 158 1 1 1 159 159 141 159 - 156 156 245 245 21 23 62 206 17 61 62 62 245 63 159 173 - 170 239 239 75 76 76 77 77 77 173 173 173 79 79 174 174 - 101 101 101 157 157 157 102 102 102 158 1 159 159 141 174 174 - 245 245 63 173 173 173 159 79 26 41 40 38 38 5 5 4 - 244 244 187 188 125 126 126 126 126 127 127 159 141 174 174 174 - 24 26 101 245 245 245 63 63 140 140 1 141 141 174 174 142 - 155 155 155 156 156 156 101 101 157 157 102 158 1 159 159 174 - 137 170 170 171 171 63 77 77 173 173 173 173 141 174 174 141 - 186 186 186 187 187 187 187 188 94 95 158 1 1 159 141 142 - 41 155 155 23 156 156 101 157 102 207 159 159 159 159 159 159 - 206 205 204 205 23 101 101 36 151 152 201 16 16 60 61 61 - 61 61 61 72 73 74 74 74 75 75 76 77 77 78 78 78 - 239 168 138 244 126 159 173 18 62 62 171 37 4 155 90 48 - 149 148 147 146 146 145 145 144 144 144 10 11 11 11 11 12 - 195 146 146 146 147 147 148 147 147 148 148 148 148 148 148 148 - 145 145 145 9 9 146 146 146 146 147 147 147 147 148 148 148 - 144 145 146 145 144 144 145 145 144 144 144 145 145 146 147 148 - 146 48 48 253 48 146 146 147 148 148 148 148 148 148 148 7 - 145 145 145 145 146 146 146 145 146 147 146 147 148 148 148 148 - 146 146 146 147 147 148 148 148 144 106 11 11 11 11 10 10 - 10 10 9 9 8 8 8 8 8 8 8 8 148 148 149 150 - 144 145 145 145 145 146 146 146 147 147 146 148 148 148 149 149 - 144 144 144 144 144 144 145 145 145 145 146 146 147 147 148 148 - 253 253 253 146 146 147 146 146 147 148 148 148 148 7 7 7 - 10 10 10 10 10 9 9 8 8 8 147 147 147 148 7 199 - 192 144 144 144 144 144 145 145 195 195 195 196 147 196 197 198 - 195 195 194 194 145 145 145 13 107 107 192 144 144 247 52 52 - 52 247 247 52 52 53 48 48 48 48 48 48 147 148 148 148 - 253 106 10 8 8 196 148 106 144 253 146 107 11 10 144 48 - 150 149 148 148 147 147 146 145 145 144 144 192 192 192 11 11 - 194 195 196 196 148 199 148 148 199 199 149 149 149 149 149 149 - 145 146 146 146 146 147 147 147 147 148 148 148 148 149 150 199 - 145 195 146 146 144 145 195 195 144 145 146 146 146 196 196 150 - 146 48 48 48 48 48 48 149 149 149 149 149 149 199 199 199 - 146 146 147 147 147 147 147 148 147 148 148 148 149 149 149 149 - 146 147 148 199 199 199 199 149 145 144 144 10 11 10 192 10 - 144 9 9 8 8 7 7 7 7 7 148 149 149 149 150 151 - 145 146 146 146 146 147 147 147 148 148 147 149 149 148 150 150 - 144 144 144 145 145 146 146 146 146 147 147 148 148 149 149 149 - 147 146 146 146 146 48 148 149 148 149 149 149 149 199 199 6 - 10 9 9 9 9 9 8 8 8 147 148 148 148 148 149 199 - 144 144 145 194 194 194 195 195 196 196 196 196 197 197 197 200 - 212 212 195 194 145 145 146 11 252 192 192 192 144 52 52 52 - 52 52 52 53 53 53 53 48 48 48 48 254 149 149 150 150 - 128 253 9 32 7 199 150 144 253 146 48 252 144 144 145 48 - 152 150 150 149 148 148 147 146 146 145 144 144 192 192 192 192 - 196 196 196 196 197 199 199 199 199 199 200 151 151 151 150 150 - 146 147 147 147 147 148 148 148 148 149 199 149 199 150 150 200 - 195 195 147 147 145 146 195 196 146 48 147 196 196 196 199 150 - 146 48 48 48 49 49 49 150 149 150 150 150 150 200 200 200 - 146 146 146 147 147 148 148 148 149 199 149 150 150 150 150 151 - 147 148 199 199 198 200 198 150 146 145 144 192 10 10 144 144 - 144 9 8 8 7 7 7 7 7 7 150 150 150 150 151 152 - 146 146 147 147 148 148 148 148 149 149 149 150 150 150 151 151 - 144 145 194 194 195 195 147 147 196 148 148 149 199 150 150 150 - 147 48 48 48 48 49 149 150 149 150 150 150 150 151 151 36 - 9 9 8 8 8 8 8 8 8 148 148 149 199 150 150 151 - 144 194 194 194 194 195 195 196 196 196 197 199 198 198 198 200 - 212 212 212 196 196 146 195 11 11 192 192 144 106 247 52 52 - 52 53 53 53 53 53 53 48 49 49 49 49 150 150 150 149 - 128 128 128 32 7 198 150 144 253 48 48 106 144 145 146 48 - 152 151 150 150 149 148 148 147 146 146 145 144 144 144 192 192 - 199 199 197 197 197 198 200 200 198 200 200 200 200 200 151 152 - 147 148 148 148 148 149 149 199 149 150 150 150 150 151 151 200 - 195 196 196 199 146 147 196 214 48 48 214 214 214 197 198 151 - 147 49 49 49 49 49 49 50 150 150 151 151 151 200 200 200 - 199 148 148 148 199 199 199 199 199 199 150 150 200 200 200 152 - 149 149 199 198 200 200 200 152 147 146 145 144 10 144 144 145 - 9 9 8 7 7 7 33 6 6 6 6 151 151 152 152 152 - 147 147 148 148 148 149 149 149 150 150 150 151 151 151 152 152 - 194 194 195 195 195 195 196 147 148 199 199 199 199 200 151 151 - 48 48 49 49 49 49 150 150 150 150 151 151 151 200 152 152 - 9 8 8 8 8 8 7 8 7 149 150 150 151 151 151 152 - 145 194 195 195 195 196 196 196 197 197 198 200 200 200 200 201 - 212 212 212 214 214 196 196 192 192 11 192 144 52 52 52 53 - 53 53 53 53 53 53 54 49 49 49 49 50 151 151 152 152 - 128 129 128 33 6 200 150 253 146 48 148 144 144 146 147 48 - 153 152 152 151 150 199 149 148 147 146 146 145 144 144 144 192 - 199 198 200 200 200 200 200 200 200 200 200 200 200 200 152 152 - 148 149 149 149 199 150 150 200 150 151 151 151 151 151 151 200 - 196 196 197 198 147 147 196 214 146 48 214 214 214 200 200 152 - 149 49 80 50 50 50 50 51 83 152 152 152 152 201 201 201 - 148 199 199 199 199 199 199 198 199 200 200 200 200 200 200 152 - 150 150 198 200 200 200 201 152 147 146 145 144 144 144 145 146 - 146 8 7 7 6 6 6 6 36 36 36 152 152 153 153 153 - 148 148 149 149 199 150 150 150 151 200 151 152 152 152 201 201 - 195 195 196 196 196 196 196 196 199 199 198 200 200 200 200 152 - 49 49 49 49 49 49 50 151 151 151 151 152 152 201 201 153 - 8 8 8 8 32 7 7 7 7 150 150 151 152 152 152 152 - 195 195 196 196 196 196 197 197 199 198 200 200 200 200 201 201 - 212 212 213 214 214 196 197 192 144 192 192 145 53 53 53 53 - 53 52 53 53 53 54 54 54 49 50 50 50 151 152 152 152 - 254 130 129 34 36 200 151 146 48 48 49 144 144 146 48 48 - 154 153 153 152 151 150 150 149 148 147 147 146 145 145 144 144 - 198 200 200 200 200 200 201 201 200 201 201 201 201 201 201 201 - 199 150 150 151 151 151 151 151 151 152 152 152 152 5 152 201 - 197 197 198 200 147 148 214 200 48 48 214 214 200 200 200 152 - 49 50 50 50 51 51 51 83 83 152 152 152 201 201 201 202 - 200 200 200 200 200 200 200 201 200 200 200 200 201 201 201 201 - 151 151 200 200 201 201 201 201 148 147 146 145 144 145 146 147 - 147 148 7 150 6 36 36 36 5 37 152 152 153 153 153 153 - 149 149 150 150 150 150 151 151 152 152 152 201 201 201 201 202 - 196 196 196 197 197 197 197 198 199 200 200 200 201 201 201 153 - 49 49 80 50 50 50 51 152 151 152 152 152 201 202 202 154 - 8 8 32 32 32 33 6 6 6 151 151 152 152 153 153 153 - 195 196 196 197 197 197 198 198 200 200 200 201 201 201 201 202 - 212 212 213 213 214 197 198 192 144 144 194 145 53 53 53 52 - 53 53 53 54 54 54 54 55 55 96 83 51 83 152 153 152 - 131 130 129 34 6 201 152 48 48 254 151 144 145 147 254 48 - 154 153 153 153 152 151 151 150 149 148 147 147 146 146 145 144 - 200 201 201 201 200 201 201 202 201 201 201 201 201 202 203 203 - 150 150 151 151 151 151 151 152 201 201 201 153 153 202 153 202 - 198 200 200 200 214 214 200 55 49 54 54 200 200 201 201 201 - 50 51 51 51 83 83 83 16 16 16 16 16 202 202 202 203 - 200 200 198 200 200 200 200 200 201 201 201 201 202 202 202 202 - 152 152 201 201 201 202 202 202 49 148 147 146 145 146 147 147 - 148 148 149 6 36 37 37 36 5 5 153 40 154 154 154 20 - 150 150 150 150 150 151 152 152 153 152 153 153 201 202 202 203 - 196 196 197 198 198 197 198 200 200 200 201 201 201 201 202 202 - 49 80 51 51 83 83 83 16 16 16 16 202 202 202 203 154 - 7 7 32 33 33 6 6 6 36 152 152 152 153 153 153 153 - 196 196 197 197 198 198 200 200 200 201 201 201 201 202 202 203 - 212 213 213 213 198 198 198 192 144 145 194 146 53 53 53 53 - 58 58 59 54 54 54 55 60 55 55 96 83 16 17 19 18 - 83 131 130 35 5 202 17 48 49 49 151 145 146 148 49 48 - 203 154 202 202 152 152 151 150 150 149 148 147 147 146 146 145 - 201 201 202 202 202 202 202 201 201 202 203 203 203 202 202 203 - 152 151 151 151 151 151 152 153 153 201 201 201 202 202 202 203 - 198 200 200 200 150 151 200 55 54 54 54 55 201 201 202 202 - 51 83 83 83 83 83 83 16 17 19 19 203 203 203 202 202 - 200 200 200 200 200 200 201 201 201 201 201 201 202 203 203 203 - 16 16 201 201 202 202 203 203 50 149 147 146 146 146 147 148 - 149 149 150 151 152 153 5 37 5 153 154 154 154 154 203 20 - 151 151 151 151 151 152 152 152 153 153 154 202 202 203 202 204 - 197 197 198 200 200 198 200 200 200 201 201 201 202 202 202 203 - 50 51 83 83 83 83 83 16 17 17 17 202 202 203 203 154 - 7 33 33 6 6 6 6 6 5 153 153 153 153 154 154 154 - 196 197 198 198 200 200 200 200 201 201 202 202 202 203 203 203 - 213 213 213 213 198 198 200 194 145 145 194 196 53 53 53 58 - 58 59 54 54 54 55 55 55 55 96 97 16 16 17 19 17 - 83 131 131 37 5 202 19 146 49 50 152 146 147 150 80 48 - 204 203 202 202 153 153 152 152 151 150 149 149 148 147 146 146 - 201 201 201 202 203 203 203 203 202 203 203 203 204 204 204 204 - 152 152 153 153 152 153 153 154 202 202 202 202 202 203 203 204 - 200 200 201 202 151 151 201 16 54 54 55 16 201 202 203 204 - 16 97 96 96 97 16 17 19 19 19 20 204 204 204 204 204 - 201 201 201 201 201 202 201 202 203 203 203 203 203 204 204 204 - 16 16 202 203 203 202 203 204 50 50 150 148 147 147 148 149 - 150 151 152 152 153 153 40 154 40 154 41 155 23 204 20 20 - 152 152 152 152 153 153 18 18 18 18 202 202 203 204 204 203 - 197 200 200 200 201 201 201 201 202 202 202 202 203 203 204 204 - 83 83 83 97 16 17 17 17 19 19 20 204 204 204 204 203 - 6 33 6 6 36 37 5 153 153 153 154 154 154 155 155 20 - 199 198 200 200 200 201 201 201 202 202 202 203 203 203 204 204 - 214 213 213 200 200 201 201 194 194 195 196 214 214 54 59 59 - 58 59 59 59 60 55 55 60 60 97 97 61 61 20 20 19 - 84 132 132 38 154 203 203 49 50 51 16 146 148 150 50 49 - 205 204 204 203 154 202 153 153 152 151 150 150 149 148 147 147 - 202 203 203 203 203 203 204 204 204 204 204 204 204 204 205 205 - 152 5 40 154 154 154 154 154 154 203 203 204 204 204 204 204 - 201 201 202 202 151 152 16 16 55 55 60 16 203 203 203 20 - 16 97 97 97 17 98 19 21 21 21 23 205 205 204 204 205 - 201 202 202 202 203 203 203 203 203 203 203 204 204 204 204 205 - 17 19 203 204 204 203 204 205 51 50 150 149 148 148 149 150 - 151 152 153 153 40 154 154 41 41 155 155 156 23 204 205 205 - 16 16 16 17 17 18 19 19 20 20 20 20 204 204 205 205 - 200 200 201 201 201 201 202 201 202 202 203 203 204 204 204 205 - 16 97 97 17 17 19 19 20 20 20 21 204 204 204 205 23 - 6 6 35 5 5 5 153 153 40 154 155 155 155 23 156 204 - 198 200 201 201 201 201 202 202 203 203 203 204 204 204 205 205 - 202 202 202 201 201 201 202 196 196 196 196 214 214 54 59 59 - 59 59 60 60 60 60 60 61 61 61 61 61 62 62 205 62 - 97 132 133 38 154 204 204 50 51 16 17 147 199 151 51 48 - 206 205 205 204 20 154 154 154 153 152 151 151 150 199 148 148 - 203 204 204 204 204 204 204 205 205 205 204 205 205 205 205 206 - 154 39 39 38 40 154 41 155 154 203 204 204 205 205 205 205 - 201 202 203 203 152 16 203 17 55 60 16 17 203 204 204 204 - 16 17 98 61 61 168 21 62 62 62 62 206 206 206 206 206 - 203 203 203 203 204 204 204 203 204 204 204 204 204 205 205 205 - 20 20 204 204 204 204 205 205 83 82 151 149 148 149 150 151 - 152 152 153 154 41 155 155 155 156 156 156 156 156 205 206 206 - 18 18 18 19 19 20 20 20 21 23 23 205 205 205 206 206 - 201 201 201 201 201 202 202 202 203 203 204 204 204 204 205 205 - 17 17 98 98 19 19 20 21 21 23 23 205 205 205 206 206 - 37 5 5 38 4 39 39 154 41 155 155 156 156 156 156 205 - 200 201 201 201 202 202 202 203 203 203 204 204 204 205 205 205 - 203 203 202 202 201 201 202 196 196 196 214 214 214 54 59 60 - 60 60 55 60 60 61 61 61 61 61 61 62 62 62 205 62 - 98 84 135 39 155 204 205 51 16 16 61 149 200 152 83 48 - 207 206 205 23 155 41 154 154 153 153 152 151 151 150 149 148 - 204 204 203 204 204 205 205 204 205 205 205 205 206 206 206 206 - 40 39 39 41 41 155 155 155 155 23 204 205 205 205 206 206 - 201 202 20 20 152 17 204 61 55 96 17 203 203 20 23 205 - 19 61 61 61 62 62 169 62 62 62 62 206 206 206 206 206 - 20 20 20 20 204 204 204 204 204 204 205 205 205 205 206 206 - 20 21 204 205 205 205 206 206 16 84 151 150 149 150 36 36 - 5 153 40 41 155 3 3 3 43 156 101 101 101 206 206 206 - 18 18 19 20 20 21 21 21 62 62 62 206 206 206 206 207 - 201 201 201 201 202 202 203 203 203 203 204 204 205 205 206 206 - 17 18 19 19 20 20 21 23 62 62 205 206 206 206 206 207 - 5 5 4 4 39 154 154 41 155 155 42 156 156 156 101 206 - 200 201 202 202 202 203 203 203 204 204 204 204 205 205 206 206 - 203 202 202 202 202 202 203 196 196 214 198 200 54 54 55 60 - 60 55 55 60 61 61 61 61 61 61 168 62 62 62 206 62 - 168 86 136 244 156 205 206 51 16 17 20 149 152 153 97 48 - 207 207 206 101 156 155 155 41 154 40 153 152 152 151 150 199 - 23 23 21 23 205 205 205 205 206 206 206 206 207 207 207 207 - 41 41 155 155 156 156 156 156 101 101 206 205 206 206 206 206 - 202 20 21 20 16 18 204 204 97 97 61 204 21 21 205 206 - 21 62 169 169 62 62 169 170 246 246 245 63 207 207 207 207 - 20 20 20 21 23 23 23 205 205 205 206 206 206 206 206 207 - 21 23 205 205 206 206 206 207 18 85 152 151 150 36 37 5 - 38 39 41 3 3 43 43 44 44 2 157 102 102 207 207 207 - 20 20 20 21 23 62 62 62 62 246 245 206 206 207 207 207 - 201 202 202 202 202 203 203 203 203 204 205 205 205 206 206 207 - 20 21 21 23 23 23 62 62 245 245 206 206 207 207 207 207 - 5 5 4 4 39 41 3 3 3 3 43 44 157 157 207 207 - 201 202 202 203 203 203 204 204 204 205 205 205 206 206 207 207 - 203 203 203 203 203 203 203 197 199 199 198 214 54 55 60 60 - 55 60 60 61 61 97 61 238 168 238 62 239 62 245 63 63 - 169 167 136 244 156 206 206 16 16 19 21 150 152 153 98 254 - 159 207 207 245 101 156 42 155 154 154 4 5 37 152 151 150 - 156 101 206 206 101 101 245 207 207 207 207 207 207 207 207 159 - 156 43 3 3 42 156 101 157 157 102 207 207 207 207 207 207 - 20 21 62 62 16 19 204 62 17 61 61 21 205 206 207 207 - 62 62 62 62 239 239 170 171 171 63 63 173 207 207 207 207 - 21 23 23 23 24 24 26 207 246 206 245 207 207 207 207 207 - 23 246 245 206 207 207 207 207 19 98 153 152 36 37 38 4 - 39 39 3 3 43 2 2 2 94 95 158 158 1 1 1 1 - 21 21 23 23 62 62 246 246 245 245 63 207 207 207 159 159 - 154 154 154 20 155 155 155 23 23 205 206 206 206 207 207 207 - 21 23 62 62 62 246 246 245 63 63 63 207 207 207 207 1 - 4 185 185 4 3 3 43 43 43 43 2 31 102 158 1 159 - 153 202 203 203 203 204 204 205 205 205 206 206 207 207 207 207 - 204 204 204 203 203 203 204 198 150 200 200 200 55 60 60 60 - 60 61 61 61 61 61 61 74 239 239 239 75 171 63 63 77 - 169 136 137 244 157 207 207 16 18 21 62 151 153 40 87 48 - 159 159 1 102 157 101 43 42 41 41 39 38 5 5 36 6 - 101 245 63 63 245 245 63 207 1 1 1 1 1 159 159 159 - 155 43 93 30 157 157 101 101 157 102 102 1 1 1 173 173 - 23 62 62 62 18 20 205 205 17 61 61 205 206 207 207 77 - 62 239 239 239 239 76 171 77 171 63 63 172 63 207 1 173 - 26 246 246 246 246 246 246 63 245 63 63 207 1 1 159 173 - 246 171 63 207 207 207 173 173 87 86 153 152 37 5 4 4 - 3 3 3 43 2 188 188 189 189 189 46 47 159 159 159 159 - 100 23 24 246 246 246 246 245 63 63 63 1 159 159 159 159 - 154 154 155 155 156 156 156 156 101 101 245 207 207 207 159 159 - 23 62 62 62 246 245 245 63 63 63 207 173 159 159 159 159 - 185 185 186 244 3 43 43 2 2 2 94 94 95 1 159 159 - 154 154 20 204 204 204 205 205 206 206 206 207 207 207 159 159 - 205 205 205 205 204 205 206 200 200 151 201 201 55 96 60 61 - 61 61 97 61 61 238 238 239 239 239 75 76 77 173 173 173 - 169 136 137 187 102 159 207 16 99 62 62 152 153 154 168 128 - 159 159 159 159 159 207 206 206 205 205 204 203 203 202 202 201 - 207 207 207 207 159 159 159 159 159 159 159 159 159 159 159 159 - 206 206 206 206 206 207 207 159 159 159 159 159 159 159 159 159 - 205 205 206 206 204 204 205 206 203 204 205 206 206 207 207 159 - 206 207 207 207 207 207 207 159 159 159 159 159 159 159 159 159 - 206 206 206 206 207 207 207 159 207 159 159 159 159 159 159 159 - 207 207 159 159 159 159 159 159 205 204 203 202 202 202 203 203 - 205 205 206 207 207 159 159 159 159 159 159 159 159 159 159 159 - 206 206 206 206 207 207 207 207 207 159 159 159 159 159 159 159 - 204 204 204 205 205 205 206 206 206 207 207 159 159 159 159 159 - 206 206 206 206 207 207 207 159 207 159 159 159 159 159 159 159 - 156 156 157 157 206 206 206 206 207 159 159 159 159 159 159 159 - 204 205 205 205 205 205 206 206 206 207 207 159 159 159 159 159 - 205 205 205 205 205 205 205 201 201 201 201 202 203 203 204 204 - 203 203 203 204 205 206 206 207 207 207 207 207 159 159 159 159 - 206 26 2 125 159 159 159 203 205 206 206 202 203 204 206 48 - 210 210 210 210 210 210 210 210 211 211 211 211 211 211 211 211 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 211 211 211 211 211 211 210 210 210 210 210 210 210 210 210 210 - 210 210 211 211 211 211 211 211 211 211 211 210 210 210 210 210 - 211 211 211 211 211 211 211 211 211 211 210 210 210 210 210 210 - 211 211 211 211 211 211 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 211 211 211 211 211 211 211 211 - 211 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 211 211 211 211 211 211 211 211 210 210 210 210 210 210 210 210 - 211 211 211 211 211 211 210 210 210 210 210 210 210 210 210 210 - 211 211 211 211 211 211 211 211 210 210 210 210 210 210 210 210 - 211 211 211 211 211 211 211 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 211 211 211 210 210 210 211 211 211 - 211 211 211 211 211 211 211 211 211 211 211 211 211 211 211 211 - 212 194 193 201 211 210 211 211 211 211 211 211 210 211 194 214 - 210 210 210 210 210 210 210 210 210 210 210 210 211 211 211 211 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 209 209 209 209 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 209 209 210 210 210 - 210 211 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 210 - 210 210 210 210 210 210 210 209 209 209 210 210 210 210 210 210 - 209 208 209 209 209 209 210 211 211 211 210 210 210 210 210 210 - 211 211 210 210 210 210 210 210 210 210 210 210 210 210 211 211 - 211 211 195 201 210 210 210 210 210 210 211 210 210 210 212 213 - 202 213 212 212 211 211 211 211 211 211 211 212 212 212 212 194 - 212 211 211 211 211 211 211 212 213 212 213 212 212 212 213 213 - 212 212 212 212 211 211 211 211 211 211 211 211 211 211 211 211 - 211 211 211 211 211 211 211 211 211 211 211 211 211 211 211 211 - 212 212 212 212 212 213 213 213 213 213 213 213 212 213 213 213 - 212 212 212 212 212 212 212 212 212 212 212 212 212 212 212 213 - 212 212 212 212 212 212 212 213 212 212 212 212 212 212 212 211 - 211 211 211 211 211 211 211 211 211 211 211 211 211 212 213 201 - 212 212 212 212 212 212 212 212 213 213 213 213 212 213 213 203 - 211 211 211 211 211 211 211 211 211 211 211 211 211 211 212 212 - 212 212 212 212 212 212 212 212 213 213 213 212 212 213 213 201 - 212 212 212 212 212 212 211 211 211 212 212 212 212 212 212 211 - 211 210 210 210 210 210 210 210 210 210 211 211 211 211 211 210 - 210 209 210 210 210 210 211 193 194 212 211 210 210 210 211 211 - 211 211 211 211 211 211 212 212 213 213 213 213 213 213 213 213 - 213 213 196 201 212 211 212 212 212 212 212 212 211 212 214 49 - 203 202 213 213 213 213 212 212 212 212 212 212 194 194 194 192 - 213 213 213 213 213 213 213 213 213 213 213 213 213 201 202 203 - 213 213 213 213 213 213 213 213 213 213 213 213 213 213 213 213 - 212 212 212 212 212 212 212 212 211 211 212 212 212 213 213 213 - 213 213 213 213 213 213 213 213 213 213 213 213 200 201 201 203 - 213 213 213 213 213 213 213 213 213 213 213 213 213 213 201 202 - 196 196 196 196 213 213 201 201 196 196 195 195 194 195 212 212 - 212 212 212 212 213 213 212 212 213 212 213 213 213 202 203 203 - 213 213 213 213 213 213 213 213 213 214 214 213 200 201 202 203 - 212 212 212 212 212 212 212 212 212 212 213 213 213 213 200 203 - 213 213 213 213 213 213 213 213 213 213 213 200 200 201 202 203 - 196 214 213 213 213 213 213 213 213 213 213 213 213 213 201 202 - 212 211 211 211 211 211 211 211 212 212 213 213 212 213 201 203 - 210 210 210 210 210 211 212 192 192 194 212 211 211 211 212 212 - 212 212 212 212 212 213 213 213 213 213 213 198 200 200 201 202 - 214 198 199 200 196 213 213 195 213 212 213 212 212 212 146 48 - 202 202 201 213 213 213 197 197 196 195 195 195 194 194 144 192 - 213 213 213 213 213 213 213 213 213 200 200 201 201 201 201 202 - 214 213 213 213 213 213 213 213 213 213 213 213 213 200 201 201 - 214 214 213 213 212 213 213 213 212 212 212 213 213 197 198 201 - 213 213 213 213 213 213 213 213 200 200 201 201 201 201 202 202 - 213 213 213 213 213 213 213 213 200 213 213 198 200 201 201 201 - 198 198 198 198 200 201 201 202 196 196 194 194 193 194 194 196 - 214 213 213 213 197 197 198 200 213 213 200 201 202 202 201 201 - 213 213 213 213 213 213 213 213 213 213 200 201 202 202 202 202 - 195 212 213 213 213 213 213 213 213 213 213 213 198 198 200 202 - 213 213 213 213 213 213 213 213 214 200 200 201 201 201 201 201 - 195 195 196 196 214 214 214 214 198 198 198 214 198 200 201 202 - 212 212 212 212 213 213 213 213 213 213 213 213 200 201 201 203 - 211 210 211 211 211 212 196 192 192 193 195 212 212 212 212 212 - 212 212 213 213 213 214 214 214 214 214 214 200 200 201 201 202 - 149 149 7 6 197 201 201 194 196 197 197 193 194 196 147 254 - 202 202 202 201 200 198 197 197 196 195 195 195 194 144 144 144 - 198 200 200 201 201 201 201 201 202 202 202 202 202 201 201 201 - 197 198 198 198 198 198 200 200 200 200 201 201 201 201 201 202 - 197 197 214 200 214 214 214 213 213 213 213 214 198 198 200 201 - 200 201 201 201 200 200 201 200 201 201 201 201 201 201 202 202 - 198 198 198 198 198 200 200 200 201 201 201 201 201 201 201 202 - 199 198 198 200 200 201 201 201 196 196 146 145 144 145 194 195 - 196 214 197 197 198 198 200 200 200 201 201 201 201 201 201 202 - 197 198 198 198 200 200 200 201 200 200 201 201 201 201 201 201 - 196 196 196 197 197 197 198 200 213 198 200 200 201 201 152 152 - 198 198 200 200 200 200 201 201 201 201 201 201 202 202 202 201 - 147 147 148 148 199 199 199 199 200 200 200 200 201 201 201 202 - 196 196 197 197 197 197 197 198 198 198 200 201 201 201 201 202 - 212 211 211 212 212 213 196 192 144 144 194 212 212 213 213 214 - 53 58 58 54 54 48 48 54 96 55 55 16 201 201 201 152 - 49 149 7 6 200 202 201 146 196 198 198 194 195 197 147 128 - 201 201 200 200 200 200 198 197 199 147 147 146 145 144 9 144 - 198 200 200 200 152 152 201 201 152 152 152 152 152 152 153 153 - 198 198 198 198 200 200 200 200 200 200 201 201 153 153 152 151 - 199 199 198 200 147 148 149 150 214 214 214 150 151 151 152 153 - 150 51 51 51 151 152 153 153 153 153 152 152 152 152 153 153 - 198 198 198 200 200 200 200 200 198 200 152 153 153 152 153 153 - 200 200 201 201 201 202 202 202 148 147 146 145 145 144 146 147 - 195 196 198 200 200 200 200 200 5 5 5 5 152 152 153 202 - 199 199 199 200 200 151 200 200 152 152 152 201 153 5 4 154 - 195 196 148 148 148 199 199 198 200 200 200 201 201 153 153 152 - 150 150 150 151 151 151 152 152 152 153 153 152 152 153 40 154 - 7 7 7 7 7 199 199 150 150 200 151 151 152 153 153 153 - 147 147 148 199 199 196 199 199 198 200 201 202 201 201 153 202 - 195 195 196 214 197 197 199 144 144 144 145 145 214 214 214 53 - 53 59 54 49 49 104 104 81 81 51 55 16 16 16 153 153 - 254 254 7 6 36 152 153 146 149 200 200 145 196 147 253 129 - 11 11 11 12 13 13 13 14 14 215 215 215 215 215 215 215 - 107 107 251 251 251 13 107 107 11 11 107 107 107 107 107 107 - 14 14 14 13 13 12 12 13 13 13 13 12 12 11 11 11 - 14 14 251 251 216 216 251 251 216 216 216 251 251 251 107 252 - 251 251 251 251 251 251 107 107 107 107 107 11 11 11 11 11 - 14 14 251 251 251 251 107 107 107 13 12 12 11 11 11 11 - 251 107 107 12 12 107 11 11 215 215 215 215 215 215 215 215 - 15 14 13 13 13 13 12 12 12 12 12 12 11 11 11 107 - 251 251 251 251 251 251 251 13 13 13 12 12 11 11 11 11 - 215 215 14 14 14 14 14 14 13 12 12 12 12 107 11 107 - 251 251 251 251 251 251 251 251 251 107 107 11 12 11 11 11 - 14 15 15 14 14 14 13 13 13 13 13 13 12 107 11 107 - 215 215 14 14 14 14 14 13 107 13 13 107 107 11 107 11 - 13 13 13 13 13 14 14 215 215 216 216 216 216 216 216 216 - 216 217 217 216 251 251 251 251 251 251 251 252 252 252 107 252 - 251 251 13 13 13 12 107 215 215 251 251 216 216 215 251 128 - 11 11 107 107 107 251 251 251 251 251 215 216 216 216 216 216 - 252 107 107 107 107 107 107 107 107 107 107 107 107 252 11 11 - 13 13 13 13 12 12 12 12 12 107 12 12 12 12 11 11 - 13 251 251 252 216 251 216 252 216 251 251 252 252 252 107 107 - 251 251 252 251 251 252 107 107 107 107 107 107 107 107 11 10 - 251 251 251 107 107 107 107 107 107 107 107 107 12 12 11 11 - 252 252 107 107 107 107 107 252 251 216 215 215 215 215 215 15 - 14 14 12 12 13 13 12 11 11 109 12 109 11 192 192 11 - 251 251 251 251 107 107 107 107 107 107 107 12 12 11 10 11 - 215 215 251 251 251 14 14 13 107 107 107 107 107 107 107 252 - 251 251 107 107 251 107 107 107 107 107 107 107 107 11 11 11 - 14 14 14 14 14 13 13 13 13 12 12 11 11 11 11 11 - 215 14 14 251 251 13 107 107 107 107 107 107 107 252 11 11 - 12 13 12 107 251 251 107 215 215 216 216 216 217 217 217 217 - 217 217 216 252 252 251 251 251 251 251 252 252 252 252 107 252 - 252 251 107 107 12 12 11 215 251 251 251 216 216 216 251 128 - 106 252 252 252 252 251 251 251 251 251 251 216 216 216 216 216 - 252 251 252 252 252 106 106 106 106 144 144 144 144 144 144 144 - 107 107 107 107 107 107 107 107 252 252 106 106 106 11 11 252 - 107 252 252 251 216 252 252 252 217 217 216 252 252 252 106 252 - 252 252 252 252 252 252 252 252 252 106 106 144 144 144 144 106 - 251 251 252 252 252 252 252 252 252 252 106 144 144 106 106 106 - 252 252 252 252 106 106 106 106 252 251 216 216 216 216 215 13 - 14 13 13 12 11 11 11 11 11 11 11 11 192 192 192 144 - 252 251 252 252 252 252 252 252 252 252 106 144 144 144 144 144 - 251 251 252 252 251 252 252 251 107 107 252 252 106 106 144 106 - 252 252 252 252 251 252 252 252 252 106 106 106 144 144 144 106 - 13 13 13 13 107 107 107 107 107 107 252 11 11 10 10 144 - 251 251 252 251 252 251 107 252 252 252 106 106 106 106 106 144 - 144 144 216 216 252 252 252 216 216 216 217 217 217 218 218 218 - 217 217 217 247 252 247 247 252 247 247 252 252 106 106 106 106 - 252 251 252 252 11 11 144 216 252 252 252 216 216 251 252 105 - 144 106 106 144 144 106 252 252 144 218 216 217 217 216 217 217 - 52 247 247 52 52 52 52 52 52 52 52 52 52 52 52 52 - 252 252 252 252 252 106 106 106 106 144 144 144 144 144 144 144 - 252 252 52 52 217 217 52 52 218 218 218 52 52 52 52 247 - 247 247 247 247 247 247 52 52 52 52 52 52 52 52 52 52 - 247 247 247 247 52 247 247 52 247 52 52 52 52 52 52 52 - 247 247 247 247 247 247 52 52 247 217 216 217 216 216 216 217 - 252 11 107 11 144 11 252 144 144 144 144 144 144 144 144 52 - 247 247 247 52 52 247 52 52 247 52 52 52 52 52 52 52 - 217 217 247 247 252 252 251 106 106 106 106 144 144 144 144 106 - 247 247 247 247 247 52 52 52 52 52 52 52 52 52 52 52 - 252 252 252 252 252 252 252 252 144 144 144 144 144 144 144 144 - 217 217 217 218 218 252 52 52 52 52 52 52 52 52 52 52 - 217 218 218 217 217 52 52 216 217 217 218 218 218 218 219 219 - 219 218 218 218 56 56 56 52 52 52 52 52 52 52 52 52 - 52 252 252 252 144 144 144 216 217 52 52 216 217 217 252 104 - 53 52 52 52 52 52 52 52 52 217 217 217 217 218 218 217 - 56 52 56 56 56 56 56 56 56 56 56 56 52 56 56 52 - 247 247 247 247 247 52 52 52 52 52 52 52 52 52 52 52 - 52 52 52 56 218 218 56 57 219 219 219 222 56 56 56 52 - 56 56 56 56 56 56 56 52 56 56 56 56 56 56 56 56 - 52 52 52 52 56 56 56 56 56 56 56 56 56 52 56 52 - 52 52 247 52 52 52 52 56 56 218 218 218 217 217 218 217 - 216 144 144 144 144 144 144 144 52 52 52 52 52 52 52 52 - 247 52 52 52 52 52 52 56 56 56 56 52 52 52 52 57 - 218 218 218 56 52 52 52 52 52 52 52 52 52 52 52 52 - 52 56 56 56 56 56 56 56 56 56 56 56 52 52 56 52 - 252 252 252 252 247 247 52 52 52 52 52 52 52 52 52 52 - 218 218 218 218 56 56 52 52 52 52 52 52 52 52 52 56 - 219 219 219 218 218 222 56 218 218 218 218 219 219 219 219 219 - 220 220 220 219 219 221 225 56 56 56 56 56 52 52 52 52 - 52 52 247 52 52 52 52 217 217 56 56 218 218 217 247 53 - 57 56 56 56 56 52 52 52 52 218 217 218 218 218 218 218 - 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 - 52 52 52 52 52 56 56 56 56 56 56 56 56 56 56 56 - 218 56 225 225 219 219 219 222 220 221 219 219 222 225 56 56 - 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 - 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 - 56 56 56 56 56 56 56 56 222 219 218 218 218 218 218 218 - 217 52 52 52 52 52 52 52 52 56 56 57 56 56 56 56 - 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 57 - 219 219 219 219 225 56 56 56 56 56 56 56 56 56 56 56 - 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 57 - 52 52 52 247 247 52 52 52 52 52 56 56 56 56 56 56 - 218 219 219 219 219 219 56 56 56 56 56 56 56 56 56 56 - 219 220 220 220 219 219 219 218 218 218 219 219 219 219 219 220 - 220 220 220 220 221 222 222 225 225 225 56 56 56 56 56 56 - 56 56 247 52 56 57 56 218 219 225 225 218 218 219 56 231 - 57 56 56 56 56 56 56 56 56 56 56 218 218 219 218 218 - 56 56 56 56 56 56 56 56 56 56 56 56 56 57 57 56 - 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 - 225 225 222 224 219 224 223 223 221 221 221 223 225 225 56 56 - 225 225 225 56 56 56 56 56 56 56 56 56 56 56 56 56 - 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 56 - 56 56 56 56 56 56 56 56 223 223 219 219 218 218 218 56 - 56 52 247 52 52 52 56 56 57 56 56 56 56 56 57 58 - 56 56 56 56 56 56 56 57 56 56 56 56 56 56 57 57 - 219 223 222 225 222 225 225 225 56 56 56 56 56 56 56 56 - 225 225 225 225 56 56 56 56 56 56 56 56 56 57 57 57 - 52 52 52 52 52 52 56 56 56 56 56 56 56 56 56 57 - 219 221 223 222 225 225 225 225 56 56 56 56 56 56 56 56 - 220 219 220 220 219 223 222 218 218 219 219 220 220 220 220 220 - 220 220 222 222 221 221 224 224 225 225 56 56 56 56 56 56 - 225 225 247 52 56 56 57 219 224 224 225 218 218 222 247 231 - 58 57 57 56 56 56 56 56 56 56 56 56 56 218 218 218 - 56 56 56 56 56 56 56 56 56 56 56 56 57 57 57 57 - 56 56 56 56 56 56 56 56 56 56 56 56 56 57 57 57 - 225 222 225 226 219 224 225 225 221 221 222 56 56 56 56 56 - 225 225 225 56 56 56 56 56 56 56 56 56 56 57 57 57 - 225 225 56 56 56 56 56 56 56 56 56 56 56 56 57 57 - 56 56 56 56 56 57 57 57 225 225 223 218 218 218 56 56 - 52 52 52 52 56 56 56 56 56 56 57 58 58 57 57 57 - 56 225 56 56 56 56 56 56 56 56 56 56 57 57 57 58 - 225 223 225 222 225 225 225 56 56 56 56 56 56 57 57 57 - 222 225 225 225 56 56 56 56 56 56 56 56 57 57 57 58 - 52 52 52 52 52 52 52 52 56 56 56 56 56 56 57 57 - 225 225 223 225 225 225 56 56 56 56 56 56 56 57 57 57 - 219 219 219 223 225 222 223 218 218 219 220 220 220 220 220 220 - 222 224 221 224 224 224 224 224 225 225 56 56 56 56 57 57 - 225 56 52 52 56 56 57 222 225 225 56 218 223 223 247 64 - 58 58 57 57 56 56 56 56 56 56 56 56 222 222 56 218 - 56 56 56 56 56 56 56 56 57 57 57 57 57 57 57 57 - 56 56 56 56 56 56 56 56 56 56 57 57 57 57 57 57 - 56 56 56 225 223 225 225 225 222 224 225 225 56 56 56 57 - 56 225 225 225 56 56 56 56 56 57 57 57 57 57 57 57 - 56 56 56 56 56 56 56 56 56 56 57 57 57 57 58 58 - 56 56 56 56 56 57 57 57 56 225 225 56 56 56 56 247 - 52 247 52 56 56 56 57 57 57 57 57 57 57 57 57 57 - 56 56 56 56 56 56 56 56 56 56 57 57 58 58 57 57 - 222 225 222 225 56 56 56 56 56 56 56 56 57 57 57 57 - 225 225 225 225 225 56 56 56 56 57 57 57 57 58 58 57 - 52 247 247 52 52 52 52 56 56 56 56 57 57 57 57 57 - 225 225 225 225 56 56 56 56 56 56 56 56 57 57 58 58 - 56 56 57 225 225 225 56 218 218 219 220 221 220 221 221 222 - 222 224 224 224 224 224 226 226 226 226 56 56 56 57 57 227 - 225 56 52 53 58 57 228 225 225 225 56 56 223 222 247 53 - 57 58 57 57 56 56 56 56 56 56 225 225 225 225 225 225 - 56 56 56 56 56 57 57 57 57 57 57 57 57 57 57 57 - 56 56 56 56 56 56 56 56 57 57 57 57 57 57 57 57 - 56 56 56 56 222 225 225 225 224 224 225 225 56 56 57 227 - 226 225 226 226 226 226 227 227 227 227 227 227 57 57 57 57 - 56 56 56 56 56 56 56 56 57 57 57 57 57 57 57 57 - 56 56 57 57 57 57 57 57 56 225 225 56 56 56 52 52 - 52 52 56 57 57 57 57 58 57 57 57 57 57 57 57 57 - 56 56 56 56 56 56 56 56 57 57 57 57 57 57 57 57 - 56 225 56 56 56 56 56 56 56 56 56 57 58 57 57 57 - 56 226 226 225 225 225 56 56 227 227 227 57 57 57 57 57 - 52 52 52 52 52 56 56 56 56 57 58 57 57 57 57 57 - 225 225 225 56 56 56 56 56 56 56 57 57 57 57 57 57 - 56 56 56 56 56 56 56 218 219 219 221 221 222 222 222 224 - 224 224 224 224 226 226 226 226 226 226 226 227 227 227 227 227 - 226 56 52 58 58 57 57 225 225 226 226 225 223 225 52 58 - 58 58 57 58 57 57 56 57 56 56 56 56 225 225 225 56 - 57 57 57 57 57 57 58 57 57 57 57 57 57 57 57 57 - 56 56 56 57 57 57 58 58 57 57 57 57 57 57 57 57 - 56 56 56 56 225 225 225 226 225 225 226 226 227 227 228 227 - 226 226 226 226 226 227 228 228 228 228 228 228 228 228 228 228 - 56 56 56 56 56 57 57 57 57 57 57 57 58 57 57 57 - 227 227 227 227 57 57 57 57 56 56 56 56 56 52 52 52 - 52 56 56 57 58 58 57 57 57 57 57 58 58 58 58 58 - 57 56 56 56 56 57 227 57 227 57 57 57 57 58 58 58 - 56 56 56 56 56 56 56 56 56 57 58 58 57 58 58 57 - 227 226 227 227 227 227 228 228 228 228 228 228 228 228 58 58 - 247 247 52 52 52 57 57 57 58 57 57 57 57 57 58 228 - 56 56 56 56 56 57 56 56 57 57 57 57 57 57 57 57 - 56 56 56 57 56 56 57 225 223 223 224 222 222 224 224 224 - 224 224 225 226 226 226 226 226 226 226 228 228 228 228 228 229 - 227 227 57 58 53 57 227 225 225 226 227 225 225 56 56 58 - 59 58 58 57 58 58 57 56 56 56 56 56 56 56 56 56 - 57 227 227 227 57 57 57 57 58 58 58 58 58 58 58 58 - 57 57 57 57 57 57 57 57 58 58 58 58 58 58 59 59 - 56 57 57 227 225 225 226 227 226 226 226 226 228 228 229 228 - 227 227 228 227 227 228 228 228 229 229 229 229 229 230 229 229 - 57 58 58 58 58 57 57 57 57 57 58 58 58 58 58 228 - 227 227 227 228 228 228 229 229 227 56 56 56 56 247 247 52 - 52 57 58 57 57 58 58 59 58 58 58 58 58 58 58 58 - 56 57 57 227 227 227 227 227 229 229 228 228 58 58 58 58 - 57 56 56 56 56 57 57 58 58 58 57 57 58 58 58 58 - 227 227 227 228 227 227 228 228 229 229 229 229 229 230 230 229 - 52 52 52 52 52 57 57 57 57 57 58 58 59 58 58 58 - 56 56 56 56 56 57 57 57 57 57 57 58 58 58 58 58 - 57 58 57 56 56 57 228 56 225 223 223 224 224 224 224 224 - 226 226 226 226 226 226 226 227 228 228 228 228 229 229 229 229 - 228 227 248 58 58 58 228 225 225 226 227 56 56 56 52 58 - 68 59 249 58 58 57 57 58 57 57 52 52 52 52 52 52 - 228 228 229 229 230 230 230 230 230 230 230 230 230 230 230 230 - 57 57 57 58 58 58 58 58 58 58 58 58 58 58 58 58 - 57 227 227 227 56 227 227 228 226 226 226 228 228 229 230 229 - 228 228 228 229 229 228 228 229 229 229 229 229 229 230 230 230 - 57 58 57 57 57 57 57 58 58 231 231 230 230 230 230 230 - 229 229 229 229 229 230 230 230 227 56 56 56 52 247 52 52 - 52 53 53 53 58 59 59 58 59 59 58 58 58 249 249 249 - 57 227 57 227 228 229 229 229 230 230 230 230 230 230 230 230 - 56 56 57 58 57 58 57 57 57 57 59 59 58 58 59 230 - 227 227 228 229 229 228 229 229 229 229 229 230 230 230 230 230 - 248 52 53 53 58 249 59 59 59 58 58 58 58 249 249 67 - 56 57 57 57 57 58 58 57 58 58 58 58 58 249 230 230 - 57 57 57 58 57 57 57 56 56 222 223 224 224 224 226 226 - 226 226 226 226 226 227 228 228 229 228 228 229 229 229 230 230 - 227 228 231 249 249 58 230 56 227 228 228 56 56 56 52 53 - 67 68 68 249 249 58 249 58 53 53 53 52 52 52 52 247 - 230 230 229 229 229 232 232 232 233 233 233 233 233 233 234 234 - 249 249 249 249 58 58 249 249 58 249 66 234 234 234 68 234 - 248 227 229 229 227 227 229 229 226 228 227 229 229 229 230 230 - 229 228 229 229 229 229 229 230 230 230 230 230 230 230 233 233 - 57 58 58 249 230 230 230 230 232 232 233 233 233 233 233 233 - 229 229 229 230 230 233 233 233 227 57 56 52 52 52 52 52 - 248 53 249 249 58 58 59 59 60 60 250 250 67 68 236 236 - 248 231 230 230 230 232 231 230 232 232 233 233 233 234 234 234 - 57 57 58 57 57 57 58 58 58 58 249 58 249 234 234 234 - 231 228 229 229 229 229 229 230 229 230 230 233 233 233 234 234 - 248 160 64 64 64 64 64 249 249 249 66 67 67 67 67 67 - 57 57 57 57 58 58 58 59 58 58 249 249 249 233 234 234 - 58 58 57 57 58 57 58 52 56 56 225 225 226 226 226 226 - 226 226 226 226 228 228 228 229 228 229 229 229 230 230 230 233 - 229 231 64 249 67 68 234 56 228 229 229 56 56 57 53 53 - 236 235 67 67 67 249 249 249 249 249 58 53 248 248 52 248 - 232 231 232 232 233 233 233 233 234 234 234 234 234 234 234 234 - 64 249 249 249 249 66 66 233 233 234 234 234 234 235 235 234 - 231 231 231 230 228 229 229 229 227 228 229 229 230 229 233 233 - 229 229 229 229 230 230 230 230 230 233 234 234 234 234 234 234 - 249 66 249 249 249 233 233 234 233 233 233 233 233 233 234 234 - 231 230 232 233 233 234 234 234 231 227 248 248 248 248 53 160 - 249 249 64 249 250 250 250 250 250 250 250 250 67 68 68 68 - 66 233 232 231 232 232 233 233 233 233 233 233 234 234 234 234 - 248 53 58 58 58 249 249 249 64 249 234 234 233 234 234 234 - 232 229 230 230 230 230 230 230 230 233 233 234 234 234 234 69 - 160 160 64 64 64 64 64 249 249 66 235 67 235 235 234 234 - 53 53 53 58 59 58 58 58 58 249 67 234 234 234 234 236 - 58 58 59 58 59 59 59 247 52 56 56 225 226 226 226 226 - 226 226 228 228 228 228 229 229 229 230 230 230 230 233 234 234 - 231 231 65 66 69 68 234 227 229 229 230 248 57 58 249 104 - 234 69 234 235 66 68 66 64 64 64 64 64 53 248 248 248 - 233 233 233 234 234 234 234 234 234 234 235 234 68 68 69 69 - 249 65 65 66 66 233 234 234 234 234 234 234 235 234 69 236 - 232 233 233 233 231 229 230 230 228 228 229 230 230 230 234 234 - 230 230 230 230 230 233 233 233 233 233 234 234 234 234 234 234 - 65 233 233 233 234 234 233 233 234 234 234 234 234 234 234 234 - 233 233 234 234 234 234 234 234 232 232 231 248 248 248 160 104 - 160 64 249 250 250 250 250 250 250 250 250 68 69 236 236 236 - 64 65 66 233 233 233 233 234 233 234 234 234 234 234 69 236 - 249 64 249 249 64 249 249 65 234 66 65 234 234 234 234 234 - 232 230 230 230 233 233 234 234 233 234 234 234 234 234 69 69 - 64 64 64 64 64 64 65 65 65 66 235 235 235 235 234 234 - 249 58 58 58 59 58 249 249 67 67 68 234 235 234 234 236 - 58 58 58 59 58 53 249 52 52 52 56 56 225 226 226 228 - 228 228 228 229 229 229 229 230 230 230 230 233 234 234 234 234 - 232 231 64 162 69 68 234 248 230 230 233 248 58 249 249 160 - 236 236 69 69 67 68 66 66 249 64 160 64 64 160 248 248 - 234 234 234 234 234 234 234 234 236 69 69 236 236 70 70 70 - 65 66 66 67 235 235 235 235 235 234 234 69 69 69 69 69 - 65 66 233 234 232 230 233 233 231 230 232 233 233 234 234 234 - 233 230 233 234 234 233 234 234 234 234 234 234 234 69 236 236 - 233 233 233 233 233 234 234 234 235 234 234 69 69 69 236 70 - 234 234 234 234 68 69 236 70 65 65 64 248 248 160 104 104 - 65 249 249 250 250 165 165 165 166 166 236 70 70 70 70 236 - 66 65 66 235 233 234 234 233 234 234 234 69 69 236 236 70 - 64 64 249 249 249 66 66 67 66 68 235 234 234 234 236 234 - 232 233 233 233 233 234 234 233 234 234 234 234 69 236 70 70 - 160 161 162 162 162 66 66 66 67 67 235 69 69 68 234 236 - 64 249 249 249 250 250 250 250 68 68 69 69 69 236 236 70 - 250 60 59 58 58 250 250 248 52 52 57 227 228 228 227 228 - 228 229 229 229 229 230 230 230 230 233 234 234 234 234 236 236 - 233 66 66 164 69 68 70 231 230 230 234 248 64 249 250 160 - 70 70 70 236 69 68 67 250 250 249 249 64 64 104 160 248 - 235 234 234 234 234 234 69 236 236 236 236 236 70 70 70 70 - 250 250 250 67 68 68 69 236 69 69 236 236 70 70 70 70 - 67 235 235 234 232 233 233 233 231 230 233 233 234 234 69 236 - 233 233 234 234 234 234 234 234 236 236 236 70 70 236 70 70 - 66 233 234 234 234 234 234 234 234 69 236 236 70 70 70 71 - 68 69 236 236 70 70 70 70 66 65 64 64 160 160 161 161 - 162 162 250 165 165 166 166 166 237 237 70 70 70 70 70 70 - 66 235 235 235 235 234 234 234 69 69 236 70 70 70 70 71 - 249 249 250 250 250 66 67 68 68 68 69 69 236 70 70 70 - 233 233 233 234 234 234 234 234 234 234 236 236 70 70 70 70 - 162 162 162 163 163 250 250 250 67 68 69 236 70 70 70 70 - 64 249 250 67 250 250 250 250 68 69 69 236 236 70 70 70 - 250 60 60 60 60 250 250 248 53 53 57 227 227 228 228 228 - 229 229 229 229 230 230 230 233 233 234 234 234 236 236 236 236 - 233 65 66 164 70 70 70 232 233 233 234 248 64 249 250 160 - 71 71 70 70 70 69 68 250 250 250 162 162 161 160 160 248 - 69 69 69 236 236 236 236 70 70 70 70 70 70 70 70 237 - 164 165 165 165 69 69 236 236 70 70 70 70 237 71 71 71 - 67 235 68 68 65 233 234 234 232 233 233 234 234 69 236 70 - 234 234 234 234 234 234 236 236 236 236 236 70 70 70 237 70 - 235 235 235 234 234 69 69 69 236 70 70 70 70 71 71 71 - 236 236 70 70 70 70 70 71 67 66 64 64 160 161 161 162 - 163 163 164 165 166 166 167 167 167 237 237 237 237 71 71 71 - 235 235 235 234 234 234 69 236 236 70 70 70 70 71 71 71 - 250 250 250 250 250 250 68 68 69 69 236 70 70 70 237 71 - 235 234 234 234 234 236 236 236 236 70 70 70 70 237 71 72 - 162 163 163 164 164 165 165 165 165 236 70 70 70 71 71 70 - 249 250 250 250 250 250 250 68 236 236 70 70 70 70 70 71 - 60 60 60 59 250 250 250 53 104 53 53 57 227 228 229 230 - 229 230 230 230 233 233 233 234 234 234 234 234 236 70 70 71 - 234 66 164 166 70 70 70 65 233 233 234 64 64 249 68 160 - 73 72 71 237 70 70 69 165 164 250 163 162 161 161 160 160 - 236 70 70 70 70 70 70 237 70 237 71 71 71 71 71 71 - 166 166 166 166 166 70 70 70 70 237 237 71 71 71 71 71 - 67 68 69 69 66 235 234 234 233 233 234 234 69 236 70 71 - 234 234 236 236 236 236 70 70 71 70 70 71 71 71 71 71 - 69 68 69 69 70 70 70 70 70 70 71 71 71 71 71 71 - 70 236 70 70 70 237 71 71 67 66 64 64 104 161 162 162 - 164 164 165 166 166 167 168 168 168 168 72 72 71 71 72 72 - 235 235 234 69 69 236 236 70 70 70 70 237 71 71 73 73 - 250 250 250 164 164 165 69 69 69 70 237 237 71 71 71 71 - 68 69 69 236 236 70 70 70 70 70 237 237 71 72 73 74 - 163 164 164 164 165 165 166 166 166 237 237 237 237 71 71 71 - 250 250 250 250 250 250 69 236 70 70 70 237 237 71 71 72 - 60 61 60 60 60 96 165 160 160 249 249 58 229 229 230 229 - 230 230 230 230 233 234 234 234 234 234 236 236 70 71 71 71 - 68 67 165 166 237 71 71 65 66 234 69 64 249 250 164 160 - 74 73 72 237 237 237 166 166 165 164 163 163 162 162 161 160 - 70 237 237 71 71 71 71 71 71 71 72 73 73 73 74 74 - 166 166 166 167 237 237 237 237 237 237 71 71 72 73 73 73 - 68 69 69 70 67 68 69 236 235 234 235 69 70 70 71 71 - 68 69 236 70 70 70 71 71 71 71 72 73 73 73 73 73 - 166 236 70 70 237 237 237 237 237 71 71 72 72 73 73 73 - 70 70 70 71 71 71 71 72 68 66 162 161 161 162 162 163 - 164 165 166 167 167 168 168 169 169 169 238 238 74 74 74 75 - 69 69 69 236 236 70 70 70 70 237 71 71 73 73 74 75 - 164 164 164 164 165 165 166 166 166 237 237 71 71 72 73 73 - 236 236 70 70 70 70 70 237 71 71 71 73 73 74 74 75 - 164 165 165 165 165 166 166 167 167 168 237 237 71 73 73 73 - 250 164 165 165 165 166 70 237 237 237 71 71 71 72 73 74 - 61 61 61 60 60 165 166 160 104 104 249 58 58 58 230 230 - 233 233 233 234 234 234 234 236 236 236 70 70 71 71 71 71 - 236 68 165 167 72 73 72 65 68 69 70 161 162 163 165 160 - 75 75 73 238 168 168 167 167 165 165 164 164 163 162 161 161 - 237 237 71 71 71 72 72 73 73 73 74 74 75 75 75 75 - 167 167 167 167 168 168 168 238 238 238 238 73 74 74 75 75 - 166 166 237 237 68 69 70 70 68 68 69 70 71 72 73 73 - 236 236 70 70 71 71 71 71 71 73 73 74 75 75 75 75 - 167 167 167 167 237 237 237 71 72 72 73 74 74 75 75 75 - 71 71 71 72 73 73 74 75 166 165 164 162 162 131 132 133 - 134 135 88 90 137 137 137 137 170 170 170 239 75 75 76 75 - 70 70 70 70 70 237 237 71 72 73 74 74 75 75 75 75 - 164 165 165 166 166 166 166 167 237 237 238 238 238 74 75 75 - 70 70 70 237 71 71 71 71 71 73 73 75 75 75 75 75 - 134 134 135 135 135 167 167 168 168 168 238 238 238 74 75 75 - 165 165 166 166 166 167 167 168 72 238 73 73 74 74 75 76 - 17 203 61 61 61 61 167 104 80 104 54 58 59 58 250 236 - 234 234 234 234 234 236 236 236 70 71 71 71 71 73 73 74 - 237 166 166 167 239 75 75 163 236 70 71 162 163 164 166 160 - 76 76 75 239 169 169 168 168 167 166 165 164 164 163 131 80 - 238 238 238 238 238 238 74 74 75 75 75 75 75 75 76 76 - 168 168 168 168 169 169 169 239 239 239 239 239 75 75 75 75 - 168 167 168 238 166 70 237 71 68 236 70 71 73 74 74 75 - 237 237 71 71 71 72 73 73 73 74 75 75 75 75 75 76 - 168 168 169 169 168 169 238 238 238 239 74 75 75 75 76 76 - 238 73 73 74 75 75 75 75 166 166 165 163 131 132 133 134 - 135 40 136 137 138 138 138 138 171 171 171 171 77 77 77 77 - 168 237 237 237 237 72 238 238 74 74 75 75 76 76 76 76 - 165 166 167 167 167 167 168 168 168 169 238 238 239 75 76 76 - 237 70 237 71 72 73 73 74 74 74 75 75 75 75 76 76 - 134 134 135 135 136 136 136 137 169 169 170 170 239 75 76 76 - 166 166 98 98 87 168 169 169 238 238 74 75 75 75 76 77 - 204 204 204 61 61 61 168 49 80 80 55 60 60 59 250 68 - 68 234 236 236 236 70 70 70 71 71 72 73 73 75 75 75 - 72 167 135 136 239 76 75 163 166 237 238 163 164 166 167 160 - 78 77 76 171 171 170 137 137 89 88 135 134 133 132 132 131 - 170 239 239 239 239 75 75 76 76 76 76 76 77 77 77 77 - 169 169 169 170 170 170 171 171 171 171 171 171 76 76 76 76 - 168 169 169 239 61 168 238 73 165 70 237 238 74 75 76 77 - 238 73 73 73 74 74 75 75 76 75 76 76 77 76 76 77 - 169 169 169 170 170 239 239 239 239 239 76 76 76 77 77 77 - 239 239 75 75 76 76 77 77 168 167 165 132 132 133 38 38 - 39 3 92 93 29 94 94 94 139 172 172 172 173 78 78 78 - 169 169 169 169 239 239 239 239 239 239 76 76 77 77 78 78 - 86 87 90 90 90 169 169 169 170 170 170 171 76 76 77 77 - 168 71 238 238 238 74 75 75 75 75 76 76 76 77 78 78 - 39 39 39 244 244 137 137 138 138 138 171 171 171 172 77 78 - 86 86 88 87 21 62 62 239 239 239 239 75 76 76 77 77 - 205 205 204 204 61 168 168 49 80 51 55 60 55 60 60 60 - 236 69 70 71 237 71 72 71 73 73 74 75 75 76 76 76 - 73 168 136 136 170 76 76 164 166 168 239 82 165 167 167 160 - 78 77 76 76 171 170 170 169 136 88 135 135 134 133 133 132 - 239 75 75 75 75 76 76 76 76 76 77 77 77 77 77 77 - 170 170 170 170 170 170 171 76 76 76 76 76 76 77 77 77 - 168 169 239 75 61 237 238 74 70 70 72 73 74 75 76 76 - 73 72 73 73 74 75 75 75 75 75 76 76 77 77 77 77 - 169 169 169 239 239 75 75 239 75 76 76 76 76 77 77 77 - 239 75 75 76 76 76 77 77 168 167 166 133 133 134 135 135 - 136 244 244 138 138 138 139 139 139 172 172 78 77 78 78 78 - 169 238 238 74 74 75 75 75 76 76 76 76 77 77 78 78 - 167 87 168 168 169 169 169 169 239 239 75 76 76 76 77 76 - 73 73 73 73 73 74 75 75 75 76 76 77 77 78 78 78 - 136 244 244 244 137 137 137 137 138 139 139 171 171 77 77 78 - 167 168 168 169 169 62 62 239 75 75 75 75 76 76 77 78 - 23 205 204 61 62 238 238 80 81 96 60 60 60 61 61 70 - 236 69 70 71 71 71 71 71 71 71 74 75 75 76 76 76 - 73 237 169 137 239 76 76 166 167 238 74 163 165 167 168 160 - 70 70 166 164 163 163 163 163 162 162 255 255 128 128 253 105 - 163 250 163 164 164 164 164 165 165 165 165 165 165 166 166 166 - 131 131 131 162 163 164 164 163 165 165 165 165 165 165 165 164 - 162 164 164 163 104 161 162 250 64 249 64 249 250 68 164 68 - 66 65 65 66 66 65 66 66 68 164 164 165 69 69 236 236 - 250 163 163 163 163 164 164 163 164 164 165 165 165 164 165 166 - 163 163 66 69 165 164 164 166 164 161 160 160 105 128 128 130 - 129 130 129 131 131 131 131 131 132 133 133 165 166 167 167 70 - 66 66 65 66 164 164 164 163 165 165 165 165 165 166 166 166 - 162 162 162 162 162 163 164 164 164 163 164 69 69 164 165 69 - 66 66 65 66 65 67 163 163 165 165 165 165 165 166 166 166 - 129 130 129 129 129 131 132 130 130 131 132 164 164 164 166 237 - 162 163 163 162 162 164 164 250 164 164 164 164 165 165 165 166 - 104 55 59 249 162 163 163 105 105 53 52 52 53 53 53 53 - 248 64 65 66 65 65 65 65 65 65 65 66 235 68 68 69 - 235 161 164 161 164 165 164 160 66 67 250 105 162 161 161 160 - 161 162 255 255 255 255 160 128 128 105 105 105 106 106 106 106 - 255 161 160 160 255 255 255 255 255 255 255 255 255 162 162 130 - 131 131 130 129 129 255 255 255 255 255 255 255 255 255 255 255 - 105 160 255 255 160 160 160 161 160 104 160 160 160 161 161 162 - 160 248 64 64 64 64 161 161 161 161 161 161 162 162 162 162 - 160 160 161 161 160 160 255 161 255 255 255 255 255 255 162 162 - 161 161 160 160 255 255 255 162 105 105 105 105 105 253 106 253 - 131 182 180 181 181 180 180 180 180 130 130 130 255 255 162 162 - 160 160 160 160 160 160 160 255 255 255 255 255 255 162 162 162 - 105 105 105 105 105 160 160 160 161 160 160 160 255 161 162 162 - 248 160 160 160 160 160 160 161 255 255 255 162 162 162 162 131 - 130 181 181 182 181 181 182 180 181 131 131 131 255 255 255 161 - 105 160 160 160 160 255 255 255 160 255 255 255 161 162 162 162 - 104 161 104 104 160 255 255 106 105 105 53 53 248 248 160 160 - 248 248 160 248 64 64 64 64 64 64 64 64 64 162 162 163 - 160 162 160 162 255 160 162 105 105 160 160 105 105 105 160 160 - 183 183 182 182 182 182 181 180 180 180 180 180 178 177 176 176 - 180 181 182 182 182 182 182 181 182 182 182 182 183 183 183 182 - 179 179 180 181 181 181 181 182 182 182 182 182 182 182 182 182 - 180 129 130 130 129 130 130 131 128 128 131 132 132 131 132 132 - 162 162 162 162 162 162 131 131 181 181 181 182 182 182 182 182 - 181 182 181 181 182 182 181 181 182 182 182 182 182 182 182 182 - 180 131 132 131 182 183 183 183 183 182 180 177 177 177 178 180 - 179 241 241 241 241 241 241 241 181 182 182 182 182 182 183 183 - 131 131 131 131 131 182 182 181 182 182 182 182 182 183 182 182 - 180 180 180 180 180 181 181 182 181 182 183 182 182 182 183 183 - 131 161 162 131 131 131 131 182 182 182 182 183 182 182 182 182 - 180 241 179 179 241 241 241 241 241 241 241 181 182 182 183 183 - 180 180 180 180 180 180 180 180 182 182 182 182 183 183 182 183 - 129 130 129 130 129 180 180 177 9 106 106 105 105 105 105 105 - 160 161 164 164 162 65 65 65 65 164 163 162 132 131 182 183 - 131 129 182 180 181 183 131 131 131 131 131 106 128 128 130 105 - 186 186 186 186 186 185 183 181 181 181 181 181 181 181 181 181 - 183 185 186 186 186 186 186 186 185 186 186 186 186 186 186 185 - 180 181 183 184 186 186 186 186 186 186 186 186 186 186 186 186 - 181 182 182 182 32 34 35 35 130 129 130 129 130 34 186 188 - 131 131 130 129 130 133 186 187 186 186 186 186 186 186 186 186 - 181 182 181 182 186 187 186 186 186 186 186 186 187 187 186 186 - 182 184 186 186 186 186 186 186 180 180 181 180 181 181 180 181 - 180 180 181 184 185 184 184 184 184 184 185 186 186 186 186 186 - 181 181 181 183 185 187 186 186 186 186 186 186 186 186 186 186 - 181 181 181 182 182 181 181 182 182 184 186 186 186 186 186 186 - 181 180 180 182 184 186 186 185 186 186 186 186 186 186 186 186 - 180 180 180 180 181 181 184 186 185 185 185 186 186 186 186 186 - 181 181 181 182 182 182 182 182 186 186 186 186 186 186 186 187 - 4 38 36 6 33 182 183 180 181 8 8 128 128 129 130 255 - 128 129 255 255 161 162 162 162 163 163 132 134 186 186 186 187 - 182 136 180 186 185 186 186 181 182 181 181 181 182 182 131 129 - 187 186 186 186 185 185 184 183 183 183 182 182 181 181 181 180 - 184 185 185 184 184 185 185 186 186 186 186 186 186 186 186 186 - 183 183 183 184 184 185 185 186 185 185 185 185 186 186 186 186 - 184 184 185 185 35 38 39 39 152 151 134 135 136 41 187 187 - 135 136 137 137 137 244 244 186 186 186 186 186 186 186 186 186 - 183 185 184 184 185 185 184 185 185 185 185 186 186 186 186 186 - 185 185 186 186 186 187 187 186 183 182 182 180 180 181 180 182 - 182 182 183 118 120 118 117 117 118 120 120 121 187 187 187 187 - 183 183 184 184 184 184 184 184 185 185 185 186 186 186 186 187 - 183 182 183 184 184 183 183 184 184 185 185 186 186 121 187 186 - 184 184 184 184 185 185 186 186 186 186 186 186 186 187 187 187 - 183 183 183 183 182 182 183 183 184 184 184 185 186 186 187 187 - 183 182 183 183 183 183 184 184 184 185 185 185 186 186 186 187 - 5 202 202 203 4 185 184 179 8 8 7 150 149 150 50 50 - 82 83 96 96 165 166 167 167 167 167 136 244 186 186 186 186 - 184 185 184 184 187 186 186 180 182 183 244 8 182 33 38 8 - 189 188 187 187 186 186 186 186 184 184 184 184 183 35 33 32 - 187 187 187 244 187 188 188 188 188 188 188 188 188 188 188 188 - 187 186 186 186 186 186 187 187 187 187 188 188 188 188 125 189 - 4 41 244 92 38 154 91 23 18 17 86 99 23 26 139 139 - 136 137 137 137 137 137 138 139 94 188 188 188 188 189 189 189 - 4 244 244 244 244 244 186 188 187 188 188 188 188 188 189 189 - 244 43 137 138 188 188 188 189 4 37 37 35 34 183 183 183 - 184 185 185 122 124 123 123 123 124 124 124 125 125 189 126 189 - 185 244 244 244 244 244 244 187 188 188 188 188 188 188 189 126 - 184 5 184 185 185 185 186 187 187 187 187 187 187 188 188 189 - 185 244 244 244 244 244 187 188 188 188 188 188 189 189 189 189 - 184 184 185 186 185 186 187 186 187 187 187 187 188 188 125 126 - 4 4 4 244 244 244 244 187 187 188 188 188 125 125 125 127 - 204 204 203 202 202 41 244 32 7 149 150 151 152 152 16 16 - 55 61 61 61 61 61 72 168 169 170 170 138 188 188 188 189 - 137 137 185 186 186 188 188 37 135 135 135 34 35 38 135 149 - 173 173 172 172 171 170 137 136 137 88 134 84 133 84 152 151 - 62 62 239 239 76 76 75 76 76 77 77 77 77 78 78 77 - 23 100 24 26 246 246 246 246 246 246 139 172 172 140 140 172 - 136 136 137 169 84 88 169 169 97 61 166 168 238 239 75 77 - 238 238 74 74 74 74 75 75 75 75 75 75 76 76 76 76 - 169 169 169 62 170 170 170 171 171 171 171 171 172 77 77 77 - 62 239 75 76 76 77 77 78 169 84 84 84 37 37 38 38 - 40 155 42 26 28 157 172 139 139 172 173 172 172 173 78 78 - 90 168 168 169 169 170 170 170 239 171 76 77 173 172 173 78 - 135 88 136 90 90 87 90 90 169 246 171 63 171 171 77 77 - 169 169 169 239 239 75 239 239 239 75 76 76 76 76 77 78 - 244 186 244 244 137 137 138 137 138 138 246 245 63 173 173 173 - 85 18 20 21 21 22 23 62 62 245 245 63 77 77 77 173 - 205 205 204 204 21 62 23 150 150 50 50 55 55 60 16 61 - 61 61 60 60 61 73 73 238 238 238 74 74 75 76 76 77 - 168 88 137 138 103 63 78 84 98 238 74 50 85 85 87 48 - 254 48 253 253 106 106 253 253 106 252 252 252 252 252 252 251 - 105 105 105 105 105 105 105 48 48 48 48 48 48 48 48 48 - 144 253 253 144 144 253 253 106 106 253 253 253 146 146 146 48 - 105 106 105 105 252 106 105 105 252 247 247 105 105 105 105 48 - 105 105 105 105 105 105 248 248 160 160 160 160 160 160 53 53 - 105 105 105 105 105 105 105 105 105 105 105 48 48 48 48 48 - 105 105 105 105 105 48 48 48 105 252 252 252 252 252 252 252 - 252 106 144 144 144 106 144 106 253 253 146 128 253 128 48 254 - 105 105 105 105 105 105 105 105 105 105 105 48 48 48 48 254 - 252 252 106 105 105 105 105 105 105 105 105 105 253 253 48 48 - 105 105 247 105 105 105 105 105 105 105 160 160 160 160 160 254 - 252 107 252 106 253 106 253 253 253 106 106 253 253 146 146 48 - 252 106 106 105 105 105 105 105 105 253 253 253 48 48 48 48 - 144 193 144 144 144 144 144 251 251 252 247 247 247 247 247 52 - 52 52 52 247 247 105 105 105 105 105 105 105 160 104 53 53 - 105 106 106 253 144 48 48 252 252 247 52 252 252 251 105 48 - 81 81 81 80 49 254 48 253 105 106 106 105 105 106 252 252 - 104 249 249 104 104 104 104 104 104 249 249 249 249 249 249 162 - 105 105 105 48 160 255 255 129 255 255 254 80 80 80 80 80 - 105 248 248 160 247 248 248 248 248 248 248 248 53 249 249 249 - 160 160 160 104 64 104 104 104 104 161 162 162 162 162 81 163 - 160 160 160 160 160 160 104 104 104 104 104 104 161 162 162 162 - 160 104 64 160 104 161 162 162 105 247 105 106 106 106 106 106 - 106 253 253 128 129 128 129 254 254 254 254 254 80 81 81 81 - 160 160 248 248 160 104 161 161 161 161 161 162 162 162 162 163 - 105 105 105 105 48 48 48 48 48 48 254 254 254 49 80 81 - 105 248 160 160 160 104 104 104 160 161 162 162 162 162 162 163 - 106 106 106 105 105 128 160 160 255 255 255 255 255 130 130 81 - 105 105 105 105 48 105 105 48 48 104 49 48 48 49 81 51 - 195 196 214 48 53 53 52 106 252 247 247 247 52 56 247 52 - 56 56 52 52 53 248 53 248 64 64 64 64 249 249 249 249 - 160 105 128 130 80 81 54 105 248 53 249 247 105 105 160 104 - 97 96 82 81 80 80 49 254 254 48 253 253 253 105 106 105 - 163 250 250 250 250 250 250 250 250 250 250 250 250 68 165 165 - 80 80 80 80 81 81 81 81 81 81 81 82 82 82 96 96 - 104 249 249 249 53 53 104 249 248 58 249 249 249 250 250 250 - 161 249 249 249 162 250 250 250 250 250 250 250 96 96 165 165 - 104 104 161 162 162 162 162 162 250 250 250 250 250 250 164 250 - 250 66 66 66 250 164 164 164 104 160 160 105 105 253 253 128 - 128 128 129 130 131 130 131 82 82 82 82 83 83 83 84 96 - 161 162 162 249 249 249 65 65 250 250 250 250 164 164 165 96 - 48 48 48 48 49 49 49 49 49 80 50 81 81 82 83 83 - 161 64 249 249 249 250 250 250 250 250 250 250 164 164 165 165 - 254 128 128 254 80 162 162 255 162 163 163 163 132 133 133 165 - 105 105 48 48 104 49 49 49 49 54 96 51 51 96 97 97 - 214 214 214 214 54 54 54 105 52 247 247 247 56 56 56 57 - 57 57 57 58 58 249 249 249 64 65 66 66 250 250 67 67 - 162 161 130 132 80 82 96 160 249 249 249 105 160 160 104 104 - 62 61 18 17 17 83 83 82 150 149 254 254 254 253 253 253 - 165 165 96 96 165 165 166 165 166 166 166 166 166 61 61 167 - 82 82 82 82 82 132 83 84 85 85 98 98 19 19 61 61 - 51 96 163 96 54 55 250 250 54 59 54 250 60 60 61 166 - 163 164 164 163 164 164 165 70 70 70 61 61 61 61 61 61 - 163 250 96 96 165 165 165 165 165 165 166 166 166 166 61 61 - 96 250 164 165 166 166 166 61 163 162 104 48 253 147 148 149 - 150 150 151 152 153 153 85 86 153 17 17 18 19 61 61 61 - 51 96 96 96 164 164 165 165 165 166 166 166 166 61 168 61 - 49 54 54 51 51 51 51 51 51 83 97 98 98 98 87 168 - 96 250 250 250 250 164 165 96 237 237 166 166 61 61 61 61 - 130 131 132 132 132 132 83 133 133 133 134 135 135 135 86 88 - 80 81 51 51 96 51 51 51 96 97 61 61 97 61 61 61 - 50 54 55 55 55 51 81 105 105 105 53 53 58 58 57 59 - 59 58 58 64 66 67 67 250 250 68 69 236 70 237 237 237 - 164 163 132 135 85 86 167 255 161 165 165 105 160 255 162 104 - 144 144 144 144 106 252 107 107 107 251 251 251 14 215 215 215 - 252 252 252 252 106 106 253 253 106 144 144 144 144 253 253 144 - 252 252 252 252 252 252 252 106 106 106 106 106 106 144 144 144 - 252 252 251 252 251 252 252 252 252 252 252 252 106 106 106 253 - 252 252 252 252 252 252 252 106 105 105 105 144 144 144 144 144 - 252 252 252 252 252 252 252 252 106 106 106 106 144 144 253 253 - 252 252 252 106 106 144 144 253 252 251 251 216 215 14 13 13 - 13 12 12 107 11 11 11 11 10 10 10 144 144 144 144 144 - 252 252 252 252 252 252 252 252 252 106 106 106 106 144 144 144 - 251 251 251 252 252 252 252 252 252 252 252 106 106 106 144 144 - 252 252 252 252 252 252 252 252 106 106 144 144 144 144 144 144 - 13 13 13 13 107 107 107 107 107 252 11 106 106 106 144 144 - 251 251 251 252 252 252 252 252 252 252 106 106 106 144 144 144 - 144 252 144 252 252 252 252 215 215 216 216 216 216 217 217 218 - 247 247 247 247 247 252 247 247 252 252 252 252 106 105 105 106 - 252 251 107 10 11 106 106 251 251 252 252 216 251 251 252 48 - 147 146 145 145 144 144 144 144 106 252 107 107 107 251 251 251 - 144 144 106 106 144 253 253 253 253 253 253 253 253 253 146 146 - 144 10 144 144 144 144 144 144 144 145 145 145 145 145 146 146 - 144 144 144 144 252 144 144 144 252 106 144 144 106 144 145 146 - 253 106 106 105 253 106 253 253 48 48 48 48 48 147 147 147 - 144 144 144 144 144 144 144 144 144 144 144 145 145 146 146 146 - 144 144 144 144 253 146 146 146 106 252 252 251 13 12 12 11 - 11 10 10 10 10 9 9 9 8 8 8 8 8 8 147 147 - 144 144 144 144 144 144 144 144 144 144 145 146 146 146 146 147 - 107 252 106 106 144 144 144 144 144 144 145 145 145 146 146 146 - 144 106 106 106 106 144 106 106 253 146 147 147 147 147 147 147 - 12 11 10 10 11 10 10 9 10 9 9 9 146 146 147 147 - 107 252 11 144 144 144 144 144 144 145 145 145 145 146 147 147 - 194 192 193 192 192 144 144 251 251 251 252 252 247 247 247 247 - 52 247 247 247 247 247 247 247 105 105 106 105 253 128 128 128 - 253 106 9 8 9 9 9 252 107 106 106 251 107 252 253 254 - 50 49 254 148 147 253 253 253 144 144 106 106 106 106 252 251 - 128 48 48 48 48 148 147 147 148 149 149 149 149 149 150 150 - 145 145 146 146 146 147 147 147 147 148 148 148 148 148 149 149 - 253 253 48 146 144 144 253 48 106 144 253 48 48 48 148 254 - 253 48 253 253 128 128 48 48 49 49 49 49 254 254 130 130 - 253 146 48 48 48 48 147 147 147 147 147 148 149 150 150 149 - 147 48 48 48 148 149 150 149 253 106 106 252 252 11 10 10 - 10 9 9 8 8 8 8 8 7 7 7 7 7 149 149 150 - 253 253 48 48 48 146 48 147 147 147 147 254 149 149 149 150 - 106 106 144 253 253 253 253 146 146 147 48 148 148 149 149 49 - 48 48 48 48 48 48 254 254 48 254 254 254 254 49 80 131 - 10 10 10 9 9 8 8 9 8 8 8 148 148 149 149 149 - 144 144 144 145 145 145 146 146 147 147 148 148 148 149 149 149 - 195 194 194 193 145 146 146 107 251 251 252 252 247 52 247 247 - 247 52 52 52 248 248 160 160 160 160 160 255 254 254 130 130 - 128 128 128 8 8 7 129 106 106 253 253 106 106 106 106 48 - 82 82 82 81 80 254 254 48 48 253 253 105 105 105 106 106 - 254 80 80 80 81 81 82 81 81 82 82 82 82 83 83 83 - 48 48 254 254 49 80 80 80 80 81 81 80 81 82 82 81 - 48 104 80 255 48 48 255 255 105 105 105 255 80 80 130 81 - 255 162 162 255 162 163 81 81 82 96 96 51 81 163 163 164 - 48 48 254 255 80 80 80 80 80 80 81 81 82 83 83 83 - 80 80 80 80 81 82 83 83 160 105 105 106 106 253 253 253 - 128 128 129 254 130 131 131 131 131 131 131 131 82 82 83 83 - 48 104 80 80 80 80 80 81 81 81 82 82 82 83 83 83 - 128 128 48 48 48 48 254 254 49 80 80 80 81 81 82 82 - 255 255 255 255 80 80 80 80 81 81 82 81 163 163 164 164 - 253 128 128 129 128 128 129 129 130 130 131 131 131 81 82 82 - 253 253 253 48 48 254 254 49 49 80 80 81 82 83 84 97 - 148 147 147 48 48 48 48 106 106 106 106 247 52 53 248 248 - 52 52 52 53 104 104 104 104 162 162 163 163 163 81 131 132 - 255 255 128 129 131 83 82 105 48 49 49 106 106 253 160 104 - 160 160 160 160 160 160 104 48 48 48 160 160 160 160 160 160 - 160 104 104 160 160 160 104 104 104 104 48 48 48 254 254 48 - 160 104 104 104 160 160 160 160 160 160 160 160 160 160 160 160 - 160 160 160 160 160 160 104 160 160 104 160 160 160 160 160 160 - 160 160 160 160 160 160 160 104 48 48 104 104 160 160 160 160 - 160 160 160 160 160 160 160 160 160 160 104 160 48 48 48 104 - 48 160 160 104 104 48 48 104 160 160 160 160 128 128 128 129 - 128 254 129 128 128 128 128 128 128 128 128 128 160 160 160 160 - 160 160 160 160 160 160 160 160 48 160 160 128 160 160 104 160 - 160 48 104 104 160 48 48 48 160 160 160 160 160 128 128 160 - 160 160 160 160 160 160 48 48 160 160 160 160 160 160 160 160 - 128 128 128 128 128 128 128 128 128 128 128 128 128 160 160 160 - 160 128 128 128 160 160 160 160 160 160 160 160 160 160 160 48 - 48 49 49 48 48 48 49 48 128 128 160 160 53 53 160 104 - 104 160 104 160 104 160 160 160 104 160 160 160 160 160 128 128 - 160 160 128 128 128 48 49 53 104 53 104 48 104 160 160 160 -])) - -data diff --git a/demo/mod/colormap.fnl b/demo/mod/colormap.fnl deleted file mode 100644 index 937abb9..0000000 --- a/demo/mod/colormap.fnl +++ /dev/null @@ -1,1031 +0,0 @@ -(require :pxl8) -(local ffi (require :ffi)) - -(local data (ffi.new "u8[16384]" [ - 254 254 48 48 48 253 253 253 253 144 106 106 106 252 252 252 - 253 253 48 48 48 48 48 48 48 48 48 48 48 254 254 254 - 253 253 253 253 253 253 253 128 128 48 48 48 48 48 48 254 - 253 105 253 253 105 105 105 105 105 105 105 105 48 48 48 48 - 105 105 105 105 128 105 48 48 48 49 49 48 48 254 254 254 - 253 253 253 253 253 253 253 48 48 48 48 48 48 48 254 254 - 253 48 48 48 48 48 254 254 105 105 106 252 252 106 106 10 - 10 9 9 9 8 8 8 8 128 128 128 147 148 148 254 49 - 253 253 253 253 253 253 48 48 48 48 48 48 48 254 254 254 - 106 106 253 253 253 253 253 253 253 253 48 48 48 48 48 254 - 105 105 105 105 253 48 48 48 48 48 48 254 254 254 254 254 - 106 10 9 9 9 9 253 253 253 253 128 128 128 128 254 254 - 106 106 144 253 253 253 253 253 253 48 48 48 48 48 254 49 - 145 145 145 145 145 145 253 252 252 252 252 247 247 52 247 52 - 52 52 52 52 248 248 248 248 248 105 160 160 160 104 254 129 - 105 105 253 128 128 128 129 106 105 105 105 252 106 106 105 160 - 84 84 82 151 150 254 254 254 128 146 253 253 253 253 106 106 - 80 81 81 81 81 81 51 82 82 83 83 83 83 83 83 83 - 254 254 254 254 130 130 130 131 131 131 131 151 152 152 152 83 - 254 104 255 80 105 48 104 104 53 53 53 104 54 54 51 96 - 161 161 162 162 162 162 162 163 163 164 164 96 96 83 83 84 - 49 49 49 80 80 80 80 80 81 81 81 82 83 83 83 96 - 80 81 162 163 82 83 83 83 160 105 105 253 144 253 253 253 - 146 147 148 149 150 150 150 150 151 151 152 152 152 84 84 84 - 254 255 255 255 255 162 162 162 162 81 163 83 83 83 84 84 - 253 48 48 48 254 49 254 254 254 49 50 50 151 151 152 84 - 49 255 255 161 162 162 162 162 163 163 164 83 83 83 84 84 - 128 8 128 128 129 254 130 130 130 130 131 131 132 132 133 133 - 253 48 48 49 49 49 49 49 49 50 51 51 82 83 83 16 - 214 214 214 214 214 49 254 106 106 106 52 52 52 52 52 53 - 58 53 53 53 53 104 249 161 162 162 162 163 164 164 164 164 - 80 129 129 36 131 152 83 253 48 104 80 105 105 105 104 104 - 186 186 185 184 184 184 183 182 182 182 182 181 180 180 180 179 - 183 184 184 184 184 184 184 185 185 185 185 185 185 185 185 185 - 183 183 183 184 184 184 184 184 185 185 185 185 185 185 185 185 - 35 132 132 133 130 131 132 133 130 80 132 132 133 133 135 136 - 164 164 164 164 164 134 135 135 135 185 185 185 185 185 185 185 - 35 132 132 35 184 184 184 184 184 184 184 185 185 185 185 186 - 133 134 135 135 185 185 186 185 131 131 129 180 180 180 180 181 - 182 182 182 183 184 183 184 184 184 184 185 185 185 185 186 186 - 132 132 132 133 133 134 184 184 185 185 185 185 185 185 185 186 - 34 34 34 34 35 35 35 183 184 184 184 184 185 185 185 185 - 132 132 132 133 133 134 135 135 184 185 185 185 185 186 186 185 - 182 182 182 182 182 182 183 183 184 184 184 184 185 185 185 186 - 34 34 34 35 35 35 35 35 184 185 184 185 185 185 185 244 - 37 153 151 152 36 35 183 8 128 128 128 254 254 254 80 255 - 255 162 163 163 163 164 164 164 164 164 165 134 135 135 185 186 - 132 133 183 184 184 185 135 130 131 132 133 128 130 130 132 128 - 239 239 169 168 168 167 167 166 165 133 133 132 131 130 130 129 - 167 237 168 168 168 168 168 238 238 238 238 238 238 238 239 239 - 166 167 167 167 167 167 168 168 168 168 169 169 169 169 169 238 - 165 166 167 167 164 165 166 70 250 68 69 70 237 71 238 238 - 69 69 69 70 70 70 237 237 71 71 238 238 238 238 238 239 - 166 166 167 167 167 167 168 168 168 168 238 238 238 238 238 238 - 237 237 237 71 238 238 238 238 165 164 163 162 130 131 131 132 - 133 134 135 135 136 136 136 136 137 137 137 170 170 239 239 239 - 166 166 166 237 237 237 237 168 168 238 238 238 238 239 239 239 - 164 165 165 165 165 166 166 166 167 167 168 168 169 238 238 238 - 69 69 69 70 70 237 237 237 71 238 238 238 238 239 239 170 - 133 133 134 134 134 135 135 135 135 136 136 168 169 169 239 239 - 164 165 165 165 166 166 167 167 168 168 168 238 238 238 238 239 - 17 19 17 97 97 166 166 104 255 80 54 54 59 59 250 250 - 66 66 234 69 69 69 69 69 236 70 70 237 71 71 238 73 - 70 165 166 135 168 238 238 163 165 70 237 255 163 164 165 160 - 71 71 237 70 70 236 69 68 250 250 162 162 162 161 160 160 - 236 236 236 70 70 70 70 70 70 70 71 71 71 71 71 71 - 165 165 69 69 236 236 70 70 70 70 70 71 71 71 71 71 - 67 68 69 69 66 234 234 234 232 233 233 234 234 236 70 70 - 234 234 234 234 236 236 236 70 70 70 70 71 71 71 71 71 - 68 68 69 69 69 236 236 236 70 70 70 71 71 71 71 71 - 236 236 70 70 70 71 71 71 67 66 65 64 160 161 162 162 - 163 164 165 166 166 167 168 168 168 237 71 71 72 72 71 71 - 68 235 68 69 69 69 236 236 70 70 70 71 71 71 72 72 - 250 250 250 250 250 68 68 69 69 236 70 70 70 71 71 71 - 68 234 69 236 236 236 70 70 70 70 70 70 71 71 72 73 - 163 163 164 164 164 165 165 166 236 70 70 70 70 71 71 71 - 250 250 250 250 250 250 69 69 70 70 70 71 71 71 71 72 - 60 60 60 60 60 60 165 53 53 53 58 58 228 228 229 229 - 230 230 230 230 233 234 234 234 234 234 236 236 70 71 71 71 - 68 67 164 166 237 71 71 65 233 234 69 64 249 250 165 160 - 67 67 66 249 249 58 58 58 53 57 57 52 52 52 52 52 - 229 229 229 229 230 230 230 230 233 233 233 233 233 233 233 233 - 58 58 58 58 58 249 249 249 249 249 249 249 66 66 66 233 - 227 227 231 228 227 227 228 229 226 227 228 228 229 229 230 230 - 228 228 229 229 229 229 229 230 230 230 230 230 230 233 233 233 - 58 58 58 58 249 231 231 232 232 232 232 233 233 233 233 233 - 229 229 229 230 230 230 233 230 227 227 56 248 52 248 248 248 - 53 53 58 58 249 59 59 59 59 59 250 250 250 250 67 67 - 58 231 231 231 231 231 231 232 230 230 233 233 233 233 233 234 - 57 57 58 58 58 58 58 58 58 58 249 249 249 66 66 233 - 231 228 229 229 229 229 229 230 230 230 230 230 233 233 233 233 - 248 248 53 53 53 64 249 249 249 249 249 249 66 66 66 67 - 57 57 57 58 58 58 58 58 58 58 249 249 249 66 233 67 - 58 58 58 58 58 58 58 52 56 56 225 225 225 226 226 226 - 226 226 226 227 228 228 228 228 229 229 229 229 230 230 230 230 - 231 231 64 249 250 250 233 56 227 228 229 56 56 57 53 53 - 58 57 57 57 56 56 56 56 56 56 56 221 221 219 219 219 - 56 56 56 56 56 57 57 57 57 57 57 57 57 57 57 57 - 56 56 56 56 56 56 56 56 57 57 57 57 57 57 57 57 - 56 225 225 225 222 224 225 225 222 224 224 225 225 56 57 227 - 225 225 225 225 226 226 226 227 227 227 227 227 227 227 227 227 - 56 56 56 56 56 56 56 56 57 56 57 57 57 57 57 57 - 56 56 56 56 57 57 57 57 225 223 222 219 219 219 219 56 - 52 56 56 56 56 56 57 57 57 57 57 57 57 57 57 57 - 56 56 56 56 56 56 56 56 57 57 57 57 57 57 57 57 - 222 223 223 225 225 225 225 56 56 56 57 57 57 57 57 57 - 225 225 225 225 225 225 226 226 227 227 227 57 57 57 57 57 - 52 52 52 52 52 56 56 56 56 56 57 57 57 57 57 57 - 222 222 223 225 225 225 56 56 56 56 56 57 57 57 57 57 - 222 222 222 223 223 225 223 219 219 220 220 220 221 221 221 222 - 224 224 224 224 224 224 225 225 226 226 226 227 227 227 227 227 - 225 56 56 57 57 57 57 222 224 225 225 219 221 222 56 58 - 144 106 106 106 106 252 252 252 252 217 217 217 217 217 217 216 - 247 247 247 247 247 247 247 247 247 247 52 52 52 52 52 144 - 252 252 252 252 252 252 252 252 106 106 106 106 106 106 144 106 - 252 247 247 247 217 218 247 52 218 218 218 247 247 247 247 247 - 247 247 247 247 247 247 247 247 247 247 247 247 247 247 52 52 - 252 247 247 247 247 247 247 247 247 247 247 52 247 247 247 52 - 247 247 247 247 247 247 52 52 247 217 217 217 216 216 216 217 - 251 252 252 252 252 252 252 106 106 106 144 144 144 144 144 52 - 252 247 247 247 247 247 247 247 247 247 247 247 247 52 144 52 - 217 217 218 252 252 252 252 252 252 252 106 106 106 106 106 247 - 247 247 247 247 247 247 247 247 247 247 247 247 247 52 52 144 - 251 251 251 251 252 252 252 252 252 252 252 106 106 144 144 144 - 217 217 217 218 252 252 247 247 247 247 247 247 247 247 52 52 - 218 218 218 218 218 247 252 216 216 217 217 218 218 218 218 218 - 218 218 218 219 219 247 247 247 247 247 247 247 247 247 247 247 - 247 252 252 252 106 144 144 217 217 247 247 216 217 217 252 160 - 198 197 196 195 195 195 194 194 194 193 193 193 192 192 192 192 - 195 195 195 195 195 195 195 195 196 196 196 196 196 197 197 197 - 194 194 194 194 195 195 195 195 195 195 195 195 196 196 197 196 - 194 194 194 195 193 194 194 195 194 194 194 194 195 195 195 196 - 195 196 196 195 195 196 196 196 196 196 196 196 196 197 197 197 - 194 194 194 195 195 195 195 195 195 195 195 196 196 196 197 197 - 195 195 195 195 196 196 197 197 193 193 192 192 192 192 192 193 - 193 193 194 194 194 195 195 195 195 196 196 196 197 197 197 198 - 194 194 194 195 195 195 195 195 195 195 196 196 197 197 197 198 - 193 193 194 194 194 194 194 194 195 195 195 195 195 196 196 197 - 194 195 195 195 195 195 195 196 196 196 196 196 197 197 197 198 - 193 193 193 193 194 194 194 194 195 195 195 195 196 196 197 197 - 193 194 194 194 194 194 194 194 195 195 195 196 196 196 197 198 - 194 211 212 194 194 194 194 12 12 192 192 192 193 194 194 144 - 144 145 145 146 146 146 145 146 147 147 214 214 214 196 197 199 - 146 146 9 8 195 196 197 192 194 194 195 192 192 193 144 129 - 203 203 202 201 201 201 201 201 213 213 213 213 213 213 213 213 - 201 201 201 201 201 201 201 201 202 202 202 202 202 203 203 203 - 201 201 201 201 201 201 201 202 202 202 202 202 202 202 203 203 - 213 201 201 201 213 213 201 201 213 213 213 201 201 201 202 203 - 201 201 201 201 202 202 202 202 202 202 202 202 202 203 203 203 - 201 201 201 201 201 201 201 202 202 202 202 202 202 202 202 203 - 201 201 202 202 202 202 203 203 201 213 213 213 213 213 213 213 - 213 201 201 201 201 201 201 201 201 201 202 202 202 203 203 203 - 201 201 201 201 201 201 201 201 202 202 202 202 202 202 203 203 - 213 213 213 213 201 201 201 201 201 201 201 202 202 202 203 203 - 201 201 201 201 201 201 202 202 202 202 202 202 202 203 203 203 - 201 201 201 201 201 201 201 201 201 201 201 202 202 202 203 203 - 213 213 213 213 213 213 201 201 201 201 202 202 201 201 202 203 - 210 210 210 211 210 211 201 212 213 213 213 213 213 213 213 213 - 213 213 213 213 213 201 201 201 202 202 202 202 202 202 202 202 - 201 201 200 3 201 203 203 213 201 201 201 213 213 201 200 49 - 207 207 206 101 156 42 155 41 40 153 153 152 152 151 150 149 - 23 205 205 205 205 205 206 206 206 206 206 206 207 207 207 207 - 41 41 3 3 3 42 156 156 156 101 101 206 206 206 206 207 - 154 20 21 21 16 18 21 61 96 97 61 21 21 205 206 245 - 87 168 168 169 169 169 169 239 170 171 63 63 207 207 207 207 - 20 21 21 21 23 23 23 205 205 206 206 206 206 206 207 207 - 23 62 206 206 206 206 207 207 98 84 152 151 150 36 37 37 - 38 39 41 3 43 43 93 44 2 31 45 102 102 102 207 207 - 99 99 90 90 22 62 62 62 246 246 245 245 207 207 207 207 - 153 202 202 202 203 203 20 204 204 204 205 205 206 206 207 207 - 20 87 90 169 169 62 62 246 246 245 245 207 207 207 207 102 - 38 184 4 4 39 41 3 3 3 43 44 44 157 157 63 207 - 152 202 202 202 203 203 204 204 205 205 205 206 206 206 207 207 - 203 203 203 203 203 203 204 197 199 199 198 200 54 59 60 60 - 60 60 60 60 61 61 61 72 168 238 238 239 239 245 63 63 - 168 167 136 244 101 206 206 83 17 19 62 150 152 153 98 48 - 202 201 201 152 200 150 150 149 148 147 147 146 145 145 144 144 - 200 200 200 200 200 201 201 201 201 201 201 201 201 201 201 202 - 199 150 150 150 150 150 200 200 200 200 200 201 201 201 201 201 - 197 197 197 200 214 214 214 214 48 53 214 214 200 200 201 201 - 49 50 50 50 51 51 51 83 16 16 16 201 201 201 201 202 - 199 198 198 198 200 200 200 200 200 200 200 201 201 201 201 202 - 151 151 200 201 201 201 201 202 149 147 146 145 144 145 146 146 - 147 148 149 150 36 36 36 36 152 152 152 153 153 153 202 202 - 149 149 150 150 150 151 151 151 152 151 152 201 201 201 201 202 - 196 196 196 197 197 197 197 198 198 200 200 200 201 201 201 202 - 49 49 50 50 50 51 51 152 152 152 201 201 201 202 202 202 - 8 8 7 7 7 33 33 6 150 151 151 152 152 153 153 153 - 195 196 196 197 197 197 198 198 200 200 201 201 201 201 201 202 - 212 212 213 213 214 197 197 192 144 144 194 194 53 53 53 53 - 53 53 53 58 54 54 54 55 54 51 51 51 83 16 16 16 - 50 130 129 35 200 201 16 146 48 49 50 144 146 147 148 48 - 153 152 152 151 150 150 149 148 147 147 146 145 145 144 10 10 - 199 199 198 198 200 200 200 200 152 152 152 152 152 152 152 152 - 148 149 199 149 149 150 150 150 150 151 151 151 151 152 152 152 - 148 199 199 149 146 147 197 199 48 48 149 149 199 198 200 152 - 149 49 49 80 50 50 50 82 152 152 152 152 152 152 152 153 - 149 149 149 199 150 150 150 150 150 151 151 151 152 152 152 152 - 150 150 151 200 152 152 152 152 148 146 145 144 144 145 145 8 - 8 8 7 7 33 6 6 6 6 6 36 37 152 152 153 153 - 148 148 149 149 150 150 150 150 151 151 151 152 152 152 153 153 - 146 195 196 196 148 148 148 149 199 199 150 151 151 152 152 152 - 149 49 49 49 150 50 151 151 151 151 152 152 152 152 153 5 - 8 8 8 8 32 32 7 7 7 150 151 151 151 152 37 153 - 146 195 196 196 196 196 199 199 198 198 200 200 200 201 201 201 - 213 213 213 214 196 148 199 10 144 144 144 145 145 52 52 53 - 53 53 53 53 54 54 54 54 80 50 50 50 151 152 152 152 - 254 129 129 34 6 152 152 146 48 254 150 144 145 146 148 48 - 189 189 188 187 187 187 186 4 4 38 5 37 35 35 33 33 - 3 43 43 43 43 44 2 2 2 2 94 189 188 189 189 189 - 186 186 186 186 186 244 187 187 187 187 188 188 188 188 189 94 - 39 41 244 3 38 40 41 91 84 85 86 89 91 26 29 94 - 136 136 136 137 137 170 246 246 246 138 94 94 45 189 189 189 - 41 3 3 3 3 3 43 43 43 43 188 188 188 188 189 189 - 43 25 93 93 29 94 94 103 39 38 37 35 34 34 34 184 - 184 185 185 186 186 187 187 187 187 124 188 188 188 189 189 189 - 39 39 41 42 42 42 43 43 43 2 188 188 188 189 189 189 - 38 38 4 4 39 39 3 3 3 3 43 2 188 188 188 189 - 39 136 91 137 92 24 27 138 138 29 188 188 189 189 189 189 - 184 184 184 184 185 185 185 186 186 187 187 187 188 188 188 189 - 5 38 4 4 39 41 3 3 43 43 44 2 2 94 95 158 - 203 203 202 203 154 155 155 7 7 150 150 150 151 51 96 96 - 97 97 97 98 167 167 168 168 169 169 170 170 246 139 45 139 - 136 134 244 186 124 125 95 37 38 136 137 34 5 4 135 128 - 185 184 184 184 183 183 182 181 181 180 180 180 8 112 112 112 - 35 35 35 35 183 184 184 184 184 184 184 184 184 184 184 184 - 182 182 182 182 182 183 183 183 183 183 184 184 184 184 184 185 - 33 34 34 35 7 33 34 35 7 7 33 34 35 5 184 185 - 34 35 35 35 37 37 5 5 5 184 185 185 185 185 184 185 - 33 34 34 34 35 35 183 183 184 184 184 184 184 184 184 185 - 35 35 5 184 184 185 185 185 33 32 8 9 112 179 179 180 - 181 181 182 182 182 183 183 183 183 184 184 184 184 184 185 185 - 33 33 34 34 35 35 183 183 184 184 184 184 184 184 185 185 - 32 32 32 33 33 33 33 34 34 183 184 184 184 184 184 185 - 33 34 35 35 35 37 5 5 5 184 184 184 184 185 185 185 - 180 180 181 181 181 182 182 182 182 183 183 183 184 184 184 185 - 32 32 33 33 33 34 6 34 35 35 5 184 184 184 185 185 - 6 6 33 33 33 34 34 10 9 9 9 145 146 147 148 147 - 49 49 49 80 131 131 132 132 132 132 37 37 5 184 185 185 - 131 130 34 182 184 184 185 8 32 34 35 9 8 32 130 128 - 183 182 182 181 181 181 180 179 179 178 178 178 177 111 110 110 - 181 181 181 181 182 182 182 182 182 182 182 182 182 182 182 182 - 180 180 180 180 180 181 181 181 181 181 181 182 182 182 182 182 - 180 180 180 181 112 8 8 33 9 8 8 8 32 182 182 183 - 32 32 32 32 33 182 182 182 182 182 182 182 182 182 182 182 - 180 181 180 181 181 181 181 181 181 182 182 182 182 182 182 183 - 181 181 181 182 182 182 182 183 113 112 112 111 110 177 177 178 - 178 179 179 180 180 181 181 181 181 182 182 182 182 182 182 183 - 180 180 180 180 181 181 181 181 182 181 182 182 182 182 183 183 - 112 113 113 180 180 180 180 180 180 181 181 181 182 182 182 182 - 180 181 181 181 181 181 181 182 182 182 182 182 182 182 183 183 - 178 178 178 179 179 179 180 180 180 181 181 181 182 182 182 183 - 112 112 113 113 113 181 181 181 181 181 181 182 182 182 182 183 - 114 114 114 113 113 113 114 110 110 110 10 10 10 144 144 145 - 253 253 128 128 128 128 7 7 32 33 33 182 182 182 182 183 - 32 8 179 181 181 182 183 10 8 7 33 110 111 113 32 128 - 141 1 103 94 29 93 43 3 39 4 38 5 5 35 35 6 - 93 28 28 28 28 94 139 139 139 139 139 140 140 140 140 140 - 3 3 3 43 43 93 44 29 29 94 94 94 45 103 140 103 - 41 42 24 24 85 88 22 62 16 98 20 21 62 171 171 172 - 169 169 169 170 170 171 171 171 172 172 172 172 172 140 140 140 - 42 92 92 25 27 138 138 138 28 94 139 139 139 140 140 140 - 246 171 171 171 139 103 140 140 136 135 133 37 35 5 5 184 - 185 185 186 187 187 124 125 125 125 125 189 126 46 46 47 47 - 137 137 137 137 137 138 138 138 139 139 139 139 140 140 47 141 - 39 39 39 41 41 42 42 92 25 93 27 29 139 103 158 140 - 137 169 169 170 170 170 171 171 171 139 172 140 140 140 140 47 - 185 185 185 186 186 186 187 187 187 188 94 94 94 103 46 47 - 39 40 154 41 41 42 24 25 28 30 30 157 103 103 158 159 - 155 204 204 203 204 23 100 150 150 151 151 51 55 60 60 60 - 97 97 61 61 237 72 238 238 238 239 239 171 171 172 172 172 - 169 167 137 244 188 45 173 84 86 87 246 36 37 40 87 128 - 76 239 170 169 169 90 88 86 85 84 83 82 50 80 130 254 - 168 168 168 168 169 238 238 238 239 239 239 239 239 239 239 239 - 86 88 88 168 168 168 168 169 169 169 169 169 170 170 170 239 - 97 61 61 61 96 165 61 237 96 60 60 61 61 238 238 74 - 167 237 237 237 237 72 238 238 238 238 238 239 239 239 239 75 - 167 167 167 168 168 168 168 168 169 169 238 239 239 239 239 75 - 168 238 238 238 238 239 239 75 166 164 163 81 131 131 132 132 - 153 153 40 41 42 42 42 24 24 26 246 246 171 171 171 76 - 166 166 167 167 168 168 168 238 238 238 238 239 239 75 75 75 - 84 84 84 17 98 98 98 19 168 168 169 169 169 170 239 75 - 166 237 237 237 237 71 72 238 238 238 238 239 239 239 75 76 - 133 133 134 134 135 135 136 136 136 169 169 169 170 170 170 75 - 83 16 16 16 17 19 61 61 61 62 62 62 239 239 239 76 - 203 203 203 203 17 19 19 254 254 49 54 54 59 59 59 59 - 250 60 68 69 236 236 70 70 70 71 71 72 73 73 74 74 - 237 166 167 136 169 170 74 163 165 166 168 80 132 84 166 160 - 167 167 165 165 164 164 132 131 130 255 255 255 160 48 105 105 - 164 165 165 165 165 165 165 165 166 166 166 166 166 166 167 167 - 163 163 163 163 164 164 164 165 165 165 165 166 166 166 166 166 - 162 250 250 250 161 249 250 250 64 249 249 250 250 164 165 70 - 163 250 250 250 250 164 165 165 69 166 166 166 166 166 70 70 - 163 250 250 250 250 250 164 165 165 165 165 166 166 166 166 237 - 164 164 68 165 165 166 166 70 162 161 104 160 48 48 254 254 - 254 80 131 82 133 133 133 134 134 135 135 166 167 167 167 167 - 163 163 250 250 250 250 250 165 165 165 166 166 166 167 167 168 - 254 80 80 80 81 81 163 132 164 164 165 165 165 166 166 167 - 163 250 250 250 250 250 68 165 69 166 166 166 166 167 167 167 - 255 130 130 131 131 131 163 132 164 133 165 165 165 166 167 167 - 254 49 80 50 50 51 55 55 96 96 61 97 166 166 167 61 - 150 200 55 55 55 51 51 105 105 105 53 53 53 58 58 58 - 58 58 249 249 66 66 66 66 66 235 68 69 69 236 70 70 - 163 162 132 133 134 166 166 160 64 250 164 105 255 255 162 160 - 139 28 27 92 42 41 39 39 38 37 37 36 34 33 7 129 - 87 168 90 169 90 91 169 24 246 26 26 246 246 246 246 138 - 39 39 39 39 41 41 41 155 42 92 92 25 93 27 28 138 - 134 85 88 88 83 84 98 61 51 96 97 98 87 22 170 170 - 167 167 167 167 168 169 169 169 169 170 170 170 246 246 246 171 - 85 88 88 88 87 90 90 90 91 23 100 24 26 246 246 246 - 90 90 90 91 137 138 246 246 84 133 82 150 149 150 36 37 - 37 38 38 39 244 244 244 43 244 43 93 93 29 29 94 139 - 85 86 86 88 87 90 90 90 169 137 137 246 246 138 30 139 - 37 153 153 153 40 40 40 40 41 41 41 42 92 93 28 138 - 85 86 88 87 168 90 169 169 169 169 170 246 246 246 171 139 - 5 5 184 38 38 4 4 39 244 244 244 92 43 93 28 94 - 37 153 153 153 40 40 154 154 41 23 24 24 26 246 246 245 - 202 203 203 202 202 202 154 148 148 148 149 54 54 55 55 55 - 55 60 60 60 166 70 70 237 237 167 168 169 169 170 170 171 - 167 133 135 39 43 93 170 82 83 98 88 254 151 152 166 160 - 3 3 41 39 4 38 5 37 6 6 33 7 7 8 8 8 - 153 153 40 40 40 154 154 154 154 154 41 41 155 3 3 3 - 5 5 5 5 5 38 4 39 154 154 154 154 41 41 155 155 - 151 152 153 153 150 151 83 16 49 51 51 83 84 18 99 90 - 83 84 84 84 85 85 86 86 89 99 99 22 91 155 155 155 - 152 153 153 153 153 153 40 40 154 154 154 154 41 155 155 155 - 153 85 40 154 154 41 41 155 152 150 149 148 8 7 32 32 - 33 6 35 5 4 4 4 4 4 4 3 3 3 3 3 24 - 152 152 84 84 153 85 40 40 154 154 41 41 155 155 42 156 - 150 151 151 151 152 152 152 5 153 153 39 154 154 41 155 155 - 152 152 84 84 85 85 86 40 154 41 41 155 155 155 42 3 - 34 34 35 35 35 5 5 5 4 4 4 39 41 3 3 155 - 150 150 151 151 152 152 153 153 153 39 154 154 154 155 155 156 - 200 200 201 201 201 201 201 146 146 195 195 214 214 54 54 54 - 54 54 54 55 55 60 96 97 97 97 98 86 87 99 41 91 - 133 132 133 38 4 3 22 149 151 152 153 146 199 150 82 48 - 151 151 150 149 148 148 147 146 146 145 145 144 144 10 11 11 - 148 148 149 149 149 149 150 150 150 150 150 150 150 150 150 151 - 147 147 147 147 148 148 148 148 149 149 199 150 150 150 150 151 - 146 147 147 147 145 146 48 48 145 146 48 48 148 149 150 150 - 48 48 48 254 254 49 49 49 150 150 150 150 150 151 151 151 - 147 147 147 148 148 148 148 148 149 149 149 150 150 150 151 151 - 148 149 149 149 149 150 150 151 146 145 144 10 10 10 10 9 - 9 9 8 8 7 7 7 7 33 33 6 6 6 151 151 151 - 146 147 148 148 148 148 149 149 149 149 150 150 150 151 151 151 - 145 145 146 146 146 146 147 147 148 148 148 149 149 150 150 151 - 147 48 48 48 254 49 49 149 150 150 150 150 151 151 151 151 - 9 9 9 8 8 8 8 7 7 7 7 7 150 150 151 151 - 145 145 146 146 146 147 147 148 148 149 149 150 150 150 151 200 - 195 212 196 195 195 196 146 11 192 192 192 144 144 52 52 52 - 52 52 52 53 53 53 48 48 49 49 49 49 150 150 151 131 - 128 128 128 32 7 6 150 144 146 48 148 106 144 145 146 48 - 43 42 155 41 39 4 5 5 36 6 33 33 7 7 8 8 - 40 40 154 154 154 154 41 41 155 155 155 155 155 42 42 43 - 5 5 5 38 38 4 39 39 154 154 41 41 155 155 155 42 - 152 153 153 153 151 152 152 17 50 51 83 153 17 154 41 22 - 84 84 85 85 98 86 88 87 90 21 22 22 42 42 156 156 - 153 153 153 153 40 40 40 154 154 154 41 155 155 155 155 156 - 40 154 154 154 41 155 155 156 152 151 149 7 7 7 32 33 - 6 35 5 5 4 4 185 185 244 3 3 3 3 43 43 156 - 152 153 153 153 153 40 154 154 154 41 41 155 155 42 43 156 - 6 36 152 152 152 152 153 153 153 40 40 154 154 155 155 42 - 84 84 85 85 85 86 88 89 99 41 41 155 42 156 156 43 - 34 34 35 35 5 5 5 5 4 4 4 39 41 155 42 156 - 150 151 151 152 152 153 153 153 154 154 154 155 155 155 42 156 - 202 202 201 201 201 201 153 146 146 147 148 148 49 54 54 54 - 59 54 55 96 96 96 97 97 166 98 98 87 90 22 91 91 - 134 133 134 38 4 3 91 150 83 152 153 148 149 151 83 128 - 140 140 139 94 27 92 42 155 41 39 38 38 37 36 36 34 - 26 170 170 246 246 171 171 171 171 171 139 172 172 172 140 140 - 42 3 3 92 43 25 27 138 138 138 139 139 139 172 172 172 - 89 22 91 62 16 61 168 62 61 61 61 168 62 62 171 171 - 168 72 238 238 74 74 75 75 76 76 76 172 172 172 172 172 - 91 91 137 137 170 170 170 170 246 246 171 139 139 172 172 173 - 26 170 170 170 139 172 172 173 136 135 133 132 36 37 5 38 - 4 4 244 244 187 188 188 188 188 125 95 158 46 140 173 173 - 136 169 169 169 169 170 170 170 170 171 171 139 172 140 140 173 - 134 86 88 89 99 22 91 23 100 24 246 246 171 139 172 172 - 136 169 169 169 170 170 170 170 171 171 171 172 172 140 173 140 - 185 185 185 185 244 244 244 3 43 93 29 94 139 172 172 173 - 153 40 154 41 41 91 92 24 246 246 245 245 63 172 172 173 - 23 204 204 204 204 21 100 149 149 150 50 55 60 60 60 60 - 60 61 61 166 237 71 237 72 238 73 74 75 75 76 172 77 - 169 167 136 137 94 139 77 133 167 168 169 131 132 135 167 160 - 89 88 86 84 84 83 82 50 80 49 254 254 48 48 146 253 - 83 164 165 165 165 165 166 166 166 166 135 135 167 167 167 167 - 131 132 132 132 132 133 133 133 133 84 134 134 85 135 86 167 - 80 82 132 133 129 80 81 164 104 54 54 81 96 165 134 166 - 163 250 250 250 164 165 165 165 166 166 166 135 135 135 135 167 - 132 132 132 164 164 164 164 165 165 165 165 166 135 135 167 167 - 133 133 165 165 135 135 167 167 162 255 129 128 8 8 8 7 - 7 33 34 35 37 5 5 5 38 38 39 40 40 88 88 167 - 131 163 163 163 164 164 164 164 165 165 135 135 167 167 88 87 - 254 49 49 50 50 50 82 82 82 83 84 84 85 85 86 167 - 131 163 132 164 164 164 165 165 165 134 135 135 135 167 167 136 - 7 33 33 34 34 34 35 37 37 133 133 84 85 86 167 167 - 254 49 80 50 50 82 82 82 83 84 84 84 85 86 88 99 - 200 200 200 200 151 151 82 253 253 253 48 53 53 53 58 58 - 58 249 249 249 249 250 250 250 250 250 165 165 166 166 167 167 - 163 162 132 132 134 135 166 255 161 163 133 253 128 255 162 160 - 137 137 136 136 135 135 134 133 132 131 131 130 149 148 147 128 - 135 135 86 135 88 88 89 136 136 136 136 136 136 137 137 137 - 133 133 134 134 134 134 135 135 135 88 136 136 136 91 137 137 - 133 84 133 135 131 132 133 85 81 55 96 96 98 86 136 136 - 165 165 165 166 166 167 167 87 136 136 136 136 137 137 137 137 - 133 134 134 134 135 135 135 135 88 88 88 136 136 137 137 137 - 135 135 135 135 136 136 137 137 132 132 131 129 8 7 33 34 - 34 35 5 4 185 185 185 185 244 244 3 3 3 92 25 138 - 133 133 134 134 134 135 135 135 88 136 136 136 137 137 137 26 - 151 151 152 152 152 152 153 153 153 40 40 88 89 136 137 137 - 133 84 134 135 135 135 135 88 136 136 136 136 137 137 137 138 - 35 35 35 35 35 5 38 38 39 135 135 136 136 136 137 137 - 131 151 151 152 152 153 153 153 18 19 99 99 41 91 92 24 - 201 201 201 201 16 153 153 8 253 147 48 49 54 54 54 54 - 54 59 250 250 164 165 165 165 166 166 167 167 168 168 137 169 - 165 133 134 134 244 244 136 131 82 84 85 128 150 132 83 160 - 126 126 125 125 124 124 187 187 186 186 185 184 183 183 34 34 - 2 31 2 2 125 125 125 126 126 126 126 126 126 126 127 190 - 187 187 187 187 187 124 124 124 125 125 125 125 125 126 126 126 - 3 43 43 2 39 155 42 101 154 20 41 42 44 157 125 127 - 43 93 28 30 157 45 45 95 95 158 46 126 126 126 127 127 - 187 187 187 188 188 188 188 188 188 125 126 126 126 126 127 127 - 2 157 45 95 126 126 127 127 3 4 38 5 183 184 184 184 - 120 120 119 119 123 123 124 124 124 125 125 125 126 126 126 127 - 122 187 187 187 187 188 188 188 189 189 126 126 126 126 127 127 - 4 39 3 244 244 244 187 187 187 124 125 125 125 125 126 126 - 3 43 43 44 2 94 94 94 95 126 126 126 126 127 127 127 - 185 185 185 121 121 121 122 122 124 124 125 125 125 125 126 127 - 4 39 41 3 3 3 43 2 188 188 125 126 126 126 127 127 - 156 156 155 155 155 156 43 33 6 6 200 201 201 202 202 202 - 17 19 20 21 21 23 24 246 246 171 139 103 158 126 127 127 - 93 244 244 122 125 125 126 5 41 92 93 35 5 4 136 128 - 119 119 119 119 118 117 117 116 115 115 115 114 114 114 114 113 - 185 185 185 186 186 121 121 121 121 119 119 119 119 119 119 119 - 116 116 117 117 117 117 118 118 118 118 119 119 119 119 119 119 - 183 184 184 185 35 5 5 4 6 37 5 5 4 185 186 187 - 5 4 4 4 185 186 186 186 186 186 186 122 122 123 119 123 - 184 184 184 185 185 185 185 185 120 120 120 119 119 119 119 119 - 185 185 185 186 120 119 119 123 183 182 33 114 114 114 114 115 - 115 115 116 116 117 117 117 118 118 118 119 119 119 119 119 123 - 184 184 184 184 185 185 185 185 185 121 121 121 119 119 119 119 - 115 115 115 183 183 116 116 117 117 117 118 118 119 119 119 119 - 184 184 184 185 185 185 186 186 186 121 121 121 121 119 119 119 - 115 115 115 116 116 116 116 116 117 117 118 119 119 119 119 123 - 115 115 115 115 116 116 117 117 117 118 119 119 119 119 119 119 - 117 116 117 116 116 116 116 113 113 8 196 196 197 197 198 198 - 151 151 152 37 5 38 4 4 4 4 185 186 186 122 122 123 - 184 183 184 117 119 119 122 33 35 5 185 32 114 182 134 128 - 183 182 182 114 114 113 113 113 113 112 111 111 111 111 110 110 - 32 32 32 32 32 32 32 33 182 182 182 182 182 182 182 115 - 113 113 113 113 113 113 114 114 114 114 182 182 182 182 182 182 - 8 8 8 8 9 8 8 7 9 9 8 8 7 32 33 182 - 8 8 32 32 32 32 32 32 33 33 33 182 182 182 182 183 - 8 8 8 8 32 32 32 32 32 32 32 182 182 182 182 182 - 32 32 32 32 32 182 182 183 8 9 112 111 110 110 111 111 - 111 113 113 113 114 114 114 114 114 115 115 115 115 115 115 183 - 8 8 8 8 32 32 32 32 32 32 182 182 182 182 183 183 - 112 113 113 113 113 113 113 113 113 114 114 114 114 182 182 183 - 8 8 32 32 32 32 32 32 32 33 182 182 182 182 183 183 - 112 112 113 113 113 113 113 113 114 114 114 114 114 115 182 115 - 112 112 112 113 113 113 113 113 114 114 32 32 182 182 182 183 - 113 113 113 113 113 113 113 109 109 11 11 10 144 144 144 144 - 145 145 145 146 8 8 8 7 7 7 33 33 33 33 182 182 - 8 8 8 180 114 182 182 10 9 8 32 110 111 9 8 128 - 9 9 9 10 11 11 11 12 12 12 12 13 13 14 14 14 - 11 10 10 10 10 10 10 10 10 10 10 9 9 9 9 9 - 11 11 11 11 11 11 11 10 10 10 10 10 10 10 9 9 - 107 252 252 106 251 252 252 106 251 252 252 252 106 106 10 9 - 252 252 106 106 106 106 144 144 10 10 10 9 9 9 9 9 - 11 11 11 11 106 106 106 106 10 10 10 10 10 9 9 9 - 106 106 106 10 10 10 9 253 107 107 251 13 14 14 108 108 - 109 109 109 110 110 110 110 111 111 111 10 9 10 9 9 9 - 107 252 252 252 106 106 106 106 10 10 10 9 9 9 9 9 - 107 107 107 107 107 107 11 11 11 11 10 10 10 10 9 9 - 252 252 252 106 106 106 106 10 10 10 10 10 9 9 253 9 - 12 109 109 109 109 109 110 110 110 10 10 10 10 10 9 9 - 107 107 107 107 107 11 11 11 10 10 10 10 10 9 9 145 - 11 192 11 11 11 11 11 15 15 14 251 251 251 251 251 251 - 252 252 252 252 252 252 106 106 106 106 106 253 106 144 9 9 - 252 106 11 10 10 10 9 251 107 252 11 14 13 251 252 128 - 137 91 136 86 134 134 133 132 132 131 130 254 129 128 128 128 - 84 84 85 85 98 86 88 88 88 87 87 90 90 90 90 91 - 153 153 153 153 153 153 85 85 135 86 88 89 136 136 136 90 - 82 83 84 84 80 82 96 96 80 51 96 96 165 166 88 168 - 164 165 165 165 165 166 167 167 167 167 168 168 168 90 90 169 - 84 84 84 84 84 84 85 98 86 86 88 88 89 90 90 90 - 84 85 98 86 88 87 168 168 82 80 254 129 128 129 7 7 - 6 36 37 38 38 39 39 39 39 39 41 136 90 91 137 169 - 82 83 84 84 165 84 85 85 86 86 88 87 90 91 91 137 - 150 151 151 151 132 152 133 153 133 153 85 40 88 89 136 90 - 164 164 165 165 165 165 166 167 167 88 87 90 90 90 91 137 - 36 36 36 36 36 37 38 38 38 38 40 41 89 136 90 91 - 149 150 151 151 152 153 153 84 85 18 86 88 88 90 90 23 - 201 201 201 201 201 201 153 146 146 48 48 53 53 58 58 59 - 54 54 250 250 250 250 165 165 165 166 166 166 167 167 168 167 - 164 163 133 134 39 136 168 49 81 96 97 48 254 80 163 160 - 63 245 246 23 23 21 20 86 85 153 152 152 151 150 149 149 - 21 21 62 62 62 62 62 62 62 62 62 246 246 245 245 245 - 154 154 99 99 99 21 22 23 23 23 62 62 246 246 246 246 - 17 17 61 61 16 16 61 61 60 60 61 61 61 169 62 239 - 167 237 237 237 238 238 238 238 239 239 239 239 239 246 171 245 - 19 19 20 20 21 21 62 62 62 62 62 62 246 246 246 171 - 168 62 62 62 62 62 245 171 98 83 82 50 150 151 152 37 - 5 38 39 41 155 3 43 43 43 93 27 101 245 245 245 245 - 86 86 167 168 168 168 168 169 62 62 62 62 246 246 245 63 - 153 153 153 18 18 18 19 20 99 21 22 23 62 246 246 239 - 61 61 61 61 168 168 62 62 62 62 62 246 246 245 245 63 - 5 38 38 4 4 39 41 41 91 91 100 24 246 246 245 245 - 152 84 16 17 18 19 19 20 21 62 62 62 62 246 245 245 - 203 203 203 203 202 17 20 148 148 49 54 54 59 59 59 59 - 60 60 60 60 166 70 70 237 237 71 238 238 238 239 239 239 - 166 166 135 136 25 246 239 51 97 61 61 49 82 84 97 48 - 1 63 157 101 25 92 155 41 39 38 38 5 37 36 34 33 - 23 23 62 62 246 246 246 246 245 245 245 245 63 63 63 63 - 41 3 3 3 42 43 156 25 26 26 101 157 157 157 103 63 - 19 99 21 23 16 19 19 62 97 97 61 87 62 62 246 171 - 168 168 168 169 169 239 239 239 239 171 171 171 63 63 63 63 - 99 90 22 22 23 23 24 246 246 246 246 246 245 63 63 63 - 62 62 246 246 246 245 139 63 89 84 133 151 36 36 37 5 - 38 4 39 3 3 43 2 2 2 2 31 94 103 158 140 172 - 89 90 90 90 91 23 24 246 246 246 246 245 245 172 172 172 - 153 40 40 154 154 41 41 22 91 23 24 26 246 245 63 63 - 87 168 168 169 169 169 170 170 170 246 171 245 245 172 172 140 - 4 185 185 185 185 244 244 244 3 43 93 44 29 94 103 103 - 5 153 40 154 41 21 22 22 23 24 246 246 245 245 63 63 - 20 203 203 203 203 203 155 149 149 150 150 55 55 55 60 60 - 60 60 60 97 61 237 237 72 238 238 238 239 239 171 172 171 - 168 166 136 136 138 246 171 83 98 87 23 150 132 85 98 48 - 246 26 100 91 41 154 40 153 153 37 36 6 33 7 7 148 - 154 20 99 99 90 22 22 23 91 92 92 24 24 26 26 26 - 39 39 39 39 40 40 41 41 99 90 22 91 23 23 24 24 - 153 85 85 86 151 16 16 17 55 60 97 97 61 20 23 62 - 85 166 166 167 167 168 168 168 169 23 23 23 24 26 26 26 - 153 85 85 86 86 88 88 99 99 22 91 91 92 24 26 246 - 19 20 99 22 91 24 26 246 84 132 131 254 148 33 34 6 - 35 5 5 4 4 4 4 244 244 3 43 43 43 43 101 246 - 153 85 85 86 86 86 88 99 22 91 91 100 24 26 246 246 - 151 152 152 153 153 153 153 40 40 86 88 90 91 91 24 137 - 135 135 135 135 88 87 90 90 22 23 23 23 26 246 246 101 - 36 35 37 5 5 38 38 4 4 39 3 3 42 92 26 101 - 36 152 152 153 153 153 40 86 20 99 90 22 23 24 26 246 - 202 202 202 202 201 201 40 147 147 148 49 54 54 59 54 59 - 59 59 60 60 60 60 165 70 237 237 237 168 168 169 170 169 - 166 165 135 135 136 92 62 50 83 16 19 254 150 82 97 48 - 88 86 85 153 152 152 151 150 149 148 148 148 146 146 146 145 - 152 83 83 83 84 84 84 85 85 134 85 85 40 86 86 86 - 151 151 151 151 151 152 152 83 84 84 84 84 85 85 85 86 - 150 50 50 83 48 50 50 51 49 54 54 51 51 83 16 85 - 131 132 132 164 83 84 84 84 97 17 85 85 85 86 40 86 - 151 82 82 82 82 83 83 83 133 84 84 85 85 85 86 86 - 83 83 84 153 153 85 85 86 50 254 254 147 146 8 8 7 - 7 33 34 6 5 5 5 5 38 38 38 39 40 40 154 99 - 150 50 82 82 82 83 83 152 84 84 85 85 85 86 86 20 - 148 149 149 150 150 50 50 151 82 83 152 84 153 153 86 86 - 131 131 132 132 132 133 84 84 84 84 85 85 86 86 88 41 - 7 32 33 33 34 35 35 35 37 37 37 38 153 85 86 19 - 148 149 149 150 150 151 151 151 83 83 84 84 85 86 86 20 - 197 198 200 200 200 200 151 144 144 253 48 53 53 53 53 53 - 58 58 58 54 249 250 250 250 250 164 165 165 165 85 135 135 - 163 162 131 132 133 134 86 48 49 50 82 253 48 254 80 48 - 172 245 246 246 92 91 22 154 40 153 153 152 151 151 150 149 - 90 23 62 62 62 170 246 246 246 246 171 171 171 63 63 63 - 41 41 91 91 91 91 91 100 24 246 246 246 246 245 139 245 - 86 20 21 21 16 17 61 61 96 96 61 61 168 62 170 171 - 167 167 168 169 169 238 239 239 239 239 171 171 171 171 63 63 - 88 99 21 22 22 23 23 24 24 246 246 246 246 245 245 171 - 169 169 169 170 246 171 171 171 86 84 133 131 36 36 37 5 - 38 4 39 3 3 43 43 2 2 2 29 94 139 172 172 172 - 88 87 90 90 90 169 169 169 170 170 246 171 171 171 172 172 - 153 153 85 86 86 20 99 99 22 22 100 26 246 246 245 171 - 167 168 168 168 169 169 169 62 170 170 171 171 171 171 172 172 - 5 5 4 4 4 244 244 244 3 43 25 138 246 245 63 63 - 153 153 18 18 20 20 21 21 23 23 246 246 246 245 63 63 - 203 203 203 203 203 20 21 148 149 149 50 55 55 55 55 60 - 60 60 60 237 70 70 237 71 71 72 238 238 239 171 171 239 - 168 166 136 136 138 138 171 83 97 167 169 150 152 85 98 48 - 77 76 76 239 170 169 169 168 88 86 84 84 83 82 131 80 - 169 238 239 239 239 239 75 239 75 75 76 76 76 76 76 76 - 169 169 169 169 169 169 169 170 239 239 239 239 75 76 76 76 - 167 168 238 238 97 166 237 73 165 60 166 72 73 238 75 75 - 71 71 71 72 73 73 73 74 74 75 75 75 75 76 76 76 - 168 168 238 238 238 238 239 239 239 239 239 75 75 76 76 76 - 238 238 238 239 75 75 76 76 167 166 165 82 132 132 133 38 - 40 40 41 92 25 138 138 246 246 245 171 172 77 77 77 77 - 168 168 168 238 238 238 238 238 239 239 75 75 76 76 76 77 - 17 17 98 61 61 168 168 168 169 62 239 239 239 75 76 76 - 168 237 71 72 73 73 74 74 75 75 75 75 76 76 76 76 - 135 135 135 136 136 136 137 137 169 170 170 171 171 171 76 76 - 97 17 98 61 61 168 62 62 62 62 239 239 76 76 76 77 - 21 203 204 204 61 61 21 49 80 80 54 55 60 60 60 60 - 250 69 68 70 70 70 70 71 71 72 73 74 74 75 75 75 - 237 167 168 137 171 171 75 165 166 237 238 81 83 166 167 160 - 71 237 237 166 166 165 164 164 163 162 162 161 104 160 160 160 - 165 165 165 166 166 166 166 166 237 237 237 237 237 237 237 237 - 164 164 164 164 165 165 165 69 236 70 70 70 70 237 237 237 - 250 250 68 68 162 250 250 67 249 65 66 67 69 236 70 70 - 235 235 234 234 234 69 69 236 70 70 70 70 70 237 237 237 - 164 250 164 68 165 165 165 69 166 166 70 70 70 237 237 71 - 69 69 69 70 70 70 237 237 250 162 161 160 160 104 255 255 - 131 132 132 133 165 166 166 166 167 167 167 168 168 237 237 71 - 250 250 164 164 164 165 69 165 166 166 70 237 237 237 71 71 - 162 250 250 250 250 250 250 250 164 165 166 166 166 237 237 70 - 66 67 235 68 68 69 69 236 236 70 70 70 237 71 71 71 - 162 162 163 163 163 164 164 164 165 165 166 166 166 237 237 237 - 162 249 250 250 250 250 250 250 165 166 70 237 237 237 237 72 - 55 16 55 60 55 60 250 248 160 53 53 53 58 58 58 58 - 229 230 230 233 233 233 234 235 234 234 69 69 236 70 70 71 - 235 66 164 165 167 168 237 64 65 66 69 160 104 162 250 160 - 169 169 168 167 166 166 165 83 83 82 80 80 80 49 48 48 - 97 166 166 166 167 167 167 167 168 168 168 168 168 169 169 168 - 84 84 84 97 97 166 166 166 61 61 167 167 168 168 168 168 - 96 96 165 97 81 96 96 165 250 250 250 165 166 237 167 237 - 68 69 69 69 236 70 70 237 237 237 237 168 238 238 238 238 - 97 97 97 97 166 166 166 166 167 167 167 168 168 168 169 238 - 166 166 167 167 167 168 168 238 164 163 80 254 48 254 130 131 - 131 132 133 134 135 135 88 136 89 136 90 90 169 169 169 238 - 96 165 165 165 166 166 166 166 167 167 168 168 168 169 169 169 - 81 81 82 164 164 164 165 165 165 166 166 167 167 168 168 168 - 165 68 69 69 236 70 70 237 237 237 168 168 168 169 169 169 - 131 132 132 132 133 133 133 134 85 86 86 167 168 168 169 238 - 81 81 51 96 96 96 97 97 97 61 61 61 168 168 168 62 - 201 202 201 16 60 96 97 253 48 53 53 53 58 58 58 58 - 59 249 250 250 67 68 68 69 69 69 70 70 237 237 238 71 - 165 164 133 135 88 168 238 80 250 250 166 160 80 163 164 160 - 60 60 60 55 54 54 54 54 53 53 53 53 53 52 105 52 - 59 59 59 59 59 59 59 59 60 60 60 60 60 60 60 60 - 54 49 54 54 54 54 54 55 55 55 55 55 55 55 55 60 - 58 59 59 59 53 58 58 59 57 57 58 58 59 59 59 60 - 58 58 59 59 59 59 59 59 59 59 60 60 60 60 60 60 - 54 59 54 54 59 59 59 59 59 59 55 60 60 60 60 60 - 59 59 59 59 55 60 60 60 53 53 53 52 52 52 48 48 - 48 48 49 49 50 50 51 51 51 55 55 96 60 60 60 60 - 53 59 59 59 59 59 59 59 59 59 55 60 60 60 60 60 - 53 53 53 53 53 53 54 54 54 54 55 55 55 60 60 60 - 58 59 59 59 59 59 59 59 59 55 55 60 60 60 60 60 - 48 48 48 49 49 49 49 54 54 55 55 55 55 55 60 60 - 53 53 53 53 54 54 54 54 59 59 59 55 60 60 60 60 - 214 213 213 214 58 58 54 52 52 52 52 56 56 56 57 57 - 57 57 57 58 58 58 58 59 59 59 59 59 59 60 60 60 - 249 249 162 162 55 55 60 53 58 58 54 52 52 53 53 53 - 55 55 54 54 49 49 48 48 48 48 253 253 105 106 106 106 - 54 54 54 54 54 54 54 54 55 55 55 55 55 55 55 55 - 48 48 48 49 49 49 49 49 54 54 54 54 54 55 55 55 - 53 53 53 53 52 53 53 58 52 57 53 53 58 54 54 55 - 53 58 58 58 58 59 59 59 54 54 55 55 55 55 55 55 - 53 53 54 54 54 54 54 54 54 54 54 54 55 55 55 55 - 54 54 54 54 54 54 55 55 53 52 52 105 144 144 253 145 - 146 146 48 148 49 149 49 150 150 150 50 51 55 55 55 55 - 53 53 53 54 54 54 54 54 54 54 54 55 55 55 55 55 - 48 53 53 53 53 53 53 53 54 54 54 54 54 54 55 55 - 53 53 53 53 54 54 54 54 54 54 54 55 55 55 55 51 - 146 146 146 48 48 48 48 49 49 49 80 54 54 55 55 55 - 52 53 53 53 53 53 53 54 54 54 54 54 54 55 55 55 - 212 212 214 214 53 53 53 106 106 52 52 52 56 56 56 56 - 56 56 57 57 57 58 58 58 58 58 59 59 59 59 55 55 - 249 160 255 130 80 51 55 52 53 53 53 247 52 52 53 160 - 91 91 99 40 153 153 152 152 151 151 149 149 148 148 8 146 - 84 84 85 85 18 18 86 86 99 99 41 41 41 22 91 22 - 152 152 152 153 153 153 153 153 40 40 40 154 41 41 41 22 - 151 152 152 84 50 51 83 97 54 54 51 83 16 17 18 87 - 84 165 165 165 97 98 98 98 19 19 20 99 21 22 22 22 - 152 152 152 153 153 153 85 153 153 40 154 41 41 41 91 22 - 153 85 85 18 86 99 21 22 151 150 149 148 147 148 7 7 - 33 6 5 5 5 4 4 4 4 39 154 41 155 155 42 100 - 152 83 133 84 84 85 85 85 86 40 41 41 41 91 42 23 - 150 151 151 151 151 152 152 152 153 153 40 40 40 41 41 22 - 132 83 84 84 84 84 17 18 18 19 20 99 99 22 91 42 - 34 34 34 34 35 5 5 5 38 38 39 39 41 41 41 91 - 150 150 151 151 152 152 153 153 153 18 18 19 20 99 22 23 - 200 201 201 201 201 152 152 9 146 146 48 48 53 53 54 54 - 59 59 59 59 250 250 250 165 165 166 166 166 167 88 90 90 - 133 132 133 38 4 41 22 254 50 83 84 147 149 150 81 128 - 158 95 2 2 43 3 3 4 4 4 5 5 35 6 33 7 - 92 24 26 26 26 101 44 44 2 31 31 94 45 95 95 95 - 244 244 3 3 3 3 43 43 43 2 2 2 2 2 94 45 - 39 41 155 22 153 85 99 21 84 16 18 21 23 26 246 245 - 136 136 169 169 169 170 170 171 246 246 245 139 139 103 103 103 - 41 3 3 3 3 3 43 43 43 44 2 2 31 31 95 102 - 24 24 26 27 28 30 139 103 39 38 37 36 34 35 35 5 - 5 4 185 186 187 187 187 187 188 188 94 45 95 95 158 158 - 39 41 41 42 42 92 25 25 93 28 29 94 45 95 158 158 - 38 38 39 39 39 41 41 3 3 3 43 2 2 31 45 103 - 41 89 90 91 23 24 246 246 246 101 157 94 45 95 95 126 - 184 184 184 185 185 185 186 186 187 187 187 2 2 31 95 158 - 38 153 40 154 154 155 155 155 156 156 101 30 157 157 45 158 - 204 203 203 203 202 155 155 7 7 199 198 200 55 55 96 96 - 60 60 61 61 61 61 168 168 169 169 170 170 170 139 139 139 - 136 135 136 244 188 31 139 132 85 89 42 6 5 38 135 128 - 3 244 4 4 38 5 35 35 34 33 32 7 8 8 8 8 - 38 38 38 38 4 4 4 4 4 4 4 39 3 3 3 3 - 35 35 37 37 5 5 5 38 38 38 4 4 4 39 39 41 - 6 36 37 153 150 150 83 83 49 50 50 152 153 153 40 136 - 132 133 133 133 134 135 135 135 88 40 40 41 41 41 41 3 - 37 37 5 5 5 5 5 38 4 4 4 4 39 39 3 41 - 38 153 40 40 39 39 41 41 36 7 7 8 8 8 32 32 - 33 34 34 183 184 184 184 184 185 185 4 39 3 3 3 3 - 35 37 37 37 5 5 38 38 38 4 39 39 41 3 3 3 - 33 33 6 6 36 37 5 5 5 5 38 4 4 4 39 41 - 132 132 132 133 84 153 153 40 40 40 39 41 41 41 3 244 - 33 33 33 34 34 35 35 5 5 5 38 4 4 4 3 3 - 7 6 6 36 36 36 37 5 5 38 4 39 39 39 3 155 - 200 201 200 200 200 152 36 9 9 146 146 147 48 48 49 49 - 54 54 54 51 51 82 83 165 165 165 85 135 135 41 41 136 - 132 131 132 35 4 3 41 148 150 151 153 8 7 33 131 128 - 3 39 4 38 5 5 35 35 34 33 32 7 8 8 8 9 - 5 38 38 38 38 4 4 4 4 4 4 39 39 39 41 244 - 35 35 35 5 5 5 5 5 5 4 4 4 4 4 4 39 - 6 36 37 38 149 150 151 83 49 50 151 152 152 153 39 135 - 132 164 133 133 134 134 135 40 40 40 39 39 39 39 244 244 - 35 35 37 5 5 5 38 38 38 38 4 4 4 4 39 39 - 37 38 38 4 4 39 39 41 36 33 7 8 8 8 32 32 - 33 34 34 183 184 184 184 185 185 185 4 4 39 244 244 244 - 35 35 35 37 5 5 5 38 38 4 4 4 4 39 3 3 - 33 33 34 6 6 35 35 37 5 5 5 38 4 4 4 41 - 36 133 133 133 133 38 38 38 39 39 39 39 39 3 3 244 - 182 182 182 182 182 34 35 35 5 5 5 38 4 4 4 244 - 33 33 33 6 6 36 37 37 5 38 4 4 39 39 3 155 - 198 200 201 200 201 200 37 9 9 9 146 146 147 48 49 49 - 49 49 80 50 82 82 132 133 133 165 134 135 135 40 41 136 - 133 131 132 37 4 4 41 254 150 152 37 8 7 33 131 128 - 141 1 102 157 2 93 43 3 3 39 4 38 5 5 35 6 - 26 246 246 245 245 245 63 63 63 172 172 158 140 140 1 47 - 3 3 43 43 43 93 44 30 30 157 103 103 103 158 1 1 - 22 23 23 246 17 21 21 62 17 61 21 169 62 245 63 172 - 169 238 238 239 239 239 75 76 76 77 172 172 173 173 173 173 - 91 100 24 26 26 246 246 245 245 245 63 63 172 140 140 173 - 246 246 245 245 103 172 140 173 90 135 133 37 36 37 5 4 - 4 39 244 43 2 188 188 188 189 189 95 158 1 47 141 141 - 91 91 24 246 246 246 246 246 139 139 139 172 140 1 159 141 - 40 154 41 41 155 155 100 24 25 26 101 157 103 172 1 173 - 91 169 169 170 170 170 171 171 171 172 172 172 140 47 159 159 - 185 185 186 186 186 244 187 187 2 2 2 45 103 158 1 159 - 4 154 41 41 155 100 24 24 246 245 63 63 63 173 173 173 - 204 204 204 204 204 204 156 150 150 150 151 55 60 60 60 60 - 60 61 61 61 168 238 238 238 238 239 239 75 76 77 77 77 - 169 167 137 137 45 158 173 153 19 62 62 151 133 135 168 128 - 63 245 246 26 24 91 41 154 40 153 153 152 151 150 199 149 - 21 23 62 62 62 62 62 62 246 246 246 245 245 245 245 245 - 41 41 41 155 155 91 23 100 24 26 246 246 246 245 245 245 - 18 20 20 21 16 17 61 61 60 60 17 19 20 62 246 171 - 167 168 168 238 238 238 239 62 239 239 246 246 245 245 245 63 - 20 99 90 21 22 23 23 62 62 62 246 246 246 245 245 63 - 22 62 62 62 246 246 245 171 86 84 132 131 150 36 37 5 - 38 4 39 3 3 3 43 43 44 44 44 30 157 139 63 63 - 86 88 99 21 22 23 23 62 62 62 246 246 245 245 63 63 - 153 153 153 40 40 88 99 99 90 22 23 24 246 246 245 63 - 167 168 168 168 168 169 62 62 62 246 246 245 245 245 63 172 - 5 5 38 4 4 39 41 3 3 42 25 26 101 157 245 245 - 152 153 40 154 20 20 20 21 21 62 62 62 246 245 245 207 - 203 203 203 203 203 203 20 148 148 150 54 54 55 59 59 60 - 60 60 60 60 61 61 237 237 72 238 238 238 239 239 171 171 - 167 166 136 136 27 246 63 152 16 61 62 150 82 84 98 48 - 21 20 18 85 153 153 152 152 151 150 149 148 147 147 146 145 - 16 16 16 16 16 16 17 17 18 18 18 19 19 20 20 20 - 151 152 152 152 152 152 153 84 85 85 85 18 18 18 20 20 - 50 51 83 83 49 54 55 96 54 54 54 55 96 16 17 98 - 96 96 96 96 96 97 97 97 97 98 98 19 19 20 20 20 - 151 83 83 83 83 16 16 16 16 16 17 18 19 19 20 20 - 83 16 16 17 18 18 19 20 50 49 254 147 146 147 148 7 - 7 6 36 37 5 5 38 4 4 39 40 154 41 41 99 21 - 151 152 152 83 83 16 16 16 16 17 18 18 19 20 99 21 - 149 149 150 150 151 151 82 152 83 84 16 17 17 18 19 20 - 51 51 96 96 97 97 97 97 17 98 98 19 20 20 21 22 - 33 33 34 6 35 36 37 37 37 153 153 40 40 86 20 99 - 149 150 150 50 50 51 83 83 16 16 16 17 18 19 20 20 - 200 200 201 200 200 200 152 145 146 145 48 53 53 53 58 58 - 58 58 54 54 55 250 250 250 96 96 165 166 166 98 88 88 - 164 163 132 133 38 40 20 48 50 51 97 146 254 49 81 48 - 9 9 10 10 10 11 11 11 12 12 12 13 13 13 14 14 - 10 10 10 10 10 10 10 10 10 10 10 9 9 9 9 9 - 11 11 11 11 11 11 10 10 10 10 10 10 9 10 9 9 - 11 11 11 11 107 107 252 106 252 252 252 252 106 10 10 9 - 106 106 106 106 106 106 106 144 144 9 9 9 9 9 9 9 - 11 11 11 11 10 10 10 10 10 10 10 10 9 9 9 9 - 106 10 10 10 10 10 9 9 107 107 13 13 14 13 13 108 - 12 109 109 110 110 110 10 10 10 9 10 9 9 9 9 9 - 11 11 11 11 11 10 10 10 10 10 10 9 9 9 9 9 - 12 12 12 11 11 11 11 11 11 10 10 10 10 10 9 9 - 252 252 106 106 106 10 10 10 10 10 9 9 9 9 9 9 - 109 109 109 109 11 11 11 11 11 10 10 10 10 10 9 9 - 12 12 12 11 11 11 11 11 10 10 10 10 9 9 9 9 - 11 192 192 11 11 11 11 15 14 14 251 251 251 251 251 107 - 107 252 252 252 252 106 106 106 106 106 106 106 144 9 9 9 - 106 106 11 9 10 10 9 251 107 252 106 13 13 12 252 128 - 35 6 33 7 7 7 8 8 9 9 9 10 10 10 11 11 - 7 148 7 7 7 33 33 33 6 33 33 34 34 6 6 6 - 8 8 8 8 7 7 7 7 7 33 32 33 33 33 6 6 - 8 147 147 148 145 146 146 147 253 146 146 147 148 148 33 36 - 128 48 254 254 254 254 254 150 150 6 6 6 6 6 6 35 - 8 8 8 8 7 7 7 7 32 32 33 33 33 34 34 6 - 148 149 7 33 33 34 6 36 253 253 9 10 10 10 10 9 - 9 9 8 8 32 32 32 32 33 33 33 34 34 34 35 35 - 8 8 8 7 7 7 7 7 33 33 33 34 34 6 35 35 - 9 9 9 8 8 8 8 8 8 7 7 32 32 33 6 6 - 147 48 48 148 148 149 149 149 33 6 6 6 6 6 35 35 - 9 9 9 8 8 8 8 8 7 7 32 33 33 33 6 6 - 9 9 9 8 8 147 148 148 148 149 199 7 6 6 6 37 - 195 196 195 195 195 147 8 11 11 11 10 144 144 144 144 145 - 253 253 253 48 48 48 48 254 254 254 130 130 130 34 36 36 - 128 128 8 32 33 6 36 144 253 147 148 10 10 9 128 128 - 94 2 43 3 3 3 4 4 5 5 35 6 6 33 7 7 - 155 155 155 155 42 43 43 43 43 93 2 2 2 2 2 2 - 4 4 39 39 3 3 3 3 3 3 43 3 43 2 2 44 - 153 154 154 21 152 153 18 20 82 84 16 18 99 91 92 246 - 86 167 87 90 90 90 137 170 26 26 27 138 28 28 29 94 - 39 39 41 41 41 155 3 3 3 3 43 43 93 44 2 30 - 90 21 156 43 43 43 2 157 153 133 36 33 33 33 34 35 - 5 5 4 185 185 186 122 122 187 187 187 2 2 2 2 45 - 39 39 39 41 41 41 3 3 3 43 43 93 2 2 94 94 - 5 5 5 38 4 4 39 39 41 3 3 3 43 93 2 29 - 40 86 88 89 90 90 91 91 24 26 27 28 29 29 94 188 - 183 183 184 184 184 185 185 186 244 244 244 244 43 43 2 31 - 37 5 153 153 40 154 154 154 155 155 156 156 43 44 2 157 - 202 203 202 202 153 154 39 8 8 199 199 214 150 55 55 55 - 55 60 60 97 97 98 167 167 168 168 169 169 170 138 138 138 - 135 133 135 185 3 2 28 36 133 40 22 7 6 5 134 128 - 143 143 143 175 191 191 141 141 141 47 47 46 46 158 95 95 - 142 142 142 142 175 175 175 175 175 175 143 143 143 143 143 143 - 141 141 141 142 141 142 142 142 142 175 175 175 175 143 143 143 - 141 174 174 142 46 141 141 174 173 173 173 79 174 142 175 143 - 141 174 174 174 174 174 142 142 175 175 175 143 175 143 143 143 - 141 141 174 142 142 142 142 142 142 175 175 175 143 143 143 143 - 174 174 142 175 191 175 143 143 141 47 1 158 95 158 46 127 - 127 127 127 191 191 191 191 191 191 191 175 175 143 143 143 143 - 141 174 174 174 174 142 142 142 175 175 143 143 143 143 143 143 - 47 159 159 159 141 141 141 141 142 142 142 175 175 175 143 143 - 141 174 174 174 174 142 142 142 175 175 175 175 143 143 143 143 - 190 190 190 190 190 190 190 191 191 191 191 175 175 143 143 143 - 1 159 159 141 141 141 141 142 142 142 142 175 143 143 143 143 - 159 142 159 159 159 141 141 45 95 95 102 158 173 173 172 173 - 173 173 173 78 79 79 79 79 174 174 174 142 175 175 143 175 - 174 141 174 190 191 143 142 47 159 141 174 103 127 1 78 128 - 143 175 191 191 159 47 1 46 95 95 94 2 2 2 43 43 - 141 141 141 141 141 141 174 174 142 142 142 142 175 175 143 143 - 46 1 47 47 47 47 159 141 141 141 142 142 142 142 175 175 - 158 1 1 141 157 46 140 173 245 63 63 173 173 141 174 142 - 173 173 173 78 79 79 79 79 174 174 142 175 175 175 175 175 - 1 1 1 47 47 141 141 141 141 141 141 142 142 175 175 143 - 141 141 141 141 142 191 175 143 158 45 29 28 43 2 2 188 - 189 189 126 127 127 127 127 127 191 191 191 191 175 143 143 143 - 1 140 140 47 141 141 141 141 141 142 142 142 175 175 143 143 - 45 102 102 158 158 46 1 1 47 159 159 141 142 142 175 175 - 140 140 140 173 173 79 79 174 174 174 142 175 143 175 143 143 - 45 189 189 189 189 47 47 46 47 159 141 142 142 142 175 143 - 45 102 102 158 158 46 1 47 159 159 159 142 142 142 143 143 - 158 1 207 207 207 159 1 43 43 156 101 205 205 206 245 245 - 245 171 76 77 77 77 77 78 78 78 79 79 174 174 142 142 - 173 172 141 189 191 191 142 245 63 173 140 93 2 102 171 128 - 143 191 47 46 95 45 2 43 3 3 39 4 4 5 5 36 - 139 172 172 140 140 140 140 141 47 141 141 141 141 142 191 191 - 2 2 2 31 94 45 95 158 158 1 47 159 159 141 141 174 - 24 246 246 63 20 23 62 75 19 21 62 62 245 63 173 79 - 239 239 75 75 76 77 77 77 78 78 78 79 79 174 142 142 - 246 246 245 245 139 139 172 140 140 1 47 141 141 141 142 142 - 172 172 140 140 173 141 174 174 25 41 39 38 5 5 4 4 - 186 186 187 124 125 125 126 126 126 127 127 127 191 191 143 143 - 27 246 246 171 139 139 172 140 140 47 141 141 142 142 143 143 - 3 155 42 156 43 93 44 30 31 45 158 1 47 159 141 174 - 138 170 171 171 171 172 77 77 173 78 79 174 174 142 175 175 - 186 186 186 187 187 187 188 188 188 189 46 46 47 141 174 143 - 41 155 155 43 43 44 30 157 102 1 1 159 159 159 142 143 - 206 205 205 205 205 205 101 36 36 151 152 16 16 60 61 61 - 61 61 61 73 74 74 75 75 75 75 76 78 78 79 174 79 - 171 136 138 2 127 142 78 86 90 169 171 37 4 155 169 160 - 143 191 47 95 2 2 3 244 4 5 37 6 33 7 8 8 - 26 246 245 245 63 63 172 140 140 1 47 141 141 141 141 142 - 3 3 3 43 43 43 2 31 94 95 158 158 46 47 141 141 - 40 22 23 62 83 17 20 62 55 60 61 61 62 245 172 78 - 168 238 238 238 74 75 76 76 77 77 78 78 79 79 174 142 - 41 91 23 100 26 246 246 245 245 139 140 140 1 141 141 79 - 246 245 245 172 140 140 141 79 135 133 36 33 7 32 33 35 - 183 185 186 122 123 124 124 125 125 126 126 126 127 191 191 175 - 41 136 91 137 246 246 246 139 139 140 140 47 141 142 142 143 - 5 153 153 40 154 41 155 155 43 43 2 45 158 1 159 174 - 136 168 169 169 170 239 171 76 77 77 173 78 79 142 175 191 - 183 183 184 185 185 186 186 187 187 188 188 189 126 127 141 142 - 152 153 153 154 41 155 156 156 101 101 207 207 159 159 159 142 - 202 204 204 203 203 203 204 146 146 147 147 214 54 59 59 59 - 59 60 60 236 70 71 71 72 73 74 75 76 77 78 78 79 - 169 134 137 244 158 159 78 131 165 167 245 148 6 153 166 160 - 143 141 158 2 3 3 4 5 35 33 7 8 9 9 10 11 - 21 23 23 24 246 245 245 63 172 172 46 1 159 141 141 141 - 38 4 4 4 39 3 3 43 44 2 94 45 95 46 47 47 - 37 85 18 20 49 51 16 61 58 59 60 97 61 62 63 77 - 166 70 237 71 72 73 74 75 76 76 77 78 78 79 79 174 - 153 86 86 88 22 22 23 26 246 246 157 103 140 140 141 79 - 90 62 246 245 139 140 141 79 132 131 128 8 10 9 8 32 - 181 182 116 118 119 119 119 123 124 125 126 126 127 191 191 142 - 134 135 135 88 136 169 169 137 170 139 172 140 141 141 142 143 - 149 150 151 152 152 153 153 40 154 155 43 44 31 158 47 79 - 84 166 167 168 168 238 238 239 75 76 77 173 79 174 142 191 - 181 181 182 183 183 184 185 185 186 187 187 188 189 126 159 142 - 148 150 151 152 153 202 202 203 204 205 206 206 207 159 159 159 - 211 210 213 201 201 202 202 11 11 144 144 52 57 57 57 58 - 58 58 229 230 234 234 69 70 70 71 72 74 75 77 78 78 - 166 131 183 185 187 126 173 48 163 165 87 10 147 49 83 160 - 143 47 45 43 3 4 5 6 7 8 9 9 11 12 12 13 - 18 20 21 21 23 62 246 245 245 63 172 140 1 141 141 141 - 35 35 5 5 38 4 39 3 3 43 44 2 94 95 46 173 - 254 82 16 61 53 54 55 60 57 58 59 55 61 61 62 76 - 250 68 69 236 70 71 71 73 75 75 76 77 77 78 78 79 - 151 83 84 84 86 86 89 22 23 24 246 245 103 140 141 79 - 98 61 62 246 245 63 173 78 255 128 106 11 12 110 110 112 - 113 114 115 116 117 118 119 119 123 124 125 125 126 127 191 142 - 131 163 164 165 166 167 168 136 137 170 139 172 140 159 142 143 - 146 147 148 149 150 150 151 153 153 39 41 43 44 102 1 78 - 163 250 68 69 70 237 71 238 238 239 76 172 173 141 142 191 - 179 179 180 181 182 182 183 184 184 186 186 187 188 189 47 142 - 145 196 196 197 200 201 201 202 203 204 205 205 206 207 159 159 - 209 209 210 212 213 200 152 14 13 251 218 219 221 222 225 225 - 226 226 227 228 229 230 233 234 236 236 70 71 73 75 77 76 - 162 161 241 184 186 189 77 105 104 163 165 251 144 48 80 48 - 143 47 2 3 4 5 6 7 8 9 10 11 13 14 15 215 - 84 17 17 19 20 21 23 246 246 246 245 103 140 173 141 141 - 33 33 34 35 35 5 38 39 39 3 43 93 2 94 95 140 - 147 49 50 55 247 53 54 60 56 56 58 59 60 61 62 75 - 249 65 233 234 236 70 71 72 73 74 75 75 76 77 78 78 - 254 50 50 82 84 84 85 88 99 22 24 246 245 172 173 78 - 97 166 61 23 246 245 173 78 160 105 252 251 14 108 109 110 - 111 113 114 115 116 117 118 118 119 119 124 125 126 127 191 175 - 130 130 131 132 133 134 135 135 136 137 246 139 140 47 174 143 - 144 144 145 146 147 148 199 150 151 153 40 41 43 30 158 173 - 161 162 163 164 165 166 237 237 238 239 239 76 173 79 174 191 - 176 177 178 178 179 180 182 183 183 184 185 186 187 188 46 142 - 144 144 194 195 196 197 200 201 202 203 204 205 206 207 159 159 - 209 208 210 211 212 213 198 215 216 216 218 218 220 220 220 222 - 224 224 226 226 228 229 229 230 234 234 236 70 71 75 76 76 - 65 161 241 184 185 188 77 252 248 64 165 216 252 253 48 104 - 143 47 2 3 5 6 7 8 10 11 12 13 14 15 15 215 - 51 96 16 16 17 19 21 23 24 26 246 245 172 140 173 47 - 8 32 32 33 34 35 5 5 4 4 244 3 43 2 95 172 - 253 48 49 54 247 52 53 59 219 225 56 58 59 60 62 75 - 162 64 65 233 234 69 70 237 73 73 74 75 75 76 78 78 - 147 254 49 80 50 83 83 85 86 88 91 24 246 63 173 78 - 96 60 61 61 62 245 172 77 105 252 251 215 15 15 108 108 - 110 111 113 114 115 116 116 117 118 119 123 125 126 127 191 175 - 128 255 255 255 131 132 133 134 88 168 170 246 172 140 141 143 - 11 11 144 144 145 146 147 148 149 151 153 40 155 43 102 173 - 160 104 64 162 163 164 166 237 237 238 239 76 77 79 174 191 - 177 176 176 176 177 179 180 181 182 183 184 185 187 188 46 142 - 11 192 144 144 195 196 197 198 201 202 203 204 205 207 159 159 - 209 208 209 210 211 212 197 215 215 216 217 218 219 220 220 220 - 222 224 224 226 226 228 228 229 230 233 234 236 71 73 76 76 - 65 161 241 184 184 188 77 252 247 53 163 215 14 252 105 160 - 143 46 43 4 35 7 8 10 11 12 14 15 15 15 15 215 - 49 55 55 96 97 17 19 21 22 24 26 246 63 172 140 173 - 9 9 8 8 32 33 34 35 5 38 4 244 3 2 94 103 - 106 48 48 54 217 52 52 58 219 222 225 56 58 60 61 74 - 248 64 232 232 233 234 234 70 71 72 73 74 75 76 77 78 - 253 48 48 48 49 50 82 83 84 85 89 91 26 245 172 77 - 54 60 60 61 62 62 171 77 106 252 216 215 215 15 15 14 - 108 110 111 113 115 115 116 116 117 118 119 123 125 126 191 142 - 106 105 160 160 255 162 132 132 134 167 136 170 139 140 141 175 - 251 107 252 11 144 144 145 147 148 150 152 153 154 43 31 77 - 105 248 64 64 64 250 164 69 70 237 238 239 172 173 174 191 - 109 176 176 176 176 177 178 180 181 182 183 185 186 187 95 141 - 13 252 11 11 144 194 195 214 198 201 202 203 205 206 207 159 - 209 208 209 210 211 212 195 215 215 216 216 218 219 220 220 220 - 220 222 224 224 226 226 227 228 229 230 234 234 70 71 75 75 - 65 161 241 184 184 188 63 216 252 248 104 215 215 251 106 160 - 143 95 3 38 33 7 9 11 12 14 15 15 15 15 15 215 - 49 54 54 55 55 16 17 19 20 23 23 246 245 63 140 173 - 10 10 9 8 8 8 32 34 35 5 4 4 244 43 2 245 - 252 105 253 53 217 52 52 58 219 220 223 56 58 59 61 73 - 248 228 228 229 230 233 234 236 70 71 72 73 74 75 77 78 - 144 253 146 48 48 49 150 50 83 84 86 99 100 246 172 77 - 54 54 60 97 61 62 171 77 252 251 215 215 215 15 15 15 - 14 108 110 113 115 115 115 116 116 117 119 123 125 126 127 174 - 106 247 105 160 160 255 162 162 133 135 136 137 171 140 141 175 - 215 251 251 107 252 10 144 145 146 148 150 152 40 155 2 172 - 247 248 248 160 65 64 66 68 69 237 238 239 171 173 174 143 - 14 108 110 176 176 176 177 178 180 181 182 184 186 187 95 141 - 216 216 251 252 144 144 194 195 197 200 201 203 204 206 207 207 - 208 208 208 209 211 194 144 215 15 215 216 217 219 220 220 220 - 220 221 224 224 224 226 226 227 228 229 230 234 236 71 75 75 - 65 160 241 184 183 187 207 216 247 247 53 215 215 14 252 160 - 143 95 3 5 7 8 10 12 13 15 15 15 15 15 15 215 - 48 54 54 54 55 96 16 17 19 20 23 62 246 245 172 46 - 11 11 10 9 9 8 7 7 33 5 5 4 4 3 43 245 - 252 247 247 53 217 218 52 57 218 219 221 224 57 59 61 73 - 56 227 227 228 229 230 233 234 236 70 71 73 73 75 77 77 - 106 105 105 253 48 48 48 150 50 152 84 86 91 26 139 77 - 53 59 250 163 17 23 246 77 252 216 215 215 215 15 15 15 - 15 14 109 111 113 115 115 115 116 117 118 119 124 126 190 174 - 252 247 247 247 160 160 161 161 163 165 135 136 138 172 141 175 - 215 215 14 251 107 252 252 144 145 195 199 151 153 155 2 172 - 252 247 248 248 64 64 65 66 68 70 237 239 171 173 79 175 - 15 14 14 108 176 176 176 177 178 180 182 183 184 186 94 79 - 216 216 216 251 252 192 192 194 196 197 201 202 203 156 207 207 - 208 208 209 210 218 144 10 15 15 215 216 217 219 220 220 220 - 219 220 221 224 224 224 226 226 240 240 240 233 234 71 74 75 - 65 160 241 184 183 3 157 216 217 247 52 216 215 215 251 160 - 143 94 3 35 8 9 11 13 15 15 15 15 15 15 15 215 - 53 53 53 54 54 55 55 16 17 19 21 23 246 245 63 158 - 12 109 11 10 10 9 8 7 7 35 35 5 4 244 43 245 - 216 247 247 52 217 218 56 56 218 219 220 222 56 58 60 72 - 247 226 226 226 228 229 230 234 69 236 70 71 73 74 76 77 - 252 252 105 105 105 48 48 49 49 50 83 85 99 24 245 77 - 53 58 249 55 16 23 62 77 252 215 215 15 15 15 15 15 - 15 15 108 110 113 114 115 115 116 116 118 119 124 126 127 174 - 252 252 247 247 247 160 160 104 162 164 166 136 170 139 141 175 - 215 216 216 216 251 107 107 11 144 145 148 150 152 39 43 63 - 252 247 248 247 248 64 64 66 67 69 70 238 239 77 79 175 - 15 15 15 14 108 176 176 176 178 179 181 182 184 186 188 141 - 216 216 216 216 217 144 192 144 195 214 198 202 203 205 206 207 - 208 208 209 218 218 218 192 15 215 215 216 217 218 219 220 220 - 220 220 220 224 224 224 224 226 240 240 240 240 233 70 73 74 - 65 161 241 185 182 3 157 216 216 247 52 216 215 215 251 160 - 143 31 4 34 8 10 12 14 15 15 15 15 15 15 15 215 - 52 53 53 53 54 55 55 96 16 17 19 23 246 246 245 103 - 13 108 109 11 11 10 9 8 7 33 34 5 38 244 3 246 - 216 247 247 247 217 218 218 56 218 218 219 220 225 57 60 72 - 247 56 226 226 228 228 229 230 234 69 70 71 71 73 76 76 - 252 251 252 247 105 105 48 48 49 49 82 153 88 23 246 76 - 52 57 58 54 16 19 62 76 251 215 215 15 15 15 15 15 - 15 15 14 110 113 113 114 115 115 116 117 119 123 125 127 174 - 251 247 247 247 247 248 248 160 161 163 165 88 137 139 140 175 - 215 215 216 216 215 14 251 107 11 144 146 149 36 4 156 207 - 252 247 247 248 248 248 64 65 66 68 236 237 239 77 79 175 - 15 15 15 15 14 14 176 176 176 178 180 182 183 185 188 46 - 215 216 216 216 216 217 144 192 194 214 198 200 203 205 206 207 - 208 208 210 219 219 218 217 215 15 215 216 216 218 219 219 220 - 220 220 220 221 224 224 224 225 240 240 240 240 233 236 72 74 - 65 160 241 184 182 244 2 215 216 247 247 215 215 215 215 160 -])) - -data diff --git a/demo/mod/first_person3d.fnl b/demo/mod/first_person3d.fnl deleted file mode 100644 index c7a7af3..0000000 --- a/demo/mod/first_person3d.fnl +++ /dev/null @@ -1,516 +0,0 @@ -(local pxl8 (require :pxl8)) -(local effects (require :pxl8.effects)) -(local net (require :pxl8.net)) - -(local colormap (require :mod.colormap)) -(local menu (require :mod.menu)) -(local palette (require :mod.palette)) -(local sky (require :mod.sky)) -(local textures (require :mod.textures)) - -(local bob-amount 4.0) -(local bob-speed 8.0) -(local cam-smoothing 0.25) -(local cell-size 64) -(local cursor-sensitivity 0.010) -(local gravity -800) -(local grid-size 64) -(local ground-y 64) -(local jump-force 175) -(local land-recovery-speed 20) -(local land-squash-amount -4) -(local max-pitch 1.5) -(local move-speed 200) -(local turn-speed 4.0) - -(local sim-tick-rate 60) -(local sim-dt (/ 1.0 sim-tick-rate)) -(local history-size 128) -(local correction-threshold 1.0) - -(var auto-run? false) -(var auto-run-cancel-key nil) -(var bob-time 0) -(var cam-pitch 0) -(var cam-x 1000) -(var cam-y 64) -(var cam-yaw 0) -(var cam-z 1000) -(var camera nil) -(var grounded? true) -(var land-squash 0) -(var light-time 0) -(var real-time 0) -(var network nil) -(var smooth-cam-x 1000) -(var smooth-cam-z 1000) -(var velocity-y 0) -(var world nil) -(var fps-avg 0) -(var fps-sample-count 0) -(var fireball-mesh nil) -(var last-dt 0.016) - -(local cursor-look? true) -(local FIREBALL_COLOR 218) -(local STONE_FLOOR_START 37) -(local STONE_WALL_START 2) -(local MOSS_COLOR 200) - -(local trail-positions []) -(local TRAIL_LENGTH 8) - -(fn create-fireball-mesh [] - (let [verts [] - indices [] - radius 5 - rings 4 - segments 6 - core-color (+ FIREBALL_COLOR 6) - spike-color (+ FIREBALL_COLOR 2)] - - ;; top pole - (table.insert verts {:x 0 :y radius :z 0 :nx 0 :ny 1 :nz 0 :color core-color :light 255}) - - ;; sphere rings - (for [ring 1 (- rings 1)] - (let [phi (* (/ ring rings) math.pi) - sin-phi (math.sin phi) - cos-phi (math.cos phi) - y (* radius cos-phi) - ring-radius (* radius sin-phi)] - (for [seg 0 (- segments 1)] - (let [theta (* (/ seg segments) math.pi 2) - x (* ring-radius (math.cos theta)) - z (* ring-radius (math.sin theta)) - nx (* sin-phi (math.cos theta)) - nz (* sin-phi (math.sin theta))] - (table.insert verts {:x x :y y :z z :nx nx :ny cos-phi :nz nz :color core-color :light 255}))))) - - ;; bottom pole - (let [bottom-idx (length verts)] - (table.insert verts {:x 0 :y (- radius) :z 0 :nx 0 :ny -1 :nz 0 :color core-color :light 255}) - - ;; top cap triangles - (for [seg 0 (- segments 1)] - (let [next-seg (% (+ seg 1) segments)] - (table.insert indices 0) - (table.insert indices (+ 1 next-seg)) - (table.insert indices (+ 1 seg)))) - - ;; middle quads - (for [ring 0 (- rings 3)] - (for [seg 0 (- segments 1)] - (let [next-seg (% (+ seg 1) segments) - curr-row (+ 1 (* ring segments)) - next-row (+ 1 (* (+ ring 1) segments))] - (table.insert indices (+ curr-row seg)) - (table.insert indices (+ curr-row next-seg)) - (table.insert indices (+ next-row seg)) - (table.insert indices (+ curr-row next-seg)) - (table.insert indices (+ next-row next-seg)) - (table.insert indices (+ next-row seg))))) - - ;; bottom cap triangles - (let [last-ring-start (+ 1 (* (- rings 2) segments))] - (for [seg 0 (- segments 1)] - (let [next-seg (% (+ seg 1) segments)] - (table.insert indices bottom-idx) - (table.insert indices (+ last-ring-start seg)) - (table.insert indices (+ last-ring-start next-seg)))))) - - ;; add spikes - evenly distributed using golden ratio - (let [num-spikes 12 - spike-len 8 - base-size 1.2 - golden-ratio (/ (+ 1 (math.sqrt 5)) 2)] - (for [i 0 (- num-spikes 1)] - (let [;; fibonacci sphere distribution - y (- 1 (* (/ i (- num-spikes 1)) 2)) - r-at-y (math.sqrt (- 1 (* y y))) - theta (* math.pi 2 i golden-ratio) - nx (* r-at-y (math.cos theta)) - ny y - nz (* r-at-y (math.sin theta)) - ;; tangent vectors for base - tx (if (> (math.abs ny) 0.9) 1 0) - ty (if (> (math.abs ny) 0.9) 0 1) - tz 0 - ;; cross product for perpendicular - px (- (* ty nz) (* tz ny)) - py (- (* tz nx) (* tx nz)) - pz (- (* tx ny) (* ty nx)) - pl (math.sqrt (+ (* px px) (* py py) (* pz pz))) - px (/ px pl) py (/ py pl) pz (/ pz pl) - ;; second perpendicular - qx (- (* ny pz) (* nz py)) - qy (- (* nz px) (* nx pz)) - qz (- (* nx py) (* ny px)) - ;; base center inside sphere - bx (* radius 0.8 nx) - by (* radius 0.8 ny) - bz (* radius 0.8 nz) - ;; spike tip - sx (* (+ radius spike-len) nx) - sy (* (+ radius spike-len) ny) - sz (* (+ radius spike-len) nz) - base-idx (length verts)] - ;; 4 base vertices forming a square - (table.insert verts {:x (+ bx (* base-size px) (* base-size qx)) - :y (+ by (* base-size py) (* base-size qy)) - :z (+ bz (* base-size pz) (* base-size qz)) - :nx nx :ny ny :nz nz :color core-color :light 255}) - (table.insert verts {:x (+ bx (* base-size px) (* (- base-size) qx)) - :y (+ by (* base-size py) (* (- base-size) qy)) - :z (+ bz (* base-size pz) (* (- base-size) qz)) - :nx nx :ny ny :nz nz :color core-color :light 255}) - (table.insert verts {:x (+ bx (* (- base-size) px) (* (- base-size) qx)) - :y (+ by (* (- base-size) py) (* (- base-size) qy)) - :z (+ bz (* (- base-size) pz) (* (- base-size) qz)) - :nx nx :ny ny :nz nz :color core-color :light 255}) - (table.insert verts {:x (+ bx (* (- base-size) px) (* base-size qx)) - :y (+ by (* (- base-size) py) (* base-size qy)) - :z (+ bz (* (- base-size) pz) (* base-size qz)) - :nx nx :ny ny :nz nz :color core-color :light 255}) - ;; spike tip - (table.insert verts {:x sx :y sy :z sz :nx nx :ny ny :nz nz :color spike-color :light 255}) - ;; 4 triangular faces of pyramid - (table.insert indices base-idx) - (table.insert indices (+ base-idx 1)) - (table.insert indices (+ base-idx 4)) - (table.insert indices (+ base-idx 1)) - (table.insert indices (+ base-idx 2)) - (table.insert indices (+ base-idx 4)) - (table.insert indices (+ base-idx 2)) - (table.insert indices (+ base-idx 3)) - (table.insert indices (+ base-idx 4)) - (table.insert indices (+ base-idx 3)) - (table.insert indices base-idx) - (table.insert indices (+ base-idx 4))))) - - (set fireball-mesh (pxl8.create_mesh verts indices)))) - -(var client-tick 0) -(var last-processed-tick 0) -(var time-accumulator 0) -(var position-history {}) -(var pending-inputs {}) - -(fn history-idx [tick] - (+ 1 (% tick history-size))) - -(fn store-position [tick x z yaw] - (tset position-history (history-idx tick) {:tick tick :x x :z z :yaw yaw})) - -(fn get-position [tick] - (let [entry (. position-history (history-idx tick))] - (when (and entry (= entry.tick tick)) - entry))) - -(fn store-pending-input [tick input] - (tset pending-inputs (history-idx tick) {:tick tick :input input})) - -(fn get-pending-input [tick] - (let [entry (. pending-inputs (history-idx tick))] - (when (and entry (= entry.tick tick)) - entry.input))) - -(fn apply-movement [x z yaw input] - (var new-x x) - (var new-z z) - - (let [move-forward (or input.move_y 0) - move-right (or input.move_x 0)] - (when (or (not= move-forward 0) (not= move-right 0)) - (let [forward-x (- (math.sin yaw)) - forward-z (- (math.cos yaw)) - right-x (math.cos yaw) - right-z (- (math.sin yaw)) - len (math.sqrt (+ (* move-forward move-forward) (* move-right move-right))) - norm-forward (/ move-forward len) - norm-right (/ move-right len) - move-delta (* move-speed sim-dt)] - (set new-x (+ new-x (* move-delta (+ (* forward-x norm-forward) (* right-x norm-right))))) - (set new-z (+ new-z (* move-delta (+ (* forward-z norm-forward) (* right-z norm-right)))))))) - - (values new-x new-z)) -(fn init [] - (pxl8.set_relative_mouse_mode true) - (pxl8.set_palette palette 256) - (pxl8.set_colormap colormap 16384) - (for [i 0 7] - (let [t (/ i 7) - r 0xFF - g (math.floor (+ 0x60 (* t (- 0xE0 0x60)))) - b (math.floor (+ 0x10 (* t (- 0x80 0x10))))] - (pxl8.set_palette_rgb (+ FIREBALL_COLOR i) r g b))) - (sky.update-gradient 1 2 6 6 10 18) - (pxl8.update_palette_deps) - (set camera (pxl8.create_camera_3d)) - (set world (pxl8.create_world)) - (sky.generate-stars 12345) - (create-fireball-mesh) - - (set network (net.Net.new {:port 7777})) - (when network - (network:connect) - (network:spawn cam-x cam-y cam-z cam-yaw cam-pitch)) - - (let [result (world:generate { - :type pxl8.PROCGEN_ROOMS - :width 64 - :height 64 - :seed 42 - :min_room_size 5 - :max_room_size 10 - :num_rooms 20})] - (if (< result 0) - (pxl8.error (.. "Failed to generate rooms - result: " result)) - (let [floor-tex (textures.mossy-cobblestone 44444 STONE_FLOOR_START MOSS_COLOR) - wall-tex (textures.ashlar-wall 55555 STONE_WALL_START MOSS_COLOR) - sky-tex (pxl8.create_texture [0] 1 1)] - - (let [result (world:apply_textures [ - {:name "floor" - :texture_id floor-tex - :rule (fn [normal] (> normal.y 0.7))} - {:name "ceiling" - :texture_id sky-tex - :rule (fn [normal] (< normal.y -0.7))} - {:name "wall" - :texture_id wall-tex - :rule (fn [normal] (and (<= normal.y 0.7) (>= normal.y -0.7)))}])] - (when (< result 0) - (pxl8.error (.. "Failed to apply textures - result: " result)))))))) - -(fn sample-input [] - (var move-forward 0) - (var move-right 0) - - (when (pxl8.key_pressed "`") - (set auto-run? (not auto-run?)) - (when (and auto-run? (pxl8.key_down "w")) - (set auto-run-cancel-key "w"))) - (when (and auto-run? (not auto-run-cancel-key) (or (pxl8.key_down "w") (pxl8.key_down "s"))) - (set auto-run? false) - (when (pxl8.key_down "s") - (set auto-run-cancel-key "s"))) - (when (and auto-run-cancel-key (not (pxl8.key_down auto-run-cancel-key))) - (set auto-run-cancel-key nil)) - - (when (or (pxl8.key_down "w") auto-run?) - (set move-forward (+ move-forward 1))) - (when (and (pxl8.key_down "s") (not= auto-run-cancel-key "s")) - (set move-forward (- move-forward 1))) - (when (pxl8.key_down "a") - (set move-right (- move-right 1))) - (when (pxl8.key_down "d") - (set move-right (+ move-right 1))) - - {:move_x move-right - :move_y move-forward - :look_dx (pxl8.mouse_dx) - :look_dy (pxl8.mouse_dy)}) - -(fn reconcile [server-tick server-x server-z] - (let [predicted (get-position server-tick)] - (when predicted - (let [dx (- predicted.x server-x) - dz (- predicted.z server-z) - error (math.sqrt (+ (* dx dx) (* dz dz)))] - (when (> error correction-threshold) - (set cam-x server-x) - (set cam-z server-z) - - (for [t (+ server-tick 1) client-tick] - (let [input (get-pending-input t) - hist (get-position t)] - (when (and input hist) - (let [(new-x new-z) (apply-movement cam-x cam-z hist.yaw input)] - (set cam-x new-x) - (set cam-z new-z) - (store-position t cam-x cam-z hist.yaw)))))))))) - -(fn update [dt] - (set last-dt dt) - (let [fps (pxl8.get_fps)] - (set fps-sample-count (+ fps-sample-count 1)) - (set fps-avg (+ (* fps-avg (/ (- fps-sample-count 1) fps-sample-count)) - (/ fps fps-sample-count))) - (when (>= fps-sample-count 120) - (set fps-sample-count 0) - (set fps-avg 0))) - - (when (world:is_loaded) - (let [input (sample-input) - grid-max (* grid-size cell-size) - movement-yaw cam-yaw] - - (set time-accumulator (+ time-accumulator dt)) - - (while (>= time-accumulator sim-dt) - (set time-accumulator (- time-accumulator sim-dt)) - (set client-tick (+ client-tick 1)) - - (store-pending-input client-tick input) - - (let [(new-x new-z) (apply-movement cam-x cam-z movement-yaw input)] - (when (and (>= new-x 0) (<= new-x grid-max) - (>= new-z 0) (<= new-z grid-max)) - (let [(resolved-x _ resolved-z) (world:resolve_collision cam-x cam-y cam-z new-x cam-y new-z 5)] - (set cam-x resolved-x) - (set cam-z resolved-z))) - - (store-position client-tick cam-x cam-z movement-yaw))) - - (when cursor-look? - (set cam-yaw (- cam-yaw (* input.look_dx cursor-sensitivity))) - (set cam-pitch (math.max (- max-pitch) - (math.min max-pitch - (- cam-pitch (* input.look_dy cursor-sensitivity)))))) - - (when (and (not cursor-look?) (pxl8.key_down "up")) - (set cam-pitch (math.min max-pitch (+ cam-pitch (* turn-speed dt))))) - (when (and (not cursor-look?) (pxl8.key_down "down")) - (set cam-pitch (math.max (- max-pitch) (- cam-pitch (* turn-speed dt))))) - (when (and (not cursor-look?) (pxl8.key_down "left")) - (set cam-yaw (- cam-yaw (* turn-speed dt)))) - (when (and (not cursor-look?) (pxl8.key_down "right")) - (set cam-yaw (+ cam-yaw (* turn-speed dt)))) - - (when network - (let [(ok err) (pcall (fn [] - (network:send_input {:move_x input.move_x - :move_y input.move_y - :look_dx input.look_dx - :look_dy input.look_dy - :yaw movement-yaw - :tick client-tick}) - (network:update dt) - (when (network:poll) - (let [snapshot (network:snapshot)] - (when (and snapshot (> snapshot.tick last-processed-tick)) - (set last-processed-tick snapshot.tick) - (let [player-id (network:player_id)] - (when (> player-id 0) - (let [curr (network:entity_userdata player-id)] - (when curr - (let [srv-x (pxl8.unpack_f32_be curr 0) - srv-z (pxl8.unpack_f32_be curr 8)] - (reconcile snapshot.tick srv-x srv-z)))))))))))] - (when (not ok) - (pxl8.error (.. "Network error: " err))))) - - (set smooth-cam-x (+ (* smooth-cam-x (- 1 cam-smoothing)) (* cam-x cam-smoothing))) - (set smooth-cam-z (+ (* smooth-cam-z (- 1 cam-smoothing)) (* cam-z cam-smoothing))) - - (when (and (pxl8.key_pressed "space") grounded?) - (set velocity-y jump-force) - (set grounded? false)) - - (set velocity-y (+ velocity-y (* gravity dt))) - (set cam-y (+ cam-y (* velocity-y dt))) - - (when (<= cam-y ground-y) - (when (not grounded?) - (set land-squash land-squash-amount)) - (set cam-y ground-y) - (set velocity-y 0) - (set grounded? true)) - - (when (< land-squash 0) - (set land-squash (math.min 0 (+ land-squash (* land-recovery-speed dt))))) - - (let [moving (or (not= input.move_x 0) (not= input.move_y 0))] - (if (and moving grounded?) - (set bob-time (+ bob-time (* dt bob-speed))) - (let [target-phase (* (math.floor (/ bob-time math.pi)) math.pi)] - (set bob-time (+ (* bob-time 0.8) (* target-phase 0.2)))))) - - (set light-time (+ light-time (* dt 0.5))) - (set real-time (+ real-time dt))))) - -(fn frame [] - (pxl8.clear 1) - - (when (not camera) - (pxl8.error "camera is nil!")) - - (when (not world) - (pxl8.error "world is nil!")) - - (when (and world (not (world:is_loaded))) - (pxl8.text "World not loaded yet..." 5 30 12)) - - (when (and camera world (world:is_loaded)) - (let [bob-offset (* (math.sin bob-time) bob-amount) - eye-y (+ cam-y bob-offset land-squash) - forward-x (- (math.sin cam-yaw)) - forward-z (- (math.cos cam-yaw)) - target-x (+ smooth-cam-x forward-x) - target-y (+ eye-y (math.sin cam-pitch)) - target-z (+ smooth-cam-z forward-z) - aspect (/ (pxl8.get_width) (pxl8.get_height))] - - (camera:lookat [smooth-cam-x eye-y smooth-cam-z] - [target-x target-y target-z] - [0 1 0]) - (camera:set_perspective 1.047 aspect 1.0 4096.0) - - (let [light-x (+ 1000 (* 50 (math.cos light-time))) - light-z (+ 940 (* 50 (math.sin light-time))) - light-y 80 - phase (+ (* light-x 0.01) 1.7) - f1 (* 0.08 (math.sin (+ (* real-time 2.5) phase))) - f2 (* 0.05 (math.sin (+ (* real-time 4.1) (* phase 0.7)))) - f3 (* 0.03 (math.sin (+ (* real-time 7.3) (* phase 1.2)))) - flicker (+ 0.92 f1 f2 f3) - light-intensity (math.floor (math.max 0 (math.min 255 (* 255 flicker)))) - r1 (* 0.06 (math.sin (+ (* real-time 1.8) (* phase 0.5)))) - r2 (* 0.04 (math.sin (+ (* real-time 3.2) phase))) - light-radius (* 150 (+ 0.95 r1 r2))] - (pxl8.begin_frame_3d camera { - :ambient 30 - :fog_density 0.0 - :celestial_dir [0.5 -0.8 0.3] - :celestial_intensity 0.5 - :lights [{:x light-x :y light-y :z light-z - :r 255 :g 200 :b 150 - :intensity light-intensity - :radius light-radius}]}) - (pxl8.clear_depth) - - (sky.update-gradient 1 2 6 6 10 18) - (sky.render smooth-cam-x eye-y smooth-cam-z (menu.is-wireframe)) - (pxl8.clear_depth) - - (world:set_wireframe (menu.is-wireframe) 15) - (world:render [smooth-cam-x eye-y smooth-cam-z]) - - (when fireball-mesh - (let [wire (menu.is-wireframe)] - (pxl8.draw_mesh fireball-mesh {:x light-x :y light-y :z light-z - :passthrough true - :wireframe wire - :emissive 1.0}))) - - (pxl8.end_frame_3d)) - - (sky.render-stars cam-yaw cam-pitch 1.0 last-dt) - - (let [cx (/ (pxl8.get_width) 2) - cy (/ (pxl8.get_height) 2) - crosshair-size 4 - crosshair-color 240 - text-color 251] - (pxl8.line (- cx crosshair-size) cy (+ cx crosshair-size) cy crosshair-color) - (pxl8.line cx (- cy crosshair-size) cx (+ cy crosshair-size) crosshair-color) - - (pxl8.text (.. "fps: " (string.format "%.0f" fps-avg)) 5 5 text-color) - (pxl8.text (.. "pos: " (string.format "%.0f" cam-x) "," - (string.format "%.0f" cam-y) "," - (string.format "%.0f" cam-z)) 5 15 text-color))))) - -{:init init - :update update - :frame frame} diff --git a/demo/mod/menu.fnl b/demo/mod/menu.fnl index dca9f0e..34ee9e0 100644 --- a/demo/mod/menu.fnl +++ b/demo/mod/menu.fnl @@ -1,8 +1,6 @@ (local pxl8 (require :pxl8)) -(local music (require :mod.music)) (var paused false) -(var wireframe false) (var gui nil) (fn init [] @@ -38,22 +36,12 @@ (when gui (gui:begin_frame) - (pxl8.gui_window 200 100 240 200 "pxl8 demo") + (pxl8.gui_window 200 100 240 140 "pxl8 demo") - (when (gui:button 1 215 140 210 30 "Resume") + (when (gui:button 1 215 145 210 32 "Resume") (hide)) - (let [music-label (if (music.is-playing) "Music: On" "Music: Off")] - (when (gui:button 3 215 175 210 30 music-label) - (if (music.is-playing) - (music.stop) - (music.start)))) - - (let [wire-label (if wireframe "Wireframe: On" "Wireframe: Off")] - (when (gui:button 4 215 210 210 30 wire-label) - (set wireframe (not wireframe)))) - - (when (gui:button 2 215 245 210 30 "Quit") + (when (gui:button 2 215 185 210 32 "Quit") (pxl8.quit)) (if (gui:is_hovering) @@ -63,7 +51,6 @@ (gui:end_frame))) {:is-paused (fn [] paused) - :is-wireframe (fn [] wireframe) :toggle toggle :show show :hide hide diff --git a/demo/mod/music.fnl b/demo/mod/music.fnl index a4e83e4..cdbfc6a 100644 --- a/demo/mod/music.fnl +++ b/demo/mod/music.fnl @@ -101,7 +101,7 @@ (fn update [dt] (when playing (set time (+ time dt)) - (while (>= time step-duration) + (when (>= time step-duration) (set time (- time step-duration)) (local melody-idx (+ 1 (% step (length melody)))) @@ -125,5 +125,4 @@ :start start :stop stop :update update - :is-playing (fn [] playing) - :get-step (fn [] step)} + :is-playing (fn [] playing)} diff --git a/demo/mod/palette.fnl b/demo/mod/palette.fnl deleted file mode 100644 index f97f744..0000000 --- a/demo/mod/palette.fnl +++ /dev/null @@ -1,263 +0,0 @@ -(require :pxl8) -(local ffi (require :ffi)) - -(local data (ffi.new "u32[256]" [ - 0x080602 - 0x14120E - 0x23211E - 0x31302C - 0x403E3B - 0x4B4946 - 0x595755 - 0x676664 - 0x767573 - 0x858382 - 0x939290 - 0xA2A09F - 0xB0AFAE - 0xBEBDBC - 0xCDCCCC - 0xDADAD9 - 0x594625 - 0x544023 - 0x4F3C24 - 0x4C3A22 - 0x453821 - 0x40321F - 0x3E2F20 - 0x382D1D - 0x33291E - 0x30271F - 0x2F251D - 0x2D231E - 0x28211C - 0x251F1D - 0x23201A - 0x221F1B - 0x646269 - 0x5F5C61 - 0x5C545A - 0x584F55 - 0x5B514F - 0x554A47 - 0x4B413F - 0x423C36 - 0x463D31 - 0x3E352A - 0x362E25 - 0x2D2922 - 0x26221D - 0x1C1916 - 0x151310 - 0x100F0D - 0x8C6F52 - 0x7E6045 - 0x73553B - 0x715134 - 0xBA8346 - 0xA1723B - 0x815C2E - 0x745226 - 0xCC8926 - 0xBB7E22 - 0x9F6B1F - 0x875A1C - 0x6E4918 - 0x553712 - 0x3B250D - 0x24180A - 0xA34331 - 0x9B3728 - 0x923220 - 0x882E18 - 0x842B16 - 0x772312 - 0x69200D - 0x5A1C06 - 0x541C04 - 0x4C1A03 - 0x411701 - 0x371000 - 0x2E0D00 - 0x250B00 - 0x1B0600 - 0x130500 - 0x7D5741 - 0x76503A - 0x6E4C37 - 0x684833 - 0x5D3F2F - 0x553A2C - 0x4F3628 - 0x483024 - 0x4A3126 - 0x483025 - 0x432D22 - 0x3C2C22 - 0x352922 - 0x2C241F - 0x221C1B - 0x1A1916 - 0x6E4626 - 0x5F4025 - 0x523924 - 0x433322 - 0x352B1E - 0x28231A - 0x1A1A14 - 0x1C1815 - 0x96544B - 0xAC7369 - 0xB48C86 - 0xBCA7A4 - 0xB1BCC2 - 0x9DB0B9 - 0x8A9FAA - 0x77929F - 0x738995 - 0x5E7C8B - 0x4A6C7D - 0x345E72 - 0x1F4C64 - 0x19445C - 0x143C51 - 0x10384B - 0x183748 - 0x1A3341 - 0x192F39 - 0x152B34 - 0x13262E - 0x101E23 - 0x0E1519 - 0x0B0E10 - 0x896463 - 0x815C5B - 0x785352 - 0x6F4C4D - 0x664444 - 0x5F3C3D - 0x573738 - 0x523233 - 0x442929 - 0x392324 - 0x2D1D1D - 0x241414 - 0x1A0E0E - 0x100909 - 0x070403 - 0x000000 - 0x98936F - 0x918B68 - 0x887F60 - 0x807759 - 0x797055 - 0x73684D - 0x6B6146 - 0x63593F - 0x5B523A - 0x504834 - 0x423D2D - 0x373226 - 0x2E2B1F - 0x222018 - 0x161511 - 0x0E0F0A - 0x9A554F - 0x904D48 - 0x87453F - 0x7D4037 - 0x743831 - 0x693329 - 0x612C24 - 0x572720 - 0x4F231A - 0x441E16 - 0x391914 - 0x2D150F - 0x22110D - 0x1A0B06 - 0x0D0403 - 0x040202 - 0x7F77C0 - 0x7770B5 - 0x6E68A8 - 0x686099 - 0x60588C - 0x575381 - 0x4E4C72 - 0x454263 - 0x3D3957 - 0x34324A - 0x2C2940 - 0x242135 - 0x1E1928 - 0x16121D - 0x0C0A12 - 0x050306 - 0x88AF7B - 0x81A473 - 0x7B9A67 - 0x728E5D - 0x6D8553 - 0x61794A - 0x5B7144 - 0x61734B - 0x586A3D - 0x4D5E2D - 0x465422 - 0x3F4D17 - 0x36420E - 0x2F3507 - 0x272804 - 0x211F02 - 0x1EF708 - 0x3CE10D - 0x51CC1B - 0x64B621 - 0x6DA12C - 0x69882B - 0x727F3B - 0xE4DDCE - 0xEEE6BA - 0xEAE290 - 0xE9E26D - 0xE5DE43 - 0xE3DB20 - 0xE1CC18 - 0xDFB911 - 0xDCA60B - 0xE8A306 - 0xDF9312 - 0xE17B05 - 0xC86815 - 0xBC5908 - 0xB14805 - 0xA63D07 - 0xB6431E - 0xAA381A - 0x9A2E12 - 0x8C270F - 0x892B17 - 0x762311 - 0x5F1F0D - 0x491B09 - 0x3B1809 - 0xE50F19 - 0x6A34C4 - 0xE00B28 - 0x2B08C8 - 0x322A33 - 0x281C0E - 0x2F1E15 - 0xD48067 - 0xC26B4C - 0x974928 - 0x814123 - 0xD5B3A9 - 0xBE9D93 - 0x9A7B6C - 0x7F5F51 - 0x8E504C -])) - -data diff --git a/demo/mod/sky.fnl b/demo/mod/sky.fnl deleted file mode 100644 index ab359c3..0000000 --- a/demo/mod/sky.fnl +++ /dev/null @@ -1,271 +0,0 @@ -(local ffi (require :ffi)) -(local pxl8 (require :pxl8)) -(local effects (require :pxl8.effects)) - -(local SKY_GRADIENT_START 144) -(local SKY_GRADIENT_COUNT 16) -(local sky-radius 900) -(local sky-segments 16) -(local sky-rings 16) - -(local NUM_RANDOM_STARS 300) -(local NUM_TINY_STARS 7000) -(local STAR_SEED 0xDEADBEEF) -(local STAR_CYCLE_PERIOD 7200) - -;; Use existing bright palette colors -;; Silver/white: indices 14-15 (brightest grays) -(local IDX_SILVER 14) -;; Warm/torch: indices 216-218 (bright creams/yellows) -(local IDX_TORCH 216) -;; Blue/magic: indices 176-178 (purples - brightest of the range) -(local IDX_MAGIC 176) - -(var sky-mesh nil) -(var star-time 0) -(var last-gradient-key nil) -(var random-stars []) -(var tiny-stars []) - -(fn generate-sky-gradient [zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b] - (for [i 0 (- SKY_GRADIENT_COUNT 1)] - (let [t (/ i (- SKY_GRADIENT_COUNT 1)) - r (math.floor (+ zenith-r (* t (- horizon-r zenith-r)))) - g (math.floor (+ zenith-g (* t (- horizon-g zenith-g)))) - b (math.floor (+ zenith-b (* t (- horizon-b zenith-b))))] - (pxl8.set_palette_rgb (+ SKY_GRADIENT_START i) r g b)))) - -(fn create-sky-dome [] - (let [verts [] - indices []] - - (for [i 0 (- sky-rings 1)] - (let [theta0 (* (/ i sky-rings) math.pi 0.5) - theta1 (* (/ (+ i 1) sky-rings) math.pi 0.5) - sin-t0 (math.sin theta0) - cos-t0 (math.cos theta0) - sin-t1 (math.sin theta1) - cos-t1 (math.cos theta1) - y0 (* sky-radius cos-t0) - y1 (* sky-radius cos-t1) - r0 (* sky-radius sin-t0) - r1 (* sky-radius sin-t1) - t0 (/ i sky-rings) - t1 (/ (+ i 1) sky-rings) - c0 (math.floor (+ SKY_GRADIENT_START (* t0 (- SKY_GRADIENT_COUNT 1)) 0.5)) - c1 (math.floor (+ SKY_GRADIENT_START (* t1 (- SKY_GRADIENT_COUNT 1)) 0.5))] - - (for [j 0 (- sky-segments 1)] - (let [phi0 (* (/ j sky-segments) math.pi 2) - phi1 (* (/ (+ j 1) sky-segments) math.pi 2) - cos-p0 (math.cos phi0) - sin-p0 (math.sin phi0) - cos-p1 (math.cos phi1) - sin-p1 (math.sin phi1) - x00 (* r0 cos-p0) z00 (* r0 sin-p0) - x01 (* r0 cos-p1) z01 (* r0 sin-p1) - x10 (* r1 cos-p0) z10 (* r1 sin-p0) - x11 (* r1 cos-p1) z11 (* r1 sin-p1) - nx00 (- (* sin-t0 cos-p0)) ny00 (- cos-t0) nz00 (- (* sin-t0 sin-p0)) - nx01 (- (* sin-t0 cos-p1)) ny01 (- cos-t0) nz01 (- (* sin-t0 sin-p1)) - nx10 (- (* sin-t1 cos-p0)) ny10 (- cos-t1) nz10 (- (* sin-t1 sin-p0)) - nx11 (- (* sin-t1 cos-p1)) ny11 (- cos-t1) nz11 (- (* sin-t1 sin-p1)) - base-idx (# verts)] - - (if (= i 0) - (do - (table.insert verts {:x x00 :y y0 :z z00 :nx nx00 :ny ny00 :nz nz00 :color c0 :light 255}) - (table.insert verts {:x x11 :y y1 :z z11 :nx nx11 :ny ny11 :nz nz11 :color c1 :light 255}) - (table.insert verts {:x x10 :y y1 :z z10 :nx nx10 :ny ny10 :nz nz10 :color c1 :light 255}) - (table.insert indices base-idx) - (table.insert indices (+ base-idx 2)) - (table.insert indices (+ base-idx 1))) - (do - (table.insert verts {:x x00 :y y0 :z z00 :nx nx00 :ny ny00 :nz nz00 :color c0 :light 255}) - (table.insert verts {:x x01 :y y0 :z z01 :nx nx01 :ny ny01 :nz nz01 :color c0 :light 255}) - (table.insert verts {:x x11 :y y1 :z z11 :nx nx11 :ny ny11 :nz nz11 :color c1 :light 255}) - (table.insert verts {:x x10 :y y1 :z z10 :nx nx10 :ny ny10 :nz nz10 :color c1 :light 255}) - (table.insert indices base-idx) - (table.insert indices (+ base-idx 3)) - (table.insert indices (+ base-idx 2)) - (table.insert indices base-idx) - (table.insert indices (+ base-idx 2)) - (table.insert indices (+ base-idx 1)))))))) - - (set sky-mesh (pxl8.create_mesh verts indices)))) - -(fn update-gradient [zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b] - (let [key (.. zenith-r "," zenith-g "," zenith-b "," horizon-r "," horizon-g "," horizon-b)] - (when (not= key last-gradient-key) - (generate-sky-gradient zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b) - (set last-gradient-key key)))) - -(fn galactic-band-factor [dx dy dz] - (let [band-len (math.sqrt (+ (* 0.6 0.6) (* 0.3 0.3) (* 0.742 0.742))) - bx (/ 0.6 band-len) - by (/ 0.3 band-len) - bz (/ 0.742 band-len) - dist-from-band (math.abs (+ (* dx bx) (* dy by) (* dz bz))) - in-band (- 1 (math.min (* dist-from-band 3) 1))] - (* in-band in-band))) - -(fn generate-stars [] - (set random-stars []) - (set tiny-stars []) - - ;; Generate random stars - use full upper hemisphere (dy > -0.1) - (for [i 0 (- NUM_RANDOM_STARS 1)] - (let [h1 (pxl8.hash32 (+ STAR_SEED (* i 5))) - h2 (pxl8.hash32 (+ STAR_SEED (* i 5) 1)) - h3 (pxl8.hash32 (+ STAR_SEED (* i 5) 2)) - h4 (pxl8.hash32 (+ STAR_SEED (* i 5) 3)) - theta (* (/ h1 0xFFFFFFFF) math.pi 2) - phi (math.acos (- 1 (* (/ h2 0xFFFFFFFF) 1.0))) - sin-phi (math.sin phi) - cos-phi (math.cos phi) - dx (* sin-phi (math.cos theta)) - dy cos-phi - dz (* sin-phi (math.sin theta)) - brightness-raw (/ (% h3 256) 255) - brightness (math.floor (+ 60 (* brightness-raw brightness-raw 195))) - color-type (% h4 100) - color (if (< color-type 8) (+ IDX_TORCH (% (bit.rshift h4 8) 2)) - (< color-type 16) (+ IDX_MAGIC (% (bit.rshift h4 8) 2)) - (+ IDX_SILVER (% (bit.rshift h4 8) 2)))] - - (when (> dy -0.1) - (table.insert random-stars {:dx dx :dy dy :dz dz - :brightness brightness - :color color})))) - - (let [tiny-seed (+ STAR_SEED 0xCAFEBABE)] - (for [i 0 (- NUM_TINY_STARS 1)] - (let [h1 (pxl8.hash32 (+ tiny-seed (* i 4))) - h2 (pxl8.hash32 (+ tiny-seed (* i 4) 1)) - h3 (pxl8.hash32 (+ tiny-seed (* i 4) 2)) - h4 (pxl8.hash32 (+ tiny-seed (* i 4) 3)) - theta (* (/ h1 0xFFFFFFFF) math.pi 2) - phi (math.acos (- 1 (* (/ h2 0xFFFFFFFF) 1.0))) - sin-phi (math.sin phi) - cos-phi (math.cos phi) - dx (* sin-phi (math.cos theta)) - dy cos-phi - dz (* sin-phi (math.sin theta)) - band-boost (galactic-band-factor dx dy dz) - base-bright (+ 40 (% h3 50)) - brightness (+ base-bright (math.floor (* band-boost 40))) - color-shift (% h4 100) - color (if (< color-shift 3) (+ IDX_TORCH (% (bit.rshift h4 8) 2)) - (< color-shift 12) (+ IDX_MAGIC (% (bit.rshift h4 8) 2)) - (+ IDX_SILVER (% (bit.rshift h4 8) 2)))] - (when (> dy -0.1) - (table.insert tiny-stars {:dx dx :dy dy :dz dz - :brightness brightness - :color color})))))) - -(fn project-direction [dir-x dir-y dir-z yaw pitch cos-rot sin-rot width height] - (let [rot-x (- (* dir-x cos-rot) (* dir-z sin-rot)) - rot-z (+ (* dir-x sin-rot) (* dir-z cos-rot)) - cos-yaw (math.cos yaw) - sin-yaw (math.sin yaw) - cos-pitch (math.cos pitch) - sin-pitch (math.sin pitch) - rotated-x (+ (* rot-x cos-yaw) (* rot-z sin-yaw)) - rotated-z (+ (* (- rot-x) sin-yaw) (* rot-z cos-yaw)) - rotated-y (- (* dir-y cos-pitch) (* rotated-z sin-pitch)) - final-z (+ (* dir-y sin-pitch) (* rotated-z cos-pitch))] - (when (> final-z 0.01) - (let [fov 1.047 - aspect (/ width height) - half-fov-tan (math.tan (* fov 0.5)) - ndc-x (/ rotated-x (* final-z half-fov-tan aspect)) - ndc-y (/ rotated-y (* final-z half-fov-tan))] - (when (and (>= ndc-x -1) (<= ndc-x 1) (>= ndc-y -1) (<= ndc-y 1)) - {:x (math.floor (* (+ 1 ndc-x) 0.5 width)) - :y (math.floor (* (- 1 ndc-y) 0.5 height))}))))) - -(fn render-stars [yaw pitch intensity dt] - (set star-time (+ star-time (or dt 0))) - (when (> intensity 0) - (let [width (pxl8.get_width) - height (pxl8.get_height) - glows [] - fade-in (* intensity intensity) - time-factor (/ star-time 60) - star-rotation (/ (* star-time math.pi 2) STAR_CYCLE_PERIOD) - cos-rot (math.cos star-rotation) - sin-rot (math.sin star-rotation)] - - (each [i star (ipairs tiny-stars)] - (let [screen (project-direction star.dx star.dy star.dz yaw pitch cos-rot sin-rot width height)] - (when screen - (let [int (math.floor (* star.brightness fade-in))] - (when (> int 8) - (table.insert glows {:x screen.x :y screen.y - :radius 1 - :intensity int - :color star.color - :shape effects.GLOW_CIRCLE})))))) - - (each [i star (ipairs random-stars)] - (let [screen (project-direction star.dx star.dy star.dz yaw pitch cos-rot sin-rot width height)] - (when screen - (let [phase (+ (* i 2.137) (* time-factor 3.0)) - twinkle (+ 0.75 (* 0.25 (math.sin (* phase 6.28)))) - int (math.floor (* star.brightness fade-in twinkle))] - (if (> star.brightness 220) - (do - (table.insert glows {:x screen.x :y screen.y - :radius 3 - :intensity (math.floor (* int 1.5)) - :color star.color - :shape effects.GLOW_DIAMOND}) - (table.insert glows {:x screen.x :y screen.y - :radius 5 - :intensity (math.floor (/ int 2)) - :color star.color - :shape effects.GLOW_CIRCLE})) - (> star.brightness 180) - (do - (table.insert glows {:x screen.x :y screen.y - :radius 2 - :intensity int - :color star.color - :shape effects.GLOW_DIAMOND}) - (table.insert glows {:x screen.x :y screen.y - :radius 4 - :intensity (math.floor (/ int 3)) - :color star.color - :shape effects.GLOW_CIRCLE})) - (> star.brightness 120) - (do - (table.insert glows {:x screen.x :y screen.y - :radius 2 - :intensity (math.floor (* int 0.67)) - :color star.color - :shape effects.GLOW_DIAMOND}) - (table.insert glows {:x screen.x :y screen.y - :radius 3 - :intensity (math.floor (/ int 4)) - :color star.color - :shape effects.GLOW_CIRCLE})) - (table.insert glows {:x screen.x :y screen.y - :radius 2 - :intensity (math.floor (* int 0.5)) - :color star.color - :shape effects.GLOW_CIRCLE})))))) - - (when (> (length glows) 0) - (effects.glows glows))))) - -(fn render [cam-x cam-y cam-z wireframe] - (when (not sky-mesh) (create-sky-dome)) - (when sky-mesh - (pxl8.draw_mesh sky-mesh {:x cam-x :y cam-y :z cam-z :passthrough true :wireframe wireframe}))) - -{:render render - :render-stars render-stars - :generate-stars generate-stars - :update-gradient update-gradient - :SKY_GRADIENT_START SKY_GRADIENT_START - :SKY_GRADIENT_COUNT SKY_GRADIENT_COUNT} diff --git a/demo/mod/textures.fnl b/demo/mod/textures.fnl deleted file mode 100644 index c4966ef..0000000 --- a/demo/mod/textures.fnl +++ /dev/null @@ -1,168 +0,0 @@ -(local pxl8 (require :pxl8)) -(local procgen (require :pxl8.procgen)) - -(local textures {}) - -(fn build-graph [seed builder] - (let [g (pxl8.create_graph 128) - x (g:add_node procgen.OP_INPUT_X 0 0 0 0 0) - y (g:add_node procgen.OP_INPUT_Y 0 0 0 0 0) - ctx {:graph g :x x :y y}] - (g:set_seed seed) - (let [output (builder ctx)] - (g:set_output output) - g))) - -(fn const [ctx val] - (ctx.graph:add_node procgen.OP_CONST 0 0 0 0 val)) - -(fn add [ctx a b] - (ctx.graph:add_node procgen.OP_ADD a b 0 0 0)) - -(fn sub [ctx a b] - (ctx.graph:add_node procgen.OP_SUB a b 0 0 0)) - -(fn mul [ctx a b] - (ctx.graph:add_node procgen.OP_MUL a b 0 0 0)) - -(fn div [ctx a b] - (ctx.graph:add_node procgen.OP_DIV a b 0 0 0)) - -(fn min-op [ctx a b] - (ctx.graph:add_node procgen.OP_MIN a b 0 0 0)) - -(fn max-op [ctx a b] - (ctx.graph:add_node procgen.OP_MAX a b 0 0 0)) - -(fn abs [ctx a] - (ctx.graph:add_node procgen.OP_ABS a 0 0 0 0)) - -(fn floor [ctx a] - (ctx.graph:add_node procgen.OP_FLOOR a 0 0 0 0)) - -(fn fract [ctx a] - (ctx.graph:add_node procgen.OP_FRACT a 0 0 0 0)) - -(fn lerp [ctx a b t] - (ctx.graph:add_node procgen.OP_LERP a b t 0 0)) - -(fn clamp [ctx val lo hi] - (ctx.graph:add_node procgen.OP_CLAMP val lo hi 0 0)) - -(fn select [ctx cond a b] - (ctx.graph:add_node procgen.OP_SELECT a b cond 0 0)) - -(fn smoothstep [ctx edge0 edge1 x] - (ctx.graph:add_node procgen.OP_SMOOTHSTEP edge0 edge1 x 0 0)) - -(fn noise-value [ctx scale] - (let [s (const ctx scale)] - (ctx.graph:add_node procgen.OP_NOISE_VALUE ctx.x ctx.y s 0 0))) - -(fn noise-perlin [ctx scale] - (let [s (const ctx scale)] - (ctx.graph:add_node procgen.OP_NOISE_PERLIN ctx.x ctx.y s 0 0))) - -(fn noise-fbm [ctx octaves scale persistence] - (let [s (const ctx scale) - p (const ctx persistence)] - (ctx.graph:add_node procgen.OP_NOISE_FBM ctx.x ctx.y s p octaves))) - -(fn noise-ridged [ctx octaves scale persistence] - (let [s (const ctx scale) - p (const ctx persistence)] - (ctx.graph:add_node procgen.OP_NOISE_RIDGED ctx.x ctx.y s p octaves))) - -(fn noise-turbulence [ctx octaves scale persistence] - (let [s (const ctx scale) - p (const ctx persistence)] - (ctx.graph:add_node procgen.OP_NOISE_TURBULENCE ctx.x ctx.y s p octaves))) - -(fn voronoi-cell [ctx scale] - (let [s (const ctx scale)] - (ctx.graph:add_node procgen.OP_VORONOI_CELL ctx.x ctx.y s 0 0))) - -(fn voronoi-edge [ctx scale] - (let [s (const ctx scale)] - (ctx.graph:add_node procgen.OP_VORONOI_EDGE ctx.x ctx.y s 0 0))) - -(fn voronoi-id [ctx scale] - (let [s (const ctx scale)] - (ctx.graph:add_node procgen.OP_VORONOI_ID ctx.x ctx.y s 0 0))) - -(fn gradient-linear [ctx angle] - (let [a (const ctx angle)] - (ctx.graph:add_node procgen.OP_GRADIENT_LINEAR ctx.x ctx.y a 0 0))) - -(fn gradient-radial [ctx cx cy] - (let [center-x (const ctx cx) - center-y (const ctx cy)] - (ctx.graph:add_node procgen.OP_GRADIENT_RADIAL ctx.x ctx.y center-x center-y 0))) - -(fn quantize [ctx val base range] - (let [r (const ctx range)] - (ctx.graph:add_node procgen.OP_QUANTIZE val r 0 0 base))) - -(fn textures.mossy-cobblestone [seed base-color moss-color] - (let [g (build-graph seed - (fn [ctx] - (let [cell (voronoi-cell ctx 6) - edge (voronoi-edge ctx 6) - mortar-threshold (const ctx 0.05) - is-mortar (sub ctx mortar-threshold edge) - mortar-color (const ctx (- base-color 2)) - stone-detail (noise-value ctx 48) - stone-base (mul ctx cell (const ctx 0.6)) - stone-combined (add ctx stone-base (mul ctx stone-detail (const ctx 0.4))) - stone-quant (quantize ctx stone-combined base-color 8) - moss-pattern (noise-fbm ctx 4 10 0.5) - moss-detail (noise-value ctx 64) - moss-var (add ctx (mul ctx moss-pattern (const ctx 0.7)) - (mul ctx moss-detail (const ctx 0.3))) - moss-threshold (const ctx 0.55) - has-moss (sub ctx moss-pattern moss-threshold) - moss-quant (quantize ctx moss-var moss-color 6) - stone-or-moss (select ctx has-moss moss-quant stone-quant)] - (select ctx is-mortar mortar-color stone-or-moss))))] - (let [tex-id (g:eval_texture 64 64)] - (g:destroy) - tex-id))) - -(fn textures.ashlar-wall [seed base-color moss-color] - (let [g (build-graph seed - (fn [ctx] - (let [cell (voronoi-cell ctx 5) - edge (voronoi-edge ctx 5) - cell-id (voronoi-id ctx 5) - mortar-threshold (const ctx 0.12) - is-mortar (sub ctx mortar-threshold edge) - stone-detail (noise-fbm ctx 3 32 0.5) - stone-tint (mul ctx cell-id (const ctx 0.4)) - stone-shade (mul ctx cell (const ctx 0.3)) - stone-combined (add ctx stone-detail (add ctx stone-tint stone-shade)) - stone-quant (quantize ctx stone-combined base-color 10) - crack-moss (noise-fbm ctx 3 16 0.5) - moss-in-crack (mul ctx crack-moss (sub ctx (const ctx 0.2) edge)) - moss-threshold (const ctx 0.06) - has-moss (sub ctx moss-in-crack moss-threshold) - moss-quant (quantize ctx crack-moss moss-color 4) - mortar-color (const ctx (+ base-color 1)) - stone-or-moss (select ctx has-moss moss-quant stone-quant)] - (select ctx is-mortar mortar-color stone-or-moss))))] - (let [tex-id (g:eval_texture 64 64)] - (g:destroy) - tex-id))) - -(fn textures.gradient-sky [seed zenith-color horizon-color] - (let [g (build-graph seed - (fn [ctx] - (let [grad (gradient-linear ctx (* math.pi 0.5)) - zenith (const ctx zenith-color) - horizon (const ctx horizon-color) - range (const ctx (- horizon-color zenith-color))] - (quantize ctx grad zenith-color (- horizon-color zenith-color)))))] - (let [tex-id (g:eval_texture 64 64)] - (g:destroy) - tex-id))) - -textures diff --git a/demo/mod/vfx.fnl b/demo/mod/vfx.fnl deleted file mode 100644 index 446de1c..0000000 --- a/demo/mod/vfx.fnl +++ /dev/null @@ -1,75 +0,0 @@ -(local vfx {}) - -(fn vfx.explosion [ps x y ?opts] - (let [opts (or ?opts {}) - color (or opts.color 208) - force (or opts.force 200)] - (ps:set_position x y) - (ps:set_colors color (+ color 15)) - (ps:set_velocity (- force) force (- force) force) - (ps:set_gravity 0 100) - (ps:set_life 0.3 0.8) - (ps:set_size 1 3) - (ps:set_drag 0.98) - (ps:set_spawn_rate 0) - (ps:emit (or opts.count 50)))) - -(fn vfx.fire [ps x y ?opts] - (let [opts (or ?opts {}) - width (or opts.width 50) - color (or opts.color 208)] - (ps:set_position x y) - (ps:set_spread width 5) - (ps:set_colors color (+ color 15)) - (ps:set_velocity -20 20 -80 -40) - (ps:set_gravity 0 -30) - (ps:set_life 0.5 1.5) - (ps:set_size 1 2) - (ps:set_turbulence 30) - (ps:set_drag 0.95) - (ps:set_spawn_rate (or opts.rate 50)))) - -(fn vfx.rain [ps width ?opts] - (let [opts (or ?opts {}) - wind (or opts.wind 0) - color (or opts.color 153)] - (ps:set_position (/ width 2) -10) - (ps:set_spread width 0) - (ps:set_colors color (+ color 3)) - (ps:set_velocity (- wind 10) (+ wind 10) 300 400) - (ps:set_gravity 0 200) - (ps:set_life 1 2) - (ps:set_size 1 1) - (ps:set_drag 1) - (ps:set_spawn_rate (or opts.rate 100)))) - -(fn vfx.smoke [ps x y ?opts] - (let [opts (or ?opts {}) - color (or opts.color 248)] - (ps:set_position x y) - (ps:set_spread 10 5) - (ps:set_colors color (+ color 7)) - (ps:set_velocity -15 15 -30 -10) - (ps:set_gravity 0 -20) - (ps:set_life 1 3) - (ps:set_size 2 4) - (ps:set_turbulence 20) - (ps:set_drag 0.98) - (ps:set_spawn_rate (or opts.rate 20)))) - -(fn vfx.snow [ps width ?opts] - (let [opts (or ?opts {}) - wind (or opts.wind 10) - color (or opts.color 15)] - (ps:set_position (/ width 2) -10) - (ps:set_spread width 0) - (ps:set_colors color color) - (ps:set_velocity (- wind 20) (+ wind 20) 30 60) - (ps:set_gravity 0 10) - (ps:set_life 3 6) - (ps:set_size 1 2) - (ps:set_turbulence 15) - (ps:set_drag 0.99) - (ps:set_spawn_rate (or opts.rate 30)))) - -vfx diff --git a/demo/mod/worldgen.fnl b/demo/mod/worldgen.fnl new file mode 100644 index 0000000..88e1358 --- /dev/null +++ b/demo/mod/worldgen.fnl @@ -0,0 +1,224 @@ +(local pxl8 (require :pxl8)) + +(local bob-amount 4.0) +(local bob-speed 8.0) +(local cam-smoothing 0.25) +(local cell-size 64) +(local cursor-sensitivity 0.008) +(local gravity -800) +(local grid-size 64) +(local ground-y 64) +(local jump-force 175) +(local land-recovery-speed 20) +(local land-squash-amount -4) +(local max-pitch 1.5) +(local move-speed 200) +(local turn-speed 2.0) + +(var auto-run? false) +(var auto-run-cancel-key nil) +(var bob-time 0) +(var cam-pitch 0) +(var cam-x 1000) +(var cam-y 64) +(var cam-yaw 0) +(var cam-z 1000) +(var camera nil) +(var cursor-look? true) +(var grounded? true) +(var land-squash 0) +(var smooth-cam-x 1000) +(var smooth-cam-z 1000) +(var velocity-y 0) +(var world nil) + +(fn init [] + (set camera (pxl8.create_camera_3d)) + (set world (pxl8.create_world)) + (let [result (world:generate { + :type pxl8.PROCGEN_ROOMS + :width 64 + :height 64 + :seed 42 + :min_room_size 5 + :max_room_size 10 + :num_rooms 20})] + (if (< result 0) + (pxl8.error (.. "Failed to generate rooms - result: " result)) + (let [floor-tex (pxl8.procgen_tex {:name "floor" + :seed 11111 + :width 64 + :height 64 + :base_color 19}) + ceiling-tex (pxl8.procgen_tex {:name "ceiling" + :seed 22222 + :width 64 + :height 64 + :base_color 1}) + wall-tex (pxl8.procgen_tex {:name "wall" + :seed 12345 + :width 64 + :height 64 + :base_color 4})] + + (let [result (world:apply_textures [ + {:name "floor" + :texture_id floor-tex + :rule (fn [normal] (> normal.y 0.7))} + {:name "ceiling" + :texture_id ceiling-tex + :rule (fn [normal] (< normal.y -0.7))} + {:name "wall" + :texture_id wall-tex + :rule (fn [normal] (and (<= normal.y 0.7) (>= normal.y -0.7)))}])] + (when (< result 0) + (pxl8.error (.. "Failed to apply textures - result: " result)))))))) + +(fn update [dt] + (when (pxl8.key_pressed "`") + (set auto-run? (not auto-run?)) + (when (and auto-run? (pxl8.key_down "w")) + (set auto-run-cancel-key "w"))) + (when (and auto-run? (not auto-run-cancel-key) (or (pxl8.key_down "w") (pxl8.key_down "s"))) + (set auto-run? false) + (when (pxl8.key_down "s") + (set auto-run-cancel-key "s"))) + (when (and auto-run-cancel-key (not (pxl8.key_down auto-run-cancel-key))) + (set auto-run-cancel-key nil)) + + (when (world:is_loaded) + (let [forward-x (- (math.sin cam-yaw)) + forward-z (- (math.cos cam-yaw)) + right-x (math.cos cam-yaw) + right-z (- (math.sin cam-yaw)) + grid-max (* grid-size cell-size) + move-delta (* move-speed dt)] + + (var moving false) + (var move-forward 0) + (var move-right 0) + + (when (or (pxl8.key_down "w") auto-run?) + (set move-forward (+ move-forward 1))) + + (when (and (pxl8.key_down "s") (not= auto-run-cancel-key "s")) + (set move-forward (- move-forward 1))) + + (when (pxl8.key_down "a") + (set move-right (- move-right 1))) + + (when (pxl8.key_down "d") + (set move-right (+ move-right 1))) + + (set moving (or (not= move-forward 0) (not= move-right 0))) + + (var new-x cam-x) + (var new-z cam-z) + + (when moving + (let [len (math.sqrt (+ (* move-forward move-forward) (* move-right move-right))) + norm-forward (/ move-forward len) + norm-right (/ move-right len)] + (set new-x (+ new-x (* move-delta (+ (* forward-x norm-forward) (* right-x norm-right))))) + (set new-z (+ new-z (* move-delta (+ (* forward-z norm-forward) (* right-z norm-right))))))) + + (when (and (>= new-x 0) (<= new-x grid-max) + (>= new-z 0) (<= new-z grid-max)) + (let [(resolved-x resolved-y resolved-z) (world:resolve_collision cam-x cam-y cam-z new-x cam-y new-z 5)] + (set cam-x resolved-x) + (set cam-z resolved-z))) + + (set smooth-cam-x (+ (* smooth-cam-x (- 1 cam-smoothing)) (* cam-x cam-smoothing))) + (set smooth-cam-z (+ (* smooth-cam-z (- 1 cam-smoothing)) (* cam-z cam-smoothing))) + + (when cursor-look? + (let [dx (pxl8.mouse_dx) + dy (pxl8.mouse_dy)] + (set cam-yaw (- cam-yaw (* dx cursor-sensitivity))) + (set cam-pitch (math.max (- max-pitch) + (math.min max-pitch + (- cam-pitch (* dy cursor-sensitivity))))))) + + (when (and (not cursor-look?) (pxl8.key_down "left")) + (set cam-yaw (+ cam-yaw (* turn-speed dt)))) + + (when (and (not cursor-look?) (pxl8.key_down "right")) + (set cam-yaw (- cam-yaw (* turn-speed dt)))) + + (when (and (not cursor-look?) (pxl8.key_down "up")) + (set cam-pitch (math.min max-pitch (+ cam-pitch (* turn-speed dt))))) + + (when (and (not cursor-look?) (pxl8.key_down "down")) + (set cam-pitch (math.max (- max-pitch) (- cam-pitch (* turn-speed dt))))) + + (when (and (pxl8.key_pressed "space") grounded?) + (set velocity-y jump-force) + (set grounded? false)) + + (set velocity-y (+ velocity-y (* gravity dt))) + (set cam-y (+ cam-y (* velocity-y dt))) + + (when (<= cam-y ground-y) + (when (not grounded?) + (set land-squash land-squash-amount)) + (set cam-y ground-y) + (set velocity-y 0) + (set grounded? true)) + + (when (< land-squash 0) + (set land-squash (math.min 0 (+ land-squash (* land-recovery-speed dt))))) + + (if (and moving grounded?) + (set bob-time (+ bob-time (* dt bob-speed))) + (let [target-phase (* (math.floor (/ bob-time math.pi)) math.pi)] + (set bob-time (+ (* bob-time 0.8) (* target-phase 0.2)))))))) + +(fn frame [] + (pxl8.clear 0) + + (when (not camera) + (pxl8.error "camera is nil!")) + + (when (not world) + (pxl8.error "world is nil!")) + + (when (and world (not (world:is_loaded))) + (pxl8.text "World not loaded yet..." 5 30 12)) + + (when (and camera world (world:is_loaded)) + (let [bob-offset (* (math.sin bob-time) bob-amount) + eye-y (+ cam-y bob-offset land-squash) + forward-x (- (math.sin cam-yaw)) + forward-z (- (math.cos cam-yaw)) + target-x (+ smooth-cam-x forward-x) + target-y (+ eye-y (math.sin cam-pitch)) + target-z (+ smooth-cam-z forward-z) + aspect (/ (pxl8.get_width) (pxl8.get_height))] + + (camera:lookat [smooth-cam-x eye-y smooth-cam-z] + [target-x target-y target-z] + [0 1 0]) + (camera:set_perspective 1.047 aspect 1.0 4096.0) + + (pxl8.begin_frame_3d camera) + (pxl8.clear_depth) + + (world:render [smooth-cam-x eye-y smooth-cam-z]) + + (pxl8.end_frame_3d) + + (let [cx (/ (pxl8.get_width) 2) + cy (/ (pxl8.get_height) 2) + crosshair-size 4 + red-color 18] + (pxl8.line (- cx crosshair-size) cy (+ cx crosshair-size) cy red-color) + (pxl8.line cx (- cy crosshair-size) cx (+ cy crosshair-size) red-color)) + + (pxl8.text (.. "fps: " (string.format "%.1f" (pxl8.get_fps))) 5 5 12) + (pxl8.text (.. "pos: " (string.format "%.0f" cam-x) "," + (string.format "%.0f" cam-y) "," + (string.format "%.0f" cam-z)) 5 15 12)))) + +{:init init + :update update + :frame frame} diff --git a/demo/res/tiles/adventurer.png b/demo/res/tiles/adventurer.png deleted file mode 100644 index d3b784d..0000000 Binary files a/demo/res/tiles/adventurer.png and /dev/null differ diff --git a/demo/res/tiles/castle-wall.jpg b/demo/res/tiles/castle-wall.jpg deleted file mode 100644 index 151a5c1..0000000 Binary files a/demo/res/tiles/castle-wall.jpg and /dev/null differ diff --git a/pxl8.sh b/pxl8.sh index 9ef8c35..140dc7a 100755 --- a/pxl8.sh +++ b/pxl8.sh @@ -56,55 +56,6 @@ build_luajit() { fi } -build_server() { - local mode="$1" - if [[ -d "server" ]]; then - print_info "Building server ($mode mode)" - cd server - if [[ "$mode" == "release" ]]; then - cargo build --release - else - cargo build - fi - local status=$? - cd - > /dev/null - if [[ $status -eq 0 ]]; then - print_info "Built server" - else - print_error "Server build failed" - fi - fi -} - -start_server() { - local mode="$1" - local server_bin - if [[ "$mode" == "release" ]]; then - server_bin="server/target/release/pxl8-server" - else - server_bin="server/target/debug/pxl8-server" - fi - print_info "Server mode: $mode, binary: $server_bin" - if [[ -f "$server_bin" ]]; then - print_info "Starting server..." - ./$server_bin & - SERVER_PID=$! - print_info "Server started with PID $SERVER_PID" - sleep 0.5 - else - print_error "Server binary not found: $server_bin" - print_error "Build the server first with: cd server && cargo build" - fi -} - -stop_server() { - if [[ -n "$SERVER_PID" ]]; then - print_info "Stopping server" - kill $SERVER_PID 2>/dev/null || true - wait $SERVER_PID 2>/dev/null || true - fi -} - build_sdl() { if [[ ! -f "lib/SDL/build/libSDL3.so" ]] && [[ ! -f "lib/SDL/build/libSDL3.a" ]] && [[ ! -f "lib/SDL/build/libSDL3.dylib" ]]; then print_info "Building SDL3" @@ -162,7 +113,6 @@ print_usage() { echo " --all Clean both build artifacts and dependencies" echo " --deps Clean only dependencies" echo " --release Build/run/clean in release mode (default: debug)" - echo " --server Start game server before running (for networked games)" } setup_sdl3() { @@ -223,7 +173,7 @@ timestamp() { update_fennel() { print_info "Fetching Fennel" - local version="1.6.1" + local version="1.6.0" if curl -sL --max-time 5 -o lib/fennel/fennel.lua "https://fennel-lang.org/downloads/fennel-${version}.lua" 2>/dev/null; then if [[ -f "lib/fennel/fennel.lua" ]] && [[ -s "lib/fennel/fennel.lua" ]]; then @@ -314,8 +264,7 @@ for arg in "$@"; do done if [ "$MODE" = "release" ]; then - CFLAGS="$CFLAGS -O3 -flto -ffast-math -funroll-loops -fno-unwind-tables -fno-asynchronous-unwind-tables" - LINKER_FLAGS="$LINKER_FLAGS -flto" + CFLAGS="$CFLAGS -O3 -ffast-math -funroll-loops -fno-unwind-tables -fno-asynchronous-unwind-tables" BUILDDIR="$BUILDDIR/release" BINDIR="$BINDIR/release" else @@ -324,7 +273,7 @@ else BINDIR="$BINDIR/debug" fi -DEP_CFLAGS="-O3 -funroll-loops" +DEP_CFLAGS="-O3 -ffast-math -funroll-loops" case "$COMMAND" in build) @@ -371,7 +320,7 @@ case "$COMMAND" in print_info "Compiler cache: ccache enabled" fi - INCLUDES="-Isrc/asset -Isrc/core -Isrc/gfx -Isrc/gui -Isrc/hal -Isrc/math -Isrc/net -Isrc/procgen -Isrc/script -Isrc/sfx -Isrc/world -Ilib/linenoise -Ilib/luajit/src -Ilib/miniz" + INCLUDES="-Iclient/src/core -Iclient/src/math -Iclient/src/gfx -Iclient/src/sfx -Iclient/src/script -Iclient/src/hal -Iclient/src/world -Iclient/src/asset -Iclient/src/game -Ilib -Ilib/luajit/src -Ilib/linenoise -Ilib/miniz" COMPILE_FLAGS="$CFLAGS $INCLUDES" DEP_COMPILE_FLAGS="$DEP_CFLAGS $INCLUDES" @@ -380,43 +329,38 @@ case "$COMMAND" in LIB_SOURCE_FILES="lib/linenoise/linenoise.c lib/miniz/miniz.c" PXL8_SOURCE_FILES=" - src/core/pxl8.c - src/core/pxl8_bytes.c - src/core/pxl8_io.c - src/core/pxl8_log.c - src/core/pxl8_rng.c - src/math/pxl8_math.c - src/gfx/pxl8_anim.c - src/gfx/pxl8_atlas.c - src/gfx/pxl8_blit.c - src/gfx/pxl8_3d_camera.c - src/gfx/pxl8_colormap.c - src/gfx/pxl8_cpu.c - src/gfx/pxl8_dither.c - src/gfx/pxl8_font.c - src/gfx/pxl8_gfx.c - src/gfx/pxl8_lightmap.c - src/gfx/pxl8_mesh.c - src/gfx/pxl8_palette.c - src/gfx/pxl8_particles.c - src/gfx/pxl8_tilemap.c - src/gfx/pxl8_tilesheet.c - src/gfx/pxl8_transition.c - src/sfx/pxl8_sfx.c - src/script/pxl8_repl.c - src/script/pxl8_script.c - src/hal/pxl8_sdl3.c - src/world/pxl8_bsp.c - src/world/pxl8_gen.c - src/world/pxl8_world.c - src/procgen/pxl8_graph.c - src/asset/pxl8_ase.c - src/asset/pxl8_cart.c - src/asset/pxl8_save.c - src/gui/pxl8_gui.c - src/core/pxl8_replay.c - src/net/pxl8_net.c - src/net/pxl8_protocol.c + client/src/core/pxl8.c + client/src/core/pxl8_io.c + client/src/core/pxl8_log.c + client/src/core/pxl8_rng.c + client/src/math/pxl8_math.c + client/src/gfx/pxl8_anim.c + client/src/gfx/pxl8_atlas.c + client/src/gfx/pxl8_blit.c + client/src/gfx/pxl8_3d_camera.c + client/src/gfx/pxl8_colormap.c + client/src/gfx/pxl8_cpu.c + client/src/gfx/pxl8_dither.c + client/src/gfx/pxl8_font.c + client/src/gfx/pxl8_gfx.c + client/src/gfx/pxl8_mesh.c + client/src/gfx/pxl8_palette.c + client/src/gfx/pxl8_particles.c + client/src/gfx/pxl8_tilemap.c + client/src/gfx/pxl8_tilesheet.c + client/src/gfx/pxl8_transition.c + client/src/sfx/pxl8_sfx.c + client/src/script/pxl8_repl.c + client/src/script/pxl8_script.c + client/src/hal/pxl8_sdl3.c + client/src/world/pxl8_bsp.c + client/src/world/pxl8_gen.c + client/src/world/pxl8_world.c + client/src/asset/pxl8_ase.c + client/src/asset/pxl8_cart.c + client/src/asset/pxl8_save.c + client/src/game/pxl8_gui.c + client/src/game/pxl8_replay.c " LUAJIT_LIB="lib/luajit/src/libluajit.a" @@ -446,13 +390,13 @@ case "$COMMAND" in NEEDS_REBUILD=false if [[ "$src_file" -nt "$obj_file" ]] || \ - [[ "src/core/pxl8_types.h" -nt "$obj_file" ]] || \ - [[ "src/core/pxl8_macros.h" -nt "$obj_file" ]]; then + [[ "client/src/core/pxl8_types.h" -nt "$obj_file" ]] || \ + [[ "client/src/core/pxl8_macros.h" -nt "$obj_file" ]]; then NEEDS_REBUILD=true fi - if [[ "$src_file" == "src/script/pxl8_script.c" ]]; then - for lua_file in src/lua/*.lua src/lua/pxl8/*.lua lib/fennel/fennel.lua; do + if [[ "$src_file" == "client/src/script/pxl8_script.c" ]]; then + for lua_file in client/src/lua/*.lua client/src/lua/pxl8/*.lua lib/fennel/fennel.lua; do if [[ -f "$lua_file" ]] && [[ "$lua_file" -nt "$obj_file" ]]; then NEEDS_REBUILD=true break @@ -486,25 +430,16 @@ case "$COMMAND" in CART="" EXTRA_ARGS="" - RUN_SERVER=false for arg in "$@"; do if [[ "$arg" == "--release" ]]; then - MODE="release" + continue elif [[ "$arg" == "--repl" ]]; then EXTRA_ARGS="$EXTRA_ARGS --repl" - elif [[ "$arg" == "--server" ]]; then - RUN_SERVER=true elif [[ -z "$CART" ]]; then CART="$arg" fi done - if [[ "$RUN_SERVER" == true ]]; then - build_server "$MODE" - start_server "$MODE" - trap stop_server EXIT - fi - if [[ -z "$CART" ]]; then "$BINDIR/pxl8" $EXTRA_ARGS else diff --git a/server/.cargo/config.toml b/server/.cargo/config.toml deleted file mode 100644 index 7317206..0000000 --- a/server/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[unstable] -build-std = ["core", "alloc"] diff --git a/server/.gitignore b/server/.gitignore deleted file mode 100644 index 2f7896d..0000000 --- a/server/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target/ diff --git a/server/Cargo.lock b/server/Cargo.lock deleted file mode 100644 index fbbf93d..0000000 --- a/server/Cargo.lock +++ /dev/null @@ -1,1090 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "assert_type_match" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f548ad2c4031f2902e3edc1f29c29e835829437de49562d8eb5dc5584d3a1043" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-channel" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "bevy_ecs" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24637a7c8643cab493f4085cda6bde4895f0e0816699c59006f18819da2ca0b8" -dependencies = [ - "arrayvec", - "bevy_ecs_macros", - "bevy_platform", - "bevy_ptr", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "bitflags", - "bumpalo", - "concurrent-queue", - "derive_more", - "fixedbitset", - "indexmap", - "log", - "nonmax", - "serde", - "slotmap", - "smallvec", - "thiserror", - "variadics_please", -] - -[[package]] -name = "bevy_ecs_macros" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eb14c18ca71e11c69fbae873c2db129064efac6d52e48d0127d37bfba1acfa8" -dependencies = [ - "bevy_macro_utils", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "bevy_macro_utils" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7272fca0bf30d8ca2571a803598856104b63e5c596d52850f811ed37c5e1e3" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "toml_edit", -] - -[[package]] -name = "bevy_platform" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b29ea749a8e85f98186ab662f607b885b97c804bb14cdb0cdf838164496d474" -dependencies = [ - "critical-section", - "foldhash", - "futures-channel", - "hashbrown", - "js-sys", - "portable-atomic", - "portable-atomic-util", - "serde", - "spin", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "bevy_ptr" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f98cbc6d34bbdb58240b72ed1731931b4991a893b3a3238bb7c42ae054aa676" - -[[package]] -name = "bevy_reflect" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2a977e2b8dba65b6e9c11039c5f9ef108be428f036b3d1cac13ad86ec59f9c" -dependencies = [ - "assert_type_match", - "bevy_platform", - "bevy_ptr", - "bevy_reflect_derive", - "bevy_utils", - "derive_more", - "disqualified", - "downcast-rs", - "erased-serde", - "foldhash", - "glam", - "indexmap", - "serde", - "smallvec", - "smol_str", - "thiserror", - "uuid", - "variadics_please", - "wgpu-types", -] - -[[package]] -name = "bevy_reflect_derive" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "067af30072b1611fda1a577f1cb678b8ea2c9226133068be808dd49aac30cef0" -dependencies = [ - "bevy_macro_utils", - "indexmap", - "proc-macro2", - "quote", - "syn", - "uuid", -] - -[[package]] -name = "bevy_tasks" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990ffedd374dd2c4fe8f0fd4bcefd5617d1ee59164b6c3fcc356a69b48e26e8e" -dependencies = [ - "async-channel", - "async-task", - "atomic-waker", - "bevy_platform", - "crossbeam-queue", - "derive_more", - "futures-lite", - "heapless", - "pin-project", -] - -[[package]] -name = "bevy_utils" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e258c44d869f9c41ac0f88a16815c67f2569eb9fff4716828a40273d127b6f84" -dependencies = [ - "bevy_platform", - "disqualified", - "thread_local", -] - -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", -] - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" -dependencies = [ - "serde_core", -] - -[[package]] -name = "bumpalo" -version = "3.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" - -[[package]] -name = "bytemuck" -version = "1.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", - "portable-atomic", -] - -[[package]] -name = "convert_case" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "critical-section" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" - -[[package]] -name = "crossbeam-queue" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "derive_more" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn", - "unicode-xid", -] - -[[package]] -name = "disqualified" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c272297e804878a2a4b707cfcfc6d2328b5bb936944613b4fdf2b9269afdfd" - -[[package]] -name = "downcast-rs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "erased-serde" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" -dependencies = [ - "serde", - "serde_core", - "typeid", -] - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - -[[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-lite" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", -] - -[[package]] -name = "glam" -version = "0.30.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9" -dependencies = [ - "serde_core", -] - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "hash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" -dependencies = [ - "byteorder", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -dependencies = [ - "equivalent", - "serde", - "serde_core", -] - -[[package]] -name = "heapless" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed" -dependencies = [ - "hash32", - "portable-atomic", - "stable_deref_trait", -] - -[[package]] -name = "indexmap" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "js-sys" -version = "0.3.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.180" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "libm" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nonmax" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "portable-atomic" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" - -[[package]] -name = "portable-atomic-util" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "pxl8-server" -version = "0.1.0" -dependencies = [ - "bevy_ecs", - "bindgen", - "libc", - "libm", - "windows-sys", -] - -[[package]] -name = "quote" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "slotmap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" -dependencies = [ - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "smol_str" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" -dependencies = [ - "serde", -] - -[[package]] -name = "spin" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "syn" -version = "2.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_edit" -version = "0.23.10+spec-1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" -dependencies = [ - "indexmap", - "toml_datetime", - "toml_parser", - "winnow", -] - -[[package]] -name = "toml_parser" -version = "1.0.6+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" -dependencies = [ - "winnow", -] - -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - -[[package]] -name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "uuid" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" -dependencies = [ - "getrandom", - "js-sys", - "serde_core", - "wasm-bindgen", -] - -[[package]] -name = "variadics_please" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b6d82be61465f97d42bd1d15bf20f3b0a3a0905018f38f9d6f6962055b0b5c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "wasip2" -version = "1.0.2+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" -dependencies = [ - "cfg-if", - "futures-util", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wgpu-types" -version = "27.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" -dependencies = [ - "bitflags", - "bytemuck", - "js-sys", - "log", - "serde", - "thiserror", - "web-sys", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "winnow" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" diff --git a/server/Cargo.toml b/server/Cargo.toml deleted file mode 100644 index 2ef61a7..0000000 --- a/server/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "pxl8-server" -version = "0.1.0" -edition = "2024" - -[build-dependencies] -bindgen = "0.72" - -[dependencies] -bevy_ecs = { version = "0.18", default-features = false } -libc = { version = "0.2", default-features = false } -libm = { version = "0.2", default-features = false } - -[target.'cfg(windows)'.dependencies] -windows-sys = { version = "0.61", default-features = false, features = [ - "Win32_System_Memory", - "Win32_System_Performance", - "Win32_System_Threading", - "Win32_Networking_WinSock", -] } - -[[bin]] -name = "pxl8-server" -path = "src/main.rs" - -[profile.dev] -panic = "abort" - -[profile.release] -panic = "abort" - -[features] -default = [] -std = ["bevy_ecs/std"] diff --git a/server/build.rs b/server/build.rs deleted file mode 100644 index 5c30ae3..0000000 --- a/server/build.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::env; -use std::path::PathBuf; - -fn main() { - let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - let pxl8_src = PathBuf::from(&manifest_dir).join("../src"); - - println!("cargo:rerun-if-changed=../src/net/pxl8_protocol.h"); - println!("cargo:rerun-if-changed=../src/core/pxl8_types.h"); - - let bindings = bindgen::Builder::default() - .header(pxl8_src.join("net/pxl8_protocol.h").to_str().unwrap()) - .clang_arg(format!("-I{}", pxl8_src.join("core").display())) - .use_core() - .rustified_enum(".*") - .generate() - .expect("Unable to generate bindings"); - - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("protocol.rs")) - .expect("Couldn't write bindings"); -} diff --git a/server/rust-toolchain.toml b/server/rust-toolchain.toml deleted file mode 100644 index 5d56faf..0000000 --- a/server/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "nightly" diff --git a/server/src/allocator.rs b/server/src/allocator.rs deleted file mode 100644 index dada493..0000000 --- a/server/src/allocator.rs +++ /dev/null @@ -1,36 +0,0 @@ -use core::alloc::{GlobalAlloc, Layout}; - -pub struct Allocator; - -#[cfg(unix)] -unsafe impl GlobalAlloc for Allocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - unsafe { libc::memalign(layout.align(), layout.size()) as *mut u8 } - } - - unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - unsafe { libc::free(ptr as *mut libc::c_void) } - } - - unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 { - unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } - } -} - -#[cfg(windows)] -unsafe impl GlobalAlloc for Allocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - use windows_sys::Win32::System::Memory::*; - unsafe { HeapAlloc(GetProcessHeap(), 0, layout.size()) as *mut u8 } - } - - unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - use windows_sys::Win32::System::Memory::*; - unsafe { HeapFree(GetProcessHeap(), 0, ptr as *mut core::ffi::c_void) }; - } - - unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 { - use windows_sys::Win32::System::Memory::*; - unsafe { HeapReAlloc(GetProcessHeap(), 0, ptr as *mut core::ffi::c_void, new_size) as *mut u8 } - } -} diff --git a/server/src/components.rs b/server/src/components.rs deleted file mode 100644 index 02f3516..0000000 --- a/server/src/components.rs +++ /dev/null @@ -1,45 +0,0 @@ -use bevy_ecs::prelude::*; - -#[derive(Component, Clone, Copy, Default)] -pub struct Position { - pub x: f32, - pub y: f32, - pub z: f32, -} - -#[derive(Component, Clone, Copy, Default)] -pub struct Rotation { - pub pitch: f32, - pub yaw: f32, -} - -#[derive(Component, Clone, Copy, Default)] -pub struct Velocity { - pub x: f32, - pub y: f32, - pub z: f32, -} - -#[derive(Component, Clone, Copy)] -pub struct Health { - pub current: f32, - pub max: f32, -} - -impl Health { - pub fn new(max: f32) -> Self { - Self { current: max, max } - } -} - -impl Default for Health { - fn default() -> Self { - Self::new(100.0) - } -} - -#[derive(Component, Clone, Copy, Default)] -pub struct Player; - -#[derive(Component, Clone, Copy)] -pub struct TypeId(pub u16); diff --git a/server/src/lib.rs b/server/src/lib.rs deleted file mode 100644 index a628640..0000000 --- a/server/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![no_std] - -extern crate alloc; - -pub mod components; -mod simulation; -pub mod transport; - -#[allow(dead_code, non_camel_case_types, non_snake_case, non_upper_case_globals)] -pub mod protocol { - include!(concat!(env!("OUT_DIR"), "/protocol.rs")); -} - -pub use bevy_ecs::prelude::*; -pub use components::*; -pub use protocol::*; -pub use simulation::*; -pub use transport::*; diff --git a/server/src/main.rs b/server/src/main.rs deleted file mode 100644 index 165fbbc..0000000 --- a/server/src/main.rs +++ /dev/null @@ -1,142 +0,0 @@ -#![no_std] -#![no_main] - -extern crate alloc; - -mod allocator; - -use core::panic::PanicInfo; -use pxl8_server::*; - -#[global_allocator] -static ALLOCATOR: allocator::Allocator = allocator::Allocator; - -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - loop {} -} - -const TICK_RATE: u64 = 30; -const TICK_NS: u64 = 1_000_000_000 / TICK_RATE; - -#[cfg(unix)] -fn get_time_ns() -> u64 { - let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 }; - unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts) }; - (ts.tv_sec as u64) * 1_000_000_000 + (ts.tv_nsec as u64) -} - -#[cfg(windows)] -fn get_time_ns() -> u64 { - use windows_sys::Win32::System::Performance::*; - static mut FREQ: i64 = 0; - unsafe { - if FREQ == 0 { - QueryPerformanceFrequency(&mut FREQ); - } - let mut count: i64 = 0; - QueryPerformanceCounter(&mut count); - ((count as u128 * 1_000_000_000) / FREQ as u128) as u64 - } -} - -#[cfg(unix)] -fn sleep_ms(ms: u64) { - let ts = libc::timespec { - tv_sec: (ms / 1000) as i64, - tv_nsec: ((ms % 1000) * 1_000_000) as i64, - }; - unsafe { libc::nanosleep(&ts, core::ptr::null_mut()) }; -} - -#[cfg(windows)] -fn sleep_ms(ms: u64) { - use windows_sys::Win32::System::Threading::Sleep; - unsafe { Sleep(ms as u32) }; -} - -fn extract_spawn_position(payload: &[u8]) -> (f32, f32, f32, f32, f32) { - let x = f32::from_be_bytes([payload[0], payload[1], payload[2], payload[3]]); - let y = f32::from_be_bytes([payload[4], payload[5], payload[6], payload[7]]); - let z = f32::from_be_bytes([payload[8], payload[9], payload[10], payload[11]]); - let yaw = f32::from_be_bytes([payload[12], payload[13], payload[14], payload[15]]); - let pitch = f32::from_be_bytes([payload[16], payload[17], payload[18], payload[19]]); - (x, y, z, yaw, pitch) -} - -#[unsafe(no_mangle)] -pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { - let mut transport = match transport::Transport::bind(transport::DEFAULT_PORT) { - Some(t) => t, - None => return 1, - }; - - let mut sim = Simulation::new(); - let mut player_id: u64 = 0; - let mut last_client_tick: u64 = 0; - - let mut sequence: u32 = 0; - let mut last_tick = get_time_ns(); - let mut entities_buf = [protocol::pxl8_entity_state { - entity_id: 0, - userdata: [0u8; 56], - }; 64]; - let mut inputs_buf: [protocol::pxl8_input_msg; 16] = unsafe { core::mem::zeroed() }; - - loop { - let now = get_time_ns(); - let elapsed = now.saturating_sub(last_tick); - - if elapsed >= TICK_NS { - last_tick = now; - let dt = (elapsed as f32) / 1_000_000_000.0; - - let mut latest_input: Option = None; - while let Some(msg_type) = transport.recv() { - match msg_type { - x if x == protocol::pxl8_msg_type::PXL8_MSG_INPUT as u8 => { - latest_input = Some(transport.get_input()); - } - x if x == protocol::pxl8_msg_type::PXL8_MSG_COMMAND as u8 => { - let cmd = transport.get_command(); - if cmd.cmd_type == protocol::pxl8_cmd_type::PXL8_CMD_SPAWN_ENTITY as u16 { - let (x, y, z, _yaw, _pitch) = extract_spawn_position(&cmd.payload); - let player = sim.spawn_player(x, y, z); - player_id = player.to_bits(); - } - } - _ => {} - } - } - - if let Some(input) = latest_input { - last_client_tick = input.tick; - inputs_buf[0] = input; - sim.step(&inputs_buf[..1], dt); - } else { - sim.step(&[], dt); - } - - let mut count = 0; - sim.generate_snapshot(player_id, |state| { - if count < entities_buf.len() { - entities_buf[count] = *state; - count += 1; - } - }); - - let header = protocol::pxl8_snapshot_header { - entity_count: count as u16, - event_count: 0, - player_id, - tick: last_client_tick, - time: sim.time, - }; - - transport.send_snapshot(&header, &entities_buf[..count], sequence); - sequence = sequence.wrapping_add(1); - } - - sleep_ms(1); - } -} diff --git a/server/src/simulation.rs b/server/src/simulation.rs deleted file mode 100644 index 5e9f231..0000000 --- a/server/src/simulation.rs +++ /dev/null @@ -1,133 +0,0 @@ -use bevy_ecs::prelude::*; -use libm::{cosf, sinf}; - -use crate::components::*; -use crate::protocol::*; - -#[derive(Resource, Default)] -pub struct SimTime { - pub dt: f32, - pub time: f32, -} - -pub struct Simulation { - pub player: Option, - pub tick: u64, - pub time: f32, - pub world: World, -} - -impl Simulation { - pub fn new() -> Self { - let mut world = World::new(); - world.insert_resource(SimTime::default()); - Self { - player: None, - tick: 0, - time: 0.0, - world, - } - } - - pub fn step(&mut self, inputs: &[pxl8_input_msg], dt: f32) { - self.tick += 1; - self.time += dt; - - if let Some(mut sim_time) = self.world.get_resource_mut::() { - sim_time.dt = dt; - sim_time.time = self.time; - } - - for input in inputs { - self.apply_input(input, dt); - } - } - - fn apply_input(&mut self, input: &pxl8_input_msg, dt: f32) { - let Some(player) = self.player else { return }; - let speed = 200.0; - - let yaw = input.yaw; - let sin_yaw = sinf(yaw); - let cos_yaw = cosf(yaw); - - let move_x = input.move_x; - let move_y = input.move_y; - let len_sq = move_x * move_x + move_y * move_y; - - if len_sq > 0.0 { - let len = libm::sqrtf(len_sq); - let norm_x = move_x / len; - let norm_y = move_y / len; - - let forward_x = -sin_yaw * norm_y * speed * dt; - let forward_z = -cos_yaw * norm_y * speed * dt; - let strafe_x = cos_yaw * norm_x * speed * dt; - let strafe_z = -sin_yaw * norm_x * speed * dt; - - if let Some(mut pos) = self.world.get_mut::(player) { - pos.x += forward_x + strafe_x; - pos.z += forward_z + strafe_z; - } - } - - if let Some(mut rot) = self.world.get_mut::(player) { - rot.yaw = yaw; - rot.pitch = (rot.pitch - input.look_dy * 0.008).clamp(-1.5, 1.5); - } - } - - pub fn spawn_entity(&mut self) -> Entity { - self.world.spawn(( - Position::default(), - Rotation::default(), - Velocity::default(), - )).id() - } - - pub fn spawn_player(&mut self, x: f32, y: f32, z: f32) -> Entity { - let entity = self.world.spawn(( - Player, - Position { x, y, z }, - Rotation::default(), - Velocity::default(), - Health::default(), - )).id(); - self.player = Some(entity); - entity - } - - pub fn generate_snapshot(&mut self, player_id: u64, mut writer: F) - where - F: FnMut(&pxl8_entity_state), - { - let mut query = self.world.query::<(Entity, &Position, &Rotation)>(); - for (entity, pos, rot) in query.iter(&self.world) { - let mut state = pxl8_entity_state { - entity_id: entity.to_bits(), - userdata: [0u8; 56], - }; - - let bytes = &mut state.userdata; - bytes[0..4].copy_from_slice(&pos.x.to_be_bytes()); - bytes[4..8].copy_from_slice(&pos.y.to_be_bytes()); - bytes[8..12].copy_from_slice(&pos.z.to_be_bytes()); - bytes[12..16].copy_from_slice(&rot.yaw.to_be_bytes()); - bytes[16..20].copy_from_slice(&rot.pitch.to_be_bytes()); - - writer(&state); - } - - let _ = player_id; - } - - pub fn entity_count(&self) -> usize { - self.world.entities().len() as usize - } -} - -impl Default for Simulation { - fn default() -> Self { - Self::new() - } -} diff --git a/server/src/transport.rs b/server/src/transport.rs deleted file mode 100644 index 2315433..0000000 --- a/server/src/transport.rs +++ /dev/null @@ -1,281 +0,0 @@ -use crate::protocol::*; - -pub const DEFAULT_PORT: u16 = 7777; - -#[cfg(unix)] -mod sys { - use libc::{c_int, c_void, sockaddr, sockaddr_in, socklen_t}; - - pub type RawSocket = c_int; - pub const INVALID_SOCKET: RawSocket = -1; - - pub fn socket() -> RawSocket { - unsafe { libc::socket(libc::AF_INET, libc::SOCK_DGRAM, 0) } - } - - pub fn bind(sock: RawSocket, port: u16) -> c_int { - let addr = sockaddr_in { - sin_family: libc::AF_INET as u16, - sin_port: port.to_be(), - sin_addr: libc::in_addr { s_addr: u32::from_be_bytes([127, 0, 0, 1]).to_be() }, - sin_zero: [0; 8], - }; - unsafe { libc::bind(sock, &addr as *const _ as *const sockaddr, core::mem::size_of::() as socklen_t) } - } - - pub fn set_nonblocking(sock: RawSocket) -> c_int { - unsafe { - let flags = libc::fcntl(sock, libc::F_GETFL, 0); - libc::fcntl(sock, libc::F_SETFL, flags | libc::O_NONBLOCK) - } - } - - pub fn recvfrom(sock: RawSocket, buf: &mut [u8], addr: &mut sockaddr_in) -> isize { - let mut addr_len = core::mem::size_of::() as socklen_t; - unsafe { - libc::recvfrom( - sock, - buf.as_mut_ptr() as *mut c_void, - buf.len(), - 0, - addr as *mut _ as *mut sockaddr, - &mut addr_len, - ) - } - } - - pub fn sendto(sock: RawSocket, buf: &[u8], addr: &sockaddr_in) -> isize { - unsafe { - libc::sendto( - sock, - buf.as_ptr() as *const c_void, - buf.len(), - 0, - addr as *const _ as *const sockaddr, - core::mem::size_of::() as socklen_t, - ) - } - } - - pub fn close(sock: RawSocket) { - unsafe { libc::close(sock) }; - } -} - -#[cfg(windows)] -mod sys { - use windows_sys::Win32::Networking::WinSock::*; - - pub type RawSocket = SOCKET; - pub const INVALID_SOCKET_VAL: RawSocket = INVALID_SOCKET; - - pub fn socket() -> RawSocket { - unsafe { socket(AF_INET as i32, SOCK_DGRAM as i32, 0) } - } - - pub fn bind(sock: RawSocket, port: u16) -> i32 { - let addr = SOCKADDR_IN { - sin_family: AF_INET, - sin_port: port.to_be(), - sin_addr: IN_ADDR { S_un: IN_ADDR_0 { S_addr: u32::from_be_bytes([127, 0, 0, 1]).to_be() } }, - sin_zero: [0; 8], - }; - unsafe { bind(sock, &addr as *const _ as *const SOCKADDR, core::mem::size_of::() as i32) } - } - - pub fn set_nonblocking(sock: RawSocket) -> i32 { - let mut nonblocking: u32 = 1; - unsafe { ioctlsocket(sock, FIONBIO as i32, &mut nonblocking) } - } - - pub fn recvfrom(sock: RawSocket, buf: &mut [u8], addr: &mut SOCKADDR_IN) -> i32 { - let mut addr_len = core::mem::size_of::() as i32; - unsafe { - recvfrom( - sock, - buf.as_mut_ptr(), - buf.len() as i32, - 0, - addr as *mut _ as *mut SOCKADDR, - &mut addr_len, - ) - } - } - - pub fn sendto(sock: RawSocket, buf: &[u8], addr: &SOCKADDR_IN) -> i32 { - unsafe { - sendto( - sock, - buf.as_ptr(), - buf.len() as i32, - 0, - addr as *const _ as *const SOCKADDR, - core::mem::size_of::() as i32, - ) - } - } - - pub fn close(sock: RawSocket) { - unsafe { closesocket(sock) }; - } -} - -#[cfg(unix)] -type SockAddr = libc::sockaddr_in; - -#[cfg(windows)] -type SockAddr = windows_sys::Win32::Networking::WinSock::SOCKADDR_IN; - -pub struct Transport { - client_addr: SockAddr, - has_client: bool, - recv_buf: [u8; 4096], - send_buf: [u8; 4096], - socket: sys::RawSocket, -} - -impl Transport { - pub fn bind(port: u16) -> Option { - let sock = sys::socket(); - if sock == sys::INVALID_SOCKET { - return None; - } - - if sys::bind(sock, port) < 0 { - sys::close(sock); - return None; - } - - if sys::set_nonblocking(sock) < 0 { - sys::close(sock); - return None; - } - - Some(Self { - client_addr: unsafe { core::mem::zeroed() }, - has_client: false, - recv_buf: [0u8; 4096], - send_buf: [0u8; 4096], - socket: sock, - }) - } - - pub fn recv(&mut self) -> Option { - let mut addr: SockAddr = unsafe { core::mem::zeroed() }; - let len = sys::recvfrom(self.socket, &mut self.recv_buf, &mut addr); - - if len <= 0 || (len as usize) < size_of::() { - return None; - } - - self.client_addr = addr; - self.has_client = true; - - let header = self.deserialize_header(); - Some(header.type_) - } - - pub fn get_input(&self) -> pxl8_input_msg { - self.deserialize_input() - } - - pub fn get_command(&self) -> pxl8_command_msg { - self.deserialize_command() - } - - pub fn send_snapshot( - &mut self, - header: &pxl8_snapshot_header, - entities: &[pxl8_entity_state], - sequence: u32, - ) { - if !self.has_client { - return; - } - - let mut offset = 0; - - let msg_header = pxl8_msg_header { - sequence, - size: 0, - type_: pxl8_msg_type::PXL8_MSG_SNAPSHOT as u8, - version: PXL8_PROTOCOL_VERSION as u8, - }; - offset += self.serialize_header(&msg_header, offset); - offset += self.serialize_snapshot_header(header, offset); - - for entity in entities { - offset += self.serialize_entity_state(entity, offset); - } - - sys::sendto(self.socket, &self.send_buf[..offset], &self.client_addr); - } - - fn serialize_header(&mut self, h: &pxl8_msg_header, offset: usize) -> usize { - let buf = &mut self.send_buf[offset..]; - buf[0..4].copy_from_slice(&h.sequence.to_be_bytes()); - buf[4..6].copy_from_slice(&h.size.to_be_bytes()); - buf[6] = h.type_; - buf[7] = h.version; - 8 - } - - fn serialize_snapshot_header(&mut self, h: &pxl8_snapshot_header, offset: usize) -> usize { - let buf = &mut self.send_buf[offset..]; - buf[0..2].copy_from_slice(&h.entity_count.to_be_bytes()); - buf[2..4].copy_from_slice(&h.event_count.to_be_bytes()); - buf[4..12].copy_from_slice(&h.player_id.to_be_bytes()); - buf[12..20].copy_from_slice(&h.tick.to_be_bytes()); - buf[20..24].copy_from_slice(&h.time.to_be_bytes()); - 24 - } - - fn serialize_entity_state(&mut self, e: &pxl8_entity_state, offset: usize) -> usize { - let buf = &mut self.send_buf[offset..]; - buf[0..8].copy_from_slice(&e.entity_id.to_be_bytes()); - buf[8..64].copy_from_slice(&e.userdata); - 64 - } - - fn deserialize_header(&self) -> pxl8_msg_header { - let buf = &self.recv_buf; - pxl8_msg_header { - sequence: u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]), - size: u16::from_be_bytes([buf[4], buf[5]]), - type_: buf[6], - version: buf[7], - } - } - - fn deserialize_input(&self) -> pxl8_input_msg { - let buf = &self.recv_buf[8..]; - pxl8_input_msg { - buttons: u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]), - look_dx: f32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]), - look_dy: f32::from_be_bytes([buf[8], buf[9], buf[10], buf[11]]), - move_x: f32::from_be_bytes([buf[12], buf[13], buf[14], buf[15]]), - move_y: f32::from_be_bytes([buf[16], buf[17], buf[18], buf[19]]), - yaw: f32::from_be_bytes([buf[20], buf[21], buf[22], buf[23]]), - tick: u64::from_be_bytes([buf[24], buf[25], buf[26], buf[27], buf[28], buf[29], buf[30], buf[31]]), - timestamp: u64::from_be_bytes([buf[32], buf[33], buf[34], buf[35], buf[36], buf[37], buf[38], buf[39]]), - } - } - - fn deserialize_command(&self) -> pxl8_command_msg { - let buf = &self.recv_buf[8..]; - let mut cmd = pxl8_command_msg { - cmd_type: u16::from_be_bytes([buf[0], buf[1]]), - payload: [0u8; 64], - payload_size: u16::from_be_bytes([buf[66], buf[67]]), - tick: u64::from_be_bytes([buf[68], buf[69], buf[70], buf[71], buf[72], buf[73], buf[74], buf[75]]), - }; - cmd.payload.copy_from_slice(&buf[2..66]); - cmd - } -} - -impl Drop for Transport { - fn drop(&mut self) { - sys::close(self.socket); - } -} diff --git a/src/core/pxl8_bytes.c b/src/core/pxl8_bytes.c deleted file mode 100644 index 1894878..0000000 --- a/src/core/pxl8_bytes.c +++ /dev/null @@ -1,234 +0,0 @@ -#include "pxl8_bytes.h" -#include - -void pxl8_pack_u8(u8* buf, size_t offset, u8 val) { - buf[offset] = val; -} - -void pxl8_pack_u16_le(u8* buf, size_t offset, u16 val) { - buf[offset] = (u8)(val); - buf[offset + 1] = (u8)(val >> 8); -} - -void pxl8_pack_u16_be(u8* buf, size_t offset, u16 val) { - buf[offset] = (u8)(val >> 8); - buf[offset + 1] = (u8)(val); -} - -void pxl8_pack_u32_le(u8* buf, size_t offset, u32 val) { - buf[offset] = (u8)(val); - buf[offset + 1] = (u8)(val >> 8); - buf[offset + 2] = (u8)(val >> 16); - buf[offset + 3] = (u8)(val >> 24); -} - -void pxl8_pack_u32_be(u8* buf, size_t offset, u32 val) { - buf[offset] = (u8)(val >> 24); - buf[offset + 1] = (u8)(val >> 16); - buf[offset + 2] = (u8)(val >> 8); - buf[offset + 3] = (u8)(val); -} - -void pxl8_pack_u64_le(u8* buf, size_t offset, u64 val) { - buf[offset] = (u8)(val); - buf[offset + 1] = (u8)(val >> 8); - buf[offset + 2] = (u8)(val >> 16); - buf[offset + 3] = (u8)(val >> 24); - buf[offset + 4] = (u8)(val >> 32); - buf[offset + 5] = (u8)(val >> 40); - buf[offset + 6] = (u8)(val >> 48); - buf[offset + 7] = (u8)(val >> 56); -} - -void pxl8_pack_u64_be(u8* buf, size_t offset, u64 val) { - buf[offset] = (u8)(val >> 56); - buf[offset + 1] = (u8)(val >> 48); - buf[offset + 2] = (u8)(val >> 40); - buf[offset + 3] = (u8)(val >> 32); - buf[offset + 4] = (u8)(val >> 24); - buf[offset + 5] = (u8)(val >> 16); - buf[offset + 6] = (u8)(val >> 8); - buf[offset + 7] = (u8)(val); -} - -void pxl8_pack_i8(u8* buf, size_t offset, i8 val) { - buf[offset] = (u8)val; -} - -void pxl8_pack_i16_le(u8* buf, size_t offset, i16 val) { - pxl8_pack_u16_le(buf, offset, (u16)val); -} - -void pxl8_pack_i16_be(u8* buf, size_t offset, i16 val) { - pxl8_pack_u16_be(buf, offset, (u16)val); -} - -void pxl8_pack_i32_le(u8* buf, size_t offset, i32 val) { - pxl8_pack_u32_le(buf, offset, (u32)val); -} - -void pxl8_pack_i32_be(u8* buf, size_t offset, i32 val) { - pxl8_pack_u32_be(buf, offset, (u32)val); -} - -void pxl8_pack_i64_le(u8* buf, size_t offset, i64 val) { - pxl8_pack_u64_le(buf, offset, (u64)val); -} - -void pxl8_pack_i64_be(u8* buf, size_t offset, i64 val) { - pxl8_pack_u64_be(buf, offset, (u64)val); -} - -void pxl8_pack_f32_le(u8* buf, size_t offset, f32 val) { - u32 bits; - memcpy(&bits, &val, sizeof(bits)); - pxl8_pack_u32_le(buf, offset, bits); -} - -void pxl8_pack_f32_be(u8* buf, size_t offset, f32 val) { - u32 bits; - memcpy(&bits, &val, sizeof(bits)); - pxl8_pack_u32_be(buf, offset, bits); -} - -void pxl8_pack_f64_le(u8* buf, size_t offset, f64 val) { - u64 bits; - memcpy(&bits, &val, sizeof(bits)); - pxl8_pack_u64_le(buf, offset, bits); -} - -void pxl8_pack_f64_be(u8* buf, size_t offset, f64 val) { - u64 bits; - memcpy(&bits, &val, sizeof(bits)); - pxl8_pack_u64_be(buf, offset, bits); -} - -u8 pxl8_unpack_u8(const u8* buf, size_t offset) { - return buf[offset]; -} - -u16 pxl8_unpack_u16_le(const u8* buf, size_t offset) { - return (u16)buf[offset] | ((u16)buf[offset + 1] << 8); -} - -u16 pxl8_unpack_u16_be(const u8* buf, size_t offset) { - return ((u16)buf[offset] << 8) | (u16)buf[offset + 1]; -} - -u32 pxl8_unpack_u32_le(const u8* buf, size_t offset) { - return (u32)buf[offset] | - ((u32)buf[offset + 1] << 8) | - ((u32)buf[offset + 2] << 16) | - ((u32)buf[offset + 3] << 24); -} - -u32 pxl8_unpack_u32_be(const u8* buf, size_t offset) { - return ((u32)buf[offset] << 24) | - ((u32)buf[offset + 1] << 16) | - ((u32)buf[offset + 2] << 8) | - (u32)buf[offset + 3]; -} - -u64 pxl8_unpack_u64_le(const u8* buf, size_t offset) { - return (u64)buf[offset] | - ((u64)buf[offset + 1] << 8) | - ((u64)buf[offset + 2] << 16) | - ((u64)buf[offset + 3] << 24) | - ((u64)buf[offset + 4] << 32) | - ((u64)buf[offset + 5] << 40) | - ((u64)buf[offset + 6] << 48) | - ((u64)buf[offset + 7] << 56); -} - -u64 pxl8_unpack_u64_be(const u8* buf, size_t offset) { - return ((u64)buf[offset] << 56) | - ((u64)buf[offset + 1] << 48) | - ((u64)buf[offset + 2] << 40) | - ((u64)buf[offset + 3] << 32) | - ((u64)buf[offset + 4] << 24) | - ((u64)buf[offset + 5] << 16) | - ((u64)buf[offset + 6] << 8) | - (u64)buf[offset + 7]; -} - -i8 pxl8_unpack_i8(const u8* buf, size_t offset) { - return (i8)buf[offset]; -} - -i16 pxl8_unpack_i16_le(const u8* buf, size_t offset) { - return (i16)pxl8_unpack_u16_le(buf, offset); -} - -i16 pxl8_unpack_i16_be(const u8* buf, size_t offset) { - return (i16)pxl8_unpack_u16_be(buf, offset); -} - -i32 pxl8_unpack_i32_le(const u8* buf, size_t offset) { - return (i32)pxl8_unpack_u32_le(buf, offset); -} - -i32 pxl8_unpack_i32_be(const u8* buf, size_t offset) { - return (i32)pxl8_unpack_u32_be(buf, offset); -} - -i64 pxl8_unpack_i64_le(const u8* buf, size_t offset) { - return (i64)pxl8_unpack_u64_le(buf, offset); -} - -i64 pxl8_unpack_i64_be(const u8* buf, size_t offset) { - return (i64)pxl8_unpack_u64_be(buf, offset); -} - -f32 pxl8_unpack_f32_le(const u8* buf, size_t offset) { - u32 bits = pxl8_unpack_u32_le(buf, offset); - f32 result; - memcpy(&result, &bits, sizeof(result)); - return result; -} - -f32 pxl8_unpack_f32_be(const u8* buf, size_t offset) { - u32 bits = pxl8_unpack_u32_be(buf, offset); - f32 result; - memcpy(&result, &bits, sizeof(result)); - return result; -} - -f64 pxl8_unpack_f64_le(const u8* buf, size_t offset) { - u64 bits = pxl8_unpack_u64_le(buf, offset); - f64 result; - memcpy(&result, &bits, sizeof(result)); - return result; -} - -f64 pxl8_unpack_f64_be(const u8* buf, size_t offset) { - u64 bits = pxl8_unpack_u64_be(buf, offset); - f64 result; - memcpy(&result, &bits, sizeof(result)); - return result; -} - -void pxl8_bit_set(u32* val, u8 bit) { - *val |= (1u << bit); -} - -void pxl8_bit_clear(u32* val, u8 bit) { - *val &= ~(1u << bit); -} - -bool pxl8_bit_test(u32 val, u8 bit) { - return (val & (1u << bit)) != 0; -} - -u32 pxl8_bit_count(u32 val) { -#if defined(__GNUC__) || defined(__clang__) - return (u32)__builtin_popcount(val); -#else - val = val - ((val >> 1) & 0x55555555); - val = (val & 0x33333333) + ((val >> 2) & 0x33333333); - return (((val + (val >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; -#endif -} - -void pxl8_bit_toggle(u32* val, u8 bit) { - *val ^= (1u << bit); -} diff --git a/src/core/pxl8_bytes.h b/src/core/pxl8_bytes.h deleted file mode 100644 index 5f5a5e7..0000000 --- a/src/core/pxl8_bytes.h +++ /dev/null @@ -1,251 +0,0 @@ -#pragma once - -#include - -#include "pxl8_types.h" - -void pxl8_bit_clear(u32* val, u8 bit); -u32 pxl8_bit_count(u32 val); -void pxl8_bit_set(u32* val, u8 bit); -bool pxl8_bit_test(u32 val, u8 bit); -void pxl8_bit_toggle(u32* val, u8 bit); - -void pxl8_pack_u8(u8* buf, size_t offset, u8 val); -void pxl8_pack_u16_be(u8* buf, size_t offset, u16 val); -void pxl8_pack_u16_le(u8* buf, size_t offset, u16 val); -void pxl8_pack_u32_be(u8* buf, size_t offset, u32 val); -void pxl8_pack_u32_le(u8* buf, size_t offset, u32 val); -void pxl8_pack_u64_be(u8* buf, size_t offset, u64 val); -void pxl8_pack_u64_le(u8* buf, size_t offset, u64 val); -void pxl8_pack_i8(u8* buf, size_t offset, i8 val); -void pxl8_pack_i16_be(u8* buf, size_t offset, i16 val); -void pxl8_pack_i16_le(u8* buf, size_t offset, i16 val); -void pxl8_pack_i32_be(u8* buf, size_t offset, i32 val); -void pxl8_pack_i32_le(u8* buf, size_t offset, i32 val); -void pxl8_pack_i64_be(u8* buf, size_t offset, i64 val); -void pxl8_pack_i64_le(u8* buf, size_t offset, i64 val); -void pxl8_pack_f32_be(u8* buf, size_t offset, f32 val); -void pxl8_pack_f32_le(u8* buf, size_t offset, f32 val); -void pxl8_pack_f64_be(u8* buf, size_t offset, f64 val); -void pxl8_pack_f64_le(u8* buf, size_t offset, f64 val); - -u8 pxl8_unpack_u8(const u8* buf, size_t offset); -u16 pxl8_unpack_u16_be(const u8* buf, size_t offset); -u16 pxl8_unpack_u16_le(const u8* buf, size_t offset); -u32 pxl8_unpack_u32_be(const u8* buf, size_t offset); -u32 pxl8_unpack_u32_le(const u8* buf, size_t offset); -u64 pxl8_unpack_u64_be(const u8* buf, size_t offset); -u64 pxl8_unpack_u64_le(const u8* buf, size_t offset); -i8 pxl8_unpack_i8(const u8* buf, size_t offset); -i16 pxl8_unpack_i16_be(const u8* buf, size_t offset); -i16 pxl8_unpack_i16_le(const u8* buf, size_t offset); -i32 pxl8_unpack_i32_be(const u8* buf, size_t offset); -i32 pxl8_unpack_i32_le(const u8* buf, size_t offset); -i64 pxl8_unpack_i64_be(const u8* buf, size_t offset); -i64 pxl8_unpack_i64_le(const u8* buf, size_t offset); -f32 pxl8_unpack_f32_be(const u8* buf, size_t offset); -f32 pxl8_unpack_f32_le(const u8* buf, size_t offset); -f64 pxl8_unpack_f64_be(const u8* buf, size_t offset); -f64 pxl8_unpack_f64_le(const u8* buf, size_t offset); - -typedef struct { - const u8* bytes; - u32 offset; - u32 size; - bool overflow; -} pxl8_stream; - -typedef struct { - u8* bytes; - u32 capacity; - u32 offset; - bool overflow; -} pxl8_write_stream; - -static inline pxl8_stream pxl8_stream_create(const u8* bytes, u32 size) { - return (pxl8_stream){ - .bytes = bytes, - .offset = 0, - .size = size, - .overflow = false - }; -} - -static inline pxl8_write_stream pxl8_write_stream_create(u8* bytes, u32 capacity) { - return (pxl8_write_stream){ - .bytes = bytes, - .capacity = capacity, - .offset = 0, - .overflow = false - }; -} - -static inline bool pxl8_stream_can_read(const pxl8_stream* s, u32 count) { - return !s->overflow && s->offset + count <= s->size; -} - -static inline bool pxl8_stream_has_overflow(const pxl8_stream* s) { - return s->overflow; -} - -static inline bool pxl8_write_stream_has_overflow(const pxl8_write_stream* s) { - return s->overflow; -} - -static inline u32 pxl8_stream_position(const pxl8_stream* s) { - return s->offset; -} - -static inline u32 pxl8_write_stream_position(const pxl8_write_stream* s) { - return s->offset; -} - -static inline void pxl8_stream_seek(pxl8_stream* s, u32 offset) { - s->offset = offset; -} - -static inline u8 pxl8_read_u8(pxl8_stream* s) { - if (s->offset + 1 > s->size) { s->overflow = true; return 0; } - return pxl8_unpack_u8(s->bytes, s->offset++); -} - -static inline u16 pxl8_read_u16(pxl8_stream* s) { - if (s->offset + 2 > s->size) { s->overflow = true; return 0; } - u16 val = pxl8_unpack_u16_le(s->bytes, s->offset); - s->offset += 2; - return val; -} - -static inline u16 pxl8_read_u16_be(pxl8_stream* s) { - if (s->offset + 2 > s->size) { s->overflow = true; return 0; } - u16 val = pxl8_unpack_u16_be(s->bytes, s->offset); - s->offset += 2; - return val; -} - -static inline u32 pxl8_read_u32(pxl8_stream* s) { - if (s->offset + 4 > s->size) { s->overflow = true; return 0; } - u32 val = pxl8_unpack_u32_le(s->bytes, s->offset); - s->offset += 4; - return val; -} - -static inline u32 pxl8_read_u32_be(pxl8_stream* s) { - if (s->offset + 4 > s->size) { s->overflow = true; return 0; } - u32 val = pxl8_unpack_u32_be(s->bytes, s->offset); - s->offset += 4; - return val; -} - -static inline u64 pxl8_read_u64(pxl8_stream* s) { - if (s->offset + 8 > s->size) { s->overflow = true; return 0; } - u64 val = pxl8_unpack_u64_le(s->bytes, s->offset); - s->offset += 8; - return val; -} - -static inline u64 pxl8_read_u64_be(pxl8_stream* s) { - if (s->offset + 8 > s->size) { s->overflow = true; return 0; } - u64 val = pxl8_unpack_u64_be(s->bytes, s->offset); - s->offset += 8; - return val; -} - -static inline i16 pxl8_read_i16(pxl8_stream* s) { - return (i16)pxl8_read_u16(s); -} - -static inline i32 pxl8_read_i32(pxl8_stream* s) { - return (i32)pxl8_read_u32(s); -} - -static inline f32 pxl8_read_f32(pxl8_stream* s) { - if (s->offset + 4 > s->size) { s->overflow = true; return 0; } - f32 val = pxl8_unpack_f32_le(s->bytes, s->offset); - s->offset += 4; - return val; -} - -static inline f32 pxl8_read_f32_be(pxl8_stream* s) { - if (s->offset + 4 > s->size) { s->overflow = true; return 0; } - f32 val = pxl8_unpack_f32_be(s->bytes, s->offset); - s->offset += 4; - return val; -} - -static inline void pxl8_read_bytes(pxl8_stream* s, void* dest, u32 count) { - if (s->offset + count > s->size) { s->overflow = true; return; } - memcpy(dest, &s->bytes[s->offset], count); - s->offset += count; -} - -static inline void pxl8_skip_bytes(pxl8_stream* s, u32 count) { - if (s->offset + count > s->size) { s->overflow = true; return; } - s->offset += count; -} - -static inline const u8* pxl8_read_ptr(pxl8_stream* s, u32 count) { - if (s->offset + count > s->size) { s->overflow = true; return NULL; } - const u8* ptr = &s->bytes[s->offset]; - s->offset += count; - return ptr; -} - -static inline void pxl8_write_u8(pxl8_write_stream* s, u8 val) { - if (s->offset + 1 > s->capacity) { s->overflow = true; return; } - pxl8_pack_u8(s->bytes, s->offset++, val); -} - -static inline void pxl8_write_u16(pxl8_write_stream* s, u16 val) { - if (s->offset + 2 > s->capacity) { s->overflow = true; return; } - pxl8_pack_u16_le(s->bytes, s->offset, val); - s->offset += 2; -} - -static inline void pxl8_write_u16_be(pxl8_write_stream* s, u16 val) { - if (s->offset + 2 > s->capacity) { s->overflow = true; return; } - pxl8_pack_u16_be(s->bytes, s->offset, val); - s->offset += 2; -} - -static inline void pxl8_write_u32(pxl8_write_stream* s, u32 val) { - if (s->offset + 4 > s->capacity) { s->overflow = true; return; } - pxl8_pack_u32_le(s->bytes, s->offset, val); - s->offset += 4; -} - -static inline void pxl8_write_u32_be(pxl8_write_stream* s, u32 val) { - if (s->offset + 4 > s->capacity) { s->overflow = true; return; } - pxl8_pack_u32_be(s->bytes, s->offset, val); - s->offset += 4; -} - -static inline void pxl8_write_u64(pxl8_write_stream* s, u64 val) { - if (s->offset + 8 > s->capacity) { s->overflow = true; return; } - pxl8_pack_u64_le(s->bytes, s->offset, val); - s->offset += 8; -} - -static inline void pxl8_write_u64_be(pxl8_write_stream* s, u64 val) { - if (s->offset + 8 > s->capacity) { s->overflow = true; return; } - pxl8_pack_u64_be(s->bytes, s->offset, val); - s->offset += 8; -} - -static inline void pxl8_write_f32(pxl8_write_stream* s, f32 val) { - if (s->offset + 4 > s->capacity) { s->overflow = true; return; } - pxl8_pack_f32_le(s->bytes, s->offset, val); - s->offset += 4; -} - -static inline void pxl8_write_f32_be(pxl8_write_stream* s, f32 val) { - if (s->offset + 4 > s->capacity) { s->overflow = true; return; } - pxl8_pack_f32_be(s->bytes, s->offset, val); - s->offset += 4; -} - -static inline void pxl8_write_bytes(pxl8_write_stream* s, const void* src, u32 count) { - if (s->offset + count > s->capacity) { s->overflow = true; return; } - memcpy(&s->bytes[s->offset], src, count); - s->offset += count; -} diff --git a/src/core/pxl8_io.h b/src/core/pxl8_io.h deleted file mode 100644 index 13daab5..0000000 --- a/src/core/pxl8_io.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include - -#include "pxl8_bytes.h" -#include "pxl8_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -pxl8_result pxl8_io_create_directory(const char* path); -bool pxl8_io_file_exists(const char* path); -void pxl8_io_free_binary_data(u8* data); -void pxl8_io_free_file_content(char* content); -f64 pxl8_io_get_file_modified_time(const char* path); -pxl8_result pxl8_io_read_binary_file(const char* path, u8** data, size_t* size); -pxl8_result pxl8_io_read_file(const char* path, char** content, size_t* size); -pxl8_result pxl8_io_write_binary_file(const char* path, const u8* data, size_t size); -pxl8_result pxl8_io_write_file(const char* path, const char* content, size_t size); - -bool pxl8_key_down(const pxl8_input_state* input, const char* key_name); -bool pxl8_key_pressed(const pxl8_input_state* input, const char* key_name); -bool pxl8_key_released(const pxl8_input_state* input, const char* key_name); - -i32 pxl8_mouse_dx(const pxl8_input_state* input); -i32 pxl8_mouse_dy(const pxl8_input_state* input); -bool pxl8_mouse_pressed(const pxl8_input_state* input, i32 button); -bool pxl8_mouse_released(const pxl8_input_state* input, i32 button); -i32 pxl8_mouse_wheel_x(const pxl8_input_state* input); -i32 pxl8_mouse_wheel_y(const pxl8_input_state* input); -i32 pxl8_mouse_x(const pxl8_input_state* input); -i32 pxl8_mouse_y(const pxl8_input_state* input); - -#ifdef __cplusplus -} -#endif diff --git a/src/gfx/pxl8_colormap.c b/src/gfx/pxl8_colormap.c deleted file mode 100644 index 925fd87..0000000 --- a/src/gfx/pxl8_colormap.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "pxl8_colormap.h" -#include - -static u8 find_closest_color(const u32* palette, u8 target_r, u8 target_g, u8 target_b) { - u8 best_idx = 1; - u32 best_dist = 0xFFFFFFFF; - - u8 dynamic_end = PXL8_DYNAMIC_RANGE_START + PXL8_DYNAMIC_RANGE_COUNT; - - for (u32 i = 1; i < PXL8_FULLBRIGHT_START; i++) { - if (i >= PXL8_DYNAMIC_RANGE_START && i < dynamic_end) { - continue; - } - - u32 c = palette[i]; - u8 pr = c & 0xFF; - u8 pg = (c >> 8) & 0xFF; - u8 pb = (c >> 16) & 0xFF; - - i32 dr = (i32)target_r - (i32)pr; - i32 dg = (i32)target_g - (i32)pg; - i32 db = (i32)target_b - (i32)pb; - u32 dist = (u32)(dr * dr + dg * dg + db * db); - - if (dist < best_dist) { - best_dist = dist; - best_idx = (u8)i; - if (dist == 0) break; - } - } - - return best_idx; -} - -void pxl8_set_colormap(pxl8_colormap* cm, const u8* data, u32 size) { - if (!cm || !data || size == 0) return; - u32 copy_size = size > PXL8_COLORMAP_SIZE ? PXL8_COLORMAP_SIZE : size; - memcpy(cm->table, data, copy_size); -} - -static void generate_light_table(pxl8_colormap* cm, const u32* palette, pxl8_light_color light_color) { - pxl8_rgb light = pxl8_light_colors[light_color]; - u32 base_row = (u32)light_color * PXL8_LIGHT_LEVELS; - - for (u32 level = 0; level < PXL8_LIGHT_LEVELS; level++) { - f32 brightness = (f32)level / (f32)(PXL8_LIGHT_LEVELS - 1); - u32 row = base_row + level; - - for (u32 pal_idx = 0; pal_idx < 256; pal_idx++) { - u8 result_idx; - - if (pal_idx == PXL8_TRANSPARENT) { - result_idx = PXL8_TRANSPARENT; - } else if (pal_idx >= PXL8_FULLBRIGHT_START) { - result_idx = (u8)pal_idx; - } else { - u32 c = palette[pal_idx]; - u8 r = c & 0xFF; - u8 g = (c >> 8) & 0xFF; - u8 b = (c >> 16) & 0xFF; - - f32 lr = (f32)light.r / 255.0f; - f32 lg = (f32)light.g / 255.0f; - f32 lb = (f32)light.b / 255.0f; - - u8 target_r = (u8)(r * brightness * lr); - u8 target_g = (u8)(g * brightness * lg); - u8 target_b = (u8)(b * brightness * lb); - - result_idx = find_closest_color(palette, target_r, target_g, target_b); - } - - cm->table[row * 256 + pal_idx] = result_idx; - } - } -} - -static void generate_blend_table(pxl8_colormap* cm, const u32* palette) { - for (u32 src = 0; src < 256; src++) { - u32 row = PXL8_LIGHT_ROWS + src; - - u8 sr, sg, sb; - if (src == PXL8_TRANSPARENT) { - sr = sg = sb = 0; - } else { - u32 sc = palette[src]; - sr = sc & 0xFF; - sg = (sc >> 8) & 0xFF; - sb = (sc >> 16) & 0xFF; - } - - for (u32 dst = 0; dst < 256; dst++) { - u8 result_idx; - - if (src == PXL8_TRANSPARENT) { - result_idx = (u8)dst; - } else { - u32 dc = palette[dst]; - u8 dr = dc & 0xFF; - u8 dg = (dc >> 8) & 0xFF; - u8 db = (dc >> 16) & 0xFF; - - u8 blend_r = (u8)((sr + dr) / 2); - u8 blend_g = (u8)((sg + dg) / 2); - u8 blend_b = (u8)((sb + db) / 2); - - result_idx = find_closest_color(palette, blend_r, blend_g, blend_b); - } - - cm->table[row * 256 + dst] = result_idx; - } - } -} - -void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette) { - if (!cm || !palette) return; - - for (u32 light = 0; light < PXL8_LIGHT_COLORS; light++) { - generate_light_table(cm, palette, (pxl8_light_color)light); - } - - generate_blend_table(cm, palette); -} diff --git a/src/gfx/pxl8_colormap.h b/src/gfx/pxl8_colormap.h deleted file mode 100644 index 04f8fd0..0000000 --- a/src/gfx/pxl8_colormap.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "pxl8_dither.h" -#include "pxl8_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PXL8_LIGHT_COLORS 8 -#define PXL8_LIGHT_LEVELS 8 -#define PXL8_LIGHT_ROWS (PXL8_LIGHT_COLORS * PXL8_LIGHT_LEVELS) -#define PXL8_BLEND_ROWS 256 -#define PXL8_COLORMAP_ROWS (PXL8_LIGHT_ROWS + PXL8_BLEND_ROWS) -#define PXL8_COLORMAP_SIZE (256 * PXL8_COLORMAP_ROWS) - -#define PXL8_FULLBRIGHT_START 240 -#define PXL8_TRANSPARENT 0 -#define PXL8_DYNAMIC_RANGE_START 144 -#define PXL8_DYNAMIC_RANGE_COUNT 16 - -typedef enum { - PXL8_LIGHT_WHITE = 0, - PXL8_LIGHT_RED = 1, - PXL8_LIGHT_ORANGE = 2, - PXL8_LIGHT_YELLOW = 3, - PXL8_LIGHT_GREEN = 4, - PXL8_LIGHT_CYAN = 5, - PXL8_LIGHT_BLUE = 6, - PXL8_LIGHT_PURPLE = 7, -} pxl8_light_color; - -typedef struct { - u8 r, g, b; -} pxl8_rgb; - -static const pxl8_rgb pxl8_light_colors[PXL8_LIGHT_COLORS] = { - {255, 255, 255}, - {255, 64, 64}, - {255, 160, 64}, - {255, 255, 64}, - {64, 255, 64}, - {64, 255, 255}, - {64, 64, 255}, - {255, 64, 255}, -}; - -typedef struct { - u8 table[PXL8_COLORMAP_SIZE]; -} pxl8_colormap; - -void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette); -void pxl8_set_colormap(pxl8_colormap* cm, const u8* data, u32 size); - -static inline u8 pxl8_colormap_lookup(const pxl8_colormap* cm, u8 pal_idx, pxl8_light_color light_color, u8 intensity) { - u32 light_row = ((u32)light_color << 3) + (intensity >> 5); - return cm->table[(light_row << 8) + pal_idx]; -} - -static inline u8 pxl8_colormap_lookup_dithered(const pxl8_colormap* cm, u8 pal_idx, pxl8_light_color light_color, u8 intensity, u32 x, u32 y) { - u8 dithered = pxl8_dither_light(intensity, x, y); - u32 light_row = ((u32)light_color << 3) + (dithered >> 5); - return cm->table[(light_row << 8) + pal_idx]; -} - -static inline u8 pxl8_colormap_blend(const pxl8_colormap* cm, u8 src, u8 dst) { - u32 blend_row = PXL8_LIGHT_ROWS + src; - return cm->table[(blend_row << 8) + dst]; -} - -#ifdef __cplusplus -} -#endif diff --git a/src/gfx/pxl8_gfx.h b/src/gfx/pxl8_gfx.h deleted file mode 100644 index e543068..0000000 --- a/src/gfx/pxl8_gfx.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once - -#include "pxl8_gfx2d.h" -#include "pxl8_gfx3d.h" -#include "pxl8_hal.h" -#include "pxl8_colormap.h" -#include "pxl8_palette.h" -#include "pxl8_types.h" -#include "pxl8_gui_palette.h" - -typedef struct pxl8_gfx pxl8_gfx; - -typedef enum pxl8_gfx_effect { - PXL8_GFX_EFFECT_GLOWS = 0, -} pxl8_gfx_effect; - -#define PXL8_MAX_GLOWS 256 - -typedef enum pxl8_glow_shape { - PXL8_GLOW_CIRCLE = 0, - PXL8_GLOW_DIAMOND = 1, - PXL8_GLOW_SHAFT = 2, -} pxl8_glow_shape; - -typedef struct pxl8_glow_source { - u8 color; - u16 depth; - u8 height; - u16 intensity; - u8 radius; - pxl8_glow_shape shape; - i16 x; - i16 y; -} pxl8_glow_source; - -static inline pxl8_glow_source pxl8_glow_create(i32 x, i32 y, u8 radius, u16 intensity, u8 color) { - return (pxl8_glow_source){ - .color = color, - .depth = 0xFFFF, - .height = 0, - .intensity = intensity, - .radius = radius, - .shape = PXL8_GLOW_CIRCLE, - .x = (i16)x, - .y = (i16)y, - }; -} - -static inline pxl8_glow_source pxl8_glow_with_depth(pxl8_glow_source g, u16 depth) { - g.depth = depth; - return g; -} - -static inline pxl8_glow_source pxl8_glow_with_shape(pxl8_glow_source g, pxl8_glow_shape shape) { - g.shape = shape; - return g; -} - -static inline pxl8_glow_source pxl8_glow_with_height(pxl8_glow_source g, u8 height) { - g.height = height; - return g; -} - -#ifdef __cplusplus -extern "C" { -#endif - -pxl8_gfx* pxl8_gfx_create(const pxl8_hal* hal, void* platform_data, pxl8_pixel_mode mode, pxl8_resolution resolution); -void pxl8_gfx_destroy(pxl8_gfx* gfx); - -void pxl8_gfx_present(pxl8_gfx* gfx); -void pxl8_gfx_update(pxl8_gfx* gfx, f32 dt); -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); -i32 pxl8_gfx_get_height(const 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); -void pxl8_gfx_project(pxl8_gfx* gfx, f32 left, f32 right, f32 top, f32 bottom); -void pxl8_gfx_set_palette_colors(pxl8_gfx* gfx, const u32* colors, u16 count); -void pxl8_gfx_set_viewport(pxl8_gfx* gfx, pxl8_viewport vp); -pxl8_viewport pxl8_gfx_viewport(pxl8_bounds bounds, i32 width, i32 height); - -void pxl8_gfx_clear_textures(pxl8_gfx* gfx); -pxl8_result pxl8_gfx_create_texture(pxl8_gfx* gfx, const u8* pixels, u32 width, u32 height); -pxl8_result pxl8_gfx_load_font_atlas(pxl8_gfx* gfx); -pxl8_result pxl8_gfx_load_sprite(pxl8_gfx* gfx, const char* path); - -bool pxl8_gfx_push_target(pxl8_gfx* gfx); -void pxl8_gfx_pop_target(pxl8_gfx* gfx); - -void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count); -void pxl8_gfx_blend_tables_update(pxl8_gfx* gfx); -void pxl8_gfx_colormap_update(pxl8_gfx* gfx); -void pxl8_gfx_ensure_blend_tables(pxl8_gfx* gfx); - -u8 pxl8_gfx_find_closest_color(pxl8_gfx* gfx, u8 r, u8 g, u8 b); -u8 pxl8_gfx_ui_color(pxl8_gfx* gfx, u8 index); - -#ifdef __cplusplus -} -#endif diff --git a/src/gfx/pxl8_gfx3d.h b/src/gfx/pxl8_gfx3d.h deleted file mode 100644 index ba045d5..0000000 --- a/src/gfx/pxl8_gfx3d.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "pxl8_3d_camera.h" -#include "pxl8_math.h" -#include "pxl8_mesh.h" -#include "pxl8_types.h" - -typedef struct pxl8_gfx pxl8_gfx; - -#define PXL8_MAX_LIGHTS 16 - -typedef struct pxl8_light { - pxl8_vec3 position; - u8 r, g, b; - u8 intensity; - f32 radius; - f32 radius_sq; - f32 inv_radius_sq; -} pxl8_light; - -static inline pxl8_light pxl8_light_create(pxl8_vec3 pos, u8 r, u8 g, u8 b, u8 intensity, f32 radius) { - f32 radius_sq = radius * radius; - return (pxl8_light){ - .position = pos, - .r = r, .g = g, .b = b, - .intensity = intensity, - .radius = radius, - .radius_sq = radius_sq, - .inv_radius_sq = radius_sq > 0.0f ? 1.0f / radius_sq : 0.0f, - }; -} - -typedef struct pxl8_3d_uniforms { - u8 ambient; - pxl8_vec3 celestial_dir; - f32 celestial_intensity; - u8 fog_color; - f32 fog_density; - pxl8_light lights[PXL8_MAX_LIGHTS]; - u32 num_lights; - f32 time; -} pxl8_3d_uniforms; - -typedef struct pxl8_3d_frame { - pxl8_3d_uniforms uniforms; - pxl8_vec3 camera_dir; - pxl8_vec3 camera_pos; - f32 far_clip; - f32 near_clip; - pxl8_mat4 projection; - pxl8_mat4 view; -} pxl8_3d_frame; - -#ifdef __cplusplus -extern "C" { -#endif - -void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms); -void pxl8_3d_clear(pxl8_gfx* gfx, u8 color); -void pxl8_3d_clear_depth(pxl8_gfx* gfx); -void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color); -void pxl8_3d_draw_mesh(pxl8_gfx* gfx, const pxl8_mesh* mesh, const pxl8_mat4* model, const pxl8_gfx_material* material); -void pxl8_3d_draw_mesh_wireframe(pxl8_gfx* gfx, const pxl8_mesh* mesh, pxl8_mat4 model, u8 color); -void pxl8_3d_end_frame(pxl8_gfx* gfx); -u8* pxl8_3d_get_framebuffer(pxl8_gfx* gfx); -const pxl8_frustum* pxl8_3d_get_frustum(pxl8_gfx* gfx); - -pxl8_3d_frame pxl8_3d_frame_from_camera(const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms); - -#ifdef __cplusplus -} -#endif diff --git a/src/gfx/pxl8_lightmap.c b/src/gfx/pxl8_lightmap.c deleted file mode 100644 index 0c29521..0000000 --- a/src/gfx/pxl8_lightmap.c +++ /dev/null @@ -1,113 +0,0 @@ -#include "pxl8_lightmap.h" - -#include -#include - -pxl8_lightmap* pxl8_lightmap_create(u32 width, u32 height, u32 scale) { - pxl8_lightmap* lm = calloc(1, sizeof(pxl8_lightmap)); - if (!lm) return NULL; - - lm->width = width; - lm->height = height; - lm->scale = scale; - lm->data = calloc(width * height * 3, sizeof(u8)); - if (!lm->data) { - free(lm); - return NULL; - } - - pxl8_lightmap_clear(lm, PXL8_LIGHTMAP_NEUTRAL, PXL8_LIGHTMAP_NEUTRAL, PXL8_LIGHTMAP_NEUTRAL); - return lm; -} - -void pxl8_lightmap_destroy(pxl8_lightmap* lm) { - if (!lm) return; - free(lm->data); - free(lm); -} - -void pxl8_lightmap_clear(pxl8_lightmap* lm, u8 r, u8 g, u8 b) { - if (!lm || !lm->data) return; - u32 count = lm->width * lm->height; - for (u32 i = 0; i < count; i++) { - lm->data[i * 3 + 0] = r; - lm->data[i * 3 + 1] = g; - lm->data[i * 3 + 2] = b; - } -} - -void pxl8_lightmap_set(pxl8_lightmap* lm, u32 x, u32 y, u8 r, u8 g, u8 b) { - if (!lm || !lm->data || x >= lm->width || y >= lm->height) return; - u32 idx = (y * lm->width + x) * 3; - lm->data[idx + 0] = r; - lm->data[idx + 1] = g; - lm->data[idx + 2] = b; -} - -void pxl8_lightmap_get(const pxl8_lightmap* lm, u32 x, u32 y, u8* r, u8* g, u8* b) { - if (!lm || !lm->data || x >= lm->width || y >= lm->height) { - *r = *g = *b = PXL8_LIGHTMAP_NEUTRAL; - return; - } - u32 idx = (y * lm->width + x) * 3; - *r = lm->data[idx + 0]; - *g = lm->data[idx + 1]; - *b = lm->data[idx + 2]; -} - -void pxl8_lightmap_add_point( - pxl8_lightmap* lm, - f32 lx, f32 ly, - u8 r, u8 g, u8 b, - f32 radius, - f32 intensity -) { - if (!lm || !lm->data || radius <= 0.0f) return; - - f32 radius_sq = radius * radius; - f32 inv_radius_sq = 1.0f / radius_sq; - - i32 cx = (i32)(lx * (f32)lm->width); - i32 cy = (i32)(ly * (f32)lm->height); - i32 rad_pixels = (i32)(radius * (f32)lm->width) + 1; - - i32 x0 = cx - rad_pixels; - i32 y0 = cy - rad_pixels; - i32 x1 = cx + rad_pixels; - i32 y1 = cy + rad_pixels; - - if (x0 < 0) x0 = 0; - if (y0 < 0) y0 = 0; - if (x1 >= (i32)lm->width) x1 = (i32)lm->width - 1; - if (y1 >= (i32)lm->height) y1 = (i32)lm->height - 1; - - f32 scale_x = 1.0f / (f32)lm->width; - f32 scale_y = 1.0f / (f32)lm->height; - - for (i32 y = y0; y <= y1; y++) { - f32 dy = ((f32)y * scale_y) - ly; - for (i32 x = x0; x <= x1; x++) { - f32 dx = ((f32)x * scale_x) - lx; - f32 dist_sq = dx * dx + dy * dy; - - if (dist_sq >= radius_sq) continue; - - f32 falloff = 1.0f - dist_sq * inv_radius_sq; - f32 contrib = falloff * falloff * intensity; - - u32 idx = ((u32)y * lm->width + (u32)x) * 3; - - i32 nr = (i32)lm->data[idx + 0] + (i32)((f32)(r - 128) * contrib); - i32 ng = (i32)lm->data[idx + 1] + (i32)((f32)(g - 128) * contrib); - i32 nb = (i32)lm->data[idx + 2] + (i32)((f32)(b - 128) * contrib); - - if (nr < 0) nr = 0; if (nr > 255) nr = 255; - if (ng < 0) ng = 0; if (ng > 255) ng = 255; - if (nb < 0) nb = 0; if (nb > 255) nb = 255; - - lm->data[idx + 0] = (u8)nr; - lm->data[idx + 1] = (u8)ng; - lm->data[idx + 2] = (u8)nb; - } - } -} diff --git a/src/gfx/pxl8_lightmap.h b/src/gfx/pxl8_lightmap.h deleted file mode 100644 index 549eb2a..0000000 --- a/src/gfx/pxl8_lightmap.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "pxl8_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PXL8_LIGHTMAP_MAX 16 -#define PXL8_LIGHTMAP_NEUTRAL 128 - -typedef struct pxl8_lightmap { - u8* data; - u32 width; - u32 height; - u32 scale; -} pxl8_lightmap; - -pxl8_lightmap* pxl8_lightmap_create(u32 width, u32 height, u32 scale); -void pxl8_lightmap_destroy(pxl8_lightmap* lm); -void pxl8_lightmap_clear(pxl8_lightmap* lm, u8 r, u8 g, u8 b); -void pxl8_lightmap_set(pxl8_lightmap* lm, u32 x, u32 y, u8 r, u8 g, u8 b); -void pxl8_lightmap_get(const pxl8_lightmap* lm, u32 x, u32 y, u8* r, u8* g, u8* b); - -void pxl8_lightmap_add_point( - pxl8_lightmap* lm, - f32 lx, f32 ly, - u8 r, u8 g, u8 b, - f32 radius, - f32 intensity -); - -static inline void pxl8_lightmap_sample( - const pxl8_lightmap* lm, - f32 u, f32 v, - u8* r, u8* g, u8* b -) { - i32 x = (i32)(u * (f32)lm->width) & (i32)(lm->width - 1); - i32 y = (i32)(v * (f32)lm->height) & (i32)(lm->height - 1); - u32 idx = ((u32)y * lm->width + (u32)x) * 3; - *r = lm->data[idx + 0]; - *g = lm->data[idx + 1]; - *b = lm->data[idx + 2]; -} - -#ifdef __cplusplus -} -#endif diff --git a/src/gui/pxl8_gui_palette.h b/src/gui/pxl8_gui_palette.h deleted file mode 100644 index 2d87599..0000000 --- a/src/gui/pxl8_gui_palette.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "pxl8_types.h" - -#define PXL8_UI_PALETTE_SIZE 16 - -#define PXL8_UI_BG0 0 -#define PXL8_UI_BG1 1 -#define PXL8_UI_BG2 2 -#define PXL8_UI_BG3 3 -#define PXL8_UI_FG0 4 -#define PXL8_UI_FG1 5 -#define PXL8_UI_FG2 6 -#define PXL8_UI_FG3 7 -#define PXL8_UI_RED 8 -#define PXL8_UI_GREEN 9 -#define PXL8_UI_YELLOW 10 -#define PXL8_UI_BLUE 11 -#define PXL8_UI_PURPLE 12 -#define PXL8_UI_AQUA 13 -#define PXL8_UI_ORANGE 14 -#define PXL8_UI_GRAY 15 - -static const u32 pxl8_ui_palette[PXL8_UI_PALETTE_SIZE] = { - 0xFF282828, - 0xFF3c3836, - 0xFF504945, - 0xFF665c54, - 0xFFc7f1fb, - 0xFFb2dbeb, - 0xFFa1c4d5, - 0xFF93aebd, - 0xFF3449fb, - 0xFF26bbb8, - 0xFF2fbdfa, - 0xFF98a583, - 0xFF9b86d3, - 0xFF7cc08e, - 0xFF1980fe, - 0xFF928374, -}; diff --git a/src/lua/pxl8/bytes.lua b/src/lua/pxl8/bytes.lua deleted file mode 100644 index b0ccb15..0000000 --- a/src/lua/pxl8/bytes.lua +++ /dev/null @@ -1,44 +0,0 @@ -local ffi = require("ffi") -local C = ffi.C - -local bytes = {} - -bytes.pack_f32_be = C.pxl8_pack_f32_be -bytes.pack_f32_le = C.pxl8_pack_f32_le -bytes.pack_f64_be = C.pxl8_pack_f64_be -bytes.pack_f64_le = C.pxl8_pack_f64_le -bytes.pack_i8 = C.pxl8_pack_i8 -bytes.pack_i16_be = C.pxl8_pack_i16_be -bytes.pack_i16_le = C.pxl8_pack_i16_le -bytes.pack_i32_be = C.pxl8_pack_i32_be -bytes.pack_i32_le = C.pxl8_pack_i32_le -bytes.pack_i64_be = C.pxl8_pack_i64_be -bytes.pack_i64_le = C.pxl8_pack_i64_le -bytes.pack_u8 = C.pxl8_pack_u8 -bytes.pack_u16_be = C.pxl8_pack_u16_be -bytes.pack_u16_le = C.pxl8_pack_u16_le -bytes.pack_u32_be = C.pxl8_pack_u32_be -bytes.pack_u32_le = C.pxl8_pack_u32_le -bytes.pack_u64_be = C.pxl8_pack_u64_be -bytes.pack_u64_le = C.pxl8_pack_u64_le - -bytes.unpack_f32_be = C.pxl8_unpack_f32_be -bytes.unpack_f32_le = C.pxl8_unpack_f32_le -bytes.unpack_f64_be = C.pxl8_unpack_f64_be -bytes.unpack_f64_le = C.pxl8_unpack_f64_le -bytes.unpack_i8 = C.pxl8_unpack_i8 -bytes.unpack_i16_be = C.pxl8_unpack_i16_be -bytes.unpack_i16_le = C.pxl8_unpack_i16_le -bytes.unpack_i32_be = C.pxl8_unpack_i32_be -bytes.unpack_i32_le = C.pxl8_unpack_i32_le -bytes.unpack_i64_be = C.pxl8_unpack_i64_be -bytes.unpack_i64_le = C.pxl8_unpack_i64_le -bytes.unpack_u8 = C.pxl8_unpack_u8 -bytes.unpack_u16_be = C.pxl8_unpack_u16_be -bytes.unpack_u16_le = C.pxl8_unpack_u16_le -bytes.unpack_u32_be = C.pxl8_unpack_u32_be -bytes.unpack_u32_le = C.pxl8_unpack_u32_le -bytes.unpack_u64_be = C.pxl8_unpack_u64_be -bytes.unpack_u64_le = C.pxl8_unpack_u64_le - -return bytes diff --git a/src/lua/pxl8/effects.lua b/src/lua/pxl8/effects.lua deleted file mode 100644 index 4db069a..0000000 --- a/src/lua/pxl8/effects.lua +++ /dev/null @@ -1,32 +0,0 @@ -local ffi = require("ffi") -local C = ffi.C -local core = require("pxl8.core") - -local effects = {} - -effects.GLOW_CIRCLE = 0 -effects.GLOW_DIAMOND = 1 -effects.GLOW_SHAFT = 2 - -function effects.glows(glows) - if not glows or #glows == 0 then return end - - local count = #glows - local glow_array = ffi.new("pxl8_glow_source[?]", count) - - for i, g in ipairs(glows) do - local idx = i - 1 - glow_array[idx].x = g.x or 0 - glow_array[idx].y = g.y or 0 - glow_array[idx].radius = g.radius or 8 - glow_array[idx].intensity = g.intensity or 255 - glow_array[idx].color = g.color or 15 - glow_array[idx].depth = g.depth or 0xFFFF - glow_array[idx].height = g.height or 0 - glow_array[idx].shape = g.shape or 0 - end - - C.pxl8_gfx_apply_effect(core.gfx, C.PXL8_GFX_EFFECT_GLOWS, glow_array, count) -end - -return effects diff --git a/src/lua/pxl8/net.lua b/src/lua/pxl8/net.lua deleted file mode 100644 index 318889f..0000000 --- a/src/lua/pxl8/net.lua +++ /dev/null @@ -1,182 +0,0 @@ -local ffi = require("ffi") -local C = ffi.C - -local net = {} - -local Net = {} -Net.__index = Net - -net.MODE_LOCAL = C.PXL8_NET_LOCAL -net.MODE_REMOTE = C.PXL8_NET_REMOTE - -function Net.new(config) - config = config or {} - local cfg = ffi.new("pxl8_net_config") - cfg.address = config.address or "127.0.0.1" - cfg.mode = config.mode or C.PXL8_NET_REMOTE - cfg.port = config.port or 7777 - - local n = C.pxl8_net_create(cfg) - if n == nil then - return nil - end - return setmetatable({ _ptr = n }, Net) -end - -function Net:connect() - return C.pxl8_net_connect(self._ptr) == 0 -end - -function Net:connected() - return C.pxl8_net_connected(self._ptr) -end - -function Net:destroy() - if self._ptr then - C.pxl8_net_destroy(self._ptr) - self._ptr = nil - end -end - -function Net:disconnect() - C.pxl8_net_disconnect(self._ptr) -end - -function Net:entities() - local snap = C.pxl8_net_snapshot(self._ptr) - if snap == nil then - return {} - end - local ents = C.pxl8_net_entities(self._ptr) - if ents == nil then - return {} - end - local result = {} - for i = 0, snap.entity_count - 1 do - result[i + 1] = { - entity_id = tonumber(ents[i].entity_id), - userdata = ents[i].userdata - } - end - return result -end - -function Net:entity_prev_userdata(entity_id) - return C.pxl8_net_entity_prev_userdata(self._ptr, entity_id) -end - -function Net:entity_userdata(entity_id) - return C.pxl8_net_entity_userdata(self._ptr, entity_id) -end - -function Net:input_at(tick) - local input = C.pxl8_net_input_at(self._ptr, tick) - if input == nil then return nil end - return { - buttons = input.buttons, - look_dx = input.look_dx, - look_dy = input.look_dy, - move_x = input.move_x, - move_y = input.move_y, - yaw = input.yaw, - tick = tonumber(input.tick), - timestamp = tonumber(input.timestamp) - } -end - -function Net:input_oldest_tick() - return tonumber(C.pxl8_net_input_oldest_tick(self._ptr)) -end - -function Net:input_push(input) - local msg = ffi.new("pxl8_input_msg") - msg.buttons = input.buttons or 0 - msg.look_dx = input.look_dx or 0 - msg.look_dy = input.look_dy or 0 - msg.move_x = input.move_x or 0 - msg.move_y = input.move_y or 0 - msg.yaw = input.yaw or 0 - msg.tick = input.tick or 0 - msg.timestamp = input.timestamp or 0 - C.pxl8_net_input_push(self._ptr, msg) -end - -function Net:lerp_alpha() - return C.pxl8_net_lerp_alpha(self._ptr) -end - -function Net:needs_correction() - return C.pxl8_net_needs_correction(self._ptr) -end - -function Net:player_id() - return tonumber(C.pxl8_net_player_id(self._ptr)) -end - -function Net:poll() - return C.pxl8_net_poll(self._ptr) -end - -function Net:predicted_state() - return C.pxl8_net_predicted_state(self._ptr) -end - -function Net:predicted_tick_set(tick) - C.pxl8_net_predicted_tick_set(self._ptr, tick) -end - -function Net:send_command(cmd) - return C.pxl8_net_send_command(self._ptr, cmd) == 0 -end - -function Net:send_input(input) - local msg = ffi.new("pxl8_input_msg") - msg.buttons = input.buttons or 0 - msg.look_dx = input.look_dx or 0 - msg.look_dy = input.look_dy or 0 - msg.move_x = input.move_x or 0 - msg.move_y = input.move_y or 0 - msg.yaw = input.yaw or 0 - msg.tick = input.tick or 0 - msg.timestamp = input.timestamp or 0 - return C.pxl8_net_send_input(self._ptr, msg) == 0 -end - -function Net:snapshot() - local snap = C.pxl8_net_snapshot(self._ptr) - if snap == nil then - return nil - end - return { - entity_count = snap.entity_count, - event_count = snap.event_count, - player_id = tonumber(snap.player_id), - tick = tonumber(snap.tick), - time = snap.time - } -end - -function Net:spawn(x, y, z, yaw, pitch) - local cmd = ffi.new("pxl8_command_msg") - cmd.cmd_type = C.PXL8_CMD_SPAWN_ENTITY - C.pxl8_pack_f32_be(cmd.payload, 0, x or 0) - C.pxl8_pack_f32_be(cmd.payload, 4, y or 0) - C.pxl8_pack_f32_be(cmd.payload, 8, z or 0) - C.pxl8_pack_f32_be(cmd.payload, 12, yaw or 0) - C.pxl8_pack_f32_be(cmd.payload, 16, pitch or 0) - cmd.payload_size = 20 - cmd.tick = 0 - return self:send_command(cmd) -end - -function Net:tick() - return tonumber(C.pxl8_net_tick(self._ptr)) -end - -function Net:update(dt) - C.pxl8_net_update(self._ptr, dt) -end - -net.Net = Net - -return net diff --git a/src/lua/pxl8/procgen.lua b/src/lua/pxl8/procgen.lua deleted file mode 100644 index d5b1c27..0000000 --- a/src/lua/pxl8/procgen.lua +++ /dev/null @@ -1,99 +0,0 @@ -local ffi = require("ffi") -local C = ffi.C -local core = require("pxl8.core") - -local procgen = {} - -procgen.OP_CONST = C.PXL8_OP_CONST -procgen.OP_INPUT_AGE = C.PXL8_OP_INPUT_AGE -procgen.OP_INPUT_SEED = C.PXL8_OP_INPUT_SEED -procgen.OP_INPUT_TIME = C.PXL8_OP_INPUT_TIME -procgen.OP_INPUT_X = C.PXL8_OP_INPUT_X -procgen.OP_INPUT_Y = C.PXL8_OP_INPUT_Y - -procgen.OP_ABS = C.PXL8_OP_ABS -procgen.OP_ADD = C.PXL8_OP_ADD -procgen.OP_CEIL = C.PXL8_OP_CEIL -procgen.OP_CLAMP = C.PXL8_OP_CLAMP -procgen.OP_COS = C.PXL8_OP_COS -procgen.OP_DIV = C.PXL8_OP_DIV -procgen.OP_FLOOR = C.PXL8_OP_FLOOR -procgen.OP_FRACT = C.PXL8_OP_FRACT -procgen.OP_GRADIENT_LINEAR = C.PXL8_OP_GRADIENT_LINEAR -procgen.OP_GRADIENT_RADIAL = C.PXL8_OP_GRADIENT_RADIAL -procgen.OP_LERP = C.PXL8_OP_LERP -procgen.OP_MAX = C.PXL8_OP_MAX -procgen.OP_MIN = C.PXL8_OP_MIN -procgen.OP_MOD = C.PXL8_OP_MOD -procgen.OP_MUL = C.PXL8_OP_MUL -procgen.OP_NEGATE = C.PXL8_OP_NEGATE -procgen.OP_NOISE_FBM = C.PXL8_OP_NOISE_FBM -procgen.OP_NOISE_PERLIN = C.PXL8_OP_NOISE_PERLIN -procgen.OP_NOISE_RIDGED = C.PXL8_OP_NOISE_RIDGED -procgen.OP_NOISE_TURBULENCE = C.PXL8_OP_NOISE_TURBULENCE -procgen.OP_NOISE_VALUE = C.PXL8_OP_NOISE_VALUE -procgen.OP_POW = C.PXL8_OP_POW -procgen.OP_QUANTIZE = C.PXL8_OP_QUANTIZE -procgen.OP_SELECT = C.PXL8_OP_SELECT -procgen.OP_SIN = C.PXL8_OP_SIN -procgen.OP_SMOOTHSTEP = C.PXL8_OP_SMOOTHSTEP -procgen.OP_SQRT = C.PXL8_OP_SQRT -procgen.OP_SUB = C.PXL8_OP_SUB -procgen.OP_VORONOI_CELL = C.PXL8_OP_VORONOI_CELL -procgen.OP_VORONOI_EDGE = C.PXL8_OP_VORONOI_EDGE -procgen.OP_VORONOI_ID = C.PXL8_OP_VORONOI_ID - -local Graph = {} -Graph.__index = Graph - -function Graph.new(capacity) - capacity = capacity or 64 - local ptr = C.pxl8_graph_create(capacity) - if ptr == nil then - return nil - end - return setmetatable({ _ptr = ptr }, Graph) -end - -function Graph:destroy() - if self._ptr then - C.pxl8_graph_destroy(self._ptr) - self._ptr = nil - end -end - -function Graph:clear() - C.pxl8_graph_clear(self._ptr) -end - -function Graph:add_node(op, in0, in1, in2, in3, param) - return C.pxl8_graph_add_node(self._ptr, op, in0 or 0, in1 or 0, in2 or 0, in3 or 0, param or 0) -end - -function Graph:set_output(reg) - C.pxl8_graph_set_output(self._ptr, reg) -end - -function Graph:set_seed(seed) - C.pxl8_graph_set_seed(self._ptr, seed) -end - -function Graph:eval_texture(width, height) - width = width or 64 - height = height or 64 - local buffer = ffi.new("u8[?]", width * height) - C.pxl8_graph_eval_texture(self._ptr, buffer, width, height) - local tex_id = C.pxl8_gfx_create_texture(core.gfx, buffer, width, height) - if tex_id < 0 then - return nil - end - return tex_id -end - -procgen.Graph = Graph - -function procgen.create_graph(capacity) - return Graph.new(capacity) -end - -return procgen diff --git a/src/net/pxl8_net.c b/src/net/pxl8_net.c deleted file mode 100644 index e5cba62..0000000 --- a/src/net/pxl8_net.c +++ /dev/null @@ -1,312 +0,0 @@ -#include "pxl8_net.h" - -#include -#include - -#ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #include - #include - typedef SOCKET socket_t; - #define INVALID_SOCK INVALID_SOCKET - #define close_socket closesocket -#else - #include - #include - #include - #include - #include - #include - typedef int socket_t; - #define INVALID_SOCK -1 - #define close_socket close -#endif - -#define PXL8_NET_DEFAULT_PORT 7777 -#define PXL8_NET_TICK_RATE 30.0f - -struct pxl8_net { - char address[256]; - bool connected; - pxl8_entity_state entities[PXL8_MAX_SNAPSHOT_ENTITIES]; - pxl8_event_msg events[PXL8_MAX_SNAPSHOT_EVENTS]; - u64 highest_tick; - pxl8_input_msg input_history[PXL8_NET_INPUT_HISTORY_SIZE]; - u64 input_head; - u64 input_oldest_tick; - f32 interp_time; - pxl8_net_mode mode; - u16 port; - u8 predicted_state[PXL8_NET_USERDATA_SIZE]; - u64 predicted_tick; - pxl8_entity_state prev_entities[PXL8_MAX_SNAPSHOT_ENTITIES]; - pxl8_snapshot_header prev_snapshot; - u8 recv_buf[4096]; - u8 send_buf[4096]; - u32 sequence; - struct sockaddr_in server_addr; - pxl8_snapshot_header snapshot; - socket_t sock; -}; - -static const pxl8_entity_state* find_entity(const pxl8_entity_state* entities, u16 count, u64 id) { - for (u16 i = 0; i < count; i++) { - if (entities[i].entity_id == id) return &entities[i]; - } - return NULL; -} - -pxl8_result pxl8_net_connect(pxl8_net* net) { - if (!net) return PXL8_ERROR_INVALID_ARGUMENT; - if (net->connected) return PXL8_OK; - -#ifdef _WIN32 - WSADATA wsa; - if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { - return PXL8_ERROR_SYSTEM_FAILURE; - } -#endif - - net->sock = socket(AF_INET, SOCK_DGRAM, 0); - if (net->sock == INVALID_SOCK) { - return PXL8_ERROR_SYSTEM_FAILURE; - } - -#ifdef _WIN32 - u_long nonblocking = 1; - ioctlsocket(net->sock, FIONBIO, &nonblocking); -#else - int flags = fcntl(net->sock, F_GETFL, 0); - fcntl(net->sock, F_SETFL, flags | O_NONBLOCK); -#endif - - memset(&net->server_addr, 0, sizeof(net->server_addr)); - net->server_addr.sin_family = AF_INET; - net->server_addr.sin_port = htons(net->port); - inet_pton(AF_INET, net->address, &net->server_addr.sin_addr); - - net->connected = true; - return PXL8_OK; -} - -bool pxl8_net_connected(const pxl8_net* net) { - return net && net->connected; -} - -pxl8_net* pxl8_net_create(const pxl8_net_config* config) { - pxl8_net* net = calloc(1, sizeof(pxl8_net)); - if (!net) return NULL; - - net->mode = config->mode; - net->port = config->port ? config->port : PXL8_NET_DEFAULT_PORT; - net->sock = INVALID_SOCK; - net->connected = false; - net->sequence = 0; - net->highest_tick = 0; - - if (config->address) { - strncpy(net->address, config->address, sizeof(net->address) - 1); - } else { - strncpy(net->address, "127.0.0.1", sizeof(net->address) - 1); - } - - return net; -} - -void pxl8_net_destroy(pxl8_net* net) { - if (!net) return; - pxl8_net_disconnect(net); - free(net); -} - -void pxl8_net_disconnect(pxl8_net* net) { - if (!net) return; - if (net->sock != INVALID_SOCK) { - close_socket(net->sock); - net->sock = INVALID_SOCK; - } -#ifdef _WIN32 - WSACleanup(); -#endif - net->connected = false; -} - -const pxl8_entity_state* pxl8_net_entities(const pxl8_net* net) { - if (!net) return NULL; - return net->entities; -} - -const u8* pxl8_net_entity_prev_userdata(const pxl8_net* net, u64 entity_id) { - if (!net) return NULL; - const pxl8_entity_state* e = find_entity(net->prev_entities, net->prev_snapshot.entity_count, entity_id); - return e ? e->userdata : NULL; -} - -const u8* pxl8_net_entity_userdata(const pxl8_net* net, u64 entity_id) { - if (!net) return NULL; - const pxl8_entity_state* e = find_entity(net->entities, net->snapshot.entity_count, entity_id); - return e ? e->userdata : NULL; -} - -const pxl8_event_msg* pxl8_net_events(const pxl8_net* net) { - if (!net) return NULL; - return net->events; -} - -const pxl8_input_msg* pxl8_net_input_at(const pxl8_net* net, u64 tick) { - if (!net) return NULL; - for (u64 i = 0; i < PXL8_NET_INPUT_HISTORY_SIZE; i++) { - if (net->input_history[i].tick == tick) { - return &net->input_history[i]; - } - } - return NULL; -} - -u64 pxl8_net_input_oldest_tick(const pxl8_net* net) { - if (!net) return 0; - return net->input_oldest_tick; -} - -void pxl8_net_input_push(pxl8_net* net, const pxl8_input_msg* input) { - if (!net || !input) return; - u64 idx = net->input_head % PXL8_NET_INPUT_HISTORY_SIZE; - net->input_history[idx] = *input; - net->input_head++; - if (net->input_oldest_tick == 0 || input->tick < net->input_oldest_tick) { - net->input_oldest_tick = input->tick; - } -} - -f32 pxl8_net_lerp_alpha(const pxl8_net* net) { - if (!net) return 1.0f; - f32 tick_duration = 1.0f / PXL8_NET_TICK_RATE; - f32 alpha = net->interp_time / tick_duration; - return alpha > 1.0f ? 1.0f : alpha; -} - -bool pxl8_net_needs_correction(const pxl8_net* net) { - if (!net) return false; - if (net->snapshot.tick == 0) return false; - if (net->predicted_tick == 0) return false; - if (net->snapshot.tick > net->predicted_tick) return true; - const u8* server = pxl8_net_entity_userdata(net, net->snapshot.player_id); - if (!server) return false; - return memcmp(server, net->predicted_state, PXL8_NET_USERDATA_SIZE) != 0; -} - -u64 pxl8_net_player_id(const pxl8_net* net) { - if (!net) return 0; - return net->snapshot.player_id; -} - -bool pxl8_net_poll(pxl8_net* net) { - if (!net || !net->connected) return false; - - size_t len = pxl8_net_recv(net, net->recv_buf, sizeof(net->recv_buf)); - if (len < sizeof(pxl8_msg_header)) return false; - - pxl8_msg_header hdr; - size_t offset = pxl8_protocol_deserialize_header(net->recv_buf, len, &hdr); - if (hdr.type != PXL8_MSG_SNAPSHOT) return false; - - pxl8_snapshot_header snap; - offset += pxl8_protocol_deserialize_snapshot_header(net->recv_buf + offset, len - offset, &snap); - - if (snap.tick <= net->highest_tick) return false; - - memcpy(net->prev_entities, net->entities, sizeof(net->entities)); - net->prev_snapshot = net->snapshot; - - net->highest_tick = snap.tick; - net->snapshot = snap; - net->interp_time = 0.0f; - - u16 count = snap.entity_count; - if (count > PXL8_MAX_SNAPSHOT_ENTITIES) count = PXL8_MAX_SNAPSHOT_ENTITIES; - - for (u16 i = 0; i < count; i++) { - offset += pxl8_protocol_deserialize_entity_state( - net->recv_buf + offset, len - offset, &net->entities[i]); - } - - return true; -} - -u8* pxl8_net_predicted_state(pxl8_net* net) { - if (!net) return NULL; - return net->predicted_state; -} - -void pxl8_net_predicted_tick_set(pxl8_net* net, u64 tick) { - if (!net) return; - net->predicted_tick = tick; -} - -size_t pxl8_net_recv(pxl8_net* net, u8* buf, size_t len) { - if (!net || !net->connected) return 0; - - struct sockaddr_in from; - socklen_t from_len = sizeof(from); - ssize_t received = recvfrom(net->sock, (char*)buf, len, 0, - (struct sockaddr*)&from, &from_len); - return (received > 0) ? (size_t)received : 0; -} - -pxl8_result pxl8_net_send(pxl8_net* net, const u8* data, size_t len) { - if (!net || !net->connected) return PXL8_ERROR_INVALID_ARGUMENT; - - ssize_t sent = sendto(net->sock, (const char*)data, len, 0, - (struct sockaddr*)&net->server_addr, - sizeof(net->server_addr)); - return (sent > 0) ? PXL8_OK : PXL8_ERROR_SYSTEM_FAILURE; -} - -pxl8_result pxl8_net_send_command(pxl8_net* net, const pxl8_command_msg* cmd) { - if (!net || !net->connected) return PXL8_ERROR_INVALID_ARGUMENT; - - u8 buf[sizeof(pxl8_msg_header) + sizeof(pxl8_command_msg)]; - pxl8_msg_header hdr = { - .type = PXL8_MSG_COMMAND, - .version = PXL8_PROTOCOL_VERSION, - .size = sizeof(pxl8_command_msg), - .sequence = 0 - }; - - size_t offset = pxl8_protocol_serialize_header(&hdr, buf, sizeof(buf)); - offset += pxl8_protocol_serialize_command(cmd, buf + offset, sizeof(buf) - offset); - - return pxl8_net_send(net, buf, offset); -} - -pxl8_result pxl8_net_send_input(pxl8_net* net, const pxl8_input_msg* input) { - if (!net || !net->connected) return PXL8_ERROR_INVALID_ARGUMENT; - - u8 buf[sizeof(pxl8_msg_header) + sizeof(pxl8_input_msg)]; - pxl8_msg_header hdr = { - .type = PXL8_MSG_INPUT, - .version = PXL8_PROTOCOL_VERSION, - .size = sizeof(pxl8_input_msg), - .sequence = 0 - }; - - size_t offset = pxl8_protocol_serialize_header(&hdr, buf, sizeof(buf)); - offset += pxl8_protocol_serialize_input(input, buf + offset, sizeof(buf) - offset); - - return pxl8_net_send(net, buf, offset); -} - -const pxl8_snapshot_header* pxl8_net_snapshot(const pxl8_net* net) { - if (!net) return NULL; - return &net->snapshot; -} - -u64 pxl8_net_tick(const pxl8_net* net) { - if (!net) return 0; - return net->snapshot.tick; -} - -void pxl8_net_update(pxl8_net* net, f32 dt) { - if (!net) return; - net->interp_time += dt; -} diff --git a/src/net/pxl8_net.h b/src/net/pxl8_net.h deleted file mode 100644 index d14ea10..0000000 --- a/src/net/pxl8_net.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "pxl8_protocol.h" -#include "pxl8_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PXL8_NET_INPUT_HISTORY_SIZE 64 -#define PXL8_NET_USERDATA_SIZE 56 - -typedef struct pxl8_net pxl8_net; - -typedef enum pxl8_net_mode { - PXL8_NET_LOCAL = 0, - PXL8_NET_REMOTE -} pxl8_net_mode; - -typedef struct pxl8_net_config { - const char* address; - pxl8_net_mode mode; - u16 port; -} pxl8_net_config; - -pxl8_result pxl8_net_connect(pxl8_net* net); -bool pxl8_net_connected(const pxl8_net* net); -pxl8_net* pxl8_net_create(const pxl8_net_config* config); -void pxl8_net_destroy(pxl8_net* net); -void pxl8_net_disconnect(pxl8_net* net); -const pxl8_entity_state* pxl8_net_entities(const pxl8_net* net); -const u8* pxl8_net_entity_prev_userdata(const pxl8_net* net, u64 entity_id); -const u8* pxl8_net_entity_userdata(const pxl8_net* net, u64 entity_id); -const pxl8_event_msg* pxl8_net_events(const pxl8_net* net); -const pxl8_input_msg* pxl8_net_input_at(const pxl8_net* net, u64 tick); -u64 pxl8_net_input_oldest_tick(const pxl8_net* net); -void pxl8_net_input_push(pxl8_net* net, const pxl8_input_msg* input); -f32 pxl8_net_lerp_alpha(const pxl8_net* net); -bool pxl8_net_needs_correction(const pxl8_net* net); -u64 pxl8_net_player_id(const pxl8_net* net); -bool pxl8_net_poll(pxl8_net* net); -u8* pxl8_net_predicted_state(pxl8_net* net); -void pxl8_net_predicted_tick_set(pxl8_net* net, u64 tick); -size_t pxl8_net_recv(pxl8_net* net, u8* buf, size_t len); -pxl8_result pxl8_net_send(pxl8_net* net, const u8* data, size_t len); -pxl8_result pxl8_net_send_command(pxl8_net* net, const pxl8_command_msg* cmd); -pxl8_result pxl8_net_send_input(pxl8_net* net, const pxl8_input_msg* input); -const pxl8_snapshot_header* pxl8_net_snapshot(const pxl8_net* net); -u64 pxl8_net_tick(const pxl8_net* net); -void pxl8_net_update(pxl8_net* net, f32 dt); - -#ifdef __cplusplus -} -#endif diff --git a/src/net/pxl8_protocol.c b/src/net/pxl8_protocol.c deleted file mode 100644 index 3c4a48d..0000000 --- a/src/net/pxl8_protocol.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "pxl8_protocol.h" -#include "pxl8_bytes.h" - -size_t pxl8_protocol_serialize_header(const pxl8_msg_header* msg, u8* buf, size_t len) { - if (len < sizeof(pxl8_msg_header)) return 0; - pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len); - pxl8_write_u32_be(&s, msg->sequence); - pxl8_write_u16_be(&s, msg->size); - pxl8_write_u8(&s, msg->type); - pxl8_write_u8(&s, msg->version); - return s.offset; -} - -size_t pxl8_protocol_deserialize_header(const u8* buf, size_t len, pxl8_msg_header* msg) { - if (len < sizeof(pxl8_msg_header)) return 0; - pxl8_stream s = pxl8_stream_create(buf, (u32)len); - msg->sequence = pxl8_read_u32_be(&s); - msg->size = pxl8_read_u16_be(&s); - msg->type = pxl8_read_u8(&s); - msg->version = pxl8_read_u8(&s); - return s.offset; -} - -size_t pxl8_protocol_serialize_input(const pxl8_input_msg* msg, u8* buf, size_t len) { - if (len < sizeof(pxl8_input_msg)) return 0; - pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len); - pxl8_write_u32_be(&s, msg->buttons); - pxl8_write_f32_be(&s, msg->look_dx); - pxl8_write_f32_be(&s, msg->look_dy); - pxl8_write_f32_be(&s, msg->move_x); - pxl8_write_f32_be(&s, msg->move_y); - pxl8_write_f32_be(&s, msg->yaw); - pxl8_write_u64_be(&s, msg->tick); - pxl8_write_u64_be(&s, msg->timestamp); - return s.offset; -} - -size_t pxl8_protocol_deserialize_input(const u8* buf, size_t len, pxl8_input_msg* msg) { - if (len < sizeof(pxl8_input_msg)) return 0; - pxl8_stream s = pxl8_stream_create(buf, (u32)len); - msg->buttons = pxl8_read_u32_be(&s); - msg->look_dx = pxl8_read_f32_be(&s); - msg->look_dy = pxl8_read_f32_be(&s); - msg->move_x = pxl8_read_f32_be(&s); - msg->move_y = pxl8_read_f32_be(&s); - msg->yaw = pxl8_read_f32_be(&s); - msg->tick = pxl8_read_u64_be(&s); - msg->timestamp = pxl8_read_u64_be(&s); - return s.offset; -} - -size_t pxl8_protocol_serialize_command(const pxl8_command_msg* msg, u8* buf, size_t len) { - if (len < sizeof(pxl8_command_msg)) return 0; - pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len); - pxl8_write_u16_be(&s, msg->cmd_type); - pxl8_write_bytes(&s, msg->payload, PXL8_COMMAND_PAYLOAD_SIZE); - pxl8_write_u16_be(&s, msg->payload_size); - pxl8_write_u64_be(&s, msg->tick); - return s.offset; -} - -size_t pxl8_protocol_deserialize_command(const u8* buf, size_t len, pxl8_command_msg* msg) { - if (len < sizeof(pxl8_command_msg)) return 0; - pxl8_stream s = pxl8_stream_create(buf, (u32)len); - msg->cmd_type = pxl8_read_u16_be(&s); - pxl8_read_bytes(&s, msg->payload, PXL8_COMMAND_PAYLOAD_SIZE); - msg->payload_size = pxl8_read_u16_be(&s); - msg->tick = pxl8_read_u64_be(&s); - return s.offset; -} - -size_t pxl8_protocol_serialize_entity_state(const pxl8_entity_state* state, u8* buf, size_t len) { - if (len < sizeof(pxl8_entity_state)) return 0; - pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len); - pxl8_write_u64_be(&s, state->entity_id); - pxl8_write_bytes(&s, state->userdata, 56); - return s.offset; -} - -size_t pxl8_protocol_deserialize_entity_state(const u8* buf, size_t len, pxl8_entity_state* state) { - if (len < sizeof(pxl8_entity_state)) return 0; - pxl8_stream s = pxl8_stream_create(buf, (u32)len); - state->entity_id = pxl8_read_u64_be(&s); - pxl8_read_bytes(&s, state->userdata, 56); - return s.offset; -} - -size_t pxl8_protocol_serialize_event(const pxl8_event_msg* msg, u8* buf, size_t len) { - if (len < sizeof(pxl8_event_msg)) return 0; - pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len); - pxl8_write_u8(&s, msg->event_type); - pxl8_write_bytes(&s, msg->payload, PXL8_EVENT_PAYLOAD_SIZE); - return s.offset; -} - -size_t pxl8_protocol_deserialize_event(const u8* buf, size_t len, pxl8_event_msg* msg) { - if (len < sizeof(pxl8_event_msg)) return 0; - pxl8_stream s = pxl8_stream_create(buf, (u32)len); - msg->event_type = pxl8_read_u8(&s); - pxl8_read_bytes(&s, msg->payload, PXL8_EVENT_PAYLOAD_SIZE); - return s.offset; -} - -size_t pxl8_protocol_serialize_snapshot_header(const pxl8_snapshot_header* hdr, u8* buf, size_t len) { - if (len < sizeof(pxl8_snapshot_header)) return 0; - pxl8_write_stream s = pxl8_write_stream_create(buf, (u32)len); - pxl8_write_u16_be(&s, hdr->entity_count); - pxl8_write_u16_be(&s, hdr->event_count); - pxl8_write_u64_be(&s, hdr->player_id); - pxl8_write_u64_be(&s, hdr->tick); - pxl8_write_f32_be(&s, hdr->time); - return s.offset; -} - -size_t pxl8_protocol_deserialize_snapshot_header(const u8* buf, size_t len, pxl8_snapshot_header* hdr) { - if (len < sizeof(pxl8_snapshot_header)) return 0; - pxl8_stream s = pxl8_stream_create(buf, (u32)len); - hdr->entity_count = pxl8_read_u16_be(&s); - hdr->event_count = pxl8_read_u16_be(&s); - hdr->player_id = pxl8_read_u64_be(&s); - hdr->tick = pxl8_read_u64_be(&s); - hdr->time = pxl8_read_f32_be(&s); - return s.offset; -} diff --git a/src/net/pxl8_protocol.h b/src/net/pxl8_protocol.h deleted file mode 100644 index 78a4207..0000000 --- a/src/net/pxl8_protocol.h +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -#include "pxl8_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PXL8_PROTOCOL_VERSION 1 -#define PXL8_MAX_SNAPSHOT_ENTITIES 256 -#define PXL8_MAX_SNAPSHOT_EVENTS 32 -#define PXL8_COMMAND_PAYLOAD_SIZE 64 -#define PXL8_EVENT_PAYLOAD_SIZE 15 - -typedef enum pxl8_msg_type { - PXL8_MSG_NONE = 0, - PXL8_MSG_CONNECT, - PXL8_MSG_DISCONNECT, - PXL8_MSG_INPUT, - PXL8_MSG_COMMAND, - PXL8_MSG_SNAPSHOT, - PXL8_MSG_EVENT -} pxl8_msg_type; - -typedef struct pxl8_msg_header { - u32 sequence; - u16 size; - u8 type; - u8 version; -} pxl8_msg_header; - -typedef enum pxl8_cmd_type { - PXL8_CMD_NONE = 0, - PXL8_CMD_SPAWN_ENTITY, -} pxl8_cmd_type; - -typedef struct pxl8_input_msg { - u32 buttons; - f32 look_dx; - f32 look_dy; - f32 move_x; - f32 move_y; - f32 yaw; - u64 tick; - u64 timestamp; -} pxl8_input_msg; - -typedef struct pxl8_command_msg { - u16 cmd_type; - u8 payload[PXL8_COMMAND_PAYLOAD_SIZE]; - u16 payload_size; - u64 tick; -} pxl8_command_msg; - -typedef struct pxl8_entity_state { - u64 entity_id; - u8 userdata[56]; -} pxl8_entity_state; - -typedef struct pxl8_event_msg { - u8 event_type; - u8 payload[PXL8_EVENT_PAYLOAD_SIZE]; -} pxl8_event_msg; - -typedef struct pxl8_snapshot_header { - u16 entity_count; - u16 event_count; - u64 player_id; - u64 tick; - f32 time; -} pxl8_snapshot_header; - -size_t pxl8_protocol_serialize_header(const pxl8_msg_header* msg, u8* buf, size_t len); -size_t pxl8_protocol_deserialize_header(const u8* buf, size_t len, pxl8_msg_header* msg); - -size_t pxl8_protocol_serialize_input(const pxl8_input_msg* msg, u8* buf, size_t len); -size_t pxl8_protocol_deserialize_input(const u8* buf, size_t len, pxl8_input_msg* msg); - -size_t pxl8_protocol_serialize_command(const pxl8_command_msg* msg, u8* buf, size_t len); -size_t pxl8_protocol_deserialize_command(const u8* buf, size_t len, pxl8_command_msg* msg); - -size_t pxl8_protocol_serialize_entity_state(const pxl8_entity_state* state, u8* buf, size_t len); -size_t pxl8_protocol_deserialize_entity_state(const u8* buf, size_t len, pxl8_entity_state* state); - -size_t pxl8_protocol_serialize_event(const pxl8_event_msg* msg, u8* buf, size_t len); -size_t pxl8_protocol_deserialize_event(const u8* buf, size_t len, pxl8_event_msg* msg); - -size_t pxl8_protocol_serialize_snapshot_header(const pxl8_snapshot_header* hdr, u8* buf, size_t len); -size_t pxl8_protocol_deserialize_snapshot_header(const u8* buf, size_t len, pxl8_snapshot_header* hdr); - -#ifdef __cplusplus -} -#endif diff --git a/src/procgen/pxl8_graph.c b/src/procgen/pxl8_graph.c deleted file mode 100644 index 9777f06..0000000 --- a/src/procgen/pxl8_graph.c +++ /dev/null @@ -1,331 +0,0 @@ -#include "pxl8_graph.h" - -#include -#include -#include - -#include "pxl8_math.h" - -static inline u32 hash2d(i32 x, i32 y, u32 seed) { - return pxl8_hash32((u32)x ^ ((u32)y * 2654435769u) ^ seed); -} - -static inline f32 hash2d_f(i32 x, i32 y, u32 seed) { - return (f32)hash2d(x, y, seed) / (f32)0xFFFFFFFF; -} - -static f32 gradient2d(i32 ix, i32 iy, f32 fx, f32 fy, u32 seed) { - u32 h = hash2d(ix, iy, seed); - f32 angle = (f32)h / (f32)0xFFFFFFFF * 6.28318530718f; - f32 gx = cosf(angle); - f32 gy = sinf(angle); - return gx * fx + gy * fy; -} - -static inline f32 smoothstep(f32 t) { - return t * t * (3.0f - 2.0f * t); -} - -static inline f32 lerp(f32 a, f32 b, f32 t) { - return a + t * (b - a); -} - -static f32 noise_value(f32 x, f32 y, f32 scale, u32 seed) { - f32 sx = x * scale; - f32 sy = y * scale; - i32 ix = (i32)floorf(sx); - i32 iy = (i32)floorf(sy); - f32 fx = sx - (f32)ix; - f32 fy = sy - (f32)iy; - f32 u = smoothstep(fx); - f32 v = smoothstep(fy); - - f32 n00 = hash2d_f(ix, iy, seed); - f32 n10 = hash2d_f(ix + 1, iy, seed); - f32 n01 = hash2d_f(ix, iy + 1, seed); - f32 n11 = hash2d_f(ix + 1, iy + 1, seed); - - return lerp(lerp(n00, n10, u), lerp(n01, n11, u), v); -} - -static f32 noise_perlin(f32 x, f32 y, f32 scale, u32 seed) { - f32 sx = x * scale; - f32 sy = y * scale; - i32 ix = (i32)floorf(sx); - i32 iy = (i32)floorf(sy); - f32 fx = sx - (f32)ix; - f32 fy = sy - (f32)iy; - f32 u = smoothstep(fx); - f32 v = smoothstep(fy); - - f32 n00 = gradient2d(ix, iy, fx, fy, seed); - f32 n10 = gradient2d(ix + 1, iy, fx - 1.0f, fy, seed); - f32 n01 = gradient2d(ix, iy + 1, fx, fy - 1.0f, seed); - f32 n11 = gradient2d(ix + 1, iy + 1, fx - 1.0f, fy - 1.0f, seed); - - f32 result = lerp(lerp(n00, n10, u), lerp(n01, n11, u), v); - return result * 0.5f + 0.5f; -} - -static f32 noise_fbm(f32 x, f32 y, i32 octaves, f32 scale, f32 persistence, u32 seed) { - f32 value = 0.0f; - f32 amplitude = 1.0f; - f32 frequency = scale; - f32 max_value = 0.0f; - - for (i32 i = 0; i < octaves; i++) { - value += amplitude * noise_perlin(x, y, frequency, seed + (u32)i * 1337); - max_value += amplitude; - amplitude *= persistence; - frequency *= 2.0f; - } - - return value / max_value; -} - -static f32 noise_ridged(f32 x, f32 y, i32 octaves, f32 scale, f32 persistence, u32 seed) { - f32 value = 0.0f; - f32 amplitude = 1.0f; - f32 frequency = scale; - f32 max_value = 0.0f; - - for (i32 i = 0; i < octaves; i++) { - f32 n = noise_perlin(x, y, frequency, seed + (u32)i * 1337); - n = 1.0f - fabsf(n * 2.0f - 1.0f); - value += amplitude * n; - max_value += amplitude; - amplitude *= persistence; - frequency *= 2.0f; - } - - return value / max_value; -} - -static f32 noise_turbulence(f32 x, f32 y, i32 octaves, f32 scale, f32 persistence, u32 seed) { - f32 value = 0.0f; - f32 amplitude = 1.0f; - f32 frequency = scale; - f32 max_value = 0.0f; - - for (i32 i = 0; i < octaves; i++) { - f32 n = noise_perlin(x, y, frequency, seed + (u32)i * 1337); - value += amplitude * fabsf(n * 2.0f - 1.0f); - max_value += amplitude; - amplitude *= persistence; - frequency *= 2.0f; - } - - return value / max_value; -} - -static void voronoi(f32 x, f32 y, f32 scale, u32 seed, f32* cell_dist, f32* edge_dist, i32* cell_id) { - f32 sx = x * scale; - f32 sy = y * scale; - i32 cx = (i32)floorf(sx); - i32 cy = (i32)floorf(sy); - f32 fx = sx - (f32)cx; - f32 fy = sy - (f32)cy; - - f32 min_dist = 1e30f; - f32 second_dist = 1e30f; - i32 closest_id = 0; - - for (i32 dy = -1; dy <= 1; dy++) { - for (i32 dx = -1; dx <= 1; dx++) { - i32 nx = cx + dx; - i32 ny = cy + dy; - u32 h = hash2d(nx, ny, seed); - f32 px = (f32)dx + (f32)(h & 0xFF) / 255.0f - 0.5f - fx; - f32 py = (f32)dy + (f32)((h >> 8) & 0xFF) / 255.0f - 0.5f - fy; - f32 dist = px * px + py * py; - - if (dist < min_dist) { - second_dist = min_dist; - min_dist = dist; - closest_id = (i32)h; - } else if (dist < second_dist) { - second_dist = dist; - } - } - } - - *cell_dist = sqrtf(min_dist); - *edge_dist = sqrtf(second_dist) - sqrtf(min_dist); - *cell_id = closest_id; -} - -static f32 gradient_linear(f32 x, f32 y, f32 angle) { - f32 dx = cosf(angle); - f32 dy = sinf(angle); - f32 result = x * dx + y * dy; - return fmaxf(0.0f, fminf(1.0f, result)); -} - -static f32 gradient_radial(f32 x, f32 y, f32 cx, f32 cy) { - f32 dx = x - cx; - f32 dy = y - cy; - return fmaxf(0.0f, fminf(1.0f, sqrtf(dx * dx + dy * dy))); -} - -pxl8_graph* pxl8_graph_create(u32 capacity) { - pxl8_graph* graph = calloc(1, sizeof(pxl8_graph)); - if (!graph) return NULL; - - graph->nodes = calloc(capacity, sizeof(pxl8_node)); - if (!graph->nodes) { - free(graph); - return NULL; - } - - graph->capacity = capacity; - graph->count = 0; - graph->seed = 0; - graph->output_reg = 0; - return graph; -} - -void pxl8_graph_destroy(pxl8_graph* graph) { - if (!graph) return; - free(graph->nodes); - free(graph); -} - -void pxl8_graph_clear(pxl8_graph* graph) { - if (!graph) return; - graph->count = 0; - graph->output_reg = 0; -} - -u8 pxl8_graph_add_node(pxl8_graph* graph, pxl8_graph_op op, u8 in0, u8 in1, u8 in2, u8 in3, f32 param) { - if (!graph || graph->count >= graph->capacity) return 0; - - u8 out = (u8)(graph->count + 4); - pxl8_node* node = &graph->nodes[graph->count++]; - node->op = (u8)op; - node->out = out; - node->in[0] = in0; - node->in[1] = in1; - node->in[2] = in2; - node->in[3] = in3; - node->param = param; - - return out; -} - -void pxl8_graph_set_output(pxl8_graph* graph, u8 reg) { - if (graph) graph->output_reg = reg; -} - -void pxl8_graph_set_seed(pxl8_graph* graph, u32 seed) { - if (graph) graph->seed = seed; -} - -f32 pxl8_graph_eval(const pxl8_graph* graph, pxl8_graph_context* ctx) { - if (!graph || !ctx) return 0.0f; - - for (u32 i = 0; i < graph->count; i++) { - const pxl8_node* n = &graph->nodes[i]; - f32 a = ctx->regs[n->in[0]]; - f32 b = ctx->regs[n->in[1]]; - f32 c = ctx->regs[n->in[2]]; - f32 d = ctx->regs[n->in[3]]; - f32 result = 0.0f; - - switch (n->op) { - case PXL8_OP_CONST: result = n->param; break; - case PXL8_OP_INPUT_AGE: result = ctx->regs[3]; break; - case PXL8_OP_INPUT_SEED: result = (f32)ctx->seed; break; - case PXL8_OP_INPUT_TIME: result = ctx->regs[2]; break; - case PXL8_OP_INPUT_X: result = ctx->regs[0]; break; - case PXL8_OP_INPUT_Y: result = ctx->regs[1]; break; - - case PXL8_OP_ABS: result = fabsf(a); break; - case PXL8_OP_CEIL: result = ceilf(a); break; - case PXL8_OP_COS: result = cosf(a); break; - case PXL8_OP_FLOOR: result = floorf(a); break; - case PXL8_OP_FRACT: result = a - floorf(a); break; - case PXL8_OP_NEGATE: result = -a; break; - case PXL8_OP_SIN: result = sinf(a); break; - case PXL8_OP_SQRT: result = sqrtf(a); break; - - case PXL8_OP_ADD: result = a + b; break; - case PXL8_OP_DIV: result = b != 0.0f ? a / b : 0.0f; break; - case PXL8_OP_MAX: result = fmaxf(a, b); break; - case PXL8_OP_MIN: result = fminf(a, b); break; - case PXL8_OP_MOD: result = b != 0.0f ? fmodf(a, b) : 0.0f; break; - case PXL8_OP_MUL: result = a * b; break; - case PXL8_OP_POW: result = powf(a, b); break; - case PXL8_OP_SUB: result = a - b; break; - - case PXL8_OP_CLAMP: result = fmaxf(b, fminf(c, a)); break; - case PXL8_OP_LERP: result = a + c * (b - a); break; - case PXL8_OP_SELECT: result = c > 0.0f ? a : b; break; - case PXL8_OP_SMOOTHSTEP: { - f32 t = fmaxf(0.0f, fminf(1.0f, (c - a) / (b - a))); - result = t * t * (3.0f - 2.0f * t); - break; - } - - case PXL8_OP_NOISE_FBM: result = noise_fbm(a, b, (i32)n->param, c, d, ctx->seed); break; - case PXL8_OP_NOISE_PERLIN: result = noise_perlin(a, b, c, ctx->seed); break; - case PXL8_OP_NOISE_RIDGED: result = noise_ridged(a, b, (i32)n->param, c, d, ctx->seed); break; - case PXL8_OP_NOISE_TURBULENCE:result = noise_turbulence(a, b, (i32)n->param, c, d, ctx->seed); break; - case PXL8_OP_NOISE_VALUE: result = noise_value(a, b, c, ctx->seed); break; - - case PXL8_OP_VORONOI_CELL: { - f32 cell, edge; i32 id; - voronoi(a, b, c, ctx->seed, &cell, &edge, &id); - result = cell; - break; - } - case PXL8_OP_VORONOI_EDGE: { - f32 cell, edge; i32 id; - voronoi(a, b, c, ctx->seed, &cell, &edge, &id); - result = edge; - break; - } - case PXL8_OP_VORONOI_ID: { - f32 cell, edge; i32 id; - voronoi(a, b, c, ctx->seed, &cell, &edge, &id); - result = (f32)(id & 0xFF) / 255.0f; - break; - } - - case PXL8_OP_GRADIENT_LINEAR: result = gradient_linear(a, b, c); break; - case PXL8_OP_GRADIENT_RADIAL: result = gradient_radial(a, b, c, d); break; - - case PXL8_OP_QUANTIZE: { - u8 base = (u8)n->param; - f32 range = b; - f32 clamped = fmaxf(0.0f, fminf(1.0f, a)); - result = (f32)(base + (u8)fminf(clamped * range, range - 1.0f)); - break; - } - - default: break; - } - - ctx->regs[n->out] = result; - } - - return ctx->regs[graph->output_reg]; -} - -void pxl8_graph_eval_texture(const pxl8_graph* graph, u8* buffer, i32 width, i32 height) { - if (!graph || !buffer) return; - - pxl8_graph_context ctx = {0}; - ctx.seed = graph->seed; - - for (i32 y = 0; y < height; y++) { - for (i32 x = 0; x < width; x++) { - ctx.regs[0] = (f32)x / (f32)width; - ctx.regs[1] = (f32)y / (f32)height; - ctx.regs[2] = 0.0f; - ctx.regs[3] = 0.0f; - - f32 result = pxl8_graph_eval(graph, &ctx); - buffer[y * width + x] = (u8)fmaxf(0.0f, fminf(255.0f, result)); - } - } -} diff --git a/src/procgen/pxl8_graph.h b/src/procgen/pxl8_graph.h deleted file mode 100644 index 81f7882..0000000 --- a/src/procgen/pxl8_graph.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include "pxl8_types.h" - -typedef enum pxl8_graph_op { - PXL8_OP_CONST, // param -> out - PXL8_OP_INPUT_AGE, // particle normalized age -> out - PXL8_OP_INPUT_SEED, // seed -> out - PXL8_OP_INPUT_TIME, // time -> out - PXL8_OP_INPUT_X, // x coord -> out - PXL8_OP_INPUT_Y, // y coord -> out - - PXL8_OP_ABS, // |a| -> out - PXL8_OP_CEIL, // ceil(a) -> out - PXL8_OP_COS, // cos(a) -> out - PXL8_OP_FLOOR, // floor(a) -> out - PXL8_OP_FRACT, // fract(a) -> out - PXL8_OP_NEGATE, // -a -> out - PXL8_OP_SIN, // sin(a) -> out - PXL8_OP_SQRT, // sqrt(a) -> out - - PXL8_OP_ADD, // a + b -> out - PXL8_OP_DIV, // a / b -> out - PXL8_OP_MAX, // max(a, b) -> out - PXL8_OP_MIN, // min(a, b) -> out - PXL8_OP_MOD, // fmod(a, b) -> out - PXL8_OP_MUL, // a * b -> out - PXL8_OP_POW, // pow(a, b) -> out - PXL8_OP_SUB, // a - b -> out - - PXL8_OP_CLAMP, // clamp(a, min, max) -> out - PXL8_OP_LERP, // lerp(a, b, t) -> out - PXL8_OP_SELECT, // t > 0 ? a : b -> out - PXL8_OP_SMOOTHSTEP, // smoothstep(edge0, edge1, x) -> out - - PXL8_OP_NOISE_FBM, // fbm(x, y, octaves, scale, persistence) -> out - PXL8_OP_NOISE_PERLIN, // perlin noise(x, y, scale) -> out - PXL8_OP_NOISE_RIDGED, // ridged(x, y, octaves, scale, persistence) -> out - PXL8_OP_NOISE_TURBULENCE,// turbulence(x, y, octaves, scale, persistence) -> out - PXL8_OP_NOISE_VALUE, // value noise(x, y, scale) -> out - - PXL8_OP_VORONOI_CELL, // voronoi cell distance(x, y, scale) -> out - PXL8_OP_VORONOI_EDGE, // voronoi edge distance(x, y, scale) -> out - PXL8_OP_VORONOI_ID, // voronoi cell id(x, y, scale) -> out - - PXL8_OP_GRADIENT_LINEAR, // linear gradient(x, y, angle) -> out - PXL8_OP_GRADIENT_RADIAL, // radial gradient(x, y, cx, cy) -> out - - PXL8_OP_QUANTIZE, // quantize to palette: base + floor(a * range) -> out - - PXL8_OP_COUNT -} pxl8_graph_op; - -typedef struct pxl8_node { - u8 in[4]; - u8 op; - u8 out; - f32 param; -} pxl8_node; - -typedef struct pxl8_graph { - u32 capacity; - u32 count; - pxl8_node* nodes; - u8 output_reg; - u32 seed; -} pxl8_graph; - -typedef struct pxl8_graph_context { - f32 regs[256]; - u32 seed; -} pxl8_graph_context; - -#ifdef __cplusplus -extern "C" { -#endif - -f32 pxl8_graph_eval(const pxl8_graph* graph, pxl8_graph_context* ctx); -void pxl8_graph_eval_texture(const pxl8_graph* graph, u8* buffer, i32 width, i32 height); - -u8 pxl8_graph_add_node(pxl8_graph* graph, pxl8_graph_op op, u8 in0, u8 in1, u8 in2, u8 in3, f32 param); -void pxl8_graph_clear(pxl8_graph* graph); -pxl8_graph* pxl8_graph_create(u32 capacity); -void pxl8_graph_destroy(pxl8_graph* graph); -void pxl8_graph_set_output(pxl8_graph* graph, u8 reg); -void pxl8_graph_set_seed(pxl8_graph* graph, u32 seed); - -#ifdef __cplusplus -} -#endif diff --git a/src/world/pxl8_gen.c b/src/world/pxl8_gen.c deleted file mode 100644 index a8b90b4..0000000 --- a/src/world/pxl8_gen.c +++ /dev/null @@ -1,1022 +0,0 @@ -#include "pxl8_gen.h" - -#include -#include -#include - -#include "pxl8_log.h" -#include "pxl8_rng.h" - -#define CELL_SIZE 64.0f -#define PVS_MAX_DEPTH 40 -#define WALL_HEIGHT 128.0f - -typedef struct room_grid { - u8* cells; - i32 width; - i32 height; -} room_grid; - -typedef struct bsp_build_context { - pxl8_bsp* bsp; - const room_grid* grid; - u32 node_count; - u32 plane_offset; -} bsp_build_context; - -typedef struct portal { - f32 x0, z0; - f32 x1, z1; - u32 target_leaf; -} portal; - -typedef struct cell_portals { - portal portals[4]; - u8 num_portals; -} cell_portals; - -typedef struct vis_window { - f32 left_x, left_z; - f32 right_x, right_z; -} vis_window; - -typedef struct light_source { - pxl8_vec3 position; - f32 intensity; - f32 radius; -} light_source; - -static bool room_grid_init(room_grid* grid, i32 width, i32 height) { - grid->width = width; - grid->height = height; - grid->cells = calloc(width * height, sizeof(u8)); - - return grid->cells != NULL; -} - -static u8 room_grid_get(const room_grid* grid, i32 x, i32 y) { - if (x < 0 || x >= grid->width || y < 0 || y >= grid->height) { - return 1; - } - return grid->cells[y * grid->width + x]; -} - -static void room_grid_set(room_grid* grid, i32 x, i32 y, u8 value) { - if (x < 0 || x >= grid->width || y < 0 || y >= grid->height) { - return; - } - grid->cells[y * grid->width + x] = value; -} - -static inline void compute_face_aabb(pxl8_bsp_face* face, const pxl8_bsp_vertex* verts, u32 vert_idx) { - face->aabb_min = (pxl8_vec3){1e30f, 1e30f, 1e30f}; - face->aabb_max = (pxl8_vec3){-1e30f, -1e30f, -1e30f}; - - for (u32 i = 0; i < 4; i++) { - pxl8_vec3 v = verts[vert_idx + i].position; - if (v.x < face->aabb_min.x) face->aabb_min.x = v.x; - if (v.x > face->aabb_max.x) face->aabb_max.x = v.x; - if (v.y < face->aabb_min.y) face->aabb_min.y = v.y; - if (v.y > face->aabb_max.y) face->aabb_max.y = v.y; - if (v.z < face->aabb_min.z) face->aabb_min.z = v.z; - if (v.z > face->aabb_max.z) face->aabb_max.z = v.z; - } -} - -static void room_grid_fill(room_grid* grid, u8 value) { - for (i32 y = 0; y < grid->height; y++) { - for (i32 x = 0; x < grid->width; x++) { - room_grid_set(grid, x, y, value); - } - } -} - -static f32 compute_vertex_light( - pxl8_vec3 pos, - pxl8_vec3 normal, - const light_source* lights, - u32 num_lights, - f32 ambient -) { - f32 total = ambient; - - for (u32 i = 0; i < num_lights; i++) { - pxl8_vec3 to_light = { - lights[i].position.x - pos.x, - lights[i].position.y - pos.y, - lights[i].position.z - pos.z - }; - - f32 dist_sq = to_light.x * to_light.x + to_light.y * to_light.y + to_light.z * to_light.z; - f32 dist = sqrtf(dist_sq); - - if (dist > lights[i].radius) continue; - if (dist < 1.0f) dist = 1.0f; - - f32 inv_dist = 1.0f / dist; - pxl8_vec3 light_dir = { - to_light.x * inv_dist, - to_light.y * inv_dist, - to_light.z * inv_dist - }; - - f32 ndotl = normal.x * light_dir.x + normal.y * light_dir.y + normal.z * light_dir.z; - if (ndotl < 0) ndotl = 0; - - f32 attenuation = 1.0f - (dist / lights[i].radius); - if (attenuation < 0) attenuation = 0; - attenuation *= attenuation; - - total += lights[i].intensity * ndotl * attenuation; - } - - if (total > 1.0f) total = 1.0f; - return total; -} - -static void compute_bsp_vertex_lighting( - pxl8_bsp* bsp, - const light_source* lights, - u32 num_lights, - f32 ambient -) { - if (!bsp || bsp->num_vertices == 0) return; - - bsp->vertex_lights = calloc(bsp->num_vertices, sizeof(u32)); - if (!bsp->vertex_lights) return; - bsp->num_vertex_lights = bsp->num_vertices; - - for (u32 f = 0; f < bsp->num_faces; f++) { - const pxl8_bsp_face* face = &bsp->faces[f]; - pxl8_vec3 normal = {0, 1, 0}; - - if (face->plane_id < bsp->num_planes) { - normal = bsp->planes[face->plane_id].normal; - } - - for (u32 e = 0; e < face->num_edges; e++) { - i32 surfedge_idx = face->first_edge + e; - if (surfedge_idx >= (i32)bsp->num_surfedges) continue; - - i32 edge_idx = bsp->surfedges[surfedge_idx]; - u32 vert_idx; - - if (edge_idx >= 0) { - if ((u32)edge_idx >= bsp->num_edges) continue; - vert_idx = bsp->edges[edge_idx].vertex[0]; - } else { - edge_idx = -edge_idx; - if ((u32)edge_idx >= bsp->num_edges) continue; - vert_idx = bsp->edges[edge_idx].vertex[1]; - } - - if (vert_idx >= bsp->num_vertices) continue; - - pxl8_vec3 pos = bsp->vertices[vert_idx].position; - f32 light = compute_vertex_light(pos, normal, lights, num_lights, ambient); - - u8 light_byte = (u8)(light * 255.0f); - bsp->vertex_lights[vert_idx] = ((u32)light_byte << 24) | 0x00FFFFFF; - } - } - - pxl8_debug("Computed vertex lighting: %u vertices, %u lights", bsp->num_vertices, num_lights); -} - -static cell_portals* build_cell_portals(const room_grid* grid, f32 cell_size) { - i32 total_cells = grid->width * grid->height; - cell_portals* portals = calloc(total_cells, sizeof(cell_portals)); - if (!portals) return NULL; - - for (i32 y = 0; y < grid->height; y++) { - for (i32 x = 0; x < grid->width; x++) { - if (room_grid_get(grid, x, y) != 0) continue; - - i32 c = y * grid->width + x; - f32 cx = x * cell_size; - f32 cz = y * cell_size; - - if (x > 0 && room_grid_get(grid, x - 1, y) == 0) { - portal* p = &portals[c].portals[portals[c].num_portals++]; - p->x0 = cx; - p->z0 = cz; - p->x1 = cx; - p->z1 = cz + cell_size; - p->target_leaf = y * grid->width + (x - 1); - } - if (x < grid->width - 1 && room_grid_get(grid, x + 1, y) == 0) { - portal* p = &portals[c].portals[portals[c].num_portals++]; - p->x0 = cx + cell_size; - p->z0 = cz + cell_size; - p->x1 = cx + cell_size; - p->z1 = cz; - p->target_leaf = y * grid->width + (x + 1); - } - if (y > 0 && room_grid_get(grid, x, y - 1) == 0) { - portal* p = &portals[c].portals[portals[c].num_portals++]; - p->x0 = cx + cell_size; - p->z0 = cz; - p->x1 = cx; - p->z1 = cz; - p->target_leaf = (y - 1) * grid->width + x; - } - if (y < grid->height - 1 && room_grid_get(grid, x, y + 1) == 0) { - portal* p = &portals[c].portals[portals[c].num_portals++]; - p->x0 = cx; - p->z0 = cz + cell_size; - p->x1 = cx + cell_size; - p->z1 = cz + cell_size; - p->target_leaf = (y + 1) * grid->width + x; - } - } - } - return portals; -} - -static inline f32 cross_2d(f32 ax, f32 az, f32 bx, f32 bz) { - return ax * bz - az * bx; -} - -static bool clip_window_through_portal( - f32 src_x, f32 src_z, - const vis_window* window, - const portal* p, - vis_window* clipped -) { - f32 wl_x = window->left_x - src_x; - f32 wl_z = window->left_z - src_z; - f32 wr_x = window->right_x - src_x; - f32 wr_z = window->right_z - src_z; - - f32 p0_x = p->x0 - src_x; - f32 p0_z = p->z0 - src_z; - f32 p1_x = p->x1 - src_x; - f32 p1_z = p->z1 - src_z; - - f32 p0_vs_wl = cross_2d(p0_x, p0_z, wl_x, wl_z); - f32 p1_vs_wl = cross_2d(p1_x, p1_z, wl_x, wl_z); - f32 p0_vs_wr = cross_2d(p0_x, p0_z, wr_x, wr_z); - f32 p1_vs_wr = cross_2d(p1_x, p1_z, wr_x, wr_z); - - if (p1_vs_wl <= 0.0f || p0_vs_wr >= 0.0f) { - return false; - } - - if (p0_vs_wl > 0.0f) { - clipped->left_x = p->x0; - clipped->left_z = p->z0; - } else { - clipped->left_x = window->left_x; - clipped->left_z = window->left_z; - } - - if (p1_vs_wr < 0.0f) { - clipped->right_x = p->x1; - clipped->right_z = p->z1; - } else { - clipped->right_x = window->right_x; - clipped->right_z = window->right_z; - } - - f32 cl_x = clipped->left_x - src_x; - f32 cl_z = clipped->left_z - src_z; - f32 cr_x = clipped->right_x - src_x; - f32 cr_z = clipped->right_z - src_z; - - if (cross_2d(cl_x, cl_z, cr_x, cr_z) >= -0.0001f) { - return false; - } - - return true; -} - -typedef struct portal_vis_context { - u8* pvs; - u8* visited; - const cell_portals* portals; - const pxl8_bsp_leaf* leafs; - f32 src_x; - f32 src_z; - u32 num_leafs; - u32 max_depth; -} portal_vis_context; - -static void portal_flood_recursive( - portal_vis_context* ctx, - u32 current_leaf, - const vis_window* window, - u32 depth -) { - if (depth > ctx->max_depth) return; - - u32 byte = current_leaf >> 3; - u32 bit = current_leaf & 7; - - if (ctx->visited[byte] & (1 << bit)) return; - ctx->visited[byte] |= (1 << bit); - - if (ctx->leafs[current_leaf].contents == -1) return; - - ctx->pvs[byte] |= (1 << bit); - - const cell_portals* cp = &ctx->portals[current_leaf]; - for (u8 i = 0; i < cp->num_portals; i++) { - const portal* p = &cp->portals[i]; - - u32 target_byte = p->target_leaf >> 3; - u32 target_bit = p->target_leaf & 7; - if (ctx->visited[target_byte] & (1 << target_bit)) continue; - - vis_window clipped; - if (clip_window_through_portal(ctx->src_x, ctx->src_z, window, p, &clipped)) { - portal_flood_recursive(ctx, p->target_leaf, &clipped, depth + 1); - } - } -} - -typedef struct vis_entry { - u32 leaf; - vis_window window; -} vis_entry; - -static void portal_flood_bfs( - u32 start_leaf, - const cell_portals* portals, - const pxl8_bsp_leaf* leafs, - u8* pvs, - u32 num_leafs, - f32 cell_size, - i32 grid_width -) { - u32 pvs_bytes = (num_leafs + 7) / 8; - u8* visited = calloc(pvs_bytes, 1); - vis_entry* queue = malloc(num_leafs * 4 * sizeof(vis_entry)); - if (!visited || !queue) { - free(visited); - free(queue); - return; - } - - i32 start_x = start_leaf % grid_width; - i32 start_y = start_leaf / grid_width; - f32 src_x = (start_x + 0.5f) * cell_size; - f32 src_z = (start_y + 0.5f) * cell_size; - - u32 head = 0, tail = 0; - - pvs[start_leaf >> 3] |= (1 << (start_leaf & 7)); - visited[start_leaf >> 3] |= (1 << (start_leaf & 7)); - - const cell_portals* start_cp = &portals[start_leaf]; - for (u8 i = 0; i < start_cp->num_portals; i++) { - const portal* p = &start_cp->portals[i]; - vis_window initial = {p->x0, p->z0, p->x1, p->z1}; - queue[tail++] = (vis_entry){p->target_leaf, initial}; - } - - while (head < tail) { - vis_entry e = queue[head++]; - - if (leafs[e.leaf].contents == -1) continue; - - u32 byte = e.leaf >> 3; - u32 bit = e.leaf & 7; - - pvs[byte] |= (1 << bit); - - if (visited[byte] & (1 << bit)) continue; - visited[byte] |= (1 << bit); - - const cell_portals* cp = &portals[e.leaf]; - for (u8 i = 0; i < cp->num_portals; i++) { - const portal* p = &cp->portals[i]; - - vis_window clipped; - if (clip_window_through_portal(src_x, src_z, &e.window, p, &clipped)) { - queue[tail++] = (vis_entry){p->target_leaf, clipped}; - } - } - } - - free(visited); - free(queue); -} - -static u8* compute_leaf_pvs(u32 start_leaf, const cell_portals* portals, - u32 num_leafs, const pxl8_bsp_leaf* leafs, - const room_grid* grid, f32 cell_size) { - u32 pvs_bytes = (num_leafs + 7) / 8; - u8* pvs = calloc(pvs_bytes, 1); - if (!pvs) return NULL; - - portal_flood_bfs(start_leaf, portals, leafs, pvs, num_leafs, cell_size, grid->width); - - return pvs; -} - -static u32 rle_compress_pvs(const u8* pvs, u32 pvs_bytes, u8* out) { - u32 out_pos = 0; - u32 i = 0; - - while (i < pvs_bytes) { - if (pvs[i] != 0) { - out[out_pos++] = pvs[i++]; - } else { - u32 count = 0; - while (i < pvs_bytes && pvs[i] == 0 && count < 255) { - count++; - i++; - } - out[out_pos++] = 0; - out[out_pos++] = (u8)count; - } - } - return out_pos; -} - -static pxl8_result build_pvs_data(pxl8_bsp* bsp, const cell_portals* portals, - const room_grid* grid, f32 cell_size) { - u32 num_leafs = bsp->num_leafs; - u32 pvs_bytes = (num_leafs + 7) / 8; - - u32 max_visdata = num_leafs * pvs_bytes * 2; - u8* visdata = malloc(max_visdata); - if (!visdata) return PXL8_ERROR_OUT_OF_MEMORY; - - u32 visdata_pos = 0; - - u8* compressed = malloc(pvs_bytes * 2); - if (!compressed) { - free(visdata); - return PXL8_ERROR_OUT_OF_MEMORY; - } - - u32 debug_count = 0; - for (u32 leaf = 0; leaf < num_leafs; leaf++) { - if (bsp->leafs[leaf].contents == -1) { - bsp->leafs[leaf].visofs = -1; - continue; - } - - u8* pvs = compute_leaf_pvs(leaf, portals, num_leafs, bsp->leafs, grid, cell_size); - if (!pvs) { - free(compressed); - free(visdata); - return PXL8_ERROR_OUT_OF_MEMORY; - } - - if (debug_count < 3) { - u32 visible = 0; - for (u32 b = 0; b < pvs_bytes; b++) { - for (u32 i = 0; i < 8; i++) { - if (pvs[b] & (1 << i)) visible++; - } - } - pxl8_debug("Leaf %u PVS: %u cells visible (portals: %u)", leaf, visible, portals[leaf].num_portals); - debug_count++; - } - - u32 compressed_size = rle_compress_pvs(pvs, pvs_bytes, compressed); - - bsp->leafs[leaf].visofs = visdata_pos; - memcpy(visdata + visdata_pos, compressed, compressed_size); - visdata_pos += compressed_size; - - free(pvs); - } - - free(compressed); - bsp->visdata = realloc(visdata, visdata_pos > 0 ? visdata_pos : 1); - bsp->visdata_size = visdata_pos; - - pxl8_debug("Built PVS: %u leafs, %u bytes visdata", num_leafs, visdata_pos); - return PXL8_OK; -} - -static i32 build_bsp_node(bsp_build_context* ctx, i32 x0, i32 y0, i32 x1, i32 y1, i32 depth) { - if (x1 - x0 == 1 && y1 - y0 == 1) { - i32 leaf_idx = y0 * ctx->grid->width + x0; - return -(leaf_idx + 1); - } - - i32 node_idx = ctx->node_count++; - pxl8_bsp_node* node = &ctx->bsp->nodes[node_idx]; - - i32 plane_idx = ctx->plane_offset++; - pxl8_bsp_plane* plane = &ctx->bsp->planes[plane_idx]; - node->plane_id = plane_idx; - - if (depth % 2 == 0) { - i32 mid_x = (x0 + x1) / 2; - f32 split_pos = mid_x * CELL_SIZE; - - plane->normal = (pxl8_vec3){1, 0, 0}; - plane->dist = split_pos; - - node->children[0] = build_bsp_node(ctx, mid_x, y0, x1, y1, depth + 1); - node->children[1] = build_bsp_node(ctx, x0, y0, mid_x, y1, depth + 1); - } else { - i32 mid_y = (y0 + y1) / 2; - f32 split_pos = mid_y * CELL_SIZE; - - plane->normal = (pxl8_vec3){0, 0, 1}; - plane->dist = split_pos; - - node->children[0] = build_bsp_node(ctx, x0, mid_y, x1, y1, depth + 1); - node->children[1] = build_bsp_node(ctx, x0, y0, x1, mid_y, depth + 1); - } - - return node_idx; -} - -static pxl8_result grid_to_bsp(pxl8_bsp* bsp, const room_grid* grid) { - i32 vertex_count = 0; - i32 face_count = 0; - i32 floor_ceiling_count = 0; - - for (i32 y = 0; y < grid->height; y++) { - for (i32 x = 0; x < grid->width; x++) { - if (room_grid_get(grid, x, y) == 0) { - if (room_grid_get(grid, x - 1, y) == 1) face_count++; - if (room_grid_get(grid, x + 1, y) == 1) face_count++; - if (room_grid_get(grid, x, y - 1) == 1) face_count++; - if (room_grid_get(grid, x, y + 1) == 1) face_count++; - floor_ceiling_count++; - } - } - } - - face_count += floor_ceiling_count; - vertex_count = face_count * 4; - - pxl8_debug("Level generation: %dx%d grid -> %d faces, %d vertices", - grid->width, grid->height, face_count, vertex_count); - - i32 total_cells = grid->width * grid->height; - u32 max_nodes = 2 * total_cells; - u32 total_planes = face_count + max_nodes; - - bsp->vertices = calloc(vertex_count, sizeof(pxl8_bsp_vertex)); - bsp->faces = calloc(face_count, sizeof(pxl8_bsp_face)); - bsp->planes = calloc(total_planes, sizeof(pxl8_bsp_plane)); - bsp->edges = calloc(vertex_count, sizeof(pxl8_bsp_edge)); - bsp->surfedges = calloc(vertex_count, sizeof(i32)); - bsp->nodes = calloc(max_nodes, sizeof(pxl8_bsp_node)); - - u32* face_cell = calloc(face_count, sizeof(u32)); - - if (!bsp->vertices || !bsp->faces || !bsp->planes || !bsp->edges || - !bsp->surfedges || !bsp->nodes || !face_cell) { - free(face_cell); - return PXL8_ERROR_OUT_OF_MEMORY; - } - - bsp->texinfo = NULL; - bsp->num_texinfo = 0; - - i32 vert_idx = 0; - i32 face_idx = 0; - i32 edge_idx = 0; - - const f32 cell_size = CELL_SIZE; - const f32 wall_height = WALL_HEIGHT; - - for (i32 y = 0; y < grid->height; y++) { - for (i32 x = 0; x < grid->width; x++) { - if (room_grid_get(grid, x, y) == 0) { - f32 fx = (f32)x * cell_size; - f32 fy = (f32)y * cell_size; - i32 cell_idx = y * grid->width + x; - - if (room_grid_get(grid, x - 1, y) == 1) { - bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, 0, fy}; - bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx, wall_height, fy}; - bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx, wall_height, fy + cell_size}; - bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx, 0, fy + cell_size}; - - bsp->planes[face_idx].normal = (pxl8_vec3){1, 0, 0}; - bsp->planes[face_idx].dist = fx; - - bsp->faces[face_idx].plane_id = face_idx; - bsp->faces[face_idx].num_edges = 4; - bsp->faces[face_idx].first_edge = edge_idx; - bsp->faces[face_idx].texinfo_id = 0; - - for (i32 i = 0; i < 4; i++) { - bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; - bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); - bsp->surfedges[edge_idx + i] = edge_idx + i; - } - - compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); - face_cell[face_idx] = cell_idx; - - vert_idx += 4; - edge_idx += 4; - face_idx++; - } - - if (room_grid_get(grid, x + 1, y) == 1) { - bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx + cell_size, 0, fy}; - bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx + cell_size, 0, fy + cell_size}; - bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, wall_height, fy + cell_size}; - bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx + cell_size, wall_height, fy}; - - bsp->planes[face_idx].normal = (pxl8_vec3){-1, 0, 0}; - bsp->planes[face_idx].dist = -(fx + cell_size); - - bsp->faces[face_idx].plane_id = face_idx; - bsp->faces[face_idx].num_edges = 4; - bsp->faces[face_idx].first_edge = edge_idx; - bsp->faces[face_idx].texinfo_id = 0; - - for (i32 i = 0; i < 4; i++) { - bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; - bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); - bsp->surfedges[edge_idx + i] = edge_idx + i; - } - - compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); - face_cell[face_idx] = cell_idx; - - vert_idx += 4; - edge_idx += 4; - face_idx++; - } - - if (room_grid_get(grid, x, y - 1) == 1) { - bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, 0, fy}; - bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx + cell_size, 0, fy}; - bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, wall_height, fy}; - bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx, wall_height, fy}; - - bsp->planes[face_idx].normal = (pxl8_vec3){0, 0, 1}; - bsp->planes[face_idx].dist = fy; - - bsp->faces[face_idx].plane_id = face_idx; - bsp->faces[face_idx].num_edges = 4; - bsp->faces[face_idx].first_edge = edge_idx; - bsp->faces[face_idx].texinfo_id = 0; - - for (i32 i = 0; i < 4; i++) { - bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; - bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); - bsp->surfedges[edge_idx + i] = edge_idx + i; - } - - compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); - face_cell[face_idx] = cell_idx; - - vert_idx += 4; - edge_idx += 4; - face_idx++; - } - - if (room_grid_get(grid, x, y + 1) == 1) { - bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, 0, fy + cell_size}; - bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx, wall_height, fy + cell_size}; - bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, wall_height, fy + cell_size}; - bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx + cell_size, 0, fy + cell_size}; - - bsp->planes[face_idx].normal = (pxl8_vec3){0, 0, -1}; - bsp->planes[face_idx].dist = -(fy + cell_size); - - bsp->faces[face_idx].plane_id = face_idx; - bsp->faces[face_idx].num_edges = 4; - bsp->faces[face_idx].first_edge = edge_idx; - bsp->faces[face_idx].texinfo_id = 0; - - for (i32 i = 0; i < 4; i++) { - bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; - bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); - bsp->surfedges[edge_idx + i] = edge_idx + i; - } - - compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); - face_cell[face_idx] = cell_idx; - - vert_idx += 4; - edge_idx += 4; - face_idx++; - } - } - } - } - - for (i32 y = 0; y < grid->height; y++) { - for (i32 x = 0; x < grid->width; x++) { - if (room_grid_get(grid, x, y) == 0) { - f32 fx = (f32)x * cell_size; - f32 fy = (f32)y * cell_size; - i32 cell_idx = y * grid->width + x; - - bsp->vertices[vert_idx + 0].position = (pxl8_vec3){fx, 0, fy}; - bsp->vertices[vert_idx + 1].position = (pxl8_vec3){fx, 0, fy + cell_size}; - bsp->vertices[vert_idx + 2].position = (pxl8_vec3){fx + cell_size, 0, fy + cell_size}; - bsp->vertices[vert_idx + 3].position = (pxl8_vec3){fx + cell_size, 0, fy}; - - bsp->planes[face_idx].normal = (pxl8_vec3){0, 1, 0}; - bsp->planes[face_idx].dist = 0; - - bsp->faces[face_idx].plane_id = face_idx; - bsp->faces[face_idx].num_edges = 4; - bsp->faces[face_idx].first_edge = edge_idx; - bsp->faces[face_idx].texinfo_id = 0; - - for (i32 i = 0; i < 4; i++) { - bsp->edges[edge_idx + i].vertex[0] = vert_idx + i; - bsp->edges[edge_idx + i].vertex[1] = vert_idx + ((i + 1) % 4); - bsp->surfedges[edge_idx + i] = edge_idx + i; - } - - compute_face_aabb(&bsp->faces[face_idx], bsp->vertices, vert_idx); - face_cell[face_idx] = cell_idx; - - vert_idx += 4; - edge_idx += 4; - face_idx++; - } - } - } - - bsp->num_vertices = vertex_count; - bsp->num_faces = face_count; - bsp->num_edges = vertex_count; - bsp->num_surfedges = vertex_count; - - bsp->leafs = calloc(total_cells, sizeof(pxl8_bsp_leaf)); - bsp->marksurfaces = calloc(face_count, sizeof(u16)); - - if (!bsp->leafs || !bsp->marksurfaces) { - free(face_cell); - return PXL8_ERROR_OUT_OF_MEMORY; - } - - bsp->num_leafs = total_cells; - bsp->num_marksurfaces = face_count; - - u32* faces_per_cell = calloc(total_cells, sizeof(u32)); - u32* cell_offset = calloc(total_cells, sizeof(u32)); - u32* cell_cursor = calloc(total_cells, sizeof(u32)); - - if (!faces_per_cell || !cell_offset || !cell_cursor) { - free(faces_per_cell); - free(cell_offset); - free(cell_cursor); - free(face_cell); - return PXL8_ERROR_OUT_OF_MEMORY; - } - - for (i32 i = 0; i < face_count; i++) { - faces_per_cell[face_cell[i]]++; - } - - u32 offset = 0; - for (i32 c = 0; c < total_cells; c++) { - cell_offset[c] = offset; - offset += faces_per_cell[c]; - } - - for (i32 i = 0; i < face_count; i++) { - u32 c = face_cell[i]; - bsp->marksurfaces[cell_offset[c] + cell_cursor[c]++] = i; - } - - for (i32 y = 0; y < grid->height; y++) { - for (i32 x = 0; x < grid->width; x++) { - i32 c = y * grid->width + x; - pxl8_bsp_leaf* leaf = &bsp->leafs[c]; - - f32 fx = (f32)x * cell_size; - f32 fz = (f32)y * cell_size; - - leaf->mins[0] = (i16)fx; - leaf->mins[1] = 0; - leaf->mins[2] = (i16)fz; - leaf->maxs[0] = (i16)(fx + cell_size); - leaf->maxs[1] = (i16)wall_height; - leaf->maxs[2] = (i16)(fz + cell_size); - - if (room_grid_get(grid, x, y) == 0) { - leaf->contents = -2; - leaf->first_marksurface = cell_offset[c]; - leaf->num_marksurfaces = faces_per_cell[c]; - } else { - leaf->contents = -1; - leaf->first_marksurface = 0; - leaf->num_marksurfaces = 0; - } - leaf->visofs = -1; - } - } - - free(faces_per_cell); - free(cell_offset); - free(cell_cursor); - free(face_cell); - - bsp_build_context ctx = { - .bsp = bsp, - .grid = grid, - .node_count = 0, - .plane_offset = face_count, - }; - - build_bsp_node(&ctx, 0, 0, grid->width, grid->height, 0); - bsp->num_nodes = ctx.node_count; - bsp->num_planes = ctx.plane_offset; - - pxl8_debug("Built BSP tree: %u nodes, %u leafs, %u planes", - bsp->num_nodes, bsp->num_leafs, bsp->num_planes); - - cell_portals* portals = build_cell_portals(grid, cell_size); - if (!portals) { - return PXL8_ERROR_OUT_OF_MEMORY; - } - - u32 walkable_cells = 0; - u32 total_portals = 0; - i32 first_walkable = -1; - for (i32 c = 0; c < total_cells; c++) { - if (bsp->leafs[c].contents == -2) { - walkable_cells++; - if (first_walkable < 0) first_walkable = c; - } - total_portals += portals[c].num_portals; - } - pxl8_debug("Portal stats: %u walkable cells, %u total portals (avg %.1f per cell)", - walkable_cells, total_portals, (f32)total_portals / walkable_cells); - - if (first_walkable >= 0) { - u32 pvs_bytes = (total_cells + 7) / 8; - u8* visited = calloc(pvs_bytes, 1); - u8* queue = malloc(total_cells * sizeof(u32)); - u32 head = 0, tail = 0; - ((u32*)queue)[tail++] = first_walkable; - visited[first_walkable >> 3] |= (1 << (first_walkable & 7)); - u32 reachable = 0; - while (head < tail) { - u32 c = ((u32*)queue)[head++]; - reachable++; - for (u8 i = 0; i < portals[c].num_portals; i++) { - u32 n = portals[c].portals[i].target_leaf; - u32 nb = n >> 3, ni = n & 7; - if (!(visited[nb] & (1 << ni))) { - visited[nb] |= (1 << ni); - ((u32*)queue)[tail++] = n; - } - } - } - pxl8_debug("Connectivity: %u/%u walkable cells reachable from leaf %d", - reachable, walkable_cells, first_walkable); - free(visited); - free(queue); - } - - pxl8_result pvs_result = build_pvs_data(bsp, portals, grid, cell_size); - free(portals); - - if (pvs_result != PXL8_OK) { - return pvs_result; - } - - return PXL8_OK; -} - -static bool bounds_intersects(const pxl8_bounds* a, const pxl8_bounds* b) { - return !(a->x + a->w <= b->x || b->x + b->w <= a->x || - a->y + a->h <= b->y || b->y + b->h <= a->y); -} - -static void carve_corridor_h(room_grid* grid, i32 x1, i32 x2, i32 y) { - i32 start = (x1 < x2) ? x1 : x2; - i32 end = (x1 > x2) ? x1 : x2; - for (i32 x = start; x <= end; x++) { - room_grid_set(grid, x, y, 0); - room_grid_set(grid, x, y - 1, 0); - room_grid_set(grid, x, y + 1, 0); - } -} - -static void carve_corridor_v(room_grid* grid, i32 y1, i32 y2, i32 x) { - i32 start = (y1 < y2) ? y1 : y2; - i32 end = (y1 > y2) ? y1 : y2; - for (i32 y = start; y <= end; y++) { - room_grid_set(grid, x, y, 0); - room_grid_set(grid, x - 1, y, 0); - room_grid_set(grid, x + 1, y, 0); - } -} - -static pxl8_result procgen_rooms(pxl8_bsp* bsp, const pxl8_procgen_params* params) { - pxl8_debug("procgen_rooms called: %dx%d, seed=%u, min=%d, max=%d, num=%d", - params->width, params->height, params->seed, - params->min_room_size, params->max_room_size, params->num_rooms); - - pxl8_rng rng; - pxl8_rng_seed(&rng, params->seed); - - room_grid grid; - if (!room_grid_init(&grid, params->width, params->height)) { - pxl8_error("Failed to allocate room grid"); - return PXL8_ERROR_OUT_OF_MEMORY; - } - - room_grid_fill(&grid, 1); - - pxl8_bounds rooms[256]; - i32 room_count = 0; - i32 max_attempts = params->num_rooms * 10; - - const f32 cell_size = CELL_SIZE; - const f32 light_height = 80.0f; - - for (i32 attempt = 0; attempt < max_attempts && room_count < params->num_rooms && room_count < 256; attempt++) { - i32 w = params->min_room_size + (pxl8_rng_next(&rng) % (params->max_room_size - params->min_room_size + 1)); - i32 h = params->min_room_size + (pxl8_rng_next(&rng) % (params->max_room_size - params->min_room_size + 1)); - i32 x = 1 + (pxl8_rng_next(&rng) % (params->width - w - 2)); - i32 y = 1 + (pxl8_rng_next(&rng) % (params->height - h - 2)); - - pxl8_bounds new_room = {x, y, w, h}; - - bool overlaps = false; - for (i32 i = 0; i < room_count; i++) { - if (bounds_intersects(&new_room, &rooms[i])) { - overlaps = true; - break; - } - } - - if (!overlaps) { - for (i32 ry = y; ry < y + h; ry++) { - for (i32 rx = x; rx < x + w; rx++) { - room_grid_set(&grid, rx, ry, 0); - } - } - - if (room_count > 0) { - i32 new_cx = x + w / 2; - i32 new_cy = y + h / 2; - i32 prev_cx = rooms[room_count - 1].x + rooms[room_count - 1].w / 2; - i32 prev_cy = rooms[room_count - 1].y + rooms[room_count - 1].h / 2; - - if (pxl8_rng_next(&rng) % 2 == 0) { - carve_corridor_h(&grid, prev_cx, new_cx, prev_cy); - carve_corridor_v(&grid, prev_cy, new_cy, new_cx); - } else { - carve_corridor_v(&grid, prev_cy, new_cy, prev_cx); - carve_corridor_h(&grid, prev_cx, new_cx, new_cy); - } - } - - rooms[room_count++] = new_room; - } - } - - pxl8_debug("Room generation: %dx%d grid -> %d rooms created", - params->width, params->height, room_count); - - pxl8_result result = grid_to_bsp(bsp, &grid); - free(grid.cells); - - if (result != PXL8_OK) { - return result; - } - - light_source lights[256]; - u32 num_lights = 0; - - for (i32 i = 0; i < room_count && num_lights < 256; i++) { - f32 cx = (rooms[i].x + rooms[i].w / 2.0f) * cell_size; - f32 cy = (rooms[i].y + rooms[i].h / 2.0f) * cell_size; - - lights[num_lights++] = (light_source){ - .position = {cx, light_height, cy}, - .intensity = 0.8f, - .radius = 300.0f, - }; - } - - compute_bsp_vertex_lighting(bsp, lights, num_lights, 0.1f); - - return result; -} - -pxl8_result pxl8_procgen(pxl8_bsp* bsp, const pxl8_procgen_params* params) { - if (!bsp || !params) { - return PXL8_ERROR_NULL_POINTER; - } - - switch (params->type) { - case PXL8_PROCGEN_ROOMS: - return procgen_rooms(bsp, params); - - case PXL8_PROCGEN_TERRAIN: - pxl8_error("Terrain generation not yet implemented"); - return PXL8_ERROR_NOT_INITIALIZED; - - default: - pxl8_error("Unknown procgen type: %d", params->type); - return PXL8_ERROR_INVALID_ARGUMENT; - } -}