Day 30 complete.
This commit is contained in:
+120
-93
@@ -57,6 +57,12 @@ static S32 RoundF32toS32(F32 Real32)
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static S32 FloorF32toS32(F32 Real32)
|
||||||
|
{
|
||||||
|
S32 Result = (S32)floorf(Real32);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static void DrawRectangle(game_offscreen_buffer *Buffer,
|
static void DrawRectangle(game_offscreen_buffer *Buffer,
|
||||||
F32 RealMinX, F32 RealMinY,
|
F32 RealMinX, F32 RealMinY,
|
||||||
F32 RealMaxX, F32 RealMaxY,
|
F32 RealMaxX, F32 RealMaxY,
|
||||||
@@ -100,28 +106,6 @@ static void DrawRectangle(game_offscreen_buffer *Buffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RenderRectangle(game_offscreen_buffer *Buffer, S32 MouseX,
|
|
||||||
S32 MouseY)
|
|
||||||
{
|
|
||||||
U8 *Row;
|
|
||||||
U32 *Pixel;
|
|
||||||
S32 X, Y;
|
|
||||||
|
|
||||||
for(Y = MouseY; Y < MouseY+10; Y++) {
|
|
||||||
if(Y >= Buffer->Height)
|
|
||||||
break;
|
|
||||||
|
|
||||||
Row = (U8 *)Buffer->Memory + (Buffer->Pitch * Y);
|
|
||||||
for(X = MouseX; X < MouseX+10; X++) {
|
|
||||||
if(X >= Buffer->Width)
|
|
||||||
break;
|
|
||||||
|
|
||||||
Pixel = (U32 *)Row + X;
|
|
||||||
*Pixel = 0xFFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static tile_map *GetTileMap(world *World, S32 TileMapX, S32 TileMapY)
|
static tile_map *GetTileMap(world *World, S32 TileMapX, S32 TileMapY)
|
||||||
{
|
{
|
||||||
tile_map *TileMap = NULL;
|
tile_map *TileMap = NULL;
|
||||||
@@ -136,57 +120,87 @@ static tile_map *GetTileMap(world *World, S32 TileMapX, S32 TileMapY)
|
|||||||
return TileMap;
|
return TileMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
static U32 GetTileValueUnchecked(tile_map *TileMap, S32 TileX, S32 TileY)
|
static U32 GetTileValueUnchecked(world *World, tile_map *TileMap, S32 TileX, S32 TileY)
|
||||||
{
|
{
|
||||||
U32 TileMapValue = TileMap->Tiles[TileY*TileMap->CountX + TileX];
|
U32 TileMapValue;
|
||||||
|
|
||||||
|
ASSERT(TileMap);
|
||||||
|
ASSERT((TileX >= 0) && (TileX < World->CountX) &&
|
||||||
|
(TileY >= 0) && (TileY < World->CountY));
|
||||||
|
|
||||||
|
TileMapValue = TileMap->Tiles[TileY*World->CountX + TileX];
|
||||||
return TileMapValue;
|
return TileMapValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static B32 IsTileMapPointEmpty(tile_map *TileMap, F32 TestX, F32 TestY)
|
static B32 IsTileMapPointEmpty(world *World, tile_map *TileMap,
|
||||||
|
S32 TestTileX, S32 TestTileY)
|
||||||
{
|
{
|
||||||
B32 Empty = FALSE;
|
B32 Empty = FALSE;
|
||||||
|
|
||||||
S32 PlayerTileX =
|
if(TileMap) {
|
||||||
(S32)((TestX - TileMap->UpperLeftX) / TileMap->TileWidth);
|
if((TestTileX >= 0) && (TestTileX < World->CountX) &&
|
||||||
S32 PlayerTileY =
|
(TestTileY >= 0) && (TestTileY < World->CountY))
|
||||||
(S32)((TestY - TileMap->UpperLeftY) / TileMap->TileHeight);
|
|
||||||
|
|
||||||
if((PlayerTileX >= 0) && (PlayerTileX < TileMap->CountX) &&
|
|
||||||
(PlayerTileY >= 0) && (PlayerTileY < TileMap->CountY))
|
|
||||||
{
|
{
|
||||||
U32 TileMapValue =
|
U32 TileMapValue =
|
||||||
GetTileValueUnchecked(TileMap, PlayerTileX, PlayerTileY);
|
GetTileValueUnchecked(World, TileMap, TestTileX, TestTileY);
|
||||||
Empty = (TileMapValue == 0);
|
Empty = (TileMapValue == 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Empty;
|
return Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static B32 IsWorldPointEmpty(world *World,
|
static cannonical_position GetCannonicalPosition(world *World,
|
||||||
S32 TileMapX, S32 TileMapY,
|
raw_position Pos)
|
||||||
F32 TestX, F32 TestY)
|
{
|
||||||
|
cannonical_position Result;
|
||||||
|
F32 X, Y;
|
||||||
|
|
||||||
|
Result.TileMapX = Pos.TileMapX;
|
||||||
|
Result.TileMapY = Pos.TileMapY;
|
||||||
|
|
||||||
|
X = Pos.X - World->UpperLeftX;
|
||||||
|
Y = Pos.Y - World->UpperLeftY;
|
||||||
|
Result.TileX = FloorF32toS32(X / World->TileWidth);
|
||||||
|
Result.TileY = FloorF32toS32(Y / World->TileHeight);
|
||||||
|
|
||||||
|
Result.X = X - Result.TileX*World->TileWidth;
|
||||||
|
Result.Y = Y - Result.TileY*World->TileHeight;
|
||||||
|
|
||||||
|
ASSERT(Result.X >= 0);
|
||||||
|
ASSERT(Result.Y >= 0);
|
||||||
|
ASSERT(Result.X < World->TileWidth);
|
||||||
|
ASSERT(Result.Y < World->TileHeight);
|
||||||
|
|
||||||
|
if(Result.TileX < 0) {
|
||||||
|
Result.TileX = World->CountX + Result.TileX;
|
||||||
|
Result.TileMapX--;
|
||||||
|
}
|
||||||
|
if(Result.TileY < 0) {
|
||||||
|
Result.TileY = World->CountY + Result.TileY;
|
||||||
|
Result.TileMapY--;
|
||||||
|
}
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static B32 IsWorldPointEmpty(world *World, raw_position TestPos)
|
||||||
{
|
{
|
||||||
B32 Empty = FALSE;
|
B32 Empty = FALSE;
|
||||||
|
|
||||||
tile_map *TileMap = GetTileMap(World, TileMapX, TileMapY);
|
tile_map *TileMap;
|
||||||
|
|
||||||
S32 PlayerTileX, PlayerTileY;
|
cannonical_position CanPos = GetCannonicalPosition(World, TestPos);
|
||||||
|
TileMap = GetTileMap(World, CanPos.TileMapX, CanPos.TileMapY);
|
||||||
TileMap = GetTileMap(World, TileMapX, TileMapY);
|
Empty = IsTileMapPointEmpty(World, TileMap, CanPos.TileX, CanPos.TileY);
|
||||||
if(TileMap) {
|
|
||||||
S32 PlayerTileX =
|
|
||||||
(S32)((TestX - TileMap->UpperLeftX) / TileMap->TileWidth);
|
|
||||||
S32 PlayerTileY =
|
|
||||||
(S32)((TestY - TileMap->UpperLeftY) / TileMap->TileHeight);
|
|
||||||
|
|
||||||
if((PlayerTileX >= 0) && (PlayerTileX < TileMap->CountX) &&
|
|
||||||
(PlayerTileY >= 0) && (PlayerTileY < TileMap->CountY))
|
|
||||||
{
|
|
||||||
U32 TileMapValue =
|
|
||||||
GetTileValueUnchecked(TileMap, PlayerTileX, PlayerTileY);
|
|
||||||
Empty = (TileMapValue == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Empty;
|
return Empty;
|
||||||
}
|
}
|
||||||
@@ -225,7 +239,7 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
|||||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||||
};
|
};
|
||||||
U32 Tiles10[TILEMAP_COUNT_Y][TILEMAP_COUNT_X] = {
|
U32 Tiles10[TILEMAP_COUNT_Y][TILEMAP_COUNT_X] = {
|
||||||
{1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
|
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||||
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
@@ -259,33 +273,24 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
|||||||
ARRAY_SIZE(Input->Controllers[0].u.Buttons));
|
ARRAY_SIZE(Input->Controllers[0].u.Buttons));
|
||||||
ASSERT(sizeof(game_state) <= Memory->PermanentStorageSize);
|
ASSERT(sizeof(game_state) <= Memory->PermanentStorageSize);
|
||||||
|
|
||||||
memset(&World, 0, sizeof(World));
|
|
||||||
|
|
||||||
TileMaps[0][0].CountX = TILEMAP_COUNT_X;
|
|
||||||
TileMaps[0][0].CountY = TILEMAP_COUNT_Y;
|
|
||||||
|
|
||||||
TileMaps[0][0].UpperLeftX = 0.0f;
|
|
||||||
TileMaps[0][0].UpperLeftY = 0.0f;
|
|
||||||
TileMaps[0][0].TileWidth = 57.0f;
|
|
||||||
TileMaps[0][0].TileHeight = 57.0f;
|
|
||||||
|
|
||||||
TileMaps[0][0].Tiles = (U32 *)Tiles00;
|
TileMaps[0][0].Tiles = (U32 *)Tiles00;
|
||||||
|
TileMaps[0][1].Tiles = (U32 *)Tiles10;
|
||||||
TileMaps[0][1] = TileMaps[0][0];
|
TileMaps[1][0].Tiles = (U32 *)Tiles01;
|
||||||
TileMaps[0][1].Tiles = (U32 *)Tiles01;
|
|
||||||
|
|
||||||
TileMaps[1][0] = TileMaps[0][0];
|
|
||||||
TileMaps[1][0].Tiles = (U32 *)Tiles10;
|
|
||||||
|
|
||||||
TileMaps[1][1] = TileMaps[0][0];
|
|
||||||
TileMaps[1][1].Tiles = (U32 *)Tiles11;
|
TileMaps[1][1].Tiles = (U32 *)Tiles11;
|
||||||
|
|
||||||
TileMap = &TileMaps[0][0];
|
memset(&World, 0, sizeof(World));
|
||||||
|
World.TileMapCountX = 2;
|
||||||
|
World.TileMapCountY = 2;
|
||||||
|
World.CountX = TILEMAP_COUNT_X;
|
||||||
|
World.CountY = TILEMAP_COUNT_Y;
|
||||||
|
World.UpperLeftX = 0.0f;
|
||||||
|
World.UpperLeftY = 0.0f;
|
||||||
|
World.TileWidth = 57.0f;
|
||||||
|
World.TileHeight = 57.0f;
|
||||||
World.TileMaps = (tile_map *)TileMaps;
|
World.TileMaps = (tile_map *)TileMaps;
|
||||||
|
|
||||||
PlayerWidth = 0.75f * TileMap->TileWidth;
|
PlayerWidth = 0.75f * World.TileWidth;
|
||||||
PlayerHeight = TileMap->TileHeight;
|
PlayerHeight = World.TileHeight;
|
||||||
|
|
||||||
GameState = (game_state *)Memory->PermanentStorage;
|
GameState = (game_state *)Memory->PermanentStorage;
|
||||||
if(!Memory->IsInitialized) {
|
if(!Memory->IsInitialized) {
|
||||||
@@ -295,6 +300,10 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
|||||||
Memory->IsInitialized = TRUE;
|
Memory->IsInitialized = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TileMap = GetTileMap(&World, GameState->PlayerTileMapX,
|
||||||
|
GameState->PlayerTileMapY);
|
||||||
|
ASSERT(TileMap);
|
||||||
|
|
||||||
for(ControllerIndex = 0;
|
for(ControllerIndex = 0;
|
||||||
ControllerIndex < ARRAY_SIZE(Input->Controllers);
|
ControllerIndex < ARRAY_SIZE(Input->Controllers);
|
||||||
ControllerIndex++)
|
ControllerIndex++)
|
||||||
@@ -308,6 +317,8 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
|||||||
|
|
||||||
F32 NewPlayerX, NewPlayerY;
|
F32 NewPlayerX, NewPlayerY;
|
||||||
|
|
||||||
|
raw_position PlayerPos, PlayerLeft, PlayerRight;
|
||||||
|
|
||||||
if(Controller->u.buttons.MoveUp.EndedDown) {
|
if(Controller->u.buttons.MoveUp.EndedDown) {
|
||||||
dPlayerY = -1.0f;
|
dPlayerY = -1.0f;
|
||||||
}
|
}
|
||||||
@@ -321,22 +332,38 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
|||||||
dPlayerX = 1.0f;
|
dPlayerX = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
dPlayerX *= 100.0f;
|
dPlayerX *= 200.0f;
|
||||||
dPlayerY *= 100.0f;
|
dPlayerY *= 200.0f;
|
||||||
|
|
||||||
NewPlayerX = RoundF32toS32(GameState->PlayerX +
|
NewPlayerX = RoundF32toS32(GameState->PlayerX +
|
||||||
Input->dtForFrame*dPlayerX);
|
Input->dtForFrame*dPlayerX);
|
||||||
NewPlayerY = RoundF32toS32(GameState->PlayerY +
|
NewPlayerY = RoundF32toS32(GameState->PlayerY +
|
||||||
Input->dtForFrame*dPlayerY);
|
Input->dtForFrame*dPlayerY);
|
||||||
|
|
||||||
if(IsTileMapPointEmpty(TileMap, NewPlayerX - 0.5f*PlayerWidth,
|
PlayerPos.TileMapX = GameState->PlayerTileMapX;
|
||||||
NewPlayerY) &&
|
PlayerPos.TileMapY = GameState->PlayerTileMapY;
|
||||||
IsTileMapPointEmpty(TileMap, NewPlayerX + 0.5f*PlayerWidth,
|
PlayerPos.X = NewPlayerX;
|
||||||
NewPlayerY) &&
|
PlayerPos.Y = NewPlayerY;
|
||||||
IsTileMapPointEmpty(TileMap, NewPlayerX, NewPlayerY))
|
|
||||||
|
PlayerLeft = PlayerPos;
|
||||||
|
PlayerLeft.X -= 0.5f*PlayerWidth;
|
||||||
|
|
||||||
|
PlayerRight = PlayerPos;
|
||||||
|
PlayerRight.X += 0.5f*PlayerWidth;
|
||||||
|
|
||||||
|
if(IsWorldPointEmpty(&World, PlayerPos) &&
|
||||||
|
IsWorldPointEmpty(&World, PlayerLeft) &&
|
||||||
|
IsWorldPointEmpty(&World, PlayerRight))
|
||||||
{
|
{
|
||||||
GameState->PlayerX = NewPlayerX;
|
cannonical_position CanPos =
|
||||||
GameState->PlayerY = NewPlayerY;
|
GetCannonicalPosition(&World, PlayerPos);
|
||||||
|
|
||||||
|
GameState->PlayerTileMapX = CanPos.TileMapX;
|
||||||
|
GameState->PlayerTileMapY = CanPos.TileMapY;
|
||||||
|
GameState->PlayerX = World.UpperLeftX +
|
||||||
|
World.TileWidth*CanPos.TileX + CanPos.X;
|
||||||
|
GameState->PlayerY = World.UpperLeftY +
|
||||||
|
World.TileHeight*CanPos.TileY + CanPos.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,15 +375,15 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
|||||||
for(Row = 0; Row < TILEMAP_COUNT_Y; Row++) {
|
for(Row = 0; Row < TILEMAP_COUNT_Y; Row++) {
|
||||||
for(Column = 0; Column < TILEMAP_COUNT_X; Column++) {
|
for(Column = 0; Column < TILEMAP_COUNT_X; Column++) {
|
||||||
F32 MinX, MinY, MaxX, MaxY;
|
F32 MinX, MinY, MaxX, MaxY;
|
||||||
U32 TileID = GetTileValueUnchecked(TileMap, Column, Row);
|
U32 TileID = GetTileValueUnchecked(&World, TileMap, Column, Row);
|
||||||
F32 Gray = 0.5f;
|
F32 Gray = 0.5f;
|
||||||
if(TileID) {
|
if(TileID) {
|
||||||
Gray = 1.0f;
|
Gray = 1.0f;
|
||||||
}
|
}
|
||||||
MinX = TileMap->UpperLeftX + (F32)(Column) * TileMap->TileWidth;
|
MinX = World.UpperLeftX + (F32)(Column) * World.TileWidth;
|
||||||
MinY = TileMap->UpperLeftY + (F32)(Row) * TileMap->TileHeight;
|
MinY = World.UpperLeftY + (F32)(Row) * World.TileHeight;
|
||||||
MaxX = MinX + TileMap->TileWidth;
|
MaxX = MinX + World.TileWidth;
|
||||||
MaxY = MinY + TileMap->TileHeight;
|
MaxY = MinY + World.TileHeight;
|
||||||
DrawRectangle(Buffer, MinX, MinY, MaxX, MaxY, Gray, Gray, Gray);
|
DrawRectangle(Buffer, MinX, MinY, MaxX, MaxY, Gray, Gray, Gray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,8 +399,8 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
|||||||
PlayerR, PlayerG, PlayerB);
|
PlayerR, PlayerG, PlayerB);
|
||||||
|
|
||||||
DrawRectangle(Buffer,
|
DrawRectangle(Buffer,
|
||||||
(F32)(Input->MouseX), (F32)(Input->MouseY),
|
(F32)(Input->MouseX) - 15.0f, (F32)(Input->MouseY) - 15.0f,
|
||||||
(F32)(Input->MouseX) + 10.0f, (F32)(Input->MouseY) + 10.0f,
|
(F32)(Input->MouseX) + 5.0f, (F32)(Input->MouseY) + 5.0f,
|
||||||
1.0f, 0.5f, 0.0f);
|
1.0f, 0.5f, 0.0f);
|
||||||
|
|
||||||
GameOutputSound(GameState, SoundBuffer, 400);
|
GameOutputSound(GameState, SoundBuffer, 400);
|
||||||
|
|||||||
+28
-4
@@ -136,7 +136,32 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct cannonical_position {
|
||||||
|
S32 TileMapX;
|
||||||
|
S32 TileMapY;
|
||||||
|
|
||||||
|
S32 TileX;
|
||||||
|
S32 TileY;
|
||||||
|
|
||||||
|
/* NOTE: Tile-relative X and Y. */
|
||||||
|
F32 X;
|
||||||
|
F32 Y;
|
||||||
|
} 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;
|
||||||
|
} tile_map;
|
||||||
|
|
||||||
|
typedef struct world {
|
||||||
S32 CountX;
|
S32 CountX;
|
||||||
S32 CountY;
|
S32 CountY;
|
||||||
|
|
||||||
@@ -145,10 +170,6 @@ typedef struct tile_map {
|
|||||||
F32 TileWidth;
|
F32 TileWidth;
|
||||||
F32 TileHeight;
|
F32 TileHeight;
|
||||||
|
|
||||||
U32 *Tiles;
|
|
||||||
} tile_map;
|
|
||||||
|
|
||||||
typedef struct world {
|
|
||||||
S32 TileMapCountX;
|
S32 TileMapCountX;
|
||||||
S32 TileMapCountY;
|
S32 TileMapCountY;
|
||||||
|
|
||||||
@@ -156,6 +177,9 @@ typedef struct world {
|
|||||||
} world;
|
} world;
|
||||||
|
|
||||||
typedef struct game_state {
|
typedef struct game_state {
|
||||||
|
S32 PlayerTileMapX;
|
||||||
|
S32 PlayerTileMapY;
|
||||||
|
|
||||||
F32 PlayerX;
|
F32 PlayerX;
|
||||||
F32 PlayerY;
|
F32 PlayerY;
|
||||||
} game_state;
|
} game_state;
|
||||||
|
|||||||
Reference in New Issue
Block a user