diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index ec49ff9..3d06898 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -6,7 +6,7 @@ "${workspaceFolder}/project/", "${workspaceFolder}/project/dependencies/", "${workspaceFolder}/project/platform/", - "${workspaceFolder}/project/engine/", + "${workspaceFolder}/project/engine/" ], "defines": [ "_DEBUG", @@ -15,11 +15,11 @@ "GEN_TIME", "INTELLISENSE_DIRECTIVES", "Build_Debug", - "Build_Development", + "Build_Development" ], "windowsSdkVersion": "10.0.22621.0", "compilerPath": "cl.exe", - "intelliSenseMode": "msvc-x64", + "intelliSenseMode": "msvc-x64" }, { "name": "Win32 clang", @@ -27,19 +27,19 @@ "${workspaceFolder}/project/", "${workspaceFolder}/project/dependencies/", "${workspaceFolder}/project/platform/", - "${workspaceFolder}/project/engine/", + "${workspaceFolder}/project/engine/" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "GEN_TIME", - "INTELLISENSE_DIRECTIVES", + "INTELLISENSE_DIRECTIVES" ], "windowsSdkVersion": "10.0.22621.0", "compilerPath": "clang.exe", - "intelliSenseMode": "clang-x64", + "intelliSenseMode": "clang-x64" } ], "version": 4 -} +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 2761511..9c527e9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -78,7 +78,7 @@ }, "C_Cpp.intelliSenseEngineFallback": "disabled", "C_Cpp.errorSquiggles": "enabled", - "C_Cpp.default.compilerPath": "cl.exe", + "C_Cpp.default.compilerPath": "C:\\Users\\Ed\\scoop\\apps\\llvm\\current\\bin\\clang-cpp.exe", "C_Cpp.exclusionPolicy": "checkFilesAndFolders", "C_Cpp.files.exclude": { "**/.vscode": true, diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..7504a4c --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,23 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build development", + "type": "shell", + "command": "pwsh.exe", + "args": [ + "-NoProfile", + "-ExecutionPolicy", + "Bypass", + "-File", + "${workspaceFolder}/scripts/build.ps1", + "msvc", + "dev" + ], + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/HandmadeHero.10x b/HandmadeHero.10x index 767c7e4..d2692bb 100644 --- a/HandmadeHero.10x +++ b/HandmadeHero.10x @@ -8,8 +8,8 @@ true false false - pwsh -ExecutionPolicy Bypass -NoProfile -NonInteractive -File $(WorkspaceDirectory)/scripts/build.ps1 msvc dev engine - pwsh -ExecutionPolicy Bypass -NoProfile -NonInteractive -File $(WorkspaceDirectory)/scripts/build.ps1 msvc dev platform + pwsh -ExecutionPolicy Bypass -NoProfile -NonInteractive -File $(WorkspaceDirectory)/scripts/build.ps1 msvc dev + pwsh -ExecutionPolicy Bypass -NoProfile -NonInteractive -File $(WorkspaceDirectory)/scripts/rebuild.ps1 msvc dev pwsh -ExecutionPolicy Bypass -NoProfile -NonInteractive -File $(WorkspaceDirectory)/scripts/clean.ps1 diff --git a/docs/Day 032.md b/docs/Day 032.md new file mode 100644 index 0000000..8b803be --- /dev/null +++ b/docs/Day 032.md @@ -0,0 +1,3 @@ +# Day 32 + + diff --git a/project/engine/engine.cpp b/project/engine/engine.cpp index e7495fc..743fbb6 100644 --- a/project/engine/engine.cpp +++ b/project/engine/engine.cpp @@ -448,12 +448,14 @@ void startup( Memory* memory, platform::ModuleAPI* platform_api ) hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent ); assert( sizeof(hh::GameState) <= state->game_memory.persistent_size ); - 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->position.tile_map_x = 0; + player->position.tile_map_y = 0; + player->position.tile_x = 3; + player->position.tile_y = 3; + player->position.x = 0.f; + player->position.y = 0.f; + player->mid_jump = false; player->jump_time = 0.f; } @@ -464,56 +466,43 @@ void shutdown( Memory* memory, platform::ModuleAPI* platform_api ) } inline -CanonPosition get_cannonical_position( World* world, RawPosition raw_pos ) +void cannonicalize_coord( World* world, s32 num_tiles, s32* tile_map_coord, s32* tile_coord, f32* pos_coord ) { - s32 tile_map_x = raw_pos.tile_map_x; - s32 tile_map_y = raw_pos.tile_map_y; + s32 new_tile_map_coord = *tile_map_coord; + f32 tile_size = scast(f32, world->tile_size_in_meters); - f32 pos_x = ( raw_pos.x - world->tile_upper_left_x ); - f32 pos_y = ( raw_pos.y - world->tile_upper_left_y ); - - f32 tile_size = scast(f32, world->tile_size_in_pixels); + // TODO(Ed) : Need to use an alt method for reconnonicalizing because this can end up rounding back up to the tile. + // TODO(Ed) : Add bounds checking to prevent wrapping + s32 offset = floor_f32_to_s32( (* pos_coord) / tile_size ); + s32 new_tile_coord = (* tile_coord) + offset; + f32 new_pos_coord = (* pos_coord) - scast(f32, offset) * tile_size; - s32 tile_x = floor_f32_to_s32( pos_x / tile_size ); - s32 tile_y = floor_f32_to_s32( pos_y / tile_size ); + assert( new_pos_coord >= 0.f ); + assert( new_pos_coord < tile_size ); - f32 tile_rel_x = pos_x - scast(f32, tile_x) * tile_size; - f32 tile_rel_y = pos_y - scast(f32, tile_y) * tile_size; - - assert( tile_rel_x >= 0.f ); - assert( tile_rel_y >= 0.f ); - assert( tile_rel_x < tile_size ); - assert( tile_rel_y < tile_size ); - - /* - 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 ) + if ( new_tile_coord < 0 ) { - tile_x += world->num_tiles_x; - -- tile_map_x; + new_tile_coord += num_tiles; + -- new_tile_map_coord; } - if ( tile_y < 0 ) + if ( new_tile_coord >= num_tiles ) { - 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; + new_tile_coord -= num_tiles; + ++ new_tile_map_coord; } - return { tile_rel_x, tile_rel_y, tile_map_x, tile_map_y, tile_x, tile_y }; + (* tile_map_coord) = new_tile_map_coord; + (* tile_coord) = new_tile_coord; + (* pos_coord) = new_pos_coord; +} + +inline +CanonPosition recannonicalize_position( World* world, CanonPosition pos ) +{ + CanonPosition result = pos; + cannonicalize_coord( world, world->num_tiles_x, & result.tile_map_x, & result.tile_x, & result.x ); + cannonicalize_coord( world, world->num_tiles_y, & result.tile_map_y, & result.tile_y, & result.y ); + return result; } inline @@ -555,20 +544,28 @@ TileMap* world_get_tilemap( World* world, s32 tile_map_x, s32 tile_map_y ) } internal -b32 world_is_point_empty( World* world, RawPosition raw_pos ) +b32 world_is_point_empty( World* world, CanonPosition position ) { 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; } +void draw_debug_point(OffscreenBuffer* back_buffer, World* world, CanonPosition pos, f32 red, f32 green, f32 blue) +{ + draw_rectangle(back_buffer, + pos.x * world->tile_meters_to_pixels + world->tile_upper_left_x + scast(f32, pos.tile_x * world->tile_size_in_pixels), + pos.y * world->tile_meters_to_pixels + world->tile_upper_left_y + scast(f32, pos.tile_y * world->tile_size_in_pixels), + (pos.x + 0.1f) * world->tile_meters_to_pixels + world->tile_upper_left_x + scast(f32, pos.tile_x * world->tile_size_in_pixels), + (pos.y + 0.1f) * world->tile_meters_to_pixels + world->tile_upper_left_y + scast(f32, pos.tile_y * world->tile_size_in_pixels), + red, green, blue); +} + Engine_API void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back_buffer , Memory* memory, platform::ModuleAPI* platform_api, ThreadContext* thread ) @@ -773,9 +770,10 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back World world; world.tile_size_in_meters = 1.4f; world.tile_size_in_pixels = 85; - + world.tile_meters_to_pixels = scast(f32, world.tile_size_in_pixels) / world.tile_size_in_meters; + f32 tile_size_in_pixels = scast(f32, world.tile_size_in_pixels); - + world.num_tiles_x = tile_map_num_x; world.num_tiles_y = tile_map_num_y; @@ -789,65 +787,90 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back 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 ); + TileMap* current_tile_map = world_get_tilemap( & world, player->position.tile_map_x, player->position.tile_map_y ); assert( current_tile_map != nullptr ); - player->width = tile_size_in_pixels * 0.70f; - player->height = tile_size_in_pixels * 0.9f; + player->height = 1.4f; + player->width = player->height * 0.7f; f32 player_half_width = player->width / 2.f; f32 player_quarter_height = player->height / 4.f; input_poll_player_actions( input, & player_actions ); { - f32 move_speed = 200.f; + f32 move_speed = 6.f; - f32 new_player_pos_x = player->pos_x; - f32 new_player_pos_y = player->pos_y; + f32 new_player_pos_x = player->position.x; + f32 new_player_pos_y = player->position.y; if ( player_actions.player_x_move_analog || player_actions.player_y_move_analog ) { - new_player_pos_x += scast(f32, player_actions.player_x_move_analog * delta_time * move_speed); - new_player_pos_y -= scast(f32, player_actions.player_y_move_analog * delta_time * move_speed); + new_player_pos_x += scast(f32, player_actions.player_x_move_analog * delta_time * move_speed); + new_player_pos_y -= scast(f32, player_actions.player_y_move_analog * delta_time * move_speed); } else { new_player_pos_x += scast(f32, player_actions.player_x_move_digital) * delta_time * move_speed; new_player_pos_y -= scast(f32, player_actions.player_y_move_digital) * delta_time * move_speed; } - new_player_pos_y += sinf( player->jump_time * TAU ) * 200.f * delta_time; + new_player_pos_y += sinf( player->jump_time * TAU ) * 10.f * delta_time; 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 + //RawPosition test_pos = { + // new_player_pos_x - player_half_width, new_player_pos_y - player_quarter_height, + // player->position.tile_map_x, player->position.tile_map_y + //}; + + CanonPosition test_pos = { + new_player_pos_x, new_player_pos_y, + player->position.tile_map_x, player->position.tile_map_y, + player->position.tile_x, player->position.tile_y }; + test_pos = recannonicalize_position( & world, test_pos ); - valid_new_pos &= world_is_point_empty( & world, test_pos ); + // TODO(Ed) : Need a delta-function that auto-reconnonicalizes. - test_pos.x = new_player_pos_x + player_half_width; - valid_new_pos &= world_is_point_empty( & world, test_pos ); + CanonPosition test_pos_nw { + new_player_pos_x - player_half_width, new_player_pos_y - player_quarter_height, + player->position.tile_map_x, player->position.tile_map_y, + player->position.tile_x, player->position.tile_y + }; + test_pos_nw = recannonicalize_position( & world, test_pos_nw ); + valid_new_pos &= world_is_point_empty( & world, test_pos_nw ); - 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 ); + CanonPosition test_pos_ne { + new_player_pos_x + player_half_width, new_player_pos_y - player_quarter_height, + player->position.tile_map_x, player->position.tile_map_y, + player->position.tile_x, player->position.tile_y + }; + test_pos_ne = recannonicalize_position( & world, test_pos_ne ); + valid_new_pos &= world_is_point_empty( & world, test_pos_ne ); - test_pos.x = new_player_pos_x + player_half_width; - valid_new_pos &= world_is_point_empty( & world, test_pos ); + CanonPosition test_pos_sw { + new_player_pos_x - player_half_width, new_player_pos_y, + player->position.tile_map_x, player->position.tile_map_y, + player->position.tile_x, player->position.tile_y + }; + test_pos_sw = recannonicalize_position( & world, test_pos_sw ); + valid_new_pos &= world_is_point_empty( & world, test_pos_sw ); + + CanonPosition test_pos_se { + new_player_pos_x + player_half_width, new_player_pos_y, + player->position.tile_map_x, player->position.tile_map_y, + player->position.tile_x, player->position.tile_y + }; + test_pos_se = recannonicalize_position( & world, test_pos_se ); + valid_new_pos &= world_is_point_empty( & world, test_pos_se ); } if ( valid_new_pos ) { - 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 + tile_size_in_pixels * scast(f32, canon_pos.tile_x) + canon_pos.x; - player->pos_y = world.tile_upper_left_y + tile_size_in_pixels * scast(f32, canon_pos.tile_y) + canon_pos.y; + CanonPosition new_pos = { + new_player_pos_x, new_player_pos_y, + player->position.tile_map_x, player->position.tile_map_y, + player->position.tile_x, player->position.tile_y + }; + player->position = recannonicalize_position( & world, new_pos ); } // player_tile_x @@ -881,35 +904,50 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back for ( s32 col = 0; col < 16; ++ col ) { u32 tileID = tilemap_tile_value( current_tile_map, & world, col, row ); - f32 grey[3] = { 0.15f, 0.15f, 0.15f }; + f32 color[3] = { 0.15f, 0.15f, 0.15f }; if ( tileID == 1 ) { - grey[0] = 0.22f; - grey[1] = 0.22f; - grey[2] = 0.22f; + color[0] = 0.22f; + color[1] = 0.22f; + color[2] = 0.22f; + } + + if ( row == player->position.tile_y && col == player->position.tile_x ) + { + color[0] = 0.44f; + color[1] = 0.3f; + color[2] = 0.3f; } f32 min_x = world.tile_upper_left_x + scast(f32, col) * tile_size_in_pixels; f32 min_y = world.tile_upper_left_y + scast(f32, row) * tile_size_in_pixels; + // f32 min_x = scast(f32, col) * tile_size_in_pixels; + // f32 min_y = scast(f32, row) * tile_size_in_pixels; f32 max_x = min_x + tile_size_in_pixels; f32 max_y = min_y + tile_size_in_pixels; draw_rectangle( back_buffer , min_x, min_y , max_x, max_y - , grey[0], grey[1], grey[2] ); + , color[0], color[1], color[2] ); } } // Player - f32 player_red = 0.3f; - f32 player_green = 0.3f; + f32 player_red = 0.7f; + f32 player_green = 0.7f; f32 player_blue = 0.3f; + f32 player_tile_x_offset = scast(f32, player->position.tile_x * world.tile_size_in_pixels); + f32 player_tile_y_offset = scast(f32, player->position.tile_y * world.tile_size_in_pixels); + + f32 player_screen_pos_x = world.tile_upper_left_x + player_tile_x_offset + player->position.x * world.tile_meters_to_pixels; + f32 player_screen_pos_y = world.tile_upper_left_y + player_tile_y_offset + player->position.y * world.tile_meters_to_pixels; + draw_rectangle( back_buffer - , player->pos_x - player_half_width, player->pos_y - player->height - , player->pos_x + player_half_width, player->pos_y + , 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 ); // Auto-Snapshot percent bar @@ -926,8 +964,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back if ( memory->replay_mode == ReplayMode_Record ) { draw_rectangle( back_buffer - , scast(f32, player->pos_x) + 50.f, scast(f32, player->pos_y) - 50.f - , scast(f32, player->pos_x) + 10.f, scast(f32, player->pos_y) + 40.f + , player->position.x + 50.f, player->position.y - 50.f + , player->position.x + 10.f, player->position.y + 40.f , 1.f, 1.f, 1.f ); } #endif diff --git a/project/engine/engine.hpp b/project/engine/engine.hpp index 95a3744..8de08a0 100644 --- a/project/engine/engine.hpp +++ b/project/engine/engine.hpp @@ -11,6 +11,11 @@ #define NS_ENGINE_BEGIN namespace engine { #define NS_ENGINE_END } +#ifndef Engine_API +// The build system is reponsible for defining this API macro for exporting symbols. +# define Engine_API +#endif + NS_ENGINE_BEGIN enum ReplayMode : s32 @@ -286,7 +291,8 @@ struct World { f32 tile_size_in_meters; s32 tile_size_in_pixels; - + f32 tile_meters_to_pixels; + f32 tile_upper_left_x; f32 tile_upper_left_y; @@ -302,8 +308,7 @@ struct World struct CanonPosition { - // TODO(Ed): Convert these to resolution-indenpent rep of world units (a proper vector space?)) - // Note: Tile-Relative position + // TODO(Ed) : Should this be from the center of the tile? f32 x; f32 y; @@ -319,15 +324,4 @@ struct CanonPosition 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/engine/engine_to_platform_api.hpp b/project/engine/engine_to_platform_api.hpp index f810d8a..3c0f52b 100644 --- a/project/engine/engine_to_platform_api.hpp +++ b/project/engine/engine_to_platform_api.hpp @@ -3,10 +3,6 @@ */ #pragma once -#ifndef Engine_API -# define Engine_API -#endif - NS_ENGINE_BEGIN using OnModuleRelaodFn = void( Memory* memory, platform::ModuleAPI* platform_api ); diff --git a/project/gen/engine_symbol_table.hpp b/project/gen/engine_symbol_table.hpp index 37d90be..f22d898 100644 --- a/project/gen/engine_symbol_table.hpp +++ b/project/gen/engine_symbol_table.hpp @@ -3,12 +3,15 @@ NS_ENGINE_BEGIN -constexpr Str const symbol_on_module_load = str_ascii( "?on_module_reload@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z" ); -constexpr Str const symbol_startup = str_ascii( "?startup@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z" ); -constexpr Str const symbol_shutdown = str_ascii( "?shutdown@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z" ); -constexpr Str const symbol_update_and_render = - str_ascii( "?update_and_render@engine@@YAXMPEAUInputState@1@PEAUOffscreenBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@PEAUThreadContext@1@@Z" ); -constexpr Str const symbol_update_audio = - str_ascii( "?update_audio@engine@@YAXMPEAUAudioBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@PEAUThreadContext@1@@Z" ); +constexpr +Str const symbol_on_module_load = str_ascii("?on_module_reload@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z"); +constexpr +Str const symbol_startup = str_ascii("?startup@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z"); +constexpr +Str const symbol_shutdown = str_ascii("?shutdown@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z"); +constexpr +Str const symbol_update_and_render = str_ascii("?update_and_render@engine@@YAXMPEAUInputState@1@PEAUOffscreenBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@PEAUThreadContext@1@@Z"); +constexpr +Str const symbol_update_audio = str_ascii("?update_audio@engine@@YAXMPEAUAudioBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@PEAUThreadContext@1@@Z"); NS_ENGINE_END diff --git a/project/handmade.hpp b/project/handmade.hpp index 55a4579..b04a3b1 100644 --- a/project/handmade.hpp +++ b/project/handmade.hpp @@ -75,9 +75,11 @@ struct PlayerState f32 height; // TODO(Ed) : Should this be canonical position now? - f32 pos_x; - f32 pos_y; - + //f32 pos_x; + //f32 pos_y; + + engine::CanonPosition position; + b32 mid_jump; f32 jump_time; }; @@ -94,9 +96,6 @@ struct PlayerActions struct GameState { - s32 tile_map_x; - s32 tile_map_y; - PlayerState player_state; }; diff --git a/project/platform/gen/context.gen.hpp b/project/platform/gen/context.gen.hpp index 096e975..2379c6d 100644 --- a/project/platform/gen/context.gen.hpp +++ b/project/platform/gen/context.gen.hpp @@ -1,3 +1,5 @@ -// This was generated by project/codegen/platform_gen.cpp +//This was generated by project/codegen/platform_gen.cpp + +#define using_context() \ +Context * parent; -#define using_context() Context* parent; diff --git a/project/platform/win32/win32_platform.cpp b/project/platform/win32/win32_platform.cpp index 139a400..b1495dd 100644 --- a/project/platform/win32/win32_platform.cpp +++ b/project/platform/win32/win32_platform.cpp @@ -97,15 +97,6 @@ FILETIME file_get_last_write_time( char const* path ) GetFileAttributesExA( path, GetFileExInfoStandard, & engine_dll_file_attributes ); return engine_dll_file_attributes.ftLastWriteTime; -#if 0 - WIN32_FIND_DATAA dll_file_info = {}; - HANDLE dll_file_handle = FindFirstFileA( path, & dll_file_info ); - if ( dll_file_handle == INVALID_HANDLE_VALUE ) - { - FindClose( dll_file_handle ); - } - return dll_file_info.ftLastWriteTime; -#endif } #pragma region Timing @@ -307,20 +298,20 @@ main_window_callback( HWND handle case WM_MOUSEMOVE: { - RECT rect; - POINT pt = { LOWORD(l_param), HIWORD(l_param) }; + RECT rect; + POINT pt = { LOWORD(l_param), HIWORD(l_param) }; - GetClientRect(handle, &rect); - if (PtInRect(&rect, pt)) - { - // Hide the cursor when it's inside the window - // while (ShowCursor(FALSE) >= 0); - } - else - { - // Show the cursor when it's outside the window - // while (ShowCursor(TRUE) < 0); - } + GetClientRect(handle, &rect); + if (PtInRect(&rect, pt)) + { + // Hide the cursor when it's inside the window + // while (ShowCursor(FALSE) >= 0); + } + else + { + // Show the cursor when it's outside the window + // while (ShowCursor(TRUE) < 0); + } } break; diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 867575d..0e2966d 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -12,15 +12,16 @@ Import-Module $target_arch Import-Module $format_cpp #region Arguments - $vendor = $null - $optimize = $null - $debug = $null - $analysis = $false - $dev = $false - $platform = $null - $engine = $null - $game = $null - $verbose = $null + $vendor = $null + $optimize = $null + $debug = $null + $analysis = $false + $dev = $false + $verbose = $null + $platform = $null + $engine = $null + $game = $null + $module_specified = $false [array] $vendors = @( "clang", "msvc" ) @@ -33,17 +34,61 @@ if ( $args ) { $args | ForEach-Object { "debug" { $debug = $true } "analysis" { $analysis = $true } "dev" { $dev = $true } - "platform" { $platform = $true } - "engine" { $engine = $true } - "game" { $game = $true } "verbose" { $verbose = $true } + "platform" { $platform = $true } + "engine" { $engine = $true; $module_specified = $true } + "game" { $game = $true; $module_specified = $true } } }} #endregion Argument +if ( -not $module_specified ) +{ + $platform = $true + $engine = $true + $game = $true +} + # Load up toolchain configuraion . $config_toolchain +# Check to see if the module has changed files since the last build +function check-ModuleForChanges +{ + param( [string]$path_module ) + + $module_name = split-path $path_module -leaf + $path_csv = Join-Path $path_build ($module_name + "_module_hashes.csv") + + $csv_file_hashes = $null + if ( test-path $path_csv ) { + $csv_file_hashes = @{} + import-csv $path_csv | foreach-object { + $csv_file_hashes[ $_.name ] = $_.value + } + } + + $file_hashes = @{} + get-childitem -path $path_module -recurse -file | foreach-object { + $id = $_.fullname + $hash_info = get-filehash -path $id -Algorithm MD5 + $file_hashes[ $id ] = $hash_info.Hash + } + + $file_hashes.GetEnumerator() | foreach-object { [PSCustomObject]$_ } | + export-csv $path_csv -NoTypeInformation + + if ( -not $csv_file_hashes ) { return $true } + if ( $csv_file_hashes.Count -ne $file_hashes.Count ) { return $true } + + foreach ( $key in $csv_file_hashes.Keys ) { + if ( $csv_file_hashes[ $key ] -ne $file_hashes[ $key ] ) { + return $true + } + } + return $false +} + #region Building write-host "Building HandmadeHero with $vendor" @@ -105,8 +150,16 @@ else { $compiler_args += ( $flag_define + 'Build_Development=0' ) } +$should_format_gen = $false + function build-engine { + $should_build = check-ModuleForChanges $path_engine + if ( $should_build -eq $false ) { + write-host "No changes detected in engine module, skipping build" -ForegroundColor Yellow + return + } + $path_pdb_lock = Join-Path $path_binaries 'handmade_engine.pdb.lock' New-Item $path_pdb_lock -ItemType File -Force @@ -123,12 +176,10 @@ function build-engine $local:compiler_args = $script:compiler_args $compiler_args += ($flag_define + 'Build_DLL=1' ) - if ( $vendor -eq 'msvc' ) - { + if ( $vendor -eq 'msvc' ) { $compiler_args += ($flag_define + 'Engine_API=__declspec(dllexport)') } - if ( $vendor -eq 'clang' ) - { + if ( $vendor -eq 'clang' ) { $compiler_args += ($flag_define + 'Engine_API=__attribute__((visibility("default")))') } @@ -146,6 +197,8 @@ function build-engine #region CodeGen Post-Build if ( -not $handmade_process_active ) { + $path_engine_symbols = Join-Path $path_build 'handmade_engine.symbols' + # Create the symbol table if ( Test-Path $dynamic_library ) { @@ -212,7 +265,6 @@ function build-engine } # Write the symbol table to a file - $path_engine_symbols = Join-Path $path_build 'handmade_engine.symbols' $engine_symbols.Values | Out-File -Path $path_engine_symbols } @@ -245,6 +297,7 @@ function build-engine $path_generated_file = Join-Path $path_build 'engine_symbol_table.hpp' move-item $path_generated_file (join-path $path_gen (split-path $path_generated_file -leaf)) -Force + $should_format_gen = $true } } if ( $engine ) { @@ -253,6 +306,17 @@ if ( $engine ) { function build-platform { + if ( $handmade_process_active ) { + write-host "Handmade process is active, skipping platform build" -ForegroundColor Yellow + return + } + + $should_build = check-ModuleForChanges $path_platform + if ( $should_build -eq $false ) { + write-host "No changes detected in platform module, skipping build" -ForegroundColor Yellow + return + } + # CodeGen Pre-Build if ( $true ) { @@ -280,7 +344,7 @@ function build-platform ) $unit = Join-Path $path_codegen 'platform_gen.cpp' - $executable = Join-Path $path_build 'platform_gen.exe' + $executable = Join-Path $path_build 'platform_gen.exe' build-simple $path_build $includes $compiler_args $linker_args $unit $executable $path_build @@ -291,6 +355,8 @@ function build-platform } } Pop-Location + + $should_format_gen = $true } # Delete old PDBs @@ -319,12 +385,6 @@ function build-platform $executable = Join-Path $path_binaries 'handmade_win32.exe' build-simple $path_build $includes $compiler_args $linker_args $unit $executable - - # if ( Test-Path $executable ) - # { - # $data_path = Join-Path $path_data 'handmade_win32.exe' - # move-item $executable $data_path -Force - # } } if ( $platform ) { build-platform @@ -338,14 +398,17 @@ if ( (Test-Path $path_jsl_dll) -eq $false ) } #endregion Handmade Runtime -push-location $path_scripts -$include = @( - '*.cpp' - '*.hpp' -) -format-cpp $path_gen $include -format-cpp (Join-Path $path_platform 'gen' ) $include -pop-location +if ( $should_format_gen ) +{ + push-location $path_scripts + $include = @( + '*.cpp' + '*.hpp' + ) + format-cpp $path_gen $include + format-cpp (Join-Path $path_platform 'gen' ) $include + pop-location +} Pop-Location #endregion Building diff --git a/scripts/helpers/configure_toolchain.ps1 b/scripts/helpers/configure_toolchain.ps1 index 4ea05f1..f57baad 100644 --- a/scripts/helpers/configure_toolchain.ps1 +++ b/scripts/helpers/configure_toolchain.ps1 @@ -14,7 +14,6 @@ if ( $dev ) { if ( $debug -eq $null ) { $debug = $true } - if ( $optimize -eq $null ) { $optimize = $false } @@ -149,12 +148,15 @@ if ( $vendor -match "clang" ) ) # https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170 - $libraries = @( - 'Kernel32' # For Windows API - # 'msvcrt', # For the C Runtime (Dynamically Linked) - # 'libucrt', - 'libcmt' # For the C Runtime (Static Linkage) - ) + if ( $IsWindows ) { + $libraries = @( + 'Kernel32' # For Windows API + # 'msvcrt', # For the C Runtime (Dynamically Linked) + # 'libucrt', + 'libcmt' # For the C Runtime (Static Linkage) + ) + } + function build-simple { param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) diff --git a/scripts/rebuild.ps1 b/scripts/rebuild.ps1 index 0ebc7b7..8315f53 100644 --- a/scripts/rebuild.ps1 +++ b/scripts/rebuild.ps1 @@ -1 +1,5 @@ -Clear-Host +$clean = join-path $PSScriptRoot 'clean.ps1' +$build = join-path $PSScriptRoot 'build.ps1' + +& $clean +& $build 'msvc' 'dev'