Day 42 complete.
This commit is contained in:
+38
-42
@@ -1,5 +1,6 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "handmade.h"
|
#include "handmade.h"
|
||||||
|
#include "handmade_math.h"
|
||||||
#include "sdl_handmade.h"
|
#include "sdl_handmade.h"
|
||||||
|
|
||||||
#include "handmade_intrinsics.h"
|
#include "handmade_intrinsics.h"
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
#include "handmade_tile.h"
|
#include "handmade_tile.h"
|
||||||
#include "handmade_tile.c"
|
#include "handmade_tile.c"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h> /* memset */
|
#include <string.h> /* memset */
|
||||||
|
|
||||||
static void GameOutputSound(game_state *GameState, game_sound_output_buffer *SoundBuffer, S32 ToneHz)
|
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 MinX = RoundF32toS32(vMin.X);
|
||||||
S32 MinY = RoundF32toS32(RealMinY);
|
S32 MinY = RoundF32toS32(vMin.Y);
|
||||||
S32 MaxX = RoundF32toS32(RealMaxX);
|
S32 MaxX = RoundF32toS32(vMax.X);
|
||||||
S32 MaxY = RoundF32toS32(RealMaxY);
|
S32 MaxY = RoundF32toS32(vMax.Y);
|
||||||
|
|
||||||
S32 Width = Buffer->Width;
|
S32 Width = Buffer->Width;
|
||||||
S32 Height = Buffer->Height;
|
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)
|
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((&Input->Controllers[0].Terminator - &Input->Controllers[0].Buttons[0]) == ARRAY_SIZE(Input->Controllers[0].Buttons));
|
||||||
ASSERT(sizeof(game_state) <= Memory->PermanentStorageSize);
|
ASSERT(sizeof(game_state) <= Memory->PermanentStorageSize);
|
||||||
|
|
||||||
#define TILEMAP_COUNT_X 256
|
|
||||||
#define TILEMAP_COUNT_Y 256
|
|
||||||
|
|
||||||
game_state *GameState;
|
game_state *GameState;
|
||||||
|
|
||||||
F32 PlayerHeight = 1.4f;
|
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.AbsTileX = 2;
|
||||||
GameState->PlayerP.AbsTileY = 3;
|
GameState->PlayerP.AbsTileY = 3;
|
||||||
GameState->PlayerP.OffsetX = 5.0f;
|
GameState->PlayerP.Offset.X = 5.0f;
|
||||||
GameState->PlayerP.OffsetY = 5.0f;
|
GameState->PlayerP.Offset.Y = 5.0f;
|
||||||
|
|
||||||
InitializeArena(&GameState->WorldArena, Memory->PermanentStorageSize - sizeof(game_state), (U8 *)Memory->PermanentStorage + sizeof(game_state));
|
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);
|
game_controller_input *Controller = GetController(Input, ControllerIndex);
|
||||||
if(Controller->IsAnalog) {
|
if(Controller->IsAnalog) {
|
||||||
} else {
|
} else {
|
||||||
F32 dPlayerX = 0.0f;
|
v2 dPlayer;
|
||||||
F32 dPlayerY = 0.0f;
|
memset(&dPlayer, 0, sizeof(dPlayer));
|
||||||
|
|
||||||
if(Controller->MoveUp.EndedDown) {
|
if(Controller->MoveUp.EndedDown) {
|
||||||
dPlayerY = 1.0f;
|
dPlayer.Y = 1.0f;
|
||||||
GameState->FacingDirection = 1;
|
GameState->FacingDirection = 1;
|
||||||
}
|
}
|
||||||
if(Controller->MoveDown.EndedDown) {
|
if(Controller->MoveDown.EndedDown) {
|
||||||
dPlayerY = -1.0f;
|
dPlayer.Y = -1.0f;
|
||||||
GameState->FacingDirection = 3;
|
GameState->FacingDirection = 3;
|
||||||
}
|
}
|
||||||
if(Controller->MoveLeft.EndedDown) {
|
if(Controller->MoveLeft.EndedDown) {
|
||||||
dPlayerX = -1.0f;
|
dPlayer.X = -1.0f;
|
||||||
GameState->FacingDirection = 2;
|
GameState->FacingDirection = 2;
|
||||||
}
|
}
|
||||||
if(Controller->MoveRight.EndedDown) {
|
if(Controller->MoveRight.EndedDown) {
|
||||||
dPlayerX = 1.0f;
|
dPlayer.X = 1.0f;
|
||||||
GameState->FacingDirection = 0;
|
GameState->FacingDirection = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 PlayerSpeed = 2.0f;
|
F32 PlayerSpeed = 2.0f;
|
||||||
|
|
||||||
if(Controller->ActionUp.EndedDown)
|
if(Controller->ActionUp.EndedDown)
|
||||||
PlayerSpeed = 10.0f;
|
PlayerSpeed = 10.0f;
|
||||||
|
dPlayer = vector_multiply(PlayerSpeed, dPlayer);
|
||||||
|
|
||||||
dPlayerX *= PlayerSpeed;
|
if((dPlayer.X != 0.0f) && (dPlayer.Y != 0.0f))
|
||||||
dPlayerY *= PlayerSpeed;
|
dPlayer = vector_multiply(0.7071067811865475244f, dPlayer);
|
||||||
|
|
||||||
tile_map_position NewPlayerP;
|
tile_map_position NewPlayerP;
|
||||||
NewPlayerP = GameState->PlayerP;
|
NewPlayerP = GameState->PlayerP;
|
||||||
NewPlayerP.OffsetX += Input->dtForFrame*dPlayerX;
|
NewPlayerP.Offset = vector_add(NewPlayerP.Offset, vector_multiply(Input->dtForFrame, dPlayer));
|
||||||
NewPlayerP.OffsetY += Input->dtForFrame*dPlayerY;
|
|
||||||
NewPlayerP = RecannonicalizePosition(TileMap, NewPlayerP);
|
NewPlayerP = RecannonicalizePosition(TileMap, NewPlayerP);
|
||||||
|
|
||||||
tile_map_position PlayerLeft;
|
tile_map_position PlayerLeft;
|
||||||
PlayerLeft = NewPlayerP;
|
PlayerLeft = NewPlayerP;
|
||||||
PlayerLeft.OffsetX -= 0.5f*PlayerWidth;
|
PlayerLeft.Offset.X -= 0.5f*PlayerWidth;
|
||||||
PlayerLeft = RecannonicalizePosition(TileMap, PlayerLeft);
|
PlayerLeft = RecannonicalizePosition(TileMap, PlayerLeft);
|
||||||
|
|
||||||
tile_map_position PlayerRight;
|
tile_map_position PlayerRight;
|
||||||
PlayerRight = NewPlayerP;
|
PlayerRight = NewPlayerP;
|
||||||
PlayerRight.OffsetX += 0.5f*PlayerWidth;
|
PlayerRight.Offset.X += 0.5f*PlayerWidth;
|
||||||
PlayerRight = RecannonicalizePosition(TileMap, PlayerRight);
|
PlayerRight = RecannonicalizePosition(TileMap, PlayerRight);
|
||||||
|
|
||||||
if(IsTileMapPointEmpty(TileMap, NewPlayerP) && IsTileMapPointEmpty(TileMap, PlayerLeft) && IsTileMapPointEmpty(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;
|
GameState->CameraP.AbsTileZ = GameState->PlayerP.AbsTileZ;
|
||||||
|
|
||||||
tile_map_difference Diff = SubtractInF32(TileMap, &GameState->PlayerP, &GameState->CameraP);
|
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;
|
GameState->CameraP.AbsTileX += 17;
|
||||||
}
|
}
|
||||||
if(Diff.dX < -(9.0f*TileMap->TileSideInMeters)) {
|
if(Diff.dXY.X < -(9.0f*TileMap->TileSideInMeters)) {
|
||||||
GameState->CameraP.AbsTileX -= 17;
|
GameState->CameraP.AbsTileX -= 17;
|
||||||
}
|
}
|
||||||
if(Diff.dY > (5.0f*TileMap->TileSideInMeters)) {
|
if(Diff.dXY.Y > (5.0f*TileMap->TileSideInMeters)) {
|
||||||
GameState->CameraP.AbsTileY += 9;
|
GameState->CameraP.AbsTileY += 9;
|
||||||
}
|
}
|
||||||
if(Diff.dY < -(5.0f*TileMap->TileSideInMeters)) {
|
if(Diff.dXY.Y < -(5.0f*TileMap->TileSideInMeters)) {
|
||||||
GameState->CameraP.AbsTileY -= 9;
|
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);
|
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;
|
Gray = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v2 TileSide = { 0.5f*(F32)TileSideInPixels, 0.5f*(F32)TileSideInPixels };
|
||||||
F32 CenterX = ScreenCenterX - MetersToPixels*GameState->CameraP.OffsetX + (F32)RelColumn*(F32)TileSideInPixels;
|
v2 Center = { ScreenCenterX - MetersToPixels*GameState->CameraP.Offset.X + (F32)RelColumn*(F32)TileSideInPixels,
|
||||||
F32 CenterY = ScreenCenterY + MetersToPixels*GameState->CameraP.OffsetY - (F32)RelRow*(F32)TileSideInPixels;
|
ScreenCenterY + MetersToPixels*GameState->CameraP.Offset.Y - (F32)RelRow*(F32)TileSideInPixels };
|
||||||
F32 MinX = CenterX - 0.5f*(F32)TileSideInPixels;
|
v2 Min = vector_subtract(Center, TileSide);
|
||||||
F32 MinY = CenterY - 0.5f*(F32)TileSideInPixels;
|
v2 Max = vector_add(Center, TileSide);
|
||||||
F32 MaxX = CenterX + 0.5f*(F32)TileSideInPixels;
|
DrawRectangle(Buffer, Min, Max, Gray, Gray, Gray);
|
||||||
F32 MaxY = CenterY + 0.5f*(F32)TileSideInPixels;
|
|
||||||
DrawRectangle(Buffer, MinX, MinY, MaxX, MaxY, Gray, Gray, Gray);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -533,11 +528,12 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In
|
|||||||
F32 PlayerR = 1.0f;
|
F32 PlayerR = 1.0f;
|
||||||
F32 PlayerG = 0.0f;
|
F32 PlayerG = 0.0f;
|
||||||
F32 PlayerB = 0.0f;
|
F32 PlayerB = 0.0f;
|
||||||
F32 PlayerGroundPointX = ScreenCenterX + MetersToPixels*Diff.dX;
|
F32 PlayerGroundPointX = ScreenCenterX + MetersToPixels*Diff.dXY.X;
|
||||||
F32 PlayerGroundPointY = ScreenCenterY - MetersToPixels*Diff.dY;
|
F32 PlayerGroundPointY = ScreenCenterY - MetersToPixels*Diff.dXY.Y;
|
||||||
F32 PlayerLeft = PlayerGroundPointX - 0.5f * MetersToPixels*PlayerWidth;
|
v2 PlayerLeftTop = { PlayerGroundPointX - 0.5f * MetersToPixels*PlayerWidth,
|
||||||
F32 PlayerTop = PlayerGroundPointY - MetersToPixels*PlayerHeight;
|
PlayerGroundPointY - MetersToPixels*PlayerHeight };
|
||||||
DrawRectangle(Buffer, PlayerLeft, PlayerTop, PlayerLeft + MetersToPixels*PlayerWidth, PlayerTop + MetersToPixels*PlayerHeight, PlayerR, PlayerG, PlayerB);
|
v2 PlayerWidthHeight = { PlayerWidth, PlayerHeight };
|
||||||
|
DrawRectangle(Buffer, PlayerLeftTop, vector_add(PlayerLeftTop, vector_multiply(MetersToPixels, PlayerWidthHeight)), PlayerR, PlayerG, PlayerB);
|
||||||
|
|
||||||
hero_bitmaps *Bitmap = &GameState->HeroBitmaps[GameState->FacingDirection];
|
hero_bitmaps *Bitmap = &GameState->HeroBitmaps[GameState->FacingDirection];
|
||||||
DrawBitmap(Buffer, &Bitmap->Torso, PlayerGroundPointX, PlayerGroundPointY, Bitmap->AlignX, Bitmap->AlignY);
|
DrawBitmap(Buffer, &Bitmap->Torso, PlayerGroundPointX, PlayerGroundPointY, Bitmap->AlignX, Bitmap->AlignY);
|
||||||
|
|||||||
@@ -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
|
||||||
+5
-7
@@ -8,7 +8,7 @@ static tile_chunk *GetTileChunk(tile_map *TileMap, U32 TileChunkX, U32 TileChunk
|
|||||||
(TileChunkY >= 0) && (TileChunkY < TileMap->TileChunkCountY) &&
|
(TileChunkY >= 0) && (TileChunkY < TileMap->TileChunkCountY) &&
|
||||||
(TileChunkZ >= 0) && (TileChunkZ < TileMap->TileChunkCountZ))
|
(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;
|
return TileChunk;
|
||||||
@@ -124,8 +124,8 @@ static tile_map_position RecannonicalizePosition(tile_map *TileMap, tile_map_pos
|
|||||||
{
|
{
|
||||||
tile_map_position Result = Pos;
|
tile_map_position Result = Pos;
|
||||||
|
|
||||||
CannonicalizeCoord(TileMap, &Result.AbsTileX, &Result.OffsetX);
|
CannonicalizeCoord(TileMap, &Result.AbsTileX, &Result.Offset.X);
|
||||||
CannonicalizeCoord(TileMap, &Result.AbsTileY, &Result.OffsetY);
|
CannonicalizeCoord(TileMap, &Result.AbsTileY, &Result.Offset.Y);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@@ -140,12 +140,10 @@ static tile_map_difference SubtractInF32(tile_map *TileMap, tile_map_position *A
|
|||||||
{
|
{
|
||||||
tile_map_difference Result;
|
tile_map_difference Result;
|
||||||
|
|
||||||
F32 dTileX = (F32)A->AbsTileX - (F32)B->AbsTileX;
|
v2 dTileXY = { ((F32)A->AbsTileX - (F32)B->AbsTileX), ((F32)A->AbsTileY - (F32)B->AbsTileY) };
|
||||||
F32 dTileY = (F32)A->AbsTileY - (F32)B->AbsTileY;
|
|
||||||
F32 dTileZ = (F32)A->AbsTileZ - (F32)B->AbsTileZ;
|
F32 dTileZ = (F32)A->AbsTileZ - (F32)B->AbsTileZ;
|
||||||
|
|
||||||
Result.dX = TileMap->TileSideInMeters*dTileX + (A->OffsetX - B->OffsetX);
|
Result.dXY = vector_add(vector_multiply(TileMap->TileSideInMeters, dTileXY), vector_subtract(A->Offset, B->Offset));
|
||||||
Result.dY = TileMap->TileSideInMeters*dTileY + (A->OffsetY - B->OffsetY);
|
|
||||||
|
|
||||||
// TODO: Incomplete . . .
|
// TODO: Incomplete . . .
|
||||||
Result.dZ = TileMap->TileSideInMeters*dTileZ;
|
Result.dZ = TileMap->TileSideInMeters*dTileZ;
|
||||||
|
|||||||
+4
-4
@@ -1,9 +1,10 @@
|
|||||||
#ifndef HANDMADE_TILE_H_SENTRY
|
#ifndef HANDMADE_TILE_H_SENTRY
|
||||||
#define HANDMADE_TILE_H_SENTRY
|
#define HANDMADE_TILE_H_SENTRY
|
||||||
|
|
||||||
|
#include "handmade_math.h"
|
||||||
|
|
||||||
typedef struct tile_map_difference {
|
typedef struct tile_map_difference {
|
||||||
F32 dX;
|
v2 dXY;
|
||||||
F32 dY;
|
|
||||||
F32 dZ;
|
F32 dZ;
|
||||||
} tile_map_difference;
|
} tile_map_difference;
|
||||||
|
|
||||||
@@ -13,8 +14,7 @@ typedef struct tile_map_position {
|
|||||||
U32 AbsTileZ;
|
U32 AbsTileZ;
|
||||||
|
|
||||||
/* NOTE: X and Y relative to tile center. */
|
/* NOTE: X and Y relative to tile center. */
|
||||||
F32 OffsetX;
|
v2 Offset;
|
||||||
F32 OffsetY;
|
|
||||||
} tile_map_position;
|
} tile_map_position;
|
||||||
|
|
||||||
typedef struct tile_chunk_position {
|
typedef struct tile_chunk_position {
|
||||||
|
|||||||
Reference in New Issue
Block a user