Half of day 32.

This commit is contained in:
igor
2026-04-11 20:08:36 -07:00
parent 1635bebb5d
commit e13e4f44e6
4 changed files with 83 additions and 101 deletions
+65 -80
View File
@@ -138,56 +138,44 @@ static B32 IsTileMapPointEmpty(world *World, tile_map *TileMap,
return Empty; return Empty;
} }
static cannonical_position GetCannonicalPosition(world *World, static void CannonicalizeCoord(world *World, S32 TileCount,
raw_position Pos) S32 *TileMap, S32 *Tile, F32 *TileRel)
{ {
cannonical_position Result; S32 Offset = FloorF32toS32(*TileRel / World->TileSideInMeters);
F32 X, Y; *Tile += Offset;
*TileRel -= (F32)Offset * World->TileSideInMeters;
Result.TileMapX = Pos.TileMapX; ASSERT(*TileRel >= 0);
Result.TileMapY = Pos.TileMapY; ASSERT(*TileRel < World->TileSideInMeters);
X = Pos.X - World->UpperLeftX; if(*Tile < 0) {
Y = Pos.Y - World->UpperLeftY; *Tile = TileCount + *Tile;
Result.TileX = FloorF32toS32(X / (F32)World->TileSideInPixels); (*TileMap)--;
Result.TileY = FloorF32toS32(Y / (F32)World->TileSideInPixels);
Result.X = X - (F32)Result.TileX*(F32)World->TileSideInPixels;
Result.Y = Y - (F32)Result.TileY*(F32)World->TileSideInPixels;
ASSERT(Result.X >= 0);
ASSERT(Result.Y >= 0);
ASSERT(Result.X < (F32)World->TileSideInPixels);
ASSERT(Result.Y < (F32)World->TileSideInPixels);
if(Result.TileX < 0) {
Result.TileX = World->CountX + Result.TileX;
Result.TileMapX--;
} }
if(Result.TileY < 0) { if(*Tile >= World->CountX) {
Result.TileY = World->CountY + Result.TileY; *Tile = *Tile - TileCount;
Result.TileMapY--; (*TileMap)++;
}
if(Result.TileX >= World->CountX) {
Result.TileX = Result.TileX - World->CountX;
Result.TileMapX++;
}
if(Result.TileY >= World->CountY) {
Result.TileY = Result.TileY - World->CountY;
Result.TileMapY++;
} }
}
static cannonical_position RecannonicalizePosition(world *World,
cannonical_position Pos)
{
cannonical_position Result = Pos;
CannonicalizeCoord(World, World->TileMapCountX,
&Result.TileMapX, &Result.TileX, &Result.TileRelX);
CannonicalizeCoord(World, World->TileMapCountY,
&Result.TileMapY, &Result.TileY, &Result.TileRelY);
return Result; return Result;
} }
static B32 IsWorldPointEmpty(world *World, raw_position TestPos) static B32 IsWorldPointEmpty(world *World, cannonical_position CanPos)
{ {
B32 Empty = FALSE; B32 Empty = FALSE;
tile_map *TileMap; tile_map *TileMap = GetTileMap(World, CanPos.TileMapX, CanPos.TileMapY);
cannonical_position CanPos = GetCannonicalPosition(World, TestPos);
TileMap = GetTileMap(World, CanPos.TileMapX, CanPos.TileMapY);
Empty = IsTileMapPointEmpty(World, TileMap, CanPos.TileX, CanPos.TileY); Empty = IsTileMapPointEmpty(World, TileMap, CanPos.TileX, CanPos.TileY);
return Empty; return Empty;
@@ -273,23 +261,29 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
World.CountY = TILEMAP_COUNT_Y; World.CountY = TILEMAP_COUNT_Y;
World.TileSideInMeters = 1.4f; World.TileSideInMeters = 1.4f;
World.TileSideInPixels = 60; World.TileSideInPixels = 60;
World.MetersToPixels =
(F32)World.TileSideInPixels / World.TileSideInMeters;
World.UpperLeftX = -((F32)World.TileSideInPixels / 2.0f); World.UpperLeftX = -((F32)World.TileSideInPixels / 2.0f);
World.UpperLeftY = 0.0f; World.UpperLeftY = 0.0f;
World.TileMaps = (tile_map *)TileMaps; World.TileMaps = (tile_map *)TileMaps;
PlayerWidth = 0.75f * (F32)World.TileSideInPixels; PlayerHeight = 1.4f;
PlayerHeight = (F32)World.TileSideInPixels; PlayerWidth = 0.75f * PlayerHeight;
GameState = (game_state *)Memory->PermanentStorage; GameState = (game_state *)Memory->PermanentStorage;
if(!Memory->IsInitialized) { if(!Memory->IsInitialized) {
GameState->PlayerX = 200.0f; GameState->PlayerP.TileMapX = 0;
GameState->PlayerY = 200.0f; GameState->PlayerP.TileMapY = 0;
GameState->PlayerP.TileX = 3;
GameState->PlayerP.TileY = 3;
GameState->PlayerP.TileRelX = 5.0f;
GameState->PlayerP.TileRelY = 5.0f;
Memory->IsInitialized = TRUE; Memory->IsInitialized = TRUE;
} }
TileMap = GetTileMap(&World, GameState->PlayerTileMapX, TileMap = GetTileMap(&World, GameState->PlayerP.TileMapX,
GameState->PlayerTileMapY); GameState->PlayerP.TileMapY);
ASSERT(TileMap); ASSERT(TileMap);
for(ControllerIndex = 0; for(ControllerIndex = 0;
@@ -303,9 +297,7 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
F32 dPlayerX = 0.0f; F32 dPlayerX = 0.0f;
F32 dPlayerY = 0.0f; F32 dPlayerY = 0.0f;
F32 NewPlayerX, NewPlayerY; cannonical_position NewPlayerP, PlayerLeft, PlayerRight;
raw_position PlayerPos, PlayerLeft, PlayerRight;
if(Controller->u.buttons.MoveUp.EndedDown) { if(Controller->u.buttons.MoveUp.EndedDown) {
dPlayerY = -1.0f; dPlayerY = -1.0f;
@@ -320,38 +312,27 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
dPlayerX = 1.0f; dPlayerX = 1.0f;
} }
dPlayerX *= 200.0f; dPlayerX *= 10.0f;
dPlayerY *= 200.0f; dPlayerY *= 10.0f;
NewPlayerX = GameState->PlayerX + Input->dtForFrame*dPlayerX; NewPlayerP = GameState->PlayerP;
NewPlayerY = GameState->PlayerY + Input->dtForFrame*dPlayerY; NewPlayerP.TileRelX += Input->dtForFrame*dPlayerX;
NewPlayerP.TileRelY += Input->dtForFrame*dPlayerY;
NewPlayerP = RecannonicalizePosition(&World, NewPlayerP);
PlayerPos.TileMapX = GameState->PlayerTileMapX; PlayerLeft = NewPlayerP;
PlayerPos.TileMapY = GameState->PlayerTileMapY; PlayerLeft.TileRelX -= 0.5f*PlayerWidth;
PlayerPos.X = NewPlayerX; PlayerLeft = RecannonicalizePosition(&World, PlayerLeft);
PlayerPos.Y = NewPlayerY;
PlayerLeft = PlayerPos; PlayerRight = NewPlayerP;
PlayerLeft.X -= 0.5f*PlayerWidth; PlayerRight.TileRelX += 0.5f*PlayerWidth;
PlayerRight = RecannonicalizePosition(&World, PlayerRight);
PlayerRight = PlayerPos; if(IsWorldPointEmpty(&World, NewPlayerP) &&
PlayerRight.X += 0.5f*PlayerWidth;
if(IsWorldPointEmpty(&World, PlayerPos) &&
IsWorldPointEmpty(&World, PlayerLeft) && IsWorldPointEmpty(&World, PlayerLeft) &&
IsWorldPointEmpty(&World, PlayerRight)) IsWorldPointEmpty(&World, PlayerRight))
{ {
cannonical_position CanPos = GameState->PlayerP = NewPlayerP;
GetCannonicalPosition(&World, PlayerPos);
GameState->PlayerTileMapX = CanPos.TileMapX;
GameState->PlayerTileMapY = CanPos.TileMapY;
GameState->PlayerX = World.UpperLeftX +
(F32)World.TileSideInPixels * (F32)CanPos.TileX +
CanPos.X;
GameState->PlayerY = World.UpperLeftY +
(F32)World.TileSideInPixels * (F32)CanPos.TileY +
CanPos.Y;
} }
} }
} }
@@ -381,18 +362,22 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
PlayerR = 1.0f; PlayerR = 1.0f;
PlayerG = 0.0f; PlayerG = 0.0f;
PlayerB = 0.0f; PlayerB = 0.0f;
PlayerLeft = GameState->PlayerX - 0.5f*PlayerWidth; PlayerLeft = World.UpperLeftX +
PlayerTop = GameState->PlayerY - PlayerHeight; (F32)World.TileSideInPixels*(F32)GameState->PlayerP.TileX +
(F32)GameState->PlayerP.TileX +
World.MetersToPixels*GameState->PlayerP.TileRelX -
0.5f*PlayerWidth;
PlayerTop = World.UpperLeftY +
(F32)World.TileSideInPixels*(F32)GameState->PlayerP.TileY +
(F32)GameState->PlayerP.TileY +
World.MetersToPixels*GameState->PlayerP.TileRelY -
PlayerHeight;
DrawRectangle(Buffer, DrawRectangle(Buffer,
PlayerLeft, PlayerTop, PlayerLeft, PlayerTop,
PlayerLeft + PlayerWidth, PlayerTop + PlayerHeight, PlayerLeft + World.MetersToPixels*PlayerWidth,
PlayerTop + World.MetersToPixels*PlayerHeight,
PlayerR, PlayerG, PlayerB); PlayerR, PlayerG, PlayerB);
DrawRectangle(Buffer,
(F32)(Input->MouseX) - 15.0f, (F32)(Input->MouseY) - 15.0f,
(F32)(Input->MouseX) + 5.0f, (F32)(Input->MouseY) + 5.0f,
1.0f, 0.5f, 0.0f);
GameOutputSound(GameState, SoundBuffer, 400); GameOutputSound(GameState, SoundBuffer, 400);
} }
+11 -18
View File
@@ -105,12 +105,12 @@ typedef struct game_memory {
B32 IsInitialized; B32 IsInitialized;
U64 PermanentStorageSize; U64 PermanentStorageSize;
void *PermanentStorage; /* WARNING: This memory is REQUIRED to be zero void *PermanentStorage; /* WARNING: This memory is REQUIRED to be zero
initialized!!! (Done by the OS initialized!!! (Done by the OS
layer.) */ layer.) */
U64 TransientStorageSize; U64 TransientStorageSize;
void *TransientStorage; /* WARNING: This memory is REQUIRED to be zero void *TransientStorage; /* WARNING: This memory is REQUIRED to be zero
initialized!!! (Done by the OS initialized!!! (Done by the OS
layer.) */ layer.) */
@@ -137,26 +137,22 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
*/ */
typedef struct cannonical_position { typedef struct cannonical_position {
#if 1
S32 TileMapX; S32 TileMapX;
S32 TileMapY; S32 TileMapY;
S32 TileX; S32 TileX;
S32 TileY; S32 TileY;
#else
U32 _TileX;
U32 _TileY;
#endif
/* NOTE: Tile-relative X and Y. */ /* NOTE: Tile-relative X and Y. */
F32 X; F32 TileRelX;
F32 Y; F32 TileRelY;
} cannonical_position; } cannonical_position;
typedef struct raw_position {
S32 TileMapX;
S32 TileMapY;
/* NOTE: Tile-map relative X and Y. */
F32 X;
F32 Y;
} raw_position;
typedef struct tile_map { typedef struct tile_map {
U32 *Tiles; U32 *Tiles;
} tile_map; } tile_map;
@@ -164,6 +160,7 @@ typedef struct tile_map {
typedef struct world { typedef struct world {
F32 TileSideInMeters; F32 TileSideInMeters;
S32 TileSideInPixels; S32 TileSideInPixels;
F32 MetersToPixels;
S32 CountX; S32 CountX;
S32 CountY; S32 CountY;
@@ -178,11 +175,7 @@ typedef struct world {
} world; } world;
typedef struct game_state { typedef struct game_state {
S32 PlayerTileMapX; cannonical_position PlayerP;
S32 PlayerTileMapY;
F32 PlayerX;
F32 PlayerY;
} game_state; } game_state;
#endif #endif
+1
View File
@@ -37,3 +37,4 @@ F32 ATan2(F32 Y, F32 X)
} }
#endif #endif
+5 -2
View File
@@ -313,6 +313,7 @@ static void HandleEvent(SDL_Event *Event)
case SDL_WINDOWEVENT_EXPOSED: { case SDL_WINDOWEVENT_EXPOSED: {
} break; } break;
#if 0
case SDL_WINDOWEVENT_FOCUS_GAINED: { case SDL_WINDOWEVENT_FOCUS_GAINED: {
if(SDL_SetWindowOpacity(Window, 1.0f) != 0) { if(SDL_SetWindowOpacity(Window, 1.0f) != 0) {
/* TODO: This didn't work . . . SDL_GetError() */ /* TODO: This didn't work . . . SDL_GetError() */
@@ -324,6 +325,7 @@ static void HandleEvent(SDL_Event *Event)
/* TODO: This didn't work . . . SDL_GetError() */ /* TODO: This didn't work . . . SDL_GetError() */
} }
} break; } break;
#endif
} }
} break; } break;
} }
@@ -759,8 +761,9 @@ S32 main(S32 argc, char *argv[])
Window = SDL_CreateWindow("Handmade Hero", SDL_WINDOWPOS_UNDEFINED, Window = SDL_CreateWindow("Handmade Hero", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
RESOLUTION_WIDTH, RESOLUTION_HEIGHT, RESOLUTION_WIDTH, RESOLUTION_HEIGHT,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_RESIZABLE);
SDL_WINDOW_ALWAYS_ON_TOP); /*SDL_WINDOW_RESIZABLE |
SDL_WINDOW_ALWAYS_ON_TOP);*/
if(Window) { if(Window) {
SDL_Renderer *Renderer; SDL_Renderer *Renderer;