From 40c34f2b9db2b00a29277f13359fe7466aa026bf Mon Sep 17 00:00:00 2001 From: igor Date: Mon, 20 Apr 2026 08:40:29 -0700 Subject: [PATCH] Day 37 complete. --- data/{test_background.bmp => background.bmp} | Bin data/hero_head_front.bmp | Bin 0 -> 125130 bytes data/test.bmp | Bin 0 -> 19338 bytes handmade.c | 92 +++++++++++++++---- handmade.h | 13 ++- sdl_handmade.c | 2 +- 6 files changed, 88 insertions(+), 19 deletions(-) rename data/{test_background.bmp => background.bmp} (100%) create mode 100644 data/hero_head_front.bmp create mode 100644 data/test.bmp diff --git a/data/test_background.bmp b/data/background.bmp similarity index 100% rename from data/test_background.bmp rename to data/background.bmp diff --git a/data/hero_head_front.bmp b/data/hero_head_front.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e7bd369facf634c187d09e1438698ea3c037445c GIT binary patch literal 125130 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 literal 0 HcmV?d00001 diff --git a/data/test.bmp b/data/test.bmp new file mode 100644 index 0000000000000000000000000000000000000000..73f4167edb9d9870722974a3179320c3cdc3f2ff GIT binary patch literal 19338 zcmeI)F%H5o3;;j_A3iMzWqs5xz zlKIS>G7oW%Q_hk5mut_u>`@~6QWidth); + S32 MaxY = RoundF32toS32(RelY + (F32)Bitmap->Height); + + S32 Width = Buffer->Width; + S32 Height = Buffer->Height; + + if(MinX < 0) + MinX = 0; + if(MinY < 0) + MinY = 0; + + if(MaxX > Width) + MaxX = Width; + if(MaxY > Height) + MaxY = Height; + + U32 *SourceRow = Bitmap->Pixels + Bitmap->Width*(Bitmap->Height - 1); + U8 *DestRow = ((U8 *)Buffer->Memory + MinX*Buffer->BytesPerPixel + MinY*Buffer->Pitch); + for(S32 Y = MinY; Y < MaxY; Y++) { + U32 *Dest = (U32 *)DestRow; + U32 *Source = SourceRow; + for(S32 X = MinX; X < MaxX; X++) { + *Dest++ = *Source++; + } + DestRow += Buffer->Pitch; + SourceRow -= Bitmap->Width; + } +} + #pragma pack(push, 1) typedef struct bitmap_header { U16 FileType; @@ -96,19 +129,47 @@ typedef struct bitmap_header { S32 Height; U16 Planes; U16 BitsPerPixel; + U32 Compression; + U32 SizeOfBitmap; + S32 HorzResolution; + S32 VertResolution; + U32 ColorsUsed; + U32 ColorsImportant; + + U32 RedMask; + U32 GreenMask; + U32 BlueMask; } bitmap_header; #pragma pack(pop) -static U32 *LoadBMP(thread_context *Thread, debug_read_file_result (*DEBUGPlatformReadEntireFile)(thread_context *Thread, const char *), char *FileName) +static loaded_bitmap DEBUGLoadBMP(thread_context *Thread, debug_read_file_result (*DEBUGPlatformReadEntireFile)(thread_context *Thread, const char *), char *FileName) { - U32 *Result = 0; + loaded_bitmap Result; + memset(&Result, 0, sizeof(Result)); + + // NOTE: Byte order in memory is AA BB GG RR, bottom up. + // Littel-endian: 0xRRGGBBAA debug_read_file_result ReadResult = DEBUGPlatformReadEntireFile(Thread, FileName); if(ReadResult.ContentsSize > 0) { bitmap_header *Header = (bitmap_header *)ReadResult.Contents; U32 *Pixels = (U32 *)((U8 *)ReadResult.Contents + Header->BitmapOffset); - Result = Pixels; + Result.Pixels = Pixels; + Result.Width = Header->Width; + Result.Height = Header->Height; + + // TODO: Is this too outdated? As of 2026, this loads fine on little-endian. + // Maybe my BMP uses a newer format. + /* + U32 *SourceDest = Pixels; + for(S32 Y = 0; Y < Header->Height; Y++) { + for(S32 X = 0; X < Header->Width; X++) { + *SourceDest = (*SourceDest >> 8) | (*SourceDest << 24); + SourceDest++; + } + } + */ } return Result; @@ -130,7 +191,10 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In GameState = (game_state *)Memory->PermanentStorage; if(!Memory->IsInitialized) { - GameState->PixelPointer = LoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_background.bmp"); + GameState->Backdrop = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/background.bmp"); + GameState->HeroHead = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/hero_head_front.bmp");; + GameState->HeroCape = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/hero_cape_front.bmp");; + GameState->HeroTorso = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/hero_torso_front.bmp");; GameState->PlayerP.AbsTileX = 2; GameState->PlayerP.AbsTileY = 3; @@ -329,10 +393,13 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In } } + DrawRectangle(Buffer, 0.0f, 0.0f, (F32)Buffer->Width, (F32)Buffer->Height, 0.0f, 1.0f, 0.0f); + + DrawBitmap(Buffer, &GameState->Backdrop, 0.0f, 0.0f); + F32 ScreenCenterX = 0.5f * (F32)Buffer->Width; F32 ScreenCenterY = 0.5f * (F32)Buffer->Height; - DrawRectangle(Buffer, 0.0f, 0.0f, (F32)Buffer->Width, (F32)Buffer->Height, 0.0f, 1.0f, 0.0f); for(S32 RelRow = -10; RelRow < 10; RelRow++) { for(S32 RelColumn = -20; RelColumn < 20; RelColumn++) { U32 Column = GameState->PlayerP.AbsTileX + RelColumn; @@ -340,7 +407,7 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In U32 TileID = GetTileValue(TileMap, Column, Row, GameState->PlayerP.AbsTileZ); - if(TileID > 0) { + if(TileID > 1) { F32 Gray = 0.5f; if(TileID == 2) { Gray = 1.0f; @@ -371,17 +438,8 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In F32 PlayerB = 0.0f; F32 PlayerLeft = ScreenCenterX - 0.5f * MetersToPixels*PlayerWidth; F32 PlayerTop = ScreenCenterY - MetersToPixels*PlayerHeight; - DrawRectangle(Buffer, PlayerLeft, PlayerTop, PlayerLeft + MetersToPixels*PlayerWidth, PlayerTop + MetersToPixels*PlayerHeight, PlayerR, PlayerG, PlayerB); - -#if 0 - U32 *Source = GameState->PixelPointer; - U32 *Dest = (U32 *)Buffer->Memory; - for(S32 Y = 0; Y < Buffer->Height; Y++) { - for(S32 X = 0; X < Buffer->Width; X++) { - *Dest++ = *Source++; - } - } -#endif + //DrawRectangle(Buffer, PlayerLeft, PlayerTop, PlayerLeft + MetersToPixels*PlayerWidth, PlayerTop + MetersToPixels*PlayerHeight, PlayerR, PlayerG, PlayerB); + DrawBitmap(Buffer, &GameState->HeroHead, PlayerLeft, PlayerTop); GameOutputSound(GameState, SoundBuffer, 400); } diff --git a/handmade.h b/handmade.h index 1f204d4..64c6ed9 100644 --- a/handmade.h +++ b/handmade.h @@ -165,12 +165,23 @@ typedef struct world { tile_map *TileMap; } world; +typedef struct loaded_bitmap { + S32 Width; + S32 Height; + U32 *Pixels; +} loaded_bitmap; + typedef struct game_state { memory_arena WorldArena; world *World; tile_map_position PlayerP; - U32 *PixelPointer; + + loaded_bitmap Backdrop; + + loaded_bitmap HeroHead; + loaded_bitmap HeroCape; + loaded_bitmap HeroTorso; } game_state; #endif diff --git a/sdl_handmade.c b/sdl_handmade.c index e67d4b2..785706e 100644 --- a/sdl_handmade.c +++ b/sdl_handmade.c @@ -557,7 +557,7 @@ S32 main(S32 argc, char *argv[]) SDL_GetCurrentDisplayMode(0, &display_mode); SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC); - SDL_SetWindowPosition(Window, (display_mode.w - RESOLUTION_WIDTH), (display_mode.h - RESOLUTION_HEIGHT)); + SDL_SetWindowPosition(Window, (display_mode.w - RESOLUTION_WIDTH-20), (display_mode.h - RESOLUTION_HEIGHT-20)); /* NOTE: For future reference, the custom window bar should use * SDL_SetWindowHitTest to define areas that will be used to