diff --git a/handmade.c b/handmade.c index 3ed63cd..9f2ed4a 100644 --- a/handmade.c +++ b/handmade.c @@ -1,5 +1,6 @@ #include "core.h" #include "handmade.h" +#include "handmade_math.h" #include "sdl_handmade.h" #include "handmade_intrinsics.h" @@ -7,6 +8,7 @@ #include "handmade_tile.h" #include "handmade_tile.c" +#include #include /* memset */ static void GameOutputSound(game_state *GameState, game_sound_output_buffer *SoundBuffer, S32 ToneHz) @@ -51,12 +53,12 @@ static void ClearBackground(game_offscreen_buffer *Buffer) } } -static void DrawRectangle(game_offscreen_buffer *Buffer, F32 RealMinX, F32 RealMinY, F32 RealMaxX, F32 RealMaxY, F32 R, F32 G, F32 B) +static void DrawRectangle(game_offscreen_buffer *Buffer, v2 vMin, v2 vMax, F32 R, F32 G, F32 B) { - S32 MinX = RoundF32toS32(RealMinX); - S32 MinY = RoundF32toS32(RealMinY); - S32 MaxX = RoundF32toS32(RealMaxX); - S32 MaxY = RoundF32toS32(RealMaxY); + S32 MinX = RoundF32toS32(vMin.X); + S32 MinY = RoundF32toS32(vMin.Y); + S32 MaxX = RoundF32toS32(vMax.X); + S32 MaxY = RoundF32toS32(vMax.Y); S32 Width = Buffer->Width; S32 Height = Buffer->Height; @@ -222,13 +224,9 @@ static loaded_bitmap DEBUGLoadBMP(thread_context *Thread, debug_read_file_result void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *Input, game_offscreen_buffer *Buffer, game_sound_output_buffer *SoundBuffer) { - ASSERT((&Input->Controllers[0].Terminator - &Input->Controllers[0].Buttons[0]) == ARRAY_SIZE(Input->Controllers[0].Buttons)); ASSERT(sizeof(game_state) <= Memory->PermanentStorageSize); -#define TILEMAP_COUNT_X 256 -#define TILEMAP_COUNT_Y 256 - game_state *GameState; F32 PlayerHeight = 1.4f; @@ -273,8 +271,8 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In GameState->PlayerP.AbsTileX = 2; GameState->PlayerP.AbsTileY = 3; - GameState->PlayerP.OffsetX = 5.0f; - GameState->PlayerP.OffsetY = 5.0f; + GameState->PlayerP.Offset.X = 5.0f; + GameState->PlayerP.Offset.Y = 5.0f; InitializeArena(&GameState->WorldArena, Memory->PermanentStorageSize - sizeof(game_state), (U8 *)Memory->PermanentStorage + sizeof(game_state)); @@ -413,48 +411,47 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In game_controller_input *Controller = GetController(Input, ControllerIndex); if(Controller->IsAnalog) { } else { - F32 dPlayerX = 0.0f; - F32 dPlayerY = 0.0f; + v2 dPlayer; + memset(&dPlayer, 0, sizeof(dPlayer)); if(Controller->MoveUp.EndedDown) { - dPlayerY = 1.0f; + dPlayer.Y = 1.0f; GameState->FacingDirection = 1; } if(Controller->MoveDown.EndedDown) { - dPlayerY = -1.0f; + dPlayer.Y = -1.0f; GameState->FacingDirection = 3; } if(Controller->MoveLeft.EndedDown) { - dPlayerX = -1.0f; + dPlayer.X = -1.0f; GameState->FacingDirection = 2; } if(Controller->MoveRight.EndedDown) { - dPlayerX = 1.0f; + dPlayer.X = 1.0f; GameState->FacingDirection = 0; } F32 PlayerSpeed = 2.0f; - if(Controller->ActionUp.EndedDown) PlayerSpeed = 10.0f; + dPlayer = vector_multiply(PlayerSpeed, dPlayer); - dPlayerX *= PlayerSpeed; - dPlayerY *= PlayerSpeed; + if((dPlayer.X != 0.0f) && (dPlayer.Y != 0.0f)) + dPlayer = vector_multiply(0.7071067811865475244f, dPlayer); tile_map_position NewPlayerP; NewPlayerP = GameState->PlayerP; - NewPlayerP.OffsetX += Input->dtForFrame*dPlayerX; - NewPlayerP.OffsetY += Input->dtForFrame*dPlayerY; + NewPlayerP.Offset = vector_add(NewPlayerP.Offset, vector_multiply(Input->dtForFrame, dPlayer)); NewPlayerP = RecannonicalizePosition(TileMap, NewPlayerP); tile_map_position PlayerLeft; PlayerLeft = NewPlayerP; - PlayerLeft.OffsetX -= 0.5f*PlayerWidth; + PlayerLeft.Offset.X -= 0.5f*PlayerWidth; PlayerLeft = RecannonicalizePosition(TileMap, PlayerLeft); tile_map_position PlayerRight; PlayerRight = NewPlayerP; - PlayerRight.OffsetX += 0.5f*PlayerWidth; + PlayerRight.Offset.X += 0.5f*PlayerWidth; PlayerRight = RecannonicalizePosition(TileMap, PlayerRight); if(IsTileMapPointEmpty(TileMap, NewPlayerP) && IsTileMapPointEmpty(TileMap, PlayerLeft) && IsTileMapPointEmpty(TileMap, PlayerRight)) { @@ -473,22 +470,22 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In GameState->CameraP.AbsTileZ = GameState->PlayerP.AbsTileZ; tile_map_difference Diff = SubtractInF32(TileMap, &GameState->PlayerP, &GameState->CameraP); - if(Diff.dX > (9.0f*TileMap->TileSideInMeters)) { + if(Diff.dXY.X > (9.0f*TileMap->TileSideInMeters)) { GameState->CameraP.AbsTileX += 17; } - if(Diff.dX < -(9.0f*TileMap->TileSideInMeters)) { + if(Diff.dXY.X < -(9.0f*TileMap->TileSideInMeters)) { GameState->CameraP.AbsTileX -= 17; } - if(Diff.dY > (5.0f*TileMap->TileSideInMeters)) { + if(Diff.dXY.Y > (5.0f*TileMap->TileSideInMeters)) { GameState->CameraP.AbsTileY += 9; } - if(Diff.dY < -(5.0f*TileMap->TileSideInMeters)) { + if(Diff.dXY.Y < -(5.0f*TileMap->TileSideInMeters)) { GameState->CameraP.AbsTileY -= 9; } } } - DrawRectangle(Buffer, 0.0f, 0.0f, (F32)Buffer->Width, (F32)Buffer->Height, 0.0f, 1.0f, 0.0f); + //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, 0, 0); @@ -516,14 +513,12 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In Gray = 0.0f; } - - F32 CenterX = ScreenCenterX - MetersToPixels*GameState->CameraP.OffsetX + (F32)RelColumn*(F32)TileSideInPixels; - F32 CenterY = ScreenCenterY + MetersToPixels*GameState->CameraP.OffsetY - (F32)RelRow*(F32)TileSideInPixels; - F32 MinX = CenterX - 0.5f*(F32)TileSideInPixels; - F32 MinY = CenterY - 0.5f*(F32)TileSideInPixels; - F32 MaxX = CenterX + 0.5f*(F32)TileSideInPixels; - F32 MaxY = CenterY + 0.5f*(F32)TileSideInPixels; - DrawRectangle(Buffer, MinX, MinY, MaxX, MaxY, Gray, Gray, Gray); + v2 TileSide = { 0.5f*(F32)TileSideInPixels, 0.5f*(F32)TileSideInPixels }; + v2 Center = { ScreenCenterX - MetersToPixels*GameState->CameraP.Offset.X + (F32)RelColumn*(F32)TileSideInPixels, + ScreenCenterY + MetersToPixels*GameState->CameraP.Offset.Y - (F32)RelRow*(F32)TileSideInPixels }; + v2 Min = vector_subtract(Center, TileSide); + v2 Max = vector_add(Center, TileSide); + DrawRectangle(Buffer, Min, Max, Gray, Gray, Gray); } } } @@ -533,11 +528,12 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In F32 PlayerR = 1.0f; F32 PlayerG = 0.0f; F32 PlayerB = 0.0f; - F32 PlayerGroundPointX = ScreenCenterX + MetersToPixels*Diff.dX; - F32 PlayerGroundPointY = ScreenCenterY - MetersToPixels*Diff.dY; - F32 PlayerLeft = PlayerGroundPointX - 0.5f * MetersToPixels*PlayerWidth; - F32 PlayerTop = PlayerGroundPointY - MetersToPixels*PlayerHeight; - DrawRectangle(Buffer, PlayerLeft, PlayerTop, PlayerLeft + MetersToPixels*PlayerWidth, PlayerTop + MetersToPixels*PlayerHeight, PlayerR, PlayerG, PlayerB); + F32 PlayerGroundPointX = ScreenCenterX + MetersToPixels*Diff.dXY.X; + F32 PlayerGroundPointY = ScreenCenterY - MetersToPixels*Diff.dXY.Y; + v2 PlayerLeftTop = { PlayerGroundPointX - 0.5f * MetersToPixels*PlayerWidth, + PlayerGroundPointY - MetersToPixels*PlayerHeight }; + v2 PlayerWidthHeight = { PlayerWidth, PlayerHeight }; + DrawRectangle(Buffer, PlayerLeftTop, vector_add(PlayerLeftTop, vector_multiply(MetersToPixels, PlayerWidthHeight)), PlayerR, PlayerG, PlayerB); hero_bitmaps *Bitmap = &GameState->HeroBitmaps[GameState->FacingDirection]; DrawBitmap(Buffer, &Bitmap->Torso, PlayerGroundPointX, PlayerGroundPointY, Bitmap->AlignX, Bitmap->AlignY); diff --git a/handmade_math.h b/handmade_math.h new file mode 100644 index 0000000..e8d9c02 --- /dev/null +++ b/handmade_math.h @@ -0,0 +1,59 @@ +#ifndef HANDMADE_MATH_H +#define HANDMADE_MATH_H + +typedef struct v2 { + F32 X, Y; + F32 E[2]; +} v2; + +v2 V2(F32 X, F32 Y) +{ + v2 Result; + + Result.X = X; + Result.Y = Y; + + return Result; +} + +v2 vector_multiply(F32 A, v2 B) +{ + v2 Result; + + Result.X = A * B.X; + Result.Y = A * B.Y; + + return Result; +} + +v2 vector_unary(v2 A) +{ + v2 Result; + + Result.X = -A.X; + Result.Y = -A.Y; + + return Result; +} + +v2 vector_add(v2 A, v2 B) +{ + v2 Result; + + Result.X = A.X + B.X; + Result.Y = A.Y + B.Y; + + return Result; +} + +v2 vector_subtract(v2 A, v2 B) +{ + v2 Result; + + Result.X = A.X - B.X; + Result.Y = A.Y - B.Y; + + return Result; +} + +#endif diff --git a/handmade_tile.c b/handmade_tile.c index fc7c250..f28ff6a 100644 --- a/handmade_tile.c +++ b/handmade_tile.c @@ -8,7 +8,7 @@ static tile_chunk *GetTileChunk(tile_map *TileMap, U32 TileChunkX, U32 TileChunk (TileChunkY >= 0) && (TileChunkY < TileMap->TileChunkCountY) && (TileChunkZ >= 0) && (TileChunkZ < TileMap->TileChunkCountZ)) { - TileChunk = &TileMap->TileChunks[ (TileChunkZ*TileMap->TileChunkCountY*TileMap->TileChunkCountX) + (TileChunkY*TileMap->TileChunkCountX) + TileChunkX]; + TileChunk = &TileMap->TileChunks[(TileChunkZ*TileMap->TileChunkCountY*TileMap->TileChunkCountX) + (TileChunkY*TileMap->TileChunkCountX) + TileChunkX]; } return TileChunk; @@ -124,8 +124,8 @@ static tile_map_position RecannonicalizePosition(tile_map *TileMap, tile_map_pos { tile_map_position Result = Pos; - CannonicalizeCoord(TileMap, &Result.AbsTileX, &Result.OffsetX); - CannonicalizeCoord(TileMap, &Result.AbsTileY, &Result.OffsetY); + CannonicalizeCoord(TileMap, &Result.AbsTileX, &Result.Offset.X); + CannonicalizeCoord(TileMap, &Result.AbsTileY, &Result.Offset.Y); return Result; } @@ -140,12 +140,10 @@ static tile_map_difference SubtractInF32(tile_map *TileMap, tile_map_position *A { tile_map_difference Result; - F32 dTileX = (F32)A->AbsTileX - (F32)B->AbsTileX; - F32 dTileY = (F32)A->AbsTileY - (F32)B->AbsTileY; + v2 dTileXY = { ((F32)A->AbsTileX - (F32)B->AbsTileX), ((F32)A->AbsTileY - (F32)B->AbsTileY) }; F32 dTileZ = (F32)A->AbsTileZ - (F32)B->AbsTileZ; - Result.dX = TileMap->TileSideInMeters*dTileX + (A->OffsetX - B->OffsetX); - Result.dY = TileMap->TileSideInMeters*dTileY + (A->OffsetY - B->OffsetY); + Result.dXY = vector_add(vector_multiply(TileMap->TileSideInMeters, dTileXY), vector_subtract(A->Offset, B->Offset)); // TODO: Incomplete . . . Result.dZ = TileMap->TileSideInMeters*dTileZ; diff --git a/handmade_tile.h b/handmade_tile.h index ca94cf2..15e6aee 100644 --- a/handmade_tile.h +++ b/handmade_tile.h @@ -1,9 +1,10 @@ #ifndef HANDMADE_TILE_H_SENTRY #define HANDMADE_TILE_H_SENTRY +#include "handmade_math.h" + typedef struct tile_map_difference { - F32 dX; - F32 dY; + v2 dXY; F32 dZ; } tile_map_difference; @@ -13,8 +14,7 @@ typedef struct tile_map_position { U32 AbsTileZ; /* NOTE: X and Y relative to tile center. */ - F32 OffsetX; - F32 OffsetY; + v2 Offset; } tile_map_position; typedef struct tile_chunk_position {