diff --git a/.gitignore b/.gitignore index b44ee16..1fd05e2 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,8 @@ build **/*.dll **/*.exe **/*.pdb -**/*.exe +**/*.exp +**/*.lib **/*.hmi **/*.symbols diff --git a/README.md b/README.md index d3bb39c..4b00717 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,19 @@ # HandmadeHero -Any code I do for this [series](https://handmadehero.org) will be here. +Any code I do for this [series](https://handmadehero.org) will be here. ***(Only original hand-written code will be here, no code from the series itself)*** ## Scripts -* `build.ps1` - Builds the project use `.\scripts\build msvc debug` or `.\scripts\build clang debug`. +* `build.ps1` - Builds the project use `.\scripts\build msvc ` or `.\scripts\build clang ` + * `debug` adds debug symbols, etc + * `dev` for development builds. (automatically adds debug) * `optimize` for optimized builds. - * `dev` for development builds. ( Dev memory layout and code paths compiled ). + * `verbose` gives more info on arguments passed to tools, etc. + * `module` is the module to build, can be any of `platform` or `engine` for this point in the codebase. (Eventually game will also be a separate module) * `clean.ps1` - Cleans the project -* `update_deps.ps1` - Updates the project dependencies to their latest from their respective repos. (Not done automatically on build) +* `update_deps.ps1` - Updates the project dependencies to their latest from their respective repos. *Make sure to run `update_deps.ps1` before building for the first time.* @@ -20,17 +23,45 @@ Building requires msvc or llvm's clang + lld, and powershell 7 The build is done in two stages: -1. ~~Build and run metaprogram to scan and generate dependent code.~~ (Not needed yet) -2. Build the handmade hero runtime. +1. Build and run metaprogram to scan and generate dependent code for the module being built. +2. Build the the runtime for the module. + +Module build order: + +1. Engine +2. Platform ## Milestone -Day 028: Drawing a Tile Map +Day 30 : Moving Between Tile Maps + +Features Done so far: + +* Tailor made build system via powershell scripts + * Supports building the repo with msvc or clang + * Can stage codegen metaprograms to run before building the module + * Will automatically not run if app process is found (for engine module). + * Can emit exported mangled symbols for the engine module for hot-reload with the platform module without needing to use C linkage symbols or a complex hot-reload library (Live++, etc). +* Platform Layer: + * Direct Sound audio + * Keyboard & Mouse Input via GetAsyncKeyState & Win32 window messagng + * XInput controller support + * Dualsense controller support via joyshock library + * Software rendering via Win32 GDI + * Instantaneous hot reload of engine module + * Block Memory allocation via VirtualAlloc for engine module + * Memory mapped files for engine & game snapshots. +* Engine Layer: + * Take & load snapshots of either the engine's or game's memory state. + * Allows for engine or game state to be restored even if a crash occurs to exact memory state it was before. + * Basic input abstraction into hard-coded actions (``EngineActions` & `PlayerActions`) + * Record & replay input. + * (WIP) : 2D Tile Map setup ## Gallery ![img](docs/imgs/handmade_win32_2023-10-01_20-22-20.gif) +![img](docs/imgs/Code_2023-10-01_19-20-56.gif) ![img](docs/imgs/Code_2023-09-28_15-14-53.gif) -![img](https://files.catbox.moe/ruv97s.gif) ![img](https://files.catbox.moe/9zau4s.png) ![img](https://files.catbox.moe/b7ifa8.png) diff --git a/docs/Day 030.md b/docs/Day 030.md new file mode 100644 index 0000000..02c5132 --- /dev/null +++ b/docs/Day 030.md @@ -0,0 +1,7 @@ +# Day 30 + +Tile map stuff is looking alright. Doing my best to not clean-up the code as Casey pleads in the vods. + +I would have perferred if he didn't just do one tilemap at a time and instead I would have had the current tile map and surrounding loaded at the same time (He might do this in the future). Since were aren't constrained memory wise like the old machines, we could have those loaded as well and it would make the management of the tilemaps easier (possibly...). + +Looking foward to when he introduces a proper vector space for the positioning. diff --git a/docs/imgs/Code_2023-10-01_19-20-56.gif b/docs/imgs/Code_2023-10-01_19-20-56.gif new file mode 100644 index 0000000..88c7333 Binary files /dev/null and b/docs/imgs/Code_2023-10-01_19-20-56.gif differ diff --git a/project/engine/engine.cpp b/project/engine/engine.cpp index 8d87dd5..bd606a6 100644 --- a/project/engine/engine.cpp +++ b/project/engine/engine.cpp @@ -382,6 +382,13 @@ output_sound( EngineState* state, AudioBuffer* sound_buffer, GetSoundSampleValue } } +inline +s32 floor_f32_to_s32( f32 value ) +{ + // TODO : Casey wants to use an intrinsic + return scast(s32, floorf( value )); +} + inline s32 round_f32_to_s32( f32 value ) { @@ -472,7 +479,7 @@ void startup( Memory* memory, platform::ModuleAPI* platform_api ) EngineState* state = rcast( EngineState*, memory->persistent ); assert( sizeof(EngineState) <= memory->persistent_size ); - state->auto_snapshot_interval = 10.f; + state->auto_snapshot_interval = 60.f; state->tone_volume = 1000; @@ -489,15 +496,17 @@ void startup( Memory* memory, platform::ModuleAPI* platform_api ) state->game_memory.transient_size = memory->transient_size / 2; state->game_memory.transient = rcast(Byte*, memory->transient) + state->game_memory.transient_size; - hh::PlayerState* player = rcast( hh::PlayerState*, state->game_memory.persistent ); - assert( sizeof(hh::PlayerState) <= state->game_memory.persistent_size ); + hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent ); + assert( sizeof(hh::GameState) <= state->game_memory.persistent_size ); - player->width = 50.f; - player->height = 100.f; - player->pos_x = 920; - player->pos_y = 466; - player->mid_jump = false; - player->jump_time = 0.f; + game_state->tile_map_x = 0; + game_state->tile_map_y = 0; + + hh::PlayerState* player = & game_state->player_state; + player->pos_x = 920; + player->pos_y = 466; + player->mid_jump = false; + player->jump_time = 0.f; } Engine_API @@ -506,45 +515,110 @@ void shutdown( Memory* memory, platform::ModuleAPI* platform_api ) } inline -u32 tilemap_tile_value( TileMap* tile_map, s32 x, s32 y ) +CanonPosition get_cannonical_position( World* world, RawPosition raw_pos ) { - assert( x >= 0 && x < scast(s32, tile_map->num_x) ); - assert( y >= 0 && y < scast(s32, tile_map->num_y) ); - return tile_map->tiles[ (y * tile_map->num_x) + x ]; + s32 tile_map_x = raw_pos.tile_map_x; + s32 tile_map_y = raw_pos.tile_map_y; + + f32 pos_x = ( raw_pos.x - world->tile_upper_left_x ); + f32 pos_y = ( raw_pos.y - world->tile_upper_left_y ); + + s32 tile_x = floor_f32_to_s32( pos_x / world->tile_width ); + s32 tile_y = floor_f32_to_s32( pos_y / world->tile_height ); + + f32 tile_rel_x = pos_x - scast(f32, tile_x) * world->tile_width; + f32 tile_rel_y = pos_y - scast(f32, tile_y) * world->tile_height; + + assert( tile_rel_x >= 0.f ); + assert( tile_rel_y >= 0.f ); + assert( tile_rel_x < world->tile_width ); + assert( tile_rel_y < world->tile_height ); + + /* + The puprpose of this is to be able to detect if the point is outside of the tilemap, + and if so, roll the point over to an adjacent tilemap. + + For example : If the point is at x = -1, then it is outside of the tilemap, and + should be rolled over to the tilemap to the left of the current tilemap. + */ + if ( tile_x < 0 ) + { + tile_x += world->num_tiles_x; + -- tile_map_x; + } + if ( tile_y < 0 ) + { + tile_y += world->num_tiles_y; + -- tile_map_y; + } + if ( tile_x >= world->num_tiles_x ) + { + tile_x -= world->num_tiles_x; + ++ tile_map_x; + } + if ( tile_y >= world->num_tiles_y ) + { + tile_y -= world->num_tiles_y; + ++ tile_map_y; + } + + return { tile_rel_x, tile_rel_y, tile_map_x, tile_map_y, tile_x, tile_y }; } inline -b32 tilemap_is_pos_empty( TileMap* tile_map, f32 x, f32 y ) +u32 tilemap_tile_value( TileMap* tile_map, World* world, s32 x, s32 y ) { - s32 tile_x = truncate_f32_to_s32(( x - scast(f32, tile_map->upper_left_X)) / scast(f32, tile_map->width) ); - s32 tile_y = truncate_f32_to_s32(( y - scast(f32, tile_map->upper_left_Y)) / scast(f32, tile_map->height) ); + assert( tile_map != nullptr ); + assert( world != nullptr ); + assert( x >= 0 && x < scast(s32, world->num_tiles_x) ); + assert( y >= 0 && y < scast(s32, world->num_tiles_y) ); + return tile_map->tiles[ (y * world->num_tiles_x) + x ]; +} + +inline +b32 tilemap_is_point_empty( TileMap* tile_map, World* world, s32 tile_x, s32 tile_y ) +{ + assert( tile_map != nullptr ); + assert( world != nullptr ); + + // Assume space is occupied if there is bad data + if ( tile_map == nullptr ) + return false; b32 is_empty = false; - if ( tile_x >= 0 && tile_x < scast(s32, tile_map->num_x) - && tile_y >= 0 && tile_y < scast(s32, tile_map->num_y) ) + if ( tile_x >= 0 && tile_x < world->num_tiles_x + && tile_y >= 0 && tile_y < world->num_tiles_y ) { - u32 tile_value = tilemap_tile_value( tile_map, tile_x, tile_y ); + u32 tile_value = tilemap_tile_value( tile_map, world, tile_x, tile_y ); is_empty = tile_value == 0; } return is_empty; } inline -TileMap* world_tilemap( World* world, s32 x, s32 y ) +TileMap* world_get_tilemap( World* world, s32 tile_map_x, s32 tile_map_y ) { - assert( x >= 0 && x < world->tilemaps_num_x ); - assert( y >= 0 && y < world->tilemaps_num_y ); - return & world->tile_maps[ (y * world->tilemaps_num_x) + x ]; + assert( tile_map_x >= 0 && tile_map_x < world->tilemaps_num_x ); + assert( tile_map_y >= 0 && tile_map_y < world->tilemaps_num_y ); + return & world->tile_maps[ (tile_map_y * world->tilemaps_num_x) + tile_map_x ]; } internal -b32 world_is_pos_empty( World* world, s32 tm_x, s32 tm_y, f32 x, f32 y ) +b32 world_is_point_empty( World* world, RawPosition raw_pos ) { - return false; + assert( world != nullptr ); + + b32 is_empty = false; + + CanonPosition position = get_cannonical_position( world, raw_pos ); + + TileMap* tile_map = world_get_tilemap( world, position.tile_map_x, position.tile_map_y ); + is_empty = tilemap_is_point_empty( tile_map, world, position.tile_x, position.tile_y ); + + return is_empty; } Engine_API -// TODO : I rather expose the back_buffer and sound_buffer using getters for access in any function. void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back_buffer , Memory* memory, platform::ModuleAPI* platform_api, ThreadContext* thread ) { @@ -684,11 +758,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back } #endif - hh::PlayerState* player = rcast( hh::PlayerState*, state->game_memory.persistent ); - assert( sizeof(hh::PlayerState) <= state->game_memory.persistent_size ); - - f32 half_width = player->width / 2.f; - f32 quater_height = player->height / 4.f; + hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent ); + hh::PlayerState* player = & game_state->player_state; f32 x_offset_f = scast(f32, state->x_offset); f32 y_offset_f = scast(f32, state->y_offset); @@ -696,70 +767,83 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back constexpr s32 tile_map_num_x = 16; constexpr s32 tile_map_num_y = 9; + // tiles_XY u32 tiles_00 [tile_map_num_y][tile_map_num_x] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, }; + u32 tiles_10 [tile_map_num_y][tile_map_num_x] = { + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + }; u32 tiles_01 [tile_map_num_y][tile_map_num_x] = { { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, }; - u32 tiles_10 [tile_map_num_y][tile_map_num_x] = { - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + u32 tiles_11 [tile_map_num_y][tile_map_num_x] = { + { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - }; - u32 tiles_11 [tile_map_num_y][tile_map_num_x] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, }; TileMap tile_maps[2][2] {}; - tile_maps[0][0].upper_left_X = 0; - tile_maps[0][0].upper_left_Y = 0; - tile_maps[0][0].width = 80; - tile_maps[0][0].height = 80; - tile_maps[0][0].num_x = tile_map_num_x; - tile_maps[0][0].num_y = tile_map_num_y; - tile_maps[0][0].tiles = rcast(u32*, tiles_00); - - tile_maps[0][1] = tile_maps[0][0]; - tile_maps[0][1].tiles = rcast(u32*, tiles_01); - - tile_maps[1][0] = tile_maps[0][0]; - tile_maps[1][0].tiles = rcast(u32*, tiles_10); - - tile_maps[1][1] = tile_maps[0][0]; + tile_maps[0][0].tiles = rcast(u32*, tiles_00); + tile_maps[0][1].tiles = rcast(u32*, tiles_10); + tile_maps[1][0].tiles = rcast(u32*, tiles_01); tile_maps[1][1].tiles = rcast(u32*, tiles_11); - s32 current_tile_map_id[2] = { 0, 0 }; - TileMap* current_tile_map = & tile_maps[current_tile_map_id[0] ][current_tile_map_id[1] ]; + World world; + world.num_tiles_x = tile_map_num_x; + world.num_tiles_y = tile_map_num_y; + + f32 scale = 85; + + world.tile_width = scale; + world.tile_height = scale * 1.05f; + + world.tile_upper_left_x = -(world.tile_width * 0.5f); + world.tile_upper_left_y = -(world.tile_height * 0.5f); + + world.tilemaps_num_x = 2; + world.tilemaps_num_y = 2; + + world.tile_maps = rcast(TileMap*, tile_maps); + + TileMap* current_tile_map = world_get_tilemap( & world, game_state->tile_map_x, game_state->tile_map_y ); + assert( current_tile_map != nullptr ); + + player->width = world.tile_width * 0.75f; + player->height = world.tile_height; + + f32 player_half_width = player->width / 2.f; + f32 player_quarter_height = player->height / 4.f; input_poll_player_actions( input, & player_actions ); { @@ -779,16 +863,35 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back } new_player_pos_y += sinf( player->jump_time * TAU ) * 200.f * delta_time; - b32 valid_new_pos = - tilemap_is_pos_empty( current_tile_map, new_player_pos_x - half_width, new_player_pos_y - quater_height ) - && tilemap_is_pos_empty( current_tile_map, new_player_pos_x + half_width, new_player_pos_y - quater_height ) - && tilemap_is_pos_empty( current_tile_map, new_player_pos_x - half_width, new_player_pos_y ) - && tilemap_is_pos_empty( current_tile_map, new_player_pos_x + half_width, new_player_pos_y ); + b32 valid_new_pos = true; + { + RawPosition test_pos = { new_player_pos_x - player_half_width, new_player_pos_y - player_quarter_height, game_state->tile_map_x, game_state->tile_map_y }; + + valid_new_pos &= world_is_point_empty( & world, test_pos ); + + test_pos.x = new_player_pos_x + player_half_width; + valid_new_pos &= world_is_point_empty( & world, test_pos ); + + test_pos.x = new_player_pos_x - player_half_width; + test_pos.y = new_player_pos_y; + valid_new_pos &= world_is_point_empty( & world, test_pos ); + + test_pos.x = new_player_pos_x + player_half_width; + valid_new_pos &= world_is_point_empty( & world, test_pos ); + } if ( valid_new_pos ) { - player->pos_x = new_player_pos_x; - player->pos_y = new_player_pos_y; + RawPosition raw_pos = { new_player_pos_x, new_player_pos_y, game_state->tile_map_x, game_state->tile_map_y }; + CanonPosition canon_pos = get_cannonical_position( & world, raw_pos); + + game_state->tile_map_x = canon_pos.tile_map_x; + game_state->tile_map_y = canon_pos.tile_map_y; + + // current_tile_map = world_get_tilemap( & world, game_state->tile_map_x, game_state->tile_map_y ); + + player->pos_x = world.tile_upper_left_x + world.tile_width * scast(f32, canon_pos.tile_x) + canon_pos.x; + player->pos_y = world.tile_upper_left_y + world.tile_height * scast(f32, canon_pos.tile_y) + canon_pos.y; } // player_tile_x @@ -821,7 +924,7 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back { for ( s32 col = 0; col < 16; ++ col ) { - u32 tileID = tilemap_tile_value( & tile_maps[0][0], col, row ); + u32 tileID = tilemap_tile_value( current_tile_map, & world, col, row ); f32 grey[3] = { 0.15f, 0.15f, 0.15f }; if ( tileID == 1 ) @@ -831,10 +934,10 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back grey[2] = 0.22f; } - f32 min_x = current_tile_map->upper_left_X + scast(f32, col) * current_tile_map->width; - f32 min_y = current_tile_map->upper_left_Y + scast(f32, row) * current_tile_map->height; - f32 max_x = min_x + current_tile_map->width; - f32 max_y = min_y + current_tile_map->height; + f32 min_x = world.tile_upper_left_x + scast(f32, col) * world.tile_width; + f32 min_y = world.tile_upper_left_y + scast(f32, row) * world.tile_height; + f32 max_x = min_x + world.tile_width; + f32 max_y = min_y + world.tile_height; draw_rectangle( back_buffer , min_x, min_y @@ -849,8 +952,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back f32 player_blue = 0.3f; draw_rectangle( back_buffer - , player->pos_x - half_width, player->pos_y - player->height - , player->pos_x + half_width, player->pos_y + , player->pos_x - player_half_width, player->pos_y - player->height + , player->pos_x + player_half_width, player->pos_y , player_red, player_green, player_blue ); // Auto-Snapshot percent bar diff --git a/project/engine/engine.hpp b/project/engine/engine.hpp index 1047b1a..637e41a 100644 --- a/project/engine/engine.hpp +++ b/project/engine/engine.hpp @@ -277,20 +277,20 @@ struct RecordedInput struct TileMap { - f32 upper_left_X; - f32 upper_left_Y; - - f32 width; - f32 height; - - s32 num_x; - s32 num_y; - u32* tiles; }; struct World { + f32 tile_upper_left_x; + f32 tile_upper_left_y; + + f32 tile_width; + f32 tile_height; + + s32 num_tiles_x; // Number of tiles on the x-axis for a tilemap. + s32 num_tiles_y; // Number of tiles on the y-axis for a tilemap. + // TODO(Ed) : Beginner's sparseness s32 tilemaps_num_x; s32 tilemaps_num_y; @@ -298,4 +298,29 @@ struct World TileMap* tile_maps; }; +struct CanonPosition +{ + // Note: Tile-Relative position + // TODO(Ed) : These are still in pixels + f32 x; + f32 y; + + s32 tile_map_x; + s32 tile_map_y; + + s32 tile_x; + s32 tile_y; +}; + +// TODO(Ed) : Is this necessary? +struct RawPosition +{ + // Note: TileMap-Relative position + f32 x; + f32 y; + + s32 tile_map_x; + s32 tile_map_y; +}; + NS_ENGINE_END diff --git a/project/handmade.hpp b/project/handmade.hpp index 0e087cd..d2321d7 100644 --- a/project/handmade.hpp +++ b/project/handmade.hpp @@ -73,6 +73,7 @@ struct PlayerState f32 width; f32 height; + // TODO(Ed) : Should this be canonical position now? f32 pos_x; f32 pos_y; @@ -90,4 +91,12 @@ struct PlayerActions b32 jump = false; }; +struct GameState +{ + s32 tile_map_x; + s32 tile_map_y; + + PlayerState player_state; +}; + NS_HANDMADE_END diff --git a/project/platform/win32/win32.hpp b/project/platform/win32/win32.hpp index 1182e03..f4a2086 100644 --- a/project/platform/win32/win32.hpp +++ b/project/platform/win32/win32.hpp @@ -7,6 +7,7 @@ #pragma warning( disable: 5105 ) #pragma warning( disable: 4820 ) #define WIN32_LEAN_AND_MEAN +#define NOMINMAX #include #include #include diff --git a/project/platform/win32/win32_platform.cpp b/project/platform/win32/win32_platform.cpp index c9651bb..c3cd545 100644 --- a/project/platform/win32/win32_platform.cpp +++ b/project/platform/win32/win32_platform.cpp @@ -642,8 +642,8 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho } window_handle = CreateWindowExW( - WS_EX_LAYERED | WS_EX_TOPMOST, - // WS_EX_LAYERED, + // WS_EX_LAYERED | WS_EX_TOPMOST, + WS_EX_LAYERED, window_class.lpszClassName, L"Handmade Hero", WS_Overlapped_Window | WS_Initially_Visible, diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 95e9d1b..6a68fa6 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -1,6 +1,4 @@ -if ( $CursorPosition ) { - Clear-Host -} +Clear-Host $target_arch = Join-Path $PSScriptRoot 'helpers/target_arch.psm1' $devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1' @@ -8,13 +6,11 @@ $format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1' $config_toolchain = Join-Path $PSScriptRoot 'helpers/configure_toolchain.ps1' $path_root = git rev-parse --show-toplevel -$path_build = Join-Path $path_root 'build' +$path_build = Join-Path $path_root 'build' Import-Module $target_arch Import-Module $format_cpp -Push-Location $path_root - #region Arguments $vendor = $null $optimize = $null @@ -49,6 +45,8 @@ if ( $args ) { $args | ForEach-Object { . $config_toolchain #region Building +write-host "Building HandmadeHero with $vendor" + $path_project = Join-Path $path_root 'project' $path_data = Join-Path $path_root 'data' $path_binaries = Join-Path $path_data 'binaries' @@ -140,7 +138,7 @@ function build-engine $unit = Join-Path $path_project 'handmade_engine.cpp' $dynamic_library = Join-Path $path_binaries 'handmade_engine.dll' - build-simple $includes $compiler_args $linker_args $unit $dynamic_library + build-simple $path_build $includes $compiler_args $linker_args $unit $dynamic_library Remove-Item $path_pdb_lock -Force @@ -233,7 +231,7 @@ function build-engine $unit = Join-Path $path_codegen 'engine_postbuild_gen.cpp' $executable = Join-Path $path_build 'engine_postbuild_gen.exe' - build-simple $includes $compiler_args $linker_args $unit $executable + build-simple $path_build $includes $compiler_args $linker_args $unit $executable Push-Location $path_build $time_taken = Measure-Command { @@ -279,7 +277,7 @@ function build-platform $unit = Join-Path $path_codegen 'platform_gen.cpp' $executable = Join-Path $path_build 'platform_gen.exe' - build-simple $includes $compiler_args $linker_args $unit $executable + build-simple $path_build $includes $compiler_args $linker_args $unit $executable $path_build Push-Location $path_platform $time_taken = Measure-Command { @@ -308,14 +306,14 @@ function build-platform $lib_jsl, - $flag_link_win_subsystem_windows + $flag_link_win_subsystem_windows, $flag_link_optimize_references ) $unit = Join-Path $path_project 'handmade_win32.cpp' $executable = Join-Path $path_binaries 'handmade_win32.exe' - build-simple $includes $compiler_args $linker_args $unit $executable + build-simple $path_build $includes $compiler_args $linker_args $unit $executable # if ( Test-Path $executable ) # { diff --git a/scripts/handmade.rdbg b/scripts/handmade.rdbg index 14c6c47..e2544a7 100644 Binary files a/scripts/handmade.rdbg and b/scripts/handmade.rdbg differ diff --git a/scripts/helpers/configure_toolchain.ps1 b/scripts/helpers/configure_toolchain.ps1 index 48e6de1..02bb99f 100644 --- a/scripts/helpers/configure_toolchain.ps1 +++ b/scripts/helpers/configure_toolchain.ps1 @@ -7,11 +7,9 @@ if ($IsWindows) { if ( $vendor -eq $null ) { write-host "No vendor specified, assuming clang available" - $compiler = "clang" + $vendor = "clang" } -write-host "Building HandmadeHero with $vendor" - if ( $dev ) { if ( $debug -eq $null ) { $debug = $true @@ -133,6 +131,8 @@ if ( $vendor -match "clang" ) $flag_set_stack_size = '-stack=' $flag_syntax_only = '-fsyntax-only' $flag_target_arch = '-target' + $flag_time_trace = '-ftime-trace' + $flag_verbose = '-v' $flag_wall = '-Wall' $flag_warning = '-W' $flag_warnings_as_errors = '-Werror' @@ -155,16 +155,15 @@ if ( $vendor -match "clang" ) # 'libucrt', 'libcmt' # For the C Runtime (Static Linkage) ) - function build-simple { - param( [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) #Write-Host "build-simple: clang" $object = $unit -replace '\.cpp', '.obj' $map = $unit -replace '\.cpp', '.map' - $object = join-path $path_build (split-path $object -Leaf) - $map = join-path $path_build (split-path $map -Leaf) + $object = join-path $path_output (split-path $object -Leaf) + $map = join-path $path_output (split-path $map -Leaf) # The PDB file has to also be time-stamped so that we can reload the DLL at runtime $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" @@ -174,11 +173,15 @@ if ( $vendor -match "clang" ) $flag_exceptions_disabled, $flag_target_arch, $target_arch, $flag_wall, - $flag_preprocess_on_intergrated, + $flag_preprocess_non_intergrated, # $flag_section_data, # $flag_section_functions, ( $flag_path_output + $object ) ) + if ( $verbose ) { + # $compiler_args += $flag_verbose + # $compiler_args += $flag_time_trace + } if ( $optimize ) { $compiler_args += $flag_optimize_fast } @@ -278,13 +281,13 @@ if ( $vendor -match "msvc" ) # This works because this project uses a single unit to build function build-simple { - param( [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) #Write-Host "build-simple: msvc" $object = $unit -replace '\.(cpp)$', '.obj' $map = $unit -replace '\.(cpp)$', '.map' - $object = join-path $path_build (split-path $object -Leaf) - $map = join-path $path_build (split-path $map -Leaf) + $object = join-path $path_output (split-path $object -Leaf) + $map = join-path $path_output (split-path $map -Leaf) # The PDB file has to also be time-stamped so that we can reload the DLL at runtime $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" @@ -297,10 +300,13 @@ if ( $vendor -match "msvc" ) $flag_RTTI_disabled, $flag_preprocess_conform, $flag_full_src_path, - ( $flag_path_interm + $path_build + '\' ), - ( $flag_path_output + $path_build + '\' ) + ( $flag_path_interm + $path_output + '\' ), + ( $flag_path_output + $path_output + '\' ) ) + if ( $verbose ) { + } + if ( $optimize ) { $compiler_args += $flag_optimize_fast } @@ -312,7 +318,7 @@ if ( $vendor -match "msvc" ) { $compiler_args += $flag_debug $compiler_args += ( $flag_define + 'Build_Debug=1' ) - $compiler_args += ( $flag_path_debug + $path_build + '\' ) + $compiler_args += ( $flag_path_debug + $path_output + '\' ) $compiler_args += $flag_link_win_rt_static_debug if ( $optimize ) { diff --git a/scripts/helpers/format_cpp.psm1 b/scripts/helpers/format_cpp.psm1 index fdfc293..e975494 100644 --- a/scripts/helpers/format_cpp.psm1 +++ b/scripts/helpers/format_cpp.psm1 @@ -8,7 +8,7 @@ function format-cpp Write-Host "Beginning format" $formatParams = @( '-i' # In-place - '-style=file:./scripts/.clang-format' + '-style=file:.clang-format' '-verbose' )