Day 37 completed
1
.gitignore
vendored
@ -29,3 +29,4 @@ build
|
|||||||
data/test.out
|
data/test.out
|
||||||
data/handmade_engine.symbols
|
data/handmade_engine.symbols
|
||||||
data/handmade_win32.exe
|
data/handmade_win32.exe
|
||||||
|
data/content/offical
|
||||||
|
@ -33,7 +33,7 @@ Module build order:
|
|||||||
|
|
||||||
## Milestone
|
## Milestone
|
||||||
|
|
||||||
Day 36 : Loading BMPs
|
Day 37 : Basic Bitmap Rendering
|
||||||
|
|
||||||
Features Done so far:
|
Features Done so far:
|
||||||
|
|
||||||
@ -59,9 +59,13 @@ Features Done so far:
|
|||||||
* Record & replay input.
|
* Record & replay input.
|
||||||
* WIP : 2.5D Tile Map
|
* WIP : 2.5D Tile Map
|
||||||
* Virtualized into chunks
|
* Virtualized into chunks
|
||||||
|
* Bitmap file loading & basic rendering
|
||||||
|
|
||||||
## Gallery
|
## Gallery
|
||||||
|
|
||||||
|
![img](docs/imgs/handmade_win32_2023-10-20_23-14-37.png)
|
||||||
|
![img](docs/imgs/Code_2023-10-20_21-57-06.png)
|
||||||
|
![img](docs/imgs/handmade_win32_2023-10-19_22-57-13.gif)
|
||||||
![img](docs/imgs/handmade_win32_2023-10-19_14-07-20.png)
|
![img](docs/imgs/handmade_win32_2023-10-19_14-07-20.png)
|
||||||
![img](docs/imgs/handmade_win32_2023-10-16_23-08-11.png)
|
![img](docs/imgs/handmade_win32_2023-10-16_23-08-11.png)
|
||||||
![img](docs/imgs/handmade_win32_2023-10-11_23-39-57.gif)
|
![img](docs/imgs/handmade_win32_2023-10-11_23-39-57.gif)
|
||||||
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 11 KiB |
BIN
data/content/debug_bitmap.bmp
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
data/content/mojito_head.bmp
Normal file
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 3.5 MiB |
10
docs/Day 037.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Day 37
|
||||||
|
|
||||||
|
I went ahead and did some extra stuff.
|
||||||
|
My "hero" is a mojito bmp for now. I'll eventually do something else for it.
|
||||||
|
I also added incremental build support for the codegen metaprograms.
|
||||||
|
|
||||||
|
I originally wanted to make the assets on the fly (just as a break from the code),
|
||||||
|
but decided to just use his assets as this series is already going to take forever.
|
||||||
|
|
||||||
|
I have the assets mapped to an "offical" directory within content, however they'll be naturally ignored on the repo.
|
BIN
docs/imgs/Code_2023-10-20_21-57-06.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
docs/imgs/handmade_win32_2023-10-19_22-57-13.gif
Normal file
After Width: | Height: | Size: 6.5 MiB |
BIN
docs/imgs/handmade_win32_2023-10-20_23-14-37.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
master_assets/debug_bitmap.aseprite
Normal file
BIN
master_assets/mojito_head.aseprite
Normal file
BIN
master_assets/test_background.kra
Normal file
BIN
master_assets/test_background.kra~
Normal file
@ -71,7 +71,7 @@ int gen_main()
|
|||||||
|
|
||||||
#pragma push_macro("str_ascii")
|
#pragma push_macro("str_ascii")
|
||||||
#undef str_ascii
|
#undef str_ascii
|
||||||
Builder builder = Builder::open( "engine_symbol_table.hpp" );
|
Builder builder = Builder::open( "engine_symbols.gen.hpp" );
|
||||||
builder.print( pragma_once );
|
builder.print( pragma_once );
|
||||||
builder.print( def_include( txt("engine/engine.hpp") ) );
|
builder.print( def_include( txt("engine/engine.hpp") ) );
|
||||||
builder.print( fmt_newline );
|
builder.print( fmt_newline );
|
||||||
|
@ -238,44 +238,58 @@ void draw_rectangle( OffscreenBuffer* buffer
|
|||||||
|
|
||||||
internal
|
internal
|
||||||
void draw_bitmap( OffscreenBuffer* buffer
|
void draw_bitmap( OffscreenBuffer* buffer
|
||||||
, f32 min_x, f32 min_y
|
, f32 pos_x, f32 pos_y
|
||||||
, f32 max_x, f32 max_y
|
, Bitmap* bitmap )
|
||||||
, u32* pixels, u32 size )
|
|
||||||
{
|
{
|
||||||
s32 min_x_32 = round( min_x );
|
s32 half_width = bitmap->width / 2;
|
||||||
s32 min_y_32 = round( min_y );
|
s32 half_height = bitmap->height / 2;
|
||||||
s32 max_x_32 = round( max_x );
|
|
||||||
s32 max_y_32 = round( max_y );
|
s32 min_x = round( pos_x ) - half_width;
|
||||||
|
s32 min_y = round( pos_y ) - half_height;
|
||||||
|
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 buffer_width = buffer->width;
|
s32 buffer_width = buffer->width;
|
||||||
s32 buffer_height = buffer->height;
|
s32 buffer_height = buffer->height;
|
||||||
|
|
||||||
if ( min_x_32 < 0 )
|
if ( min_x < 0 )
|
||||||
min_x_32 = 0;
|
min_x = 0;
|
||||||
if ( min_y_32 < 0 )
|
if ( min_y < 0 )
|
||||||
min_y_32 = 0;
|
min_y = 0;
|
||||||
if ( max_x_32 > buffer_width )
|
if ( max_x > buffer_width )
|
||||||
max_x_32 = buffer_width;
|
max_x = buffer_width;
|
||||||
if ( max_y_32 > buffer_height )
|
if ( max_y > buffer_height )
|
||||||
max_y_32 = buffer_height;
|
max_y = buffer_height;
|
||||||
|
|
||||||
// Start with the pixel on the top left corner of the rectangle
|
// Start with the pixel on the top left corner of the rectangle
|
||||||
u8* row = rcast(u8*, buffer->memory )
|
u8* row = rcast(u8*, buffer->memory )
|
||||||
+ min_x_32 * buffer->bytes_per_pixel
|
+ min_x * buffer->bytes_per_pixel
|
||||||
+ min_y_32 * buffer->pitch;
|
+ min_y * buffer->pitch;
|
||||||
|
|
||||||
for ( s32 y = min_y_32; y < max_y_32; ++ y )
|
s32 bmp_y = bmp_start_y;
|
||||||
|
for ( s32 y = min_y; y < max_y; ++ y )
|
||||||
{
|
{
|
||||||
s32* pixel_32 = rcast(s32*, row);
|
s32* pixel_32 = rcast(s32*, row);
|
||||||
|
|
||||||
for ( s32 x = min_x_32; x < max_x_32; ++ x )
|
s32 bmp_x = bmp_start_x;
|
||||||
|
for ( s32 x = min_x; x < max_x; ++ x )
|
||||||
{
|
{
|
||||||
u32 color = pixels[ y * max_x_32 + x ];
|
u32 color = bitmap->pixels[ bmp_y * bitmap->width + bmp_x ];
|
||||||
|
|
||||||
*pixel_32 = color;
|
// TODO(Ed): This is a bad alpha check, fix it.
|
||||||
pixel_32++;
|
// if ( (color >> 24) != 0 )
|
||||||
|
// {
|
||||||
|
*pixel_32 = color;
|
||||||
|
// }
|
||||||
|
++ pixel_32;
|
||||||
|
++ bmp_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
row += buffer->pitch;
|
row += buffer->pitch;
|
||||||
|
-- bmp_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,23 +307,52 @@ void draw_debug_point(OffscreenBuffer* back_buffer, World* world, TileMapPositio
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
Bitmap load_bmp( platform::FileReadContentFn* file_read_content, Str file_path )
|
Bitmap load_bmp( platform::ModuleAPI* platform_api, Str file_path )
|
||||||
{
|
{
|
||||||
Bitmap result {};
|
Bitmap result {};
|
||||||
|
|
||||||
platform::File file {
|
platform::File file {
|
||||||
file_path
|
file_path
|
||||||
};
|
};
|
||||||
if ( ! file_read_content( & file ) )
|
if ( ! platform_api->file_read_content( & file ) )
|
||||||
{
|
{
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitmapHeaderPacked* header = pcast(BitmapHeaderPacked*, file.data);
|
BitmapHeaderPacked* header = pcast(BitmapHeaderPacked*, file.data);
|
||||||
|
// Note: Byte order is in little-endian AA BB GG RR (bottom up) (ABGR)
|
||||||
|
//
|
||||||
|
|
||||||
|
// TODO(Ed) : Do not directly assign this, allocate the pixels to somewhere in game or engine persistent.
|
||||||
result.pixels = rcast(u32*, rcast(Byte*, file.data) + header->bitmap_offset);
|
result.pixels = rcast(u32*, rcast(Byte*, file.data) + header->bitmap_offset);
|
||||||
result.width = header->width;
|
result.width = header->width;
|
||||||
result.height = header->height;
|
result.height = header->height;
|
||||||
result.bits_per_pixel = header->bits_per_pixel;
|
result.bits_per_pixel = header->bits_per_pixel;
|
||||||
|
|
||||||
|
u32* src = result.pixels;
|
||||||
|
// Note: Do not use this generically, code is bad)
|
||||||
|
for ( s32 y = 0; y < header->width; ++ y )
|
||||||
|
{
|
||||||
|
for ( s32 x = 0; x < header->height; ++ x )
|
||||||
|
{
|
||||||
|
struct Pixel
|
||||||
|
{
|
||||||
|
u8 Alpha;
|
||||||
|
u8 Blue;
|
||||||
|
u8 Green;
|
||||||
|
u8 Red;
|
||||||
|
};
|
||||||
|
|
||||||
|
Pixel* px = rcast(Pixel*, src);
|
||||||
|
Pixel cpy = *px;
|
||||||
|
// *src = (u32(px->Alpha) << 0) | (u32(px->Red) << 24) | (u32(px->Green) << 16) | (u32(px->Blue) << 8);
|
||||||
|
*src = (*src >> 8) | (*src << 24);
|
||||||
|
++ src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//platform_api->file_close( & file );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,13 +585,43 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
|
|||||||
hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent );
|
hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent );
|
||||||
assert( sizeof(hh::GameState) <= state->game_memory.persistent_size );
|
assert( sizeof(hh::GameState) <= state->game_memory.persistent_size );
|
||||||
|
|
||||||
StrPath path_test_bg;
|
// Personally made assets
|
||||||
path_test_bg.concat( platform_api->path_content, str_ascii("test_background.bmp") );
|
{
|
||||||
game_state->test_bg = load_bmp( platform_api->file_read_content, 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") );
|
path_mojito.concat( platform_api->path_content, str_ascii("mojito.bmp") );
|
||||||
game_state->mojito = load_bmp( platform_api->file_read_content, path_mojito );
|
game_state->mojito = load_bmp( platform_api, path_mojito );
|
||||||
|
|
||||||
|
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;
|
||||||
|
path_debug_bitmap.concat( platform_api->path_content, str_ascii("debug_bitmap2.bmp") );
|
||||||
|
game_state->debug_bitmap = load_bmp( platform_api, path_debug_bitmap );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offical assets
|
||||||
|
{
|
||||||
|
StrPath path_test_bg_hh;
|
||||||
|
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 );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
hh::PlayerState* player = & game_state->player_state;
|
hh::PlayerState* player = & game_state->player_state;
|
||||||
player->position.tile_x = 4;
|
player->position.tile_x = 4;
|
||||||
@ -833,6 +906,11 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
|||||||
, 1.f, 0.24f, 0.24f );
|
, 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_hh
|
||||||
|
);
|
||||||
|
|
||||||
// Scrolling
|
// Scrolling
|
||||||
f32 screen_center_x = 0.5f * scast(f32, back_buffer->width);
|
f32 screen_center_x = 0.5f * scast(f32, back_buffer->width);
|
||||||
f32 screen_center_y = 0.5f * scast(f32, back_buffer->height);
|
f32 screen_center_y = 0.5f * scast(f32, back_buffer->height);
|
||||||
@ -847,25 +925,25 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
|||||||
u32 tile_id = TileMap_get_tile_value( tile_map, col, row, player->position.tile_z );
|
u32 tile_id = TileMap_get_tile_value( tile_map, col, row, player->position.tile_z );
|
||||||
f32 color[3] = { 0.15f, 0.15f, 0.15f };
|
f32 color[3] = { 0.15f, 0.15f, 0.15f };
|
||||||
|
|
||||||
if ( tile_id > 0 )
|
if ( tile_id > 1 || row == player->position.tile_y && col == player->position.tile_x )
|
||||||
{
|
{
|
||||||
if ( tile_id == 2 )
|
if ( tile_id == 2 )
|
||||||
{
|
{
|
||||||
color[0] = 0.22f;
|
color[0] = 0.42f;
|
||||||
color[1] = 0.22f;
|
color[1] = 0.42f;
|
||||||
color[2] = 0.22f;
|
color[2] = 0.52f;
|
||||||
}
|
}
|
||||||
if ( tile_id == 3 )
|
if ( tile_id == 3 )
|
||||||
{
|
{
|
||||||
color[0] = 0.12f;
|
color[0] = 0.02f;
|
||||||
color[1] = 0.12f;
|
color[1] = 0.02f;
|
||||||
color[2] = 0.12f;
|
color[2] = 0.02f;
|
||||||
}
|
}
|
||||||
if ( tile_id == 4 )
|
if ( tile_id == 4 )
|
||||||
{
|
{
|
||||||
color[0] = 0.52f;
|
color[0] = 0.42f;
|
||||||
color[1] = 0.52f;
|
color[1] = 0.62f;
|
||||||
color[2] = 0.52f;
|
color[2] = 0.42f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( row == player->position.tile_y && col == player->position.tile_x )
|
if ( row == player->position.tile_y && col == player->position.tile_x )
|
||||||
@ -884,26 +962,21 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
|||||||
f32 max_y = center_y + tile_size_in_pixels * 0.5f;
|
f32 max_y = center_y + tile_size_in_pixels * 0.5f;
|
||||||
|
|
||||||
draw_rectangle( back_buffer
|
draw_rectangle( back_buffer
|
||||||
, min_x, min_y
|
, min_x, min_y
|
||||||
, max_x, max_y
|
, max_x, max_y
|
||||||
, color[0], color[1], color[2] );
|
, color[0], color[1], color[2] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw_bitmap( back_buffer
|
|
||||||
// , 0, 0
|
|
||||||
// , scast(f32, game_state->mojito.width), scast(f32, game_state->mojito.height)
|
|
||||||
// , game_state->mojito.pixels, game_state->mojito.size
|
|
||||||
// );
|
|
||||||
|
|
||||||
// Bad bitmap test
|
// Bad bitmap test
|
||||||
|
#if 0
|
||||||
{
|
{
|
||||||
u32* src = game_state->mojito.pixels;
|
u32* src = game_state->mojito_head.pixels;
|
||||||
u32* dst = rcast(u32*, back_buffer->memory);
|
u32* dst = rcast(u32*, back_buffer->memory);
|
||||||
for ( s32 y = 0; y < game_state->mojito.height; ++ y )
|
for ( s32 y = 0; y < game_state->mojito_head.height; ++ y )
|
||||||
{
|
{
|
||||||
for ( s32 x = 0; x < game_state->mojito.width; ++ x )
|
for ( s32 x = 0; x < game_state->mojito_head.width; ++ x )
|
||||||
{
|
{
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
++ dst;
|
++ dst;
|
||||||
@ -911,6 +984,7 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Player
|
// Player
|
||||||
f32 player_red = 0.7f;
|
f32 player_red = 0.7f;
|
||||||
@ -923,12 +997,16 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
|||||||
f32 player_screen_pos_x = screen_center_x;
|
f32 player_screen_pos_x = screen_center_x;
|
||||||
f32 player_screen_pos_y = screen_center_y;
|
f32 player_screen_pos_y = screen_center_y;
|
||||||
|
|
||||||
// player_min_x = player_tile_x_offset - player_half_width * world;
|
draw_bitmap( back_buffer
|
||||||
|
, player_screen_pos_x, player_screen_pos_y
|
||||||
|
, & game_state->hero_front_head );
|
||||||
|
|
||||||
|
#if 0
|
||||||
draw_rectangle( back_buffer
|
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->height * world->tile_meters_to_pixels
|
||||||
, player_screen_pos_x + player_half_width * world->tile_meters_to_pixels, player_screen_pos_y
|
, player_screen_pos_x + player_half_width * world->tile_meters_to_pixels, player_screen_pos_y
|
||||||
, player_red, player_green, player_blue );
|
, player_red, player_green, player_blue );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Auto-Snapshot percent bar
|
// Auto-Snapshot percent bar
|
||||||
if (1)
|
if (1)
|
||||||
|
@ -194,6 +194,16 @@ struct BitmapHeaderPacked
|
|||||||
s32 height;
|
s32 height;
|
||||||
u16 planes;
|
u16 planes;
|
||||||
u16 bits_per_pixel;
|
u16 bits_per_pixel;
|
||||||
|
u32 compression;
|
||||||
|
u32 size_of_bitmap;
|
||||||
|
s32 horizontal_resolution;
|
||||||
|
s32 vertical_resolution;
|
||||||
|
u32 colors_used;
|
||||||
|
u32 colors_important;
|
||||||
|
|
||||||
|
u32 red_mask;
|
||||||
|
u32 green_mask;
|
||||||
|
u32 blue_mask;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
@ -203,7 +213,6 @@ struct Bitmap
|
|||||||
s32 width;
|
s32 width;
|
||||||
s32 height;
|
s32 height;
|
||||||
u32 bits_per_pixel;
|
u32 bits_per_pixel;
|
||||||
u32 size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_ENGINE_END
|
NS_ENGINE_END
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
# Universal Generated Code
|
|
||||||
|
|
||||||
This is for generated code used for multiple modules.
|
|
@ -95,8 +95,17 @@ struct GameState
|
|||||||
{
|
{
|
||||||
PlayerState player_state;
|
PlayerState player_state;
|
||||||
|
|
||||||
engine::Bitmap test_bg;
|
using Bitmap = engine::Bitmap;
|
||||||
engine::Bitmap mojito;
|
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_HANDMADE_END
|
NS_HANDMADE_END
|
||||||
|
@ -24,7 +24,7 @@ Handmade Win32 Platform Translation Unit
|
|||||||
#include "engine/tile_map.hpp"
|
#include "engine/tile_map.hpp"
|
||||||
#include "engine/engine.hpp"
|
#include "engine/engine.hpp"
|
||||||
#include "engine/engine_to_platform_api.hpp"
|
#include "engine/engine_to_platform_api.hpp"
|
||||||
#include "gen/engine_symbol_table.hpp"
|
#include "engine/gen/engine_symbols.gen.hpp"
|
||||||
|
|
||||||
#include "jsl.hpp" // Using this to get dualsense controllers
|
#include "jsl.hpp" // Using this to get dualsense controllers
|
||||||
#include "win32/win32.hpp"
|
#include "win32/win32.hpp"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "platform/platform.hpp"
|
#include "platform/platform.hpp"
|
||||||
#include "engine/engine.hpp"
|
#include "engine/engine.hpp"
|
||||||
#include "engine/engine_to_platform_api.hpp"
|
#include "engine/engine_to_platform_api.hpp"
|
||||||
#include "gen/engine_symbol_table.hpp"
|
#include "engine/gen/engine_symbols.gen.hpp"
|
||||||
#include "win32.hpp"
|
#include "win32.hpp"
|
||||||
#include "jsl.hpp"
|
#include "jsl.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,10 +52,45 @@ if ( -not $module_specified )
|
|||||||
# Load up toolchain configuraion
|
# Load up toolchain configuraion
|
||||||
. $config_toolchain
|
. $config_toolchain
|
||||||
|
|
||||||
|
function check-FileForChanges
|
||||||
|
{
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$path_file
|
||||||
|
)
|
||||||
|
|
||||||
|
if (-not (Test-Path $path_file -PathType Leaf)) {
|
||||||
|
Write-Error "The provided path is not a valid file: $path_file"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
$file_name = Split-Path $path_file -Leaf
|
||||||
|
$path_csv = Join-Path $path_build ($file_name + "_file_hash.csv")
|
||||||
|
|
||||||
|
$csv_file_hash = $null
|
||||||
|
if (Test-Path $path_csv) {
|
||||||
|
$csv_file_hash = Import-Csv $path_csv | Select-Object -ExpandProperty value
|
||||||
|
}
|
||||||
|
|
||||||
|
$current_hash_info = Get-FileHash -Path $path_file -Algorithm MD5
|
||||||
|
$current_file_hash = $current_hash_info.Hash
|
||||||
|
|
||||||
|
# Save the current hash to the CSV
|
||||||
|
[PSCustomObject]@{
|
||||||
|
name = $path_file
|
||||||
|
value = $current_file_hash
|
||||||
|
} | Export-Csv $path_csv -NoTypeInformation
|
||||||
|
|
||||||
|
if ($csv_file_hash -and $csv_file_hash -eq $current_file_hash) {
|
||||||
|
return $false
|
||||||
|
} else {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Check to see if the module has changed files since the last build
|
# Check to see if the module has changed files since the last build
|
||||||
function check-ModuleForChanges
|
function check-ModuleForChanges
|
||||||
{
|
{
|
||||||
param( [string]$path_module )
|
param( [string]$path_module, [array]$excludes )
|
||||||
|
|
||||||
$module_name = split-path $path_module -leaf
|
$module_name = split-path $path_module -leaf
|
||||||
$path_csv = Join-Path $path_build ($module_name + "_module_hashes.csv")
|
$path_csv = Join-Path $path_build ($module_name + "_module_hashes.csv")
|
||||||
@ -69,7 +104,7 @@ function check-ModuleForChanges
|
|||||||
}
|
}
|
||||||
|
|
||||||
$file_hashes = @{}
|
$file_hashes = @{}
|
||||||
get-childitem -path $path_module -recurse -file | foreach-object {
|
get-childitem -path $path_module -recurse -file -Exclude $excludes | foreach-object {
|
||||||
$id = $_.fullname
|
$id = $_.fullname
|
||||||
$hash_info = get-filehash -path $id -Algorithm MD5
|
$hash_info = get-filehash -path $id -Algorithm MD5
|
||||||
$file_hashes[ $id ] = $hash_info.Hash
|
$file_hashes[ $id ] = $hash_info.Hash
|
||||||
@ -92,15 +127,16 @@ function check-ModuleForChanges
|
|||||||
#region Building
|
#region Building
|
||||||
write-host "Building HandmadeHero with $vendor"
|
write-host "Building HandmadeHero with $vendor"
|
||||||
|
|
||||||
$path_project = Join-Path $path_root 'project'
|
$path_project = Join-Path $path_root 'project'
|
||||||
$path_scripts = Join-Path $path_root 'scripts'
|
$path_scripts = Join-Path $path_root 'scripts'
|
||||||
$path_data = Join-Path $path_root 'data'
|
$path_data = Join-Path $path_root 'data'
|
||||||
$path_binaries = Join-Path $path_data 'binaries'
|
$path_binaries = Join-Path $path_data 'binaries'
|
||||||
$path_deps = Join-Path $path_project 'dependencies'
|
$path_deps = Join-Path $path_project 'dependencies'
|
||||||
$path_codegen = Join-Path $path_project 'codegen'
|
$path_codegen = Join-Path $path_project 'codegen'
|
||||||
$path_gen = Join-Path $path_project 'gen'
|
$path_platform = Join-Path $path_project 'platform'
|
||||||
$path_platform = Join-Path $path_project 'platform'
|
$path_engine = Join-Path $path_project 'engine'
|
||||||
$path_engine = Join-Path $path_project 'engine'
|
$path_engine_gen = Join-Path $path_engine 'gen'
|
||||||
|
|
||||||
|
|
||||||
$update_deps = Join-Path $PSScriptRoot 'update_deps.ps1'
|
$update_deps = Join-Path $PSScriptRoot 'update_deps.ps1'
|
||||||
|
|
||||||
@ -150,9 +186,6 @@ else {
|
|||||||
$compiler_args += ( $flag_define + 'Build_Development=0' )
|
$compiler_args += ( $flag_define + 'Build_Development=0' )
|
||||||
}
|
}
|
||||||
|
|
||||||
$should_format_gen = $false
|
|
||||||
|
|
||||||
# TODO(Ed) : Support detecting codegen changes separate from the module's runtime builds (so that it can be rebuild only when necessary as well)
|
|
||||||
function build-engine
|
function build-engine
|
||||||
{
|
{
|
||||||
$should_build = check-ModuleForChanges $path_engine
|
$should_build = check-ModuleForChanges $path_engine
|
||||||
@ -160,6 +193,7 @@ function build-engine
|
|||||||
write-host "No changes detected in engine module, skipping build" -ForegroundColor Yellow
|
write-host "No changes detected in engine module, skipping build" -ForegroundColor Yellow
|
||||||
return $true
|
return $true
|
||||||
}
|
}
|
||||||
|
write-host "`nBuilding Engine Module" -ForegroundColor Green
|
||||||
|
|
||||||
$path_pdb_lock = Join-Path $path_binaries 'handmade_engine.pdb.lock'
|
$path_pdb_lock = Join-Path $path_binaries 'handmade_engine.pdb.lock'
|
||||||
New-Item $path_pdb_lock -ItemType File -Force > $null
|
New-Item $path_pdb_lock -ItemType File -Force > $null
|
||||||
@ -171,36 +205,38 @@ function build-engine
|
|||||||
if ( $verbose ) { Write-Host "Deleted $file" -ForegroundColor Green }
|
if ( $verbose ) { Write-Host "Deleted $file" -ForegroundColor Green }
|
||||||
}
|
}
|
||||||
|
|
||||||
$local:includes = $script:includes
|
#region Building Engine Module Runtime
|
||||||
$includes += $path_engine
|
$local:includes = $script:includes
|
||||||
|
$includes += $path_engine
|
||||||
|
|
||||||
$local:compiler_args = $script:compiler_args
|
$local:compiler_args = $script:compiler_args
|
||||||
$compiler_args += ($flag_define + 'Build_DLL=1' )
|
$compiler_args += ($flag_define + 'Build_DLL=1' )
|
||||||
|
|
||||||
if ( $vendor -eq 'msvc' ) {
|
if ( $vendor -eq 'msvc' ) {
|
||||||
$compiler_args += ($flag_define + 'Engine_API=__declspec(dllexport)')
|
$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")))')
|
$compiler_args += ($flag_define + 'Engine_API=__attribute__((visibility("default")))')
|
||||||
}
|
}
|
||||||
|
|
||||||
$local:linker_args = @(
|
$local:linker_args = @(
|
||||||
$flag_link_dll
|
$flag_link_dll
|
||||||
# $flag_link_optimize_references
|
# $flag_link_optimize_references
|
||||||
)
|
)
|
||||||
|
|
||||||
$unit = Join-Path $path_project 'handmade_engine.cpp'
|
$unit = Join-Path $path_project 'handmade_engine.cpp'
|
||||||
$dynamic_library = Join-Path $path_binaries 'handmade_engine.dll'
|
$dynamic_library = Join-Path $path_binaries 'handmade_engine.dll'
|
||||||
|
|
||||||
$build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dynamic_library
|
$build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dynamic_library
|
||||||
|
|
||||||
Remove-Item $path_pdb_lock -Force
|
Remove-Item $path_pdb_lock -Force
|
||||||
|
|
||||||
if ( $build_result -eq $false ) {
|
if ( $build_result -eq $false ) {
|
||||||
return $false
|
return $false
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region CodeGen Post-Build
|
#CodeGen Post-Build
|
||||||
if ( -not $handmade_process_active -and $build_result )
|
if ( -not $handmade_process_active -and $build_result )
|
||||||
{
|
{
|
||||||
$path_engine_symbols = Join-Path $path_build 'handmade_engine.symbols'
|
$path_engine_symbols = Join-Path $path_build 'handmade_engine.symbols'
|
||||||
@ -273,42 +309,58 @@ function build-engine
|
|||||||
# Write the symbol table to a file
|
# Write the symbol table to a file
|
||||||
$engine_symbols.Values | Out-File -Path $path_engine_symbols
|
$engine_symbols.Values | Out-File -Path $path_engine_symbols
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
# Delete old PDBs
|
return $false
|
||||||
$pdb_files = Get-ChildItem -Path $path_build -Filter "engine_postbuild_gen_*.pdb"
|
|
||||||
foreach ($file in $pdb_files) {
|
|
||||||
Remove-Item -Path $file.FullName -Force
|
|
||||||
if ($verbose) { Write-Host "Deleted $file" -ForegroundColor Green }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$compiler_args = @()
|
$unit = Join-Path $path_codegen 'engine_postbuild_gen.cpp'
|
||||||
$compiler_args += ( $flag_define + 'GEN_TIME' )
|
$executable = Join-Path $path_build 'engine_postbuild_gen.exe'
|
||||||
|
$should_build = (check-FileForChanges $unit) -eq $true
|
||||||
$linker_args = @(
|
if ( $should_build )
|
||||||
$flag_link_win_subsystem_console
|
|
||||||
)
|
|
||||||
|
|
||||||
$unit = Join-Path $path_codegen 'engine_postbuild_gen.cpp'
|
|
||||||
$executable = Join-Path $path_build 'engine_postbuild_gen.exe'
|
|
||||||
|
|
||||||
if ( build-simple $path_build $local:includes $compiler_args $linker_args $unit $executable )
|
|
||||||
{
|
{
|
||||||
Push-Location $path_build
|
# Delete old PDBs
|
||||||
$time_taken = Measure-Command {
|
$pdb_files = Get-ChildItem -Path $path_build -Filter "engine_postbuild_gen_*.pdb"
|
||||||
& $executable 2>&1 | ForEach-Object {
|
foreach ($file in $pdb_files) {
|
||||||
write-host `t $_ -ForegroundColor Green
|
Remove-Item -Path $file.FullName -Force
|
||||||
}
|
if ($verbose) { Write-Host "Deleted $file" -ForegroundColor Green }
|
||||||
}
|
}
|
||||||
Pop-Location
|
|
||||||
|
|
||||||
$path_generated_file = Join-Path $path_build 'engine_symbol_table.hpp'
|
$compiler_args = @()
|
||||||
move-item $path_generated_file (join-path $path_gen (split-path $path_generated_file -leaf)) -Force
|
$compiler_args += ( $flag_define + 'GEN_TIME' )
|
||||||
$script:should_format_gen = $true
|
|
||||||
|
|
||||||
return $true
|
$linker_args = @(
|
||||||
|
$flag_link_win_subsystem_console
|
||||||
|
)
|
||||||
|
|
||||||
|
$build_result = build-simple $path_build $local:includes $compiler_args $linker_args $unit $executable
|
||||||
|
if ( $build_result -eq $false ) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
write-host "No changes detected in engine post-build gen, skipping build" -ForegroundColor Yellow
|
||||||
}
|
}
|
||||||
|
|
||||||
return $false
|
Push-Location $path_build
|
||||||
|
$time_taken = Measure-Command {
|
||||||
|
& $executable 2>&1 | ForEach-Object {
|
||||||
|
write-host `t $_ -ForegroundColor Green
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Pop-Location
|
||||||
|
|
||||||
|
$path_generated_file = Join-Path $path_build 'engine_symbols.gen.hpp'
|
||||||
|
move-item $path_generated_file (join-path $path_engine_gen (split-path $path_generated_file -leaf)) -Force
|
||||||
|
|
||||||
|
push-location $path_scripts
|
||||||
|
$include = @(
|
||||||
|
'*.cpp'
|
||||||
|
'*.hpp'
|
||||||
|
)
|
||||||
|
format-cpp $path_engine_gen $include
|
||||||
|
pop-location
|
||||||
|
|
||||||
|
return $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( $engine ) {
|
if ( $engine ) {
|
||||||
@ -331,9 +383,13 @@ function build-platform
|
|||||||
write-host "No changes detected in platform module, skipping build" -ForegroundColor Yellow
|
write-host "No changes detected in platform module, skipping build" -ForegroundColor Yellow
|
||||||
return $true
|
return $true
|
||||||
}
|
}
|
||||||
|
write-host "Building Platform Module" -ForegroundColor Green
|
||||||
|
|
||||||
# CodeGen Pre-Build
|
# CodeGen Pre-Build
|
||||||
if ( $true )
|
$path_engine_symbols = Join-Path $path_engine_gen 'engine_symbols.gen.hpp'
|
||||||
|
$unit = Join-Path $path_codegen 'platform_gen.cpp'
|
||||||
|
$should_build = (check-FileForChanges $unit) -eq $true -or (check-FileForChanges $path_engine_symbols) -eq $true
|
||||||
|
if ( $should_build )
|
||||||
{
|
{
|
||||||
# Delete old PDBs
|
# Delete old PDBs
|
||||||
$pdb_files = Get-ChildItem -Path $path_build -Filter "platform_gen_*.pdb"
|
$pdb_files = Get-ChildItem -Path $path_build -Filter "platform_gen_*.pdb"
|
||||||
@ -374,7 +430,16 @@ function build-platform
|
|||||||
}
|
}
|
||||||
Pop-Location
|
Pop-Location
|
||||||
|
|
||||||
$script:should_format_gen = $true
|
push-location $path_scripts
|
||||||
|
$include = @(
|
||||||
|
'*.cpp'
|
||||||
|
'*.hpp'
|
||||||
|
)
|
||||||
|
format-cpp (Join-Path $path_platform 'gen' ) $include
|
||||||
|
pop-location
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
write-host "No changes detected in platform gen, skipping build" -ForegroundColor Yellow
|
||||||
}
|
}
|
||||||
|
|
||||||
# Delete old PDBs
|
# Delete old PDBs
|
||||||
@ -403,7 +468,6 @@ function build-platform
|
|||||||
$executable = Join-Path $path_binaries 'handmade_win32.exe'
|
$executable = Join-Path $path_binaries 'handmade_win32.exe'
|
||||||
|
|
||||||
return build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
return build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
||||||
|
|
||||||
}
|
}
|
||||||
if ( $platform ) {
|
if ( $platform ) {
|
||||||
$build_result = build-platform
|
$build_result = build-platform
|
||||||
@ -421,18 +485,5 @@ if ( (Test-Path $path_jsl_dll) -eq $false )
|
|||||||
}
|
}
|
||||||
#endregion Handmade Runtime
|
#endregion Handmade Runtime
|
||||||
|
|
||||||
if ( $should_format_gen )
|
|
||||||
{
|
|
||||||
write-host 'Formatting...'
|
|
||||||
push-location $path_scripts
|
|
||||||
$include = @(
|
|
||||||
'*.cpp'
|
|
||||||
'*.hpp'
|
|
||||||
)
|
|
||||||
format-cpp $path_gen $include
|
|
||||||
format-cpp (Join-Path $path_platform 'gen' ) $include
|
|
||||||
pop-location
|
|
||||||
}
|
|
||||||
|
|
||||||
Pop-Location
|
Pop-Location
|
||||||
#endregion Building
|
#endregion Building
|
||||||
|