Day 36 complete

This commit is contained in:
Edward R. Gonzalez 2023-10-19 14:16:50 -04:00
parent b81e439038
commit ffba625a24
12 changed files with 216 additions and 44 deletions

View File

@ -33,7 +33,7 @@ Module build order:
## Milestone ## Milestone
Day 35 : Basic Sparse Tilemap Storage Day 36 : Loading BMPs
Features Done so far: Features Done so far:
@ -62,6 +62,7 @@ Features Done so far:
## Gallery ## Gallery
![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)
![img](docs/imgs/handmade_win32_2023-10-11_00-47-19.gif) ![img](docs/imgs/handmade_win32_2023-10-11_00-47-19.gif)

BIN
data/content/MOJITO.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

5
docs/Day 036.md Normal file
View File

@ -0,0 +1,5 @@
# Day 36
Just dealing with Casey's "methods" for going about the code exploration...
Loading an image was nice, I got it to render somewhat properly with draw_bitmap but until he does it I kept the bad way hes doing it.

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

View File

@ -236,6 +236,49 @@ void draw_rectangle( OffscreenBuffer* buffer
} }
} }
internal
void draw_bitmap( OffscreenBuffer* buffer
, f32 min_x, f32 min_y
, f32 max_x, f32 max_y
, u32* pixels, u32 size )
{
s32 min_x_32 = round( min_x );
s32 min_y_32 = round( min_y );
s32 max_x_32 = round( max_x );
s32 max_y_32 = round( max_y );
s32 buffer_width = buffer->width;
s32 buffer_height = buffer->height;
if ( min_x_32 < 0 )
min_x_32 = 0;
if ( min_y_32 < 0 )
min_y_32 = 0;
if ( max_x_32 > buffer_width )
max_x_32 = buffer_width;
if ( max_y_32 > buffer_height )
max_y_32 = buffer_height;
// Start with the pixel on the top left corner of the rectangle
u8* row = rcast(u8*, buffer->memory )
+ min_x_32 * buffer->bytes_per_pixel
+ min_y_32 * buffer->pitch;
for ( s32 y = min_y_32; y < max_y_32; ++ y )
{
s32* pixel_32 = rcast(s32*, row);
for ( s32 x = min_x_32; x < max_x_32; ++ x )
{
u32 color = pixels[ y * max_x_32 + x ];
*pixel_32 = color;
pixel_32++;
}
row += buffer->pitch;
}
}
inline inline
void draw_debug_point(OffscreenBuffer* back_buffer, World* world, TileMapPosition pos, f32 red, f32 green, f32 blue) void draw_debug_point(OffscreenBuffer* back_buffer, World* world, TileMapPosition pos, f32 red, f32 green, f32 blue)
{ {
@ -249,6 +292,26 @@ void draw_debug_point(OffscreenBuffer* back_buffer, World* world, TileMapPositio
red, green, blue); red, green, blue);
} }
internal
Bitmap load_bmp( platform::FileReadContentFn* file_read_content, Str file_path )
{
Bitmap result {};
platform::File file {
file_path
};
if ( ! file_read_content( & file ) )
{
return result;
}
BitmapHeaderPacked* header = pcast(BitmapHeaderPacked*, file.data);
result.pixels = rcast(u32*, rcast(Byte*, file.data) + header->bitmap_offset);
result.width = header->width;
result.height = header->height;
result.bits_per_pixel = header->bits_per_pixel;
return result;
}
Engine_API Engine_API
void on_module_reload( Memory* memory, platform::ModuleAPI* platfom_api ) void on_module_reload( Memory* memory, platform::ModuleAPI* platfom_api )
@ -362,8 +425,10 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
} }
++ rng_index; ++ rng_index;
b32 created_z_door = false;
if ( random_choice == 2 ) if ( random_choice == 2 )
{ {
created_z_door = true;
if ( abs_tile_z == 0 ) if ( abs_tile_z == 0 )
{ {
door_up = true; door_up = true;
@ -438,15 +503,10 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
door_left = door_right; door_left = door_right;
door_bottom = door_top; door_bottom = door_top;
if ( door_up ) if ( created_z_door )
{ {
door_down = true; door_down = ! door_down;
door_up = false; door_up = ! door_up;
}
else if ( door_down )
{
door_up = true;
door_down = false;
} }
else else
{ {
@ -482,6 +542,14 @@ 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;
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_mojito;
path_mojito.concat( platform_api->path_content, str_ascii("mojito.bmp") );
game_state->mojito = load_bmp( platform_api->file_read_content, path_mojito );
hh::PlayerState* player = & game_state->player_state; hh::PlayerState* player = & game_state->player_state;
player->position.tile_x = 4; player->position.tile_x = 4;
player->position.tile_y = 4; player->position.tile_y = 4;
@ -680,7 +748,7 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
{ {
TileMapPosition test_pos = { TileMapPosition test_pos = {
new_player_pos_x, new_player_pos_y, new_player_pos_x, new_player_pos_y,
player->position.tile_x, player->position.tile_y player->position.tile_x, player->position.tile_y, player->position.tile_z
}; };
test_pos = recannonicalize_position( tile_map, test_pos ); test_pos = recannonicalize_position( tile_map, test_pos );
@ -688,28 +756,28 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
TileMapPosition test_pos_nw { TileMapPosition test_pos_nw {
new_player_pos_x - player_half_width, new_player_pos_y + player_quarter_height, new_player_pos_x - player_half_width, new_player_pos_y + player_quarter_height,
player->position.tile_x, player->position.tile_y player->position.tile_x, player->position.tile_y, player->position.tile_z
}; };
test_pos_nw = recannonicalize_position( tile_map, test_pos_nw ); test_pos_nw = recannonicalize_position( tile_map, test_pos_nw );
valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_nw ); valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_nw );
TileMapPosition test_pos_ne { TileMapPosition test_pos_ne {
new_player_pos_x + player_half_width, new_player_pos_y + player_quarter_height, new_player_pos_x + player_half_width, new_player_pos_y + player_quarter_height,
player->position.tile_x, player->position.tile_y player->position.tile_x, player->position.tile_y, player->position.tile_z
}; };
test_pos_ne = recannonicalize_position( tile_map, test_pos_ne ); test_pos_ne = recannonicalize_position( tile_map, test_pos_ne );
valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_ne ); valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_ne );
TileMapPosition test_pos_sw { TileMapPosition test_pos_sw {
new_player_pos_x - player_half_width, new_player_pos_y, new_player_pos_x - player_half_width, new_player_pos_y,
player->position.tile_x, player->position.tile_y player->position.tile_x, player->position.tile_y, player->position.tile_z
}; };
test_pos_sw = recannonicalize_position( tile_map, test_pos_sw ); test_pos_sw = recannonicalize_position( tile_map, test_pos_sw );
valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_sw ); valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_sw );
TileMapPosition test_pos_se { TileMapPosition test_pos_se {
new_player_pos_x + player_half_width, new_player_pos_y, new_player_pos_x + player_half_width, new_player_pos_y,
player->position.tile_x, player->position.tile_y player->position.tile_x, player->position.tile_y, player->position.tile_z
}; };
test_pos_se = recannonicalize_position( tile_map, test_pos_se ); test_pos_se = recannonicalize_position( tile_map, test_pos_se );
valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_se ); valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_se );
@ -717,11 +785,29 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
if ( valid_new_pos ) if ( valid_new_pos )
{ {
TileMapPosition new_pos = { TileMapPosition new_pos = {
new_player_pos_x, new_player_pos_y, new_player_pos_x, new_player_pos_y,
player->position.tile_x, player->position.tile_y player->position.tile_x, player->position.tile_y, player->position.tile_z
}; };
player->position = recannonicalize_position( tile_map, new_pos ); new_pos = recannonicalize_position( tile_map, new_pos );
bool on_new_tile = TileMap_are_on_same_tile( & new_pos, & player->position );
if ( ! on_new_tile )
{
u32 new_tile_value = TileMap_get_tile_value( tile_map, new_pos );
if ( new_tile_value == 3 )
{
++ new_pos.tile_z;
}
else if ( new_tile_value == 4 )
{
-- new_pos.tile_z;
}
}
player->position = new_pos;
} }
if ( player->jump_time > 0.f ) if ( player->jump_time > 0.f )
@ -805,6 +891,27 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
} }
} }
// 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
{
u32* src = game_state->mojito.pixels;
u32* dst = rcast(u32*, back_buffer->memory);
for ( s32 y = 0; y < game_state->mojito.height; ++ y )
{
for ( s32 x = 0; x < game_state->mojito.width; ++ x )
{
*dst = *src;
++ dst;
++ src;
}
}
}
// Player // Player
f32 player_red = 0.7f; f32 player_red = 0.7f;
f32 player_green = 0.7f; f32 player_green = 0.7f;

View File

@ -94,9 +94,9 @@ struct Memory
//ReplayData replay; //ReplayData replay;
#endif #endif
// The game will have 1/4 of persistent's memory available ot it. // The game will have 1/2 of persistent's memory available ot it.
static constexpr static constexpr
ssize game_memory_factor = 4; ssize game_memory_factor = 2;
ssize engine_persistent_size() ssize engine_persistent_size()
{ {
@ -181,4 +181,29 @@ struct World
TileMap* tile_map; TileMap* tile_map;
}; };
#pragma pack(push, 1)
struct BitmapHeaderPacked
{
u16 file_type;
u32 file_size;
u16 _reserved_1_;
u16 _reserved_2_;
u32 bitmap_offset;
u32 size;
s32 width;
s32 height;
u16 planes;
u16 bits_per_pixel;
};
#pragma pack(pop)
struct Bitmap
{
u32* pixels;
s32 width;
s32 height;
u32 bits_per_pixel;
u32 size;
};
NS_ENGINE_END NS_ENGINE_END

View File

@ -4,6 +4,7 @@
NS_ENGINE_BEGIN NS_ENGINE_BEGIN
// TODO(Ed) : Consider moving (Casey wants to)
inline inline
void cannonicalize_coord( TileMap* tile_map, u32* tile_coord, f32* pos_coord ) void cannonicalize_coord( TileMap* tile_map, u32* tile_coord, f32* pos_coord )
{ {
@ -24,6 +25,7 @@ void cannonicalize_coord( TileMap* tile_map, u32* tile_coord, f32* pos_coord )
(* pos_coord) = new_pos_coord; (* pos_coord) = new_pos_coord;
} }
// TODO(Ed) : Consider moving (Casey wants to)
inline inline
TileMapPosition recannonicalize_position( TileMap* tile_map, TileMapPosition pos ) TileMapPosition recannonicalize_position( TileMap* tile_map, TileMapPosition pos )
{ {
@ -91,6 +93,7 @@ TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, u32 abs_tile_x
return chunk_pos; return chunk_pos;
} }
inline
u32 TileMap_get_tile_value( TileMap* tile_map, u32 tile_x, u32 tile_y, u32 tile_z ) u32 TileMap_get_tile_value( TileMap* tile_map, u32 tile_x, u32 tile_y, u32 tile_z )
{ {
assert( tile_map != nullptr ); assert( tile_map != nullptr );
@ -105,13 +108,24 @@ u32 TileMap_get_tile_value( TileMap* tile_map, u32 tile_x, u32 tile_y, u32 tile_
return value; return value;
} }
inline
u32 TileMap_get_tile_value( TileMap* tile_map, TileMapPosition position )
{
u32 value = TileMap_get_tile_value( tile_map, position.tile_x, position.tile_y, position.tile_z );
return value;
}
internal internal
b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPosition position ) b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPosition position )
{ {
assert( tile_map != nullptr ); assert( tile_map != nullptr );
u32 chunk_value = TileMap_get_tile_value( tile_map, position.tile_x, position.tile_y, position.tile_z ); u32 chunk_value = TileMap_get_tile_value( tile_map, position.tile_x, position.tile_y, position.tile_z );
b32 is_empty = chunk_value == 1;
b32
is_empty = chunk_value == 1;
is_empty |= chunk_value == 3;
is_empty |= chunk_value == 4;
return is_empty; return is_empty;
} }
@ -137,4 +151,15 @@ void TileMap_set_tile_value( MemoryArena* arena, TileMap* tile_map, u32 abs_tile
TileChunk_set_tile_value( chunk, tile_map, chunk_pos.tile_x, chunk_pos.tile_y, value ); TileChunk_set_tile_value( chunk, tile_map, chunk_pos.tile_x, chunk_pos.tile_y, value );
} }
internal
b32 TileMap_are_on_same_tile( TileMapPosition* pos_a, TileMapPosition* pos_b )
{
b32 result =
pos_a->tile_x == pos_b->tile_x
&& pos_a->tile_y == pos_b->tile_y
&& pos_a->tile_z == pos_b->tile_z;
return result;
}
NS_ENGINE_END NS_ENGINE_END

View File

@ -50,8 +50,7 @@ struct TileMap
struct TileMapPosition struct TileMapPosition
{ {
// TODO(Ed) : Should this be from the center of the tile? // Note(Ed) : Relative position from tile center.
f32 x; f32 x;
f32 y; f32 y;

View File

@ -94,6 +94,9 @@ struct PlayerActions
struct GameState struct GameState
{ {
PlayerState player_state; PlayerState player_state;
engine::Bitmap test_bg;
engine::Bitmap mojito;
}; };
NS_HANDMADE_END NS_HANDMADE_END

View File

@ -35,8 +35,8 @@ using DebugSetPauseRenderingFn = void (b32 value);
struct File struct File
{ {
void* opaque_handle;
Str path; Str path;
void* opaque_handle;
void* data; void* data;
u32 size; u32 size;
}; };
@ -87,6 +87,7 @@ struct ModuleAPI
{ {
Str path_root; Str path_root;
Str path_binaries; Str path_binaries;
Str path_content;
Str path_scratch; Str path_scratch;
#if Build_Development #if Build_Development

View File

@ -58,6 +58,7 @@ global PlatformContext Platform_Context;
global StrPath Path_Root; global StrPath Path_Root;
global StrPath Path_Binaries; global StrPath Path_Binaries;
global StrPath Path_Content;
global StrPath Path_Scratch; global StrPath Path_Scratch;
// TODO(Ed) : This is a global for now. // TODO(Ed) : This is a global for now.
@ -520,6 +521,10 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho
++ Path_Scratch.len; ++ Path_Scratch.len;
CreateDirectoryA( Path_Scratch, 0 ); CreateDirectoryA( Path_Scratch, 0 );
Path_Content.concat( Path_Root, str_ascii("content") );
Path_Content.ptr[ Path_Content.len ] = '\\';
++ Path_Content.len;
} }
// Memory // Memory
@ -667,6 +672,7 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho
{ {
platform_api.path_root = Path_Root; platform_api.path_root = Path_Root;
platform_api.path_binaries = Path_Binaries; platform_api.path_binaries = Path_Binaries;
platform_api.path_content = Path_Content;
platform_api.path_scratch = Path_Scratch; platform_api.path_scratch = Path_Scratch;
#if Build_Development #if Build_Development