diff --git a/README.md b/README.md index c95bb5e..d6e2306 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Module build order: ## Milestone -Day 38 : Basic Linear Bitmap Blending +Day 39 : Basic Bitmap Rendering Cleanup Features Done so far: @@ -59,12 +59,16 @@ Features Done so far: * Record & replay input. * WIP : 2.5D Tile Map * Virtualized into chunks + * Some basic collision detection & math (pre-math coverage by Casey) * Bitmap file loading * Compression mode 3 - * Linear alpha blending + * Basic rendering + * Linear alpha blending + * Anchored to center position ## Gallery +![img](docs/imgs/handmade_win32_2023-10-21_22-18-47.gif) ![img](docs/imgs/handmade_win32_2023-10-21_02-16-43.png) ![img](docs/imgs/handmade_win32_2023-10-20_23-14-37.png) ![img](docs/imgs/Code_2023-10-20_21-57-06.png) diff --git a/data/content/mojito_head.bmp b/data/content/mojito_head.bmp index f87b7c9..904c28c 100644 Binary files a/data/content/mojito_head.bmp and b/data/content/mojito_head.bmp differ diff --git a/docs/Day 039.md b/docs/Day 039.md new file mode 100644 index 0000000..502ad38 --- /dev/null +++ b/docs/Day 039.md @@ -0,0 +1,18 @@ +# Day 39 + +My `draw_bitmap` proc has been already setup to have the position specified +from the assumped position of the center of the image. +Its how I'm used to anchoring images by default so thats why I decided to go with it. + +Casey however is using the corner however... +and then is doing some offset alignment based on what he sees for the coordinates on GIMP.. + +I decided to hand calibrate the alignment by eye. Since I already have it centered on X, the `align_x` could +stay zeroed for now and all I needed to do was align_y. + +I also did not do the difference using a `tile_map_diff` like he did, +I just returned a tile_map_position and switch the map coodinates to be signed +(which tbh is fine I'll just adjust the math later when I need to). + +I'm assuming it won't matter because the tile map setup we currently have is before he revamps the project with proper +vector math data structures, and he might switch to signed coordinates for them in the stream. diff --git a/docs/imgs/handmade_win32_2023-10-21_22-18-47.gif b/docs/imgs/handmade_win32_2023-10-21_22-18-47.gif new file mode 100644 index 0000000..a453a0c Binary files /dev/null and b/docs/imgs/handmade_win32_2023-10-21_22-18-47.gif differ diff --git a/project/engine/engine.cpp b/project/engine/engine.cpp index a3920ed..2d5d03b 100644 --- a/project/engine/engine.cpp +++ b/project/engine/engine.cpp @@ -249,8 +249,8 @@ void draw_bitmap( OffscreenBuffer* buffer s32 max_x = round( pos_x ) + half_width; s32 max_y = round( pos_y ) + half_height; - s32 bmp_start_x = min_x < 0 ? min_x * -1 : 0; - u32 bmp_start_y = min_y < 0 ? bitmap->height + min_y - 1 : bitmap->height - 1; + s32 bmp_offset_x = min_x < 0 ? min_x * -1 : 0; + u32 bmp_offset_y = min_y < 0 ? bitmap->height + min_y - 1 : bitmap->height - 1; s32 buffer_width = buffer->width; s32 buffer_height = buffer->height; @@ -268,12 +268,12 @@ void draw_bitmap( OffscreenBuffer* buffer u8* dst_row = rcast(u8*, buffer->memory ) + min_x * buffer->bytes_per_pixel + min_y * buffer->pitch; - u32* src_row = bitmap->pixels + bitmap->width * (bitmap->height - 1); + u32* src_row = bitmap->pixels + bitmap->width * bmp_offset_y; for ( s32 y = min_y; y < max_y; ++ y ) { u32* dst = rcast(u32*, dst_row); - u32* src = src_row; + u32* src = src_row + bmp_offset_x; for ( s32 x = min_x; x < max_x; ++ x ) { @@ -418,8 +418,8 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* state->x_offset = 0; state->y_offset = 0; - state->sample_wave_switch = false; - state->wave_tone_hz = 60; + state->sample_wave_switch = false; + state->wave_tone_hz = 60; state->sample_wave_sine_time = 0.f; state->renderer_paused = false; @@ -457,7 +457,7 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* //tile_map->chunks = & temp_chunk; tile_map->tile_size_in_meters = 1.4f; - world->tile_size_in_pixels = 85; + world->tile_size_in_pixels = 80; world->tile_meters_to_pixels = scast(f32, world->tile_size_in_pixels) / tile_map->tile_size_in_meters; f32 tile_size_in_pixels = scast(f32, world->tile_size_in_pixels); @@ -465,8 +465,8 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* world->tile_lower_left_x = -( tile_size_in_pixels * 0.5f); world->tile_lower_left_y = +( tile_size_in_pixels * 0.25f) + scast(f32, back_buffer->height); - u32 tiles_per_screen_x = 17; - u32 tiles_per_screen_y = 9; + world->tiles_per_screen_x = 17; + world->tiles_per_screen_y = 9; u32 screen_x = 0; u32 screen_y = 0; @@ -518,23 +518,23 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* door_top = true; } - for (u32 tile_y = 0; tile_y < tiles_per_screen_y; ++ tile_y ) + for (s32 tile_y = 0; tile_y < world->tiles_per_screen_y; ++ tile_y ) { - for ( u32 tile_x = 0; tile_x < tiles_per_screen_x; ++ tile_x ) + for ( s32 tile_x = 0; tile_x < world->tiles_per_screen_x; ++ tile_x ) { - u32 abs_tile_x = screen_x * tiles_per_screen_x + tile_x; - u32 abs_tile_y = screen_y * tiles_per_screen_y + tile_y; + s32 abs_tile_x = screen_x * world->tiles_per_screen_x + tile_x; + s32 abs_tile_y = screen_y * world->tiles_per_screen_y + tile_y; - u32 tile_value = 1; + s32 tile_value = 1; - bool in_middle_x = tile_x == (tiles_per_screen_x / 2); - bool in_middle_y = tile_y == (tiles_per_screen_y / 2); + bool in_middle_x = tile_x == (world->tiles_per_screen_x / 2); + bool in_middle_y = tile_y == (world->tiles_per_screen_y / 2); - bool on_right = tile_x == (tiles_per_screen_x - 1); + bool on_right = tile_x == (world->tiles_per_screen_x - 1); bool on_left = tile_x == 0; bool on_bottom = tile_y == 0; - bool on_top = tile_y == (tiles_per_screen_y - 1); + bool on_top = tile_y == (world->tiles_per_screen_y - 1); if ( on_left && (! in_middle_y || ! door_left )) { @@ -615,19 +615,19 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* // Personally made assets { - StrPath path_test_bg; + StrPath path_test_bg {}; path_test_bg.concat( platform_api->path_content, str_ascii("test_background.bmp") ); game_state->test_bg = load_bmp( platform_api, path_test_bg ); - StrPath path_mojito; + StrPath path_mojito {}; path_mojito.concat( platform_api->path_content, str_ascii("mojito.bmp") ); game_state->mojito = load_bmp( platform_api, path_mojito ); - StrPath path_mojito_head; + StrPath path_mojito_head {}; path_mojito_head.concat( platform_api->path_content, str_ascii("mojito_head.bmp") ); game_state->mojito_head = load_bmp( platform_api, path_mojito_head ); - StrPath path_debug_bitmap; + StrPath path_debug_bitmap {}; path_debug_bitmap.concat( platform_api->path_content, str_ascii("debug_bitmap2.bmp") ); game_state->debug_bitmap = load_bmp( platform_api, path_debug_bitmap ); } @@ -638,19 +638,69 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* path_test_bg_hh.concat( platform_api->path_content, str_ascii("offical/test/test_background.bmp")); game_state->test_bg_hh = load_bmp( platform_api, path_test_bg_hh ); - StrPath path_hero_front_head; - path_hero_front_head.concat( platform_api->path_content, str_ascii("offical/test/test_hero_front_head.bmp")); - game_state->hero_front_head = load_bmp( platform_api, path_hero_front_head ); + #define path_test "offical\\test\\" + constexpr char const subpath_hero_front_head[] = path_test "test_hero_front_head.bmp"; + constexpr char const subpath_hero_back_head [] = path_test "test_hero_back_head.bmp"; + constexpr char const subpath_hero_right_head[] = path_test "test_hero_right_head.bmp"; + constexpr char const subpath_hero_left_head [] = path_test "test_hero_left_head.bmp"; - StrPath path_hero_front_cape; - path_hero_front_cape.concat( platform_api->path_content, str_ascii("offical/test/test_hero_front_cape.bmp")); - game_state->hero_front_cape = load_bmp( platform_api, path_hero_front_cape ); + constexpr char const subpath_hero_front_cape[] = path_test "test_hero_front_cape.bmp"; + constexpr char const subpath_hero_back_cape [] = path_test "test_hero_back_cape.bmp"; + constexpr char const subpath_hero_left_cape [] = path_test "test_hero_left_cape.bmp"; + constexpr char const subpath_hero_right_cape[] = path_test "test_hero_right_cape.bmp"; - StrPath path_hero_front_torso; - path_hero_front_torso.concat( platform_api->path_content, str_ascii("offical/test/test_hero_front_torso.bmp")); - game_state->hero_front_torso = load_bmp( platform_api, path_hero_front_torso ); + constexpr char const subpath_hero_front_torso[] = path_test "test_hero_front_torso.bmp"; + constexpr char const subpath_hero_back_torso [] = path_test "test_hero_back_torso.bmp"; + constexpr char const subpath_hero_left_torso [] = path_test "test_hero_left_torso.bmp"; + constexpr char const subpath_hero_right_torso[] = path_test "test_hero_right_torso.bmp"; + #undef path_test + + #define load_bmp_asset( sub_path, container ) \ + { \ + StrPath path {}; \ + path.concat( platform_api->path_content, str_ascii( sub_path ) ); \ + container = load_bmp( platform_api, path ); \ + } + + using hh::HeroBitmaps_Front; + using hh::HeroBitmaps_Back; + using hh::HeroBitmaps_Left; + using hh::HeroBitmaps_Right; + + load_bmp_asset( subpath_hero_front_head, game_state->hero_bitmaps[HeroBitmaps_Front].head ); + load_bmp_asset( subpath_hero_back_head, game_state->hero_bitmaps[HeroBitmaps_Back ].head ); + load_bmp_asset( subpath_hero_left_head, game_state->hero_bitmaps[HeroBitmaps_Left ].head ); + load_bmp_asset( subpath_hero_right_head, game_state->hero_bitmaps[HeroBitmaps_Right].head ); + + load_bmp_asset( subpath_hero_front_cape, game_state->hero_bitmaps[HeroBitmaps_Front].cape ); + load_bmp_asset( subpath_hero_back_cape, game_state->hero_bitmaps[HeroBitmaps_Back ].cape ); + load_bmp_asset( subpath_hero_left_cape, game_state->hero_bitmaps[HeroBitmaps_Left ].cape ); + load_bmp_asset( subpath_hero_right_cape, game_state->hero_bitmaps[HeroBitmaps_Right].cape ); + + load_bmp_asset( subpath_hero_front_torso, game_state->hero_bitmaps[HeroBitmaps_Front].torso ); + load_bmp_asset( subpath_hero_back_torso, game_state->hero_bitmaps[HeroBitmaps_Back ].torso ); + load_bmp_asset( subpath_hero_left_torso, game_state->hero_bitmaps[HeroBitmaps_Left ].torso ); + load_bmp_asset( subpath_hero_right_torso, game_state->hero_bitmaps[HeroBitmaps_Right].torso ); + + s32 align_x = 0; + s32 align_y = 76; + game_state->hero_bitmaps[HeroBitmaps_Front].align_x = align_x; + game_state->hero_bitmaps[HeroBitmaps_Back ].align_x = align_x; + game_state->hero_bitmaps[HeroBitmaps_Left ].align_x = align_x; + game_state->hero_bitmaps[HeroBitmaps_Right].align_x = align_x; + game_state->hero_bitmaps[HeroBitmaps_Front].align_y = align_y; + game_state->hero_bitmaps[HeroBitmaps_Back ].align_y = align_y; + game_state->hero_bitmaps[HeroBitmaps_Left ].align_y = align_y; + game_state->hero_bitmaps[HeroBitmaps_Right].align_y = align_y; + + #undef load_bmp_asset + + game_state->hero_direction = HeroBitmaps_Front; } + game_state->camera_pos.tile_x = state->world->tiles_per_screen_x / 2; + game_state->camera_pos.tile_y = state->world->tiles_per_screen_y / 2; + hh::PlayerState* player = & game_state->player_state; player->position.tile_x = 4; player->position.tile_y = 4; @@ -822,6 +872,12 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back f32 player_half_width = player->width / 2.f; f32 player_quarter_height = player->height / 4.f; + using hh::EHeroBitmapsDirection; + using hh::HeroBitmaps_Front; + using hh::HeroBitmaps_Back; + using hh::HeroBitmaps_Left; + using hh::HeroBitmaps_Right; + input_poll_player_actions( input, & player_actions ); { f32 move_speed = 6.f; @@ -848,8 +904,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back b32 valid_new_pos = true; { TileMapPosition test_pos = { - new_player_pos_x, new_player_pos_y, - player->position.tile_x, player->position.tile_y, player->position.tile_z + new_player_pos_x, new_player_pos_y, + player->position.tile_x, player->position.tile_y, player->position.tile_z }; test_pos = recannonicalize_position( tile_map, test_pos ); @@ -886,10 +942,9 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back if ( valid_new_pos ) { - TileMapPosition new_pos = { - new_player_pos_x, new_player_pos_y, - player->position.tile_x, player->position.tile_y, player->position.tile_z + new_player_pos_x, new_player_pos_y, + player->position.tile_x, player->position.tile_y, player->position.tile_z }; new_pos = recannonicalize_position( tile_map, new_pos ); @@ -909,6 +964,23 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back } player->position = new_pos; + + if ( player_actions.player_y_move_digital > 0 || player_actions.player_y_move_analog > 0 ) + { + game_state->hero_direction = HeroBitmaps_Back; + } + if ( player_actions.player_y_move_digital < 0 || player_actions.player_y_move_analog < 0 ) + { + game_state->hero_direction = HeroBitmaps_Front; + } + if ( player_actions.player_x_move_digital > 0 || player_actions.player_x_move_analog > 0 ) + { + game_state->hero_direction = HeroBitmaps_Right; + } + if ( player_actions.player_x_move_digital < 0 || player_actions.player_x_move_analog < 0 ) + { + game_state->hero_direction = HeroBitmaps_Left; + } } if ( player->jump_time > 0.f ) @@ -926,25 +998,46 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back player->jump_time = 1.f; player->mid_jump = true; } + + TileMapPosition player_to_camera = subtract( player->position, game_state->camera_pos ); + + game_state->camera_pos.tile_z = player->position.tile_z; + + if ( player_to_camera.tile_x > world->tiles_per_screen_x / 2 ) + { + game_state->camera_pos.tile_x += world->tiles_per_screen_x; + } + if ( player_to_camera.tile_y > world->tiles_per_screen_y / 2 ) + { + game_state->camera_pos.tile_y += world->tiles_per_screen_y; + } + if ( player_to_camera.tile_x < -world->tiles_per_screen_x / 2 ) + { + game_state->camera_pos.tile_x -= world->tiles_per_screen_x; + } + if ( player_to_camera.tile_y < -world->tiles_per_screen_y / 2 ) + { + game_state->camera_pos.tile_y -= world->tiles_per_screen_y; + } } + draw_rectangle( back_buffer , 0.f, 0.f , scast(f32, back_buffer->width), scast(f32, back_buffer->height) , 1.f, 0.24f, 0.24f ); + draw_bitmap( back_buffer + , scast(f32, back_buffer->width) / 2.f, scast(f32, back_buffer->height) / 2.f + , & game_state->test_bg + ); draw_bitmap( back_buffer , scast(f32, back_buffer->width) / 2.f, scast(f32, back_buffer->height) / 2.f , & game_state->test_bg_hh ); - draw_bitmap( back_buffer - , scast(f32, back_buffer->width) / 2.5f, scast(f32, back_buffer->height) / 2.5f - , & game_state->hero_front_head - ); - -// Scrolling +// Screen Camera f32 screen_center_x = 0.5f * scast(f32, back_buffer->width); f32 screen_center_y = 0.5f * scast(f32, back_buffer->height); @@ -952,13 +1045,14 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back { for ( s32 relative_col = -20; relative_col < +20; ++ relative_col ) { - u32 col = player->position.tile_x + relative_col; - u32 row = player->position.tile_y + relative_row; + s32 col = game_state->camera_pos.tile_x + relative_col; + s32 row = game_state->camera_pos.tile_y + relative_row; - u32 tile_id = TileMap_get_tile_value( tile_map, col, row, player->position.tile_z ); + s32 tile_id = TileMap_get_tile_value( tile_map, col, row, game_state->camera_pos.tile_z ); f32 color[3] = { 0.15f, 0.15f, 0.15f }; if ( tile_id > 1 || row == player->position.tile_y && col == player->position.tile_x ) +// if ( tile_id > 1 ) { if ( tile_id == 2 ) { @@ -986,8 +1080,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back color[2] = 0.3f; } - f32 center_x = screen_center_x + scast(f32, relative_col) * tile_size_in_pixels - player->position.x * world->tile_meters_to_pixels; - f32 center_y = screen_center_y - scast(f32, relative_row) * tile_size_in_pixels + player->position.y * world->tile_meters_to_pixels; + f32 center_x = screen_center_x + scast(f32, relative_col) * tile_size_in_pixels - game_state->camera_pos.x * world->tile_meters_to_pixels; + f32 center_y = screen_center_y - scast(f32, relative_row) * tile_size_in_pixels + game_state->camera_pos.y * world->tile_meters_to_pixels; f32 min_x = center_x - tile_size_in_pixels * 0.5f; f32 min_y = center_y - tile_size_in_pixels * 0.5f; @@ -1024,21 +1118,39 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back f32 player_green = 0.7f; f32 player_blue = 0.3f; - f32 player_tile_x_offset = screen_center_x + scast(f32, player->position.tile_x) * world->tile_meters_to_pixels + player->position.x * world->tile_meters_to_pixels; - f32 player_tile_y_offset = screen_center_y - scast(f32, player->position.tile_y) * world->tile_meters_to_pixels + player->position.y * world->tile_meters_to_pixels; + TileMapPosition player_to_camera = subtract( player->position, game_state->camera_pos ); - f32 player_screen_pos_x = screen_center_x; - f32 player_screen_pos_y = screen_center_y; + f32 offcenter_amount_x = player_to_camera.x + scast(f32, player_to_camera.tile_x) * world->tile_map->tile_size_in_meters; + f32 offcenter_amount_y = player_to_camera.y + scast(f32, player_to_camera.tile_y) * world->tile_map->tile_size_in_meters; + offcenter_amount_x *= world->tile_meters_to_pixels; + offcenter_amount_y *= world->tile_meters_to_pixels * -1; + + f32 player_ground_pos_x = screen_center_x + offcenter_amount_x; + f32 player_ground_pos_y = screen_center_y + offcenter_amount_y; + + hh::HeroBitmaps* hero_bitmaps = & game_state->hero_bitmaps[game_state->hero_direction]; + +#if 1 + draw_rectangle( back_buffer + , player_ground_pos_x - player_half_width * world->tile_meters_to_pixels, player_ground_pos_y - player->height * world->tile_meters_to_pixels + , player_ground_pos_x + player_half_width * world->tile_meters_to_pixels, player_ground_pos_y + , player_red, player_green, player_blue ); +#endif draw_bitmap( back_buffer - , player_screen_pos_x, player_screen_pos_y - , & game_state->mojito_head ); - + , player_ground_pos_x, player_ground_pos_y - scast(f32, hero_bitmaps->align_y) + , & hero_bitmaps->torso ); + draw_bitmap( back_buffer + , player_ground_pos_x, player_ground_pos_y - scast(f32, hero_bitmaps->align_y) + , & hero_bitmaps->cape ); #if 0 - draw_rectangle( back_buffer - , player_screen_pos_x - player_half_width * world->tile_meters_to_pixels, player_screen_pos_y - player->height * world->tile_meters_to_pixels - , player_screen_pos_x + player_half_width * world->tile_meters_to_pixels, player_screen_pos_y - , player_red, player_green, player_blue ); + draw_bitmap( back_buffer + , player_ground_pos_x, player_ground_pos_y - 45.f + , & game_state->mojito_head ); +#else + draw_bitmap( back_buffer + , player_ground_pos_x, player_ground_pos_y - scast(f32, hero_bitmaps->align_y) + , & hero_bitmaps->head ); #endif // Auto-Snapshot percent bar diff --git a/project/engine/engine.hpp b/project/engine/engine.hpp index 7c9dde2..009e9e6 100644 --- a/project/engine/engine.hpp +++ b/project/engine/engine.hpp @@ -177,6 +177,9 @@ struct World f32 tile_meters_to_pixels; s32 tile_size_in_pixels; + + s32 tiles_per_screen_x; + s32 tiles_per_screen_y; TileMap* tile_map; }; diff --git a/project/engine/tile_map.cpp b/project/engine/tile_map.cpp index b439c6b..061b42a 100644 --- a/project/engine/tile_map.cpp +++ b/project/engine/tile_map.cpp @@ -4,9 +4,24 @@ NS_ENGINE_BEGIN +inline +TileMapPosition subtract( TileMapPosition pos_a, TileMapPosition pos_b ) +{ + TileMapPosition result { + pos_a.x - pos_b.x, + pos_a.y - pos_b.y, + pos_a.tile_x - pos_b.tile_x, + pos_a.tile_y - pos_b.tile_y, + + // TODO(Ed) : Think about how to handle z... + pos_a.tile_z - pos_b.tile_z + }; + return result; +} + // TODO(Ed) : Consider moving (Casey wants to) inline -void cannonicalize_coord( TileMap* tile_map, u32* tile_coord, f32* pos_coord ) +void cannonicalize_coord( TileMap* tile_map, s32* tile_coord, f32* pos_coord ) { assert( tile_map != nullptr ); assert( tile_coord != nullptr ); @@ -15,7 +30,7 @@ void cannonicalize_coord( TileMap* tile_map, u32* tile_coord, f32* pos_coord ) // Note(Ed) : World is assumed to be a "torodial topology" s32 offset = round( (* pos_coord) / tile_size ); - u32 new_tile_coord = (* tile_coord) + offset; + s32 new_tile_coord = (* tile_coord) + offset; f32 new_pos_coord = (* pos_coord) - scast(f32, offset) * tile_size; assert( new_pos_coord >= -tile_size * 0.5f ); @@ -38,9 +53,9 @@ TileMapPosition recannonicalize_position( TileMap* tile_map, TileMapPosition pos } inline -u32 TileChunk_get_tile_value( TileChunk* tile_chunk, TileMap* tile_map, u32 x, u32 y ) +u32 TileChunk_get_tile_value( TileChunk* tile_chunk, TileMap* tile_map, s32 x, s32 y ) { - assert( tile_map != nullptr ); + assert( tile_map != nullptr ); assert( tile_chunk != nullptr ); assert( x < tile_map->chunk_dimension ); assert( y < tile_map->chunk_dimension ); @@ -50,7 +65,7 @@ u32 TileChunk_get_tile_value( TileChunk* tile_chunk, TileMap* tile_map, u32 x, u } inline -void TileChunk_set_tile_value( TileChunk* tile_chunk, TileMap* tile_map, u32 x, u32 y, u32 value) +void TileChunk_set_tile_value( TileChunk* tile_chunk, TileMap* tile_map, s32 x, s32 y, s32 value) { assert( tile_map != nullptr ); assert( tile_chunk != nullptr ); @@ -130,7 +145,7 @@ b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPosition position ) } internal -void TileMap_set_tile_value( MemoryArena* arena, TileMap* tile_map, u32 abs_tile_x, u32 abs_tile_y, u32 abs_tile_z, u32 value ) +void TileMap_set_tile_value( MemoryArena* arena, TileMap* tile_map, s32 abs_tile_x, s32 abs_tile_y, s32 abs_tile_z, s32 value ) { TileChunkPosition chunk_pos = get_tile_chunk_position_for( tile_map, abs_tile_x, abs_tile_y, abs_tile_z ); TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y, chunk_pos.tile_chunk_z ); @@ -140,7 +155,7 @@ void TileMap_set_tile_value( MemoryArena* arena, TileMap* tile_map, u32 abs_tile if ( chunk->tiles == nullptr ) { ssize num_tiles = tile_map->chunk_dimension * tile_map->chunk_dimension; - chunk->tiles = arena->push_array( u32, num_tiles ); + chunk->tiles = arena->push_array( s32, num_tiles ); for ( ssize tile_index = 0; tile_index < num_tiles; ++ tile_index ) { diff --git a/project/engine/tile_map.hpp b/project/engine/tile_map.hpp index ae67761..c82999c 100644 --- a/project/engine/tile_map.hpp +++ b/project/engine/tile_map.hpp @@ -11,9 +11,11 @@ NS_ENGINE_BEGIN +// TODO(Ed) : I switch the tile coordinates to signed values, I'm clamping rn to force positive + struct TileChunk { - u32* tiles; + s32* tiles; }; /* @@ -21,14 +23,14 @@ struct TileChunk */ struct TileChunkPosition { - u32 tile_chunk_x; - u32 tile_chunk_y; - u32 tile_chunk_z; + s32 tile_chunk_x; + s32 tile_chunk_y; + s32 tile_chunk_z; // "Chunk-relative (x, y) - u32 tile_x; - u32 tile_y; + s32 tile_x; + s32 tile_y; }; struct TileMap @@ -41,9 +43,9 @@ struct TileMap f32 tile_size_in_meters; // TODO(Ed) : Real sparseness ? (not use the giant pointer array) - u32 chunk_shift; - u32 chunk_mask; - u32 chunk_dimension; + s32 chunk_shift; + s32 chunk_mask; + s32 chunk_dimension; TileChunk* chunks; }; @@ -58,9 +60,9 @@ struct TileMapPosition // Fixed point tile locations. // High bits are the tile-chunk index, and the low bits are the tile index in the chunk. - u32 tile_x; - u32 tile_y; - u32 tile_z; + s32 tile_x; + s32 tile_y; + s32 tile_z; }; NS_ENGINE_END diff --git a/project/handmade.hpp b/project/handmade.hpp index 2e1cad0..8b3ea38 100644 --- a/project/handmade.hpp +++ b/project/handmade.hpp @@ -91,21 +91,43 @@ struct PlayerActions b32 jump; }; +enum EHeroBitmapsDirection : u32 +{ + HeroBitmaps_Front, + HeroBitmaps_Back, + HeroBitmaps_Left, + HeroBitmaps_Right +}; + +struct HeroBitmaps +{ + using Bitmap = engine::Bitmap; + + s32 align_x; + s32 align_y; + + Bitmap head; + Bitmap cape; + Bitmap torso; +}; + struct GameState { PlayerState player_state; - + using Bitmap = engine::Bitmap; - + Bitmap debug_bitmap; Bitmap test_bg; Bitmap mojito; Bitmap mojito_head; - + Bitmap test_bg_hh; - Bitmap hero_front_head; - Bitmap hero_front_cape; - Bitmap hero_front_torso; + + engine::TileMapPosition camera_pos; + + EHeroBitmapsDirection hero_direction; + HeroBitmaps hero_bitmaps[4]; }; NS_HANDMADE_END