Comply with ansi C and clean up.
This commit is contained in:
@@ -15,7 +15,7 @@ endif
|
|||||||
CC = clang
|
CC = clang
|
||||||
|
|
||||||
UFLAGS =
|
UFLAGS =
|
||||||
FLAGS = -Wall -Wextra \
|
FLAGS = -ansi -pedantic -pedantic-errors -Wno-long-long -Wall -Wextra \
|
||||||
-Wincompatible-pointer-types \
|
-Wincompatible-pointer-types \
|
||||||
-Wint-conversion -Wimplicit-int-float-conversion -Wformat \
|
-Wint-conversion -Wimplicit-int-float-conversion -Wformat \
|
||||||
-Wno-strict-prototypes -Wno-missing-field-initializers \
|
-Wno-strict-prototypes -Wno-missing-field-initializers \
|
||||||
@@ -48,10 +48,13 @@ EXE=handmadehero
|
|||||||
default: tags libhandmade $(EXE)
|
default: tags libhandmade $(EXE)
|
||||||
|
|
||||||
libhandmade: handmade.c
|
libhandmade: handmade.c
|
||||||
@ $(CC) $(FLAGS) $(UFLAGS) -fPIC -shared $(INCLUDE) $^ $(LIBS) $(FRAMEWORKS) -o libhandmade.so
|
@ $(CC) $(FLAGS) $(UFLAGS) -fPIC -shared $(INCLUDE) $^ $(LIBS) \
|
||||||
|
$(FRAMEWORKS) -o libhandmade.so
|
||||||
|
|
||||||
$(EXE): sdl_handmade.c libhandmade
|
$(EXE): sdl_handmade.c libhandmade
|
||||||
@ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.c $(LIBS) $(FRAMEWORKS) -o $@ $(ifneq $(filter $(DETECTED_OS), macos linux), /link /FORCE:MULTIPLE)
|
@ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.c $(LIBS) \
|
||||||
|
$(FRAMEWORKS) -o $@ $(ifneq $(filter $(DETECTED_OS), macos linux), \
|
||||||
|
/link /FORCE:MULTIPLE)
|
||||||
|
|
||||||
run:
|
run:
|
||||||
@ ./$(EXE)
|
@ ./$(EXE)
|
||||||
|
|||||||
+240
-147
@@ -49,7 +49,8 @@ static void ClearBackground(struct game_offscreen_buffer *Buffer)
|
|||||||
int Width = Buffer->Width;
|
int Width = Buffer->Width;
|
||||||
int Height = Buffer->Height;
|
int Height = Buffer->Height;
|
||||||
|
|
||||||
for(int X = 0; X < Width * Height; X++) {
|
int X;
|
||||||
|
for(X = 0; X < Width * Height; X++) {
|
||||||
unsigned int *Pixel = &((unsigned int *)Buffer->Memory)[X];
|
unsigned int *Pixel = &((unsigned int *)Buffer->Memory)[X];
|
||||||
*Pixel = 0xFFFFFF;
|
*Pixel = 0xFFFFFF;
|
||||||
}
|
}
|
||||||
@@ -59,13 +60,24 @@ static void DrawRectangle(struct game_offscreen_buffer *Buffer,
|
|||||||
struct v2 vMin, struct v2 vMax,
|
struct v2 vMin, struct v2 vMax,
|
||||||
float R, float G, float B)
|
float R, float G, float B)
|
||||||
{
|
{
|
||||||
int MinX = RoundFloatToInt(vMin.X);
|
int Y, X;
|
||||||
int MinY = RoundFloatToInt(vMin.Y);
|
|
||||||
int MaxX = RoundFloatToInt(vMax.X);
|
|
||||||
int MaxY = RoundFloatToInt(vMax.Y);
|
|
||||||
|
|
||||||
int Width = Buffer->Width;
|
int Width, Height;
|
||||||
int Height = Buffer->Height;
|
|
||||||
|
int MinX, MinY, MaxX, MaxY;
|
||||||
|
|
||||||
|
unsigned int Color;
|
||||||
|
|
||||||
|
unsigned char *Row;
|
||||||
|
unsigned int *Pixel;
|
||||||
|
|
||||||
|
MinX = RoundFloatToInt(vMin.X);
|
||||||
|
MinY = RoundFloatToInt(vMin.Y);
|
||||||
|
MaxX = RoundFloatToInt(vMax.X);
|
||||||
|
MaxY = RoundFloatToInt(vMax.Y);
|
||||||
|
|
||||||
|
Width = Buffer->Width;
|
||||||
|
Height = Buffer->Height;
|
||||||
|
|
||||||
if(MinX < 0)
|
if(MinX < 0)
|
||||||
MinX = 0;
|
MinX = 0;
|
||||||
@@ -80,16 +92,16 @@ static void DrawRectangle(struct game_offscreen_buffer *Buffer,
|
|||||||
/*unsigned int Color = (unsigned int)((RoundFloatToInt(R * 255.0f) << 16) |
|
/*unsigned int Color = (unsigned int)((RoundFloatToInt(R * 255.0f) << 16) |
|
||||||
(RoundFloatToInt(G * 255.0f) << 8) |
|
(RoundFloatToInt(G * 255.0f) << 8) |
|
||||||
(RoundFloatToInt(B * 255.0f) << 0));*/
|
(RoundFloatToInt(B * 255.0f) << 0));*/
|
||||||
unsigned int Color = (unsigned int)((RoundFloatToInt(255.0f) << 24) |
|
Color = (unsigned int)((RoundFloatToInt(255.0f) << 24) |
|
||||||
(RoundFloatToInt(R * 255.0f) << 16) |
|
(RoundFloatToInt(R * 255.0f) << 16) |
|
||||||
(RoundFloatToInt(G * 255.0f) << 8) |
|
(RoundFloatToInt(G * 255.0f) << 8) |
|
||||||
(RoundFloatToInt(B * 255.0f) << 0));
|
(RoundFloatToInt(B * 255.0f) << 0));
|
||||||
|
|
||||||
unsigned char *Row = ((unsigned char *)Buffer->Memory +
|
Row = ((unsigned char *)Buffer->Memory + MinX*Buffer->BytesPerPixel +
|
||||||
MinX*Buffer->BytesPerPixel + MinY*Buffer->Pitch);
|
MinY*Buffer->Pitch);
|
||||||
for(int Y = MinY; Y < MaxY; Y++) {
|
for(Y = MinY; Y < MaxY; Y++) {
|
||||||
unsigned int *Pixel = (unsigned int *)Row;
|
Pixel = (unsigned int *)Row;
|
||||||
for(int X = MinX; X < MaxX; X++) {
|
for(X = MinX; X < MaxX; X++) {
|
||||||
*(unsigned int *)Pixel = Color;
|
*(unsigned int *)Pixel = Color;
|
||||||
Pixel++;
|
Pixel++;
|
||||||
}
|
}
|
||||||
@@ -101,24 +113,35 @@ static void DrawBitmap(struct game_offscreen_buffer *Buffer,
|
|||||||
struct loaded_bitmap *Bitmap,
|
struct loaded_bitmap *Bitmap,
|
||||||
float RelX, float RelY, int AlignX, int AlignY)
|
float RelX, float RelY, int AlignX, int AlignY)
|
||||||
{
|
{
|
||||||
|
int MinX, MinY, MaxX, MaxY;
|
||||||
|
|
||||||
|
int Width, Height;
|
||||||
|
|
||||||
|
int SourceOffsetX, SourceOffsetY;
|
||||||
|
|
||||||
|
unsigned int *SourceRow;
|
||||||
|
unsigned char *DestRow;
|
||||||
|
|
||||||
|
int Y, X;
|
||||||
|
|
||||||
RelX -= (float)AlignX;
|
RelX -= (float)AlignX;
|
||||||
RelY -= (float)AlignY;
|
RelY -= (float)AlignY;
|
||||||
|
|
||||||
int MinX = RoundFloatToInt(RelX);
|
MinX = RoundFloatToInt(RelX);
|
||||||
int MinY = RoundFloatToInt(RelY);
|
MinY = RoundFloatToInt(RelY);
|
||||||
int MaxX = RoundFloatToInt(RelX + (float)Bitmap->Width);
|
MaxX = RoundFloatToInt(RelX + (float)Bitmap->Width);
|
||||||
int MaxY = RoundFloatToInt(RelY + (float)Bitmap->Height);
|
MaxY = RoundFloatToInt(RelY + (float)Bitmap->Height);
|
||||||
|
|
||||||
int Width = Buffer->Width;
|
Width = Buffer->Width;
|
||||||
int Height = Buffer->Height;
|
Height = Buffer->Height;
|
||||||
|
|
||||||
int SourceOffsetX = 0;
|
SourceOffsetX = 0;
|
||||||
if(MinX < 0) {
|
if(MinX < 0) {
|
||||||
SourceOffsetX = -MinX;
|
SourceOffsetX = -MinX;
|
||||||
MinX = 0;
|
MinX = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SourceOffsetY = 0;
|
SourceOffsetY = 0;
|
||||||
if(MinY < 0) {
|
if(MinY < 0) {
|
||||||
SourceOffsetY = -MinY;
|
SourceOffsetY = -MinY;
|
||||||
MinY = 0;
|
MinY = 0;
|
||||||
@@ -129,15 +152,15 @@ static void DrawBitmap(struct game_offscreen_buffer *Buffer,
|
|||||||
if(MaxY > Height)
|
if(MaxY > Height)
|
||||||
MaxY = Height;
|
MaxY = Height;
|
||||||
|
|
||||||
unsigned int *SourceRow =
|
SourceRow =
|
||||||
Bitmap->Pixels + Bitmap->Width*(Bitmap->Height - 1);
|
Bitmap->Pixels + Bitmap->Width*(Bitmap->Height - 1);
|
||||||
SourceRow += -Bitmap->Width*SourceOffsetY + SourceOffsetX;
|
SourceRow += -Bitmap->Width*SourceOffsetY + SourceOffsetX;
|
||||||
unsigned char *DestRow = ((unsigned char *)Buffer->Memory +
|
DestRow = ((unsigned char *)Buffer->Memory +
|
||||||
MinX*Buffer->BytesPerPixel + MinY*Buffer->Pitch);
|
MinX*Buffer->BytesPerPixel + MinY*Buffer->Pitch);
|
||||||
for(int Y = MinY; Y < MaxY; Y++) {
|
for(Y = MinY; Y < MaxY; Y++) {
|
||||||
unsigned int *Dest = (unsigned int *)DestRow;
|
unsigned int *Dest = (unsigned int *)DestRow;
|
||||||
unsigned int *Source = SourceRow;
|
unsigned int *Source = SourceRow;
|
||||||
for(int X = MinX; X < MaxX; X++) {
|
for(X = MinX; X < MaxX; X++) {
|
||||||
float SA = (float)((*Source >> 24) & 0xFF);
|
float SA = (float)((*Source >> 24) & 0xFF);
|
||||||
float SR = (float)((*Source >> 16) & 0xFF);
|
float SR = (float)((*Source >> 16) & 0xFF);
|
||||||
float SG = (float)((*Source >> 8) & 0xFF);
|
float SG = (float)((*Source >> 8) & 0xFF);
|
||||||
@@ -149,7 +172,7 @@ static void DrawBitmap(struct game_offscreen_buffer *Buffer,
|
|||||||
|
|
||||||
float A = SA / 255.0f;
|
float A = SA / 255.0f;
|
||||||
|
|
||||||
// TODO: This should be replaced by premultiplied alpha.
|
/* TODO: This should be replaced by premultiplied alpha. */
|
||||||
float R = (1.0f-A)*DR + A*SR;
|
float R = (1.0f-A)*DR + A*SR;
|
||||||
float G = (1.0f-A)*DG + A*SG;
|
float G = (1.0f-A)*DG + A*SG;
|
||||||
float B = (1.0f-A)*DB + A*SB;
|
float B = (1.0f-A)*DB + A*SB;
|
||||||
@@ -198,16 +221,29 @@ static struct loaded_bitmap DEBUGLoadBMP(struct thread_context *Thread,
|
|||||||
const char *), char *FileName)
|
const char *), char *FileName)
|
||||||
{
|
{
|
||||||
struct loaded_bitmap Result;
|
struct loaded_bitmap Result;
|
||||||
|
|
||||||
|
struct debug_read_file_result ReadResult;
|
||||||
|
|
||||||
memset(&Result, 0, sizeof(Result));
|
memset(&Result, 0, sizeof(Result));
|
||||||
|
|
||||||
struct debug_read_file_result ReadResult =
|
ReadResult = DEBUGPlatformReadEntireFile(Thread, FileName);
|
||||||
DEBUGPlatformReadEntireFile(Thread, FileName);
|
|
||||||
if(ReadResult.ContentsSize > 0) {
|
if(ReadResult.ContentsSize > 0) {
|
||||||
struct bitmap_header *Header =
|
struct bitmap_header *Header;
|
||||||
(struct bitmap_header *)ReadResult.Contents;
|
|
||||||
|
|
||||||
unsigned int *Pixels =
|
unsigned int *Pixels;
|
||||||
(unsigned int *)((unsigned char *)ReadResult.Contents +
|
|
||||||
|
unsigned int RedMask, GreenMask, BlueMask, AlphaMask;
|
||||||
|
|
||||||
|
struct bit_scan_result RedShift, GreenShift,
|
||||||
|
BlueShift, AlphaShift;
|
||||||
|
|
||||||
|
unsigned int *SourceDest;
|
||||||
|
|
||||||
|
int X, Y;
|
||||||
|
|
||||||
|
Header = (struct bitmap_header *)ReadResult.Contents;
|
||||||
|
|
||||||
|
Pixels = (unsigned int *)((unsigned char *)ReadResult.Contents +
|
||||||
Header->BitmapOffset);
|
Header->BitmapOffset);
|
||||||
Result.Pixels = Pixels;
|
Result.Pixels = Pixels;
|
||||||
Result.Width = Header->Width;
|
Result.Width = Header->Width;
|
||||||
@@ -215,30 +251,26 @@ static struct loaded_bitmap DEBUGLoadBMP(struct thread_context *Thread,
|
|||||||
|
|
||||||
ASSERT(Header->Compression == 3);
|
ASSERT(Header->Compression == 3);
|
||||||
|
|
||||||
// NOTE: The byte order in memory is determined by the Header.
|
/* NOTE: The byte order in memory is determined by the Header. */
|
||||||
|
|
||||||
unsigned int RedMask = Header->RedMask;
|
RedMask = Header->RedMask;
|
||||||
unsigned int GreenMask = Header->GreenMask;
|
GreenMask = Header->GreenMask;
|
||||||
unsigned int BlueMask = Header->BlueMask;
|
BlueMask = Header->BlueMask;
|
||||||
unsigned int AlphaMask = ~(RedMask | GreenMask | BlueMask);
|
AlphaMask = ~(RedMask | GreenMask | BlueMask);
|
||||||
|
|
||||||
struct bit_scan_result RedShift =
|
RedShift = FindLeastSignificantSetBit(RedMask);
|
||||||
FindLeastSignificantSetBit(RedMask);
|
GreenShift = FindLeastSignificantSetBit(GreenMask);
|
||||||
struct bit_scan_result GreenShift =
|
BlueShift = FindLeastSignificantSetBit(BlueMask);
|
||||||
FindLeastSignificantSetBit(GreenMask);
|
AlphaShift = FindLeastSignificantSetBit(AlphaMask);
|
||||||
struct bit_scan_result BlueShift =
|
|
||||||
FindLeastSignificantSetBit(BlueMask);
|
|
||||||
struct bit_scan_result AlphaShift =
|
|
||||||
FindLeastSignificantSetBit(AlphaMask);
|
|
||||||
|
|
||||||
ASSERT(RedShift.Found);
|
ASSERT(RedShift.Found);
|
||||||
ASSERT(GreenShift.Found);
|
ASSERT(GreenShift.Found);
|
||||||
ASSERT(BlueShift.Found);
|
ASSERT(BlueShift.Found);
|
||||||
ASSERT(AlphaShift.Found);
|
ASSERT(AlphaShift.Found);
|
||||||
|
|
||||||
unsigned int *SourceDest = Pixels;
|
SourceDest = Pixels;
|
||||||
for(int Y = 0; Y < Header->Height; Y++) {
|
for(Y = 0; Y < Header->Height; Y++) {
|
||||||
for(int X = 0; X < Header->Width; X++) {
|
for(X = 0; X < Header->Width; X++) {
|
||||||
unsigned int C = *SourceDest;
|
unsigned int C = *SourceDest;
|
||||||
|
|
||||||
*SourceDest = ((((C >> AlphaShift.Index) & 0xFF) << 24) |
|
*SourceDest = ((((C >> AlphaShift.Index) & 0xFF) << 24) |
|
||||||
@@ -279,9 +311,10 @@ static void InitializePlayer(struct entity *Entity)
|
|||||||
static unsigned int AddEntity(struct game_state *GameState)
|
static unsigned int AddEntity(struct game_state *GameState)
|
||||||
{
|
{
|
||||||
unsigned int EntityIndex = ++GameState->EntityCount;
|
unsigned int EntityIndex = ++GameState->EntityCount;
|
||||||
|
struct entity *Entity;
|
||||||
|
|
||||||
ASSERT(GameState->EntityCount < ARRAY_SIZE(GameState->Entities));
|
ASSERT(GameState->EntityCount < ARRAY_SIZE(GameState->Entities));
|
||||||
struct entity *Entity = &GameState->Entities[EntityIndex];
|
Entity = &GameState->Entities[EntityIndex];
|
||||||
memset(Entity, 0, sizeof(struct entity));
|
memset(Entity, 0, sizeof(struct entity));
|
||||||
|
|
||||||
return EntityIndex;
|
return EntityIndex;
|
||||||
@@ -290,38 +323,48 @@ static unsigned int AddEntity(struct game_state *GameState)
|
|||||||
static void MovePlayer(struct game_state *GameState,
|
static void MovePlayer(struct game_state *GameState,
|
||||||
struct entity *Entity, float dt, struct v2 ddPlayer)
|
struct entity *Entity, float dt, struct v2 ddPlayer)
|
||||||
{
|
{
|
||||||
struct tile_map *TileMap = GameState->World->TileMap;
|
struct tile_map *TileMap;
|
||||||
|
|
||||||
|
float PlayerSpeed;
|
||||||
|
|
||||||
|
struct tile_map_position OldPlayerP, NewPlayerP;
|
||||||
|
struct v2 PlayerDelta;
|
||||||
|
|
||||||
|
TileMap = GameState->World->TileMap;
|
||||||
|
|
||||||
if((ddPlayer.X != 0.0f) && (ddPlayer.Y != 0.0f))
|
if((ddPlayer.X != 0.0f) && (ddPlayer.Y != 0.0f))
|
||||||
ddPlayer = V2Multiply(0.7071067811865475244f, ddPlayer);
|
ddPlayer = V2Multiply(0.7071067811865475244f, ddPlayer);
|
||||||
|
|
||||||
float PlayerSpeed = 10.0f;
|
PlayerSpeed = 10.0f;
|
||||||
ddPlayer = V2Multiply(PlayerSpeed, ddPlayer);
|
ddPlayer = V2Multiply(PlayerSpeed, ddPlayer);
|
||||||
|
|
||||||
ddPlayer = V2Add(ddPlayer, V2Unary(V2Multiply(1.5f, Entity->dP)));
|
ddPlayer = V2Add(ddPlayer, V2Unary(V2Multiply(1.5f, Entity->dP)));
|
||||||
|
|
||||||
struct tile_map_position OldPlayerP = Entity->P;
|
OldPlayerP = Entity->P;
|
||||||
struct tile_map_position NewPlayerP = OldPlayerP;
|
NewPlayerP = OldPlayerP;
|
||||||
struct v2 PlayerDelta = V2Add(V2Multiply(0.5f, V2Multiply(Square(dt),
|
PlayerDelta = V2Add(V2Multiply(0.5f, V2Multiply(Square(dt), ddPlayer)),
|
||||||
ddPlayer)),
|
|
||||||
V2Multiply(dt, Entity->dP));
|
V2Multiply(dt, Entity->dP));
|
||||||
NewPlayerP.Offset = V2Add(PlayerDelta, NewPlayerP.Offset);
|
NewPlayerP.Offset = V2Add(PlayerDelta, NewPlayerP.Offset);
|
||||||
Entity->dP = V2Add(V2Multiply(dt, ddPlayer), Entity->dP);
|
Entity->dP = V2Add(V2Multiply(dt, ddPlayer), Entity->dP);
|
||||||
NewPlayerP = RecannonicalizePosition(TileMap, NewPlayerP);
|
NewPlayerP = RecannonicalizePosition(TileMap, NewPlayerP);
|
||||||
|
|
||||||
|
{
|
||||||
#if 1
|
#if 1
|
||||||
struct tile_map_position PlayerLeft;
|
struct tile_map_position PlayerLeft, PlayerRight;
|
||||||
|
|
||||||
|
int Collided;
|
||||||
|
|
||||||
|
struct tile_map_position ColP;
|
||||||
|
|
||||||
PlayerLeft = NewPlayerP;
|
PlayerLeft = NewPlayerP;
|
||||||
PlayerLeft.Offset.X -= 0.5f*Entity->Width;
|
PlayerLeft.Offset.X -= 0.5f*Entity->Width;
|
||||||
PlayerLeft = RecannonicalizePosition(TileMap, PlayerLeft);
|
PlayerLeft = RecannonicalizePosition(TileMap, PlayerLeft);
|
||||||
|
|
||||||
struct tile_map_position PlayerRight;
|
|
||||||
PlayerRight = NewPlayerP;
|
PlayerRight = NewPlayerP;
|
||||||
PlayerRight.Offset.X += 0.5f*Entity->Width;
|
PlayerRight.Offset.X += 0.5f*Entity->Width;
|
||||||
PlayerRight = RecannonicalizePosition(TileMap, PlayerRight);
|
PlayerRight = RecannonicalizePosition(TileMap, PlayerRight);
|
||||||
|
|
||||||
int Collided = 0;
|
Collided = 0;
|
||||||
struct tile_map_position ColP;
|
|
||||||
memset(&ColP, 0, sizeof(ColP));
|
memset(&ColP, 0, sizeof(ColP));
|
||||||
if(!IsTileMapPointEmpty(TileMap, NewPlayerP)) {
|
if(!IsTileMapPointEmpty(TileMap, NewPlayerP)) {
|
||||||
ColP = NewPlayerP;
|
ColP = NewPlayerP;
|
||||||
@@ -339,16 +382,20 @@ static void MovePlayer(struct game_state *GameState,
|
|||||||
if(Collided) {
|
if(Collided) {
|
||||||
struct v2 r = { 0, 0 };
|
struct v2 r = { 0, 0 };
|
||||||
if(ColP.AbsTileX < Entity->P.AbsTileX) {
|
if(ColP.AbsTileX < Entity->P.AbsTileX) {
|
||||||
r = (struct v2){ 1, 0 };
|
r.X = 1;
|
||||||
|
r.Y = 0;
|
||||||
}
|
}
|
||||||
if(ColP.AbsTileX > Entity->P.AbsTileX) {
|
if(ColP.AbsTileX > Entity->P.AbsTileX) {
|
||||||
r = (struct v2){ -1, 0 };
|
r.X = -1;
|
||||||
|
r.Y = 0;
|
||||||
}
|
}
|
||||||
if(ColP.AbsTileY < Entity->P.AbsTileY) {
|
if(ColP.AbsTileY < Entity->P.AbsTileY) {
|
||||||
r = (struct v2){ 0, 1 };
|
r.X = 0;
|
||||||
|
r.Y = 1;
|
||||||
}
|
}
|
||||||
if(ColP.AbsTileY > Entity->P.AbsTileY) {
|
if(ColP.AbsTileY > Entity->P.AbsTileY) {
|
||||||
r = (struct v2){ 0, -1 };
|
r.X = 0;
|
||||||
|
r.Y = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity->dP = V2Subtract(Entity->dP,
|
Entity->dP = V2Subtract(Entity->dP,
|
||||||
@@ -393,6 +440,7 @@ static void MovePlayer(struct game_state *GameState,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if(!AreOnSameTile(&OldPlayerP, &Entity->P)) {
|
if(!AreOnSameTile(&OldPlayerP, &Entity->P)) {
|
||||||
unsigned int NewTileValue = GetTileValueByPos(TileMap, Entity->P);
|
unsigned int NewTileValue = GetTileValueByPos(TileMap, Entity->P);
|
||||||
@@ -424,16 +472,49 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
struct game_offscreen_buffer *Buffer,
|
struct game_offscreen_buffer *Buffer,
|
||||||
struct game_sound_output_buffer *SoundBuffer)
|
struct game_sound_output_buffer *SoundBuffer)
|
||||||
{
|
{
|
||||||
ASSERT((&Input->Controllers[0].Terminator -
|
|
||||||
&Input->Controllers[0].Buttons[0]) ==
|
|
||||||
ARRAY_SIZE(Input->Controllers[0].Buttons));
|
|
||||||
ASSERT(sizeof(struct game_state) <= Memory->PermanentStorageSize);
|
|
||||||
|
|
||||||
struct game_state *GameState;
|
struct game_state *GameState;
|
||||||
|
|
||||||
|
struct world *World;
|
||||||
|
struct tile_map *TileMap;
|
||||||
|
|
||||||
|
int TileSideInPixels;
|
||||||
|
float MetersToPixels;
|
||||||
|
|
||||||
|
unsigned int ControllerIndex;
|
||||||
|
|
||||||
|
struct entity *CameraFollowingEntity;
|
||||||
|
|
||||||
|
float ScreenCenterX, ScreenCenterY;
|
||||||
|
|
||||||
|
int RelRow, RelColumn;
|
||||||
|
|
||||||
|
struct entity *Entity;
|
||||||
|
|
||||||
|
unsigned int EntityIndex;
|
||||||
|
|
||||||
|
ASSERT((&Input->Controllers[0].u.s.Terminator -
|
||||||
|
&Input->Controllers[0].u.Buttons[0]) ==
|
||||||
|
ARRAY_SIZE(Input->Controllers[0].u.Buttons));
|
||||||
|
ASSERT(sizeof(struct game_state) <= Memory->PermanentStorageSize);
|
||||||
|
|
||||||
GameState = (struct game_state *)Memory->PermanentStorage;
|
GameState = (struct game_state *)Memory->PermanentStorage;
|
||||||
if(!Memory->IsInitialized) {
|
if(!Memory->IsInitialized) {
|
||||||
// NOTE: Reserve entity slot 0 for null entity
|
struct hero_bitmaps *Bitmap;
|
||||||
|
struct world *World;
|
||||||
|
struct tile_map *TileMap;
|
||||||
|
|
||||||
|
unsigned int RandomNumberIndex;
|
||||||
|
|
||||||
|
unsigned int TilesPerWidth, TilesPerHeight;
|
||||||
|
unsigned int ScreenX, ScreenY;
|
||||||
|
|
||||||
|
unsigned int AbsTileZ;
|
||||||
|
|
||||||
|
int DoorTop, DoorBottom, DoorLeft, DoorRight, DoorUp, DoorDown;
|
||||||
|
|
||||||
|
unsigned int ScreenIndex;
|
||||||
|
|
||||||
|
/* NOTE: Reserve entity slot 0 for null entity */
|
||||||
AddEntity(GameState);
|
AddEntity(GameState);
|
||||||
|
|
||||||
GameState->rect_pos.X = 0.0f;
|
GameState->rect_pos.X = 0.0f;
|
||||||
@@ -464,8 +545,6 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
GameState->Backdrop = DEBUGLoadBMP(Thread,
|
GameState->Backdrop = DEBUGLoadBMP(Thread,
|
||||||
Memory->DEBUGPlatformReadEntireFile, "data/test_background.bmp");
|
Memory->DEBUGPlatformReadEntireFile, "data/test_background.bmp");
|
||||||
|
|
||||||
struct hero_bitmaps *Bitmap;
|
|
||||||
|
|
||||||
Bitmap = &GameState->HeroBitmaps[0];
|
Bitmap = &GameState->HeroBitmaps[0];
|
||||||
Bitmap->AlignX = 72;
|
Bitmap->AlignX = 72;
|
||||||
Bitmap->AlignY = 182;
|
Bitmap->AlignY = 182;
|
||||||
@@ -527,10 +606,10 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
sizeof(struct game_state));
|
sizeof(struct game_state));
|
||||||
|
|
||||||
GameState->World = PUSH_STRUCT(&GameState->WorldArena, struct world);
|
GameState->World = PUSH_STRUCT(&GameState->WorldArena, struct world);
|
||||||
struct world *World = GameState->World;
|
World = GameState->World;
|
||||||
World->TileMap = PUSH_STRUCT(&GameState->WorldArena, struct tile_map);
|
World->TileMap = PUSH_STRUCT(&GameState->WorldArena, struct tile_map);
|
||||||
|
|
||||||
struct tile_map *TileMap = World->TileMap;
|
TileMap = World->TileMap;
|
||||||
|
|
||||||
TileMap->ChunkShift = 4;
|
TileMap->ChunkShift = 4;
|
||||||
TileMap->ChunkMask = (1 << TileMap->ChunkShift) - 1;
|
TileMap->ChunkMask = (1 << TileMap->ChunkShift) - 1;
|
||||||
@@ -547,33 +626,39 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
|
|
||||||
TileMap->TileSideInMeters = 1.4f;
|
TileMap->TileSideInMeters = 1.4f;
|
||||||
|
|
||||||
unsigned int RandomNumberIndex = 0;
|
RandomNumberIndex = 0;
|
||||||
|
|
||||||
unsigned int TilesPerWidth = 17;
|
TilesPerWidth = 17;
|
||||||
unsigned int TilesPerHeight = 9;
|
TilesPerHeight = 9;
|
||||||
unsigned int ScreenX = 0;
|
ScreenX = 0;
|
||||||
unsigned int ScreenY = 0;
|
ScreenY = 0;
|
||||||
|
|
||||||
unsigned int AbsTileZ = 0;
|
AbsTileZ = 0;
|
||||||
|
|
||||||
int DoorTop = 0;
|
DoorTop = 0;
|
||||||
int DoorBottom = 0;
|
DoorBottom = 0;
|
||||||
int DoorLeft = 0;
|
DoorLeft = 0;
|
||||||
int DoorRight = 0;
|
DoorRight = 0;
|
||||||
int DoorUp = 0;
|
DoorUp = 0;
|
||||||
int DoorDown = 0;
|
DoorDown = 0;
|
||||||
for(unsigned int ScreenIndex = 0; ScreenIndex < 100; ScreenIndex++) {
|
for(ScreenIndex = 0; ScreenIndex < 100; ScreenIndex++) {
|
||||||
ASSERT(RandomNumberIndex < ARRAY_SIZE(RandomNumberTable));
|
|
||||||
|
|
||||||
/* TODO: Random number generator. */
|
/* TODO: Random number generator. */
|
||||||
unsigned int RandomChoice;
|
unsigned int RandomChoice;
|
||||||
|
|
||||||
|
int CreatedZDoor;
|
||||||
|
|
||||||
|
unsigned int TileY, TileX;
|
||||||
|
|
||||||
|
ASSERT(RandomNumberIndex < ARRAY_SIZE(RandomNumberTable));
|
||||||
|
|
||||||
if(DoorUp || DoorDown) {
|
if(DoorUp || DoorDown) {
|
||||||
RandomChoice = RandomNumberTable[RandomNumberIndex++] % 2;
|
RandomChoice = RandomNumberTable[RandomNumberIndex++] % 2;
|
||||||
} else {
|
} else {
|
||||||
RandomChoice = RandomNumberTable[RandomNumberIndex++] % 3;
|
RandomChoice = RandomNumberTable[RandomNumberIndex++] % 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CreatedZDoor = 0;
|
CreatedZDoor = 0;
|
||||||
|
|
||||||
if(RandomChoice == 2) {
|
if(RandomChoice == 2) {
|
||||||
CreatedZDoor = 1;
|
CreatedZDoor = 1;
|
||||||
@@ -589,14 +674,8 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
DoorTop = 1;
|
DoorTop = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int TileY = 0;
|
for(TileY = 0; TileY < TilesPerHeight; TileY++) {
|
||||||
TileY < TilesPerHeight;
|
for(TileX = 0; TileX < TilesPerWidth; TileX++) {
|
||||||
TileY++)
|
|
||||||
{
|
|
||||||
for(unsigned int TileX = 0;
|
|
||||||
TileX < TilesPerWidth;
|
|
||||||
TileX++)
|
|
||||||
{
|
|
||||||
unsigned int AbsTileX = ScreenX * TilesPerWidth + TileX;
|
unsigned int AbsTileX = ScreenX * TilesPerWidth + TileX;
|
||||||
unsigned int AbsTileY = ScreenY * TilesPerHeight + TileY;
|
unsigned int AbsTileY = ScreenY * TilesPerHeight + TileY;
|
||||||
|
|
||||||
@@ -669,58 +748,56 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
Memory->IsInitialized = 1;
|
Memory->IsInitialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct world *World = GameState->World;
|
World = GameState->World;
|
||||||
struct tile_map *TileMap = World->TileMap;
|
TileMap = World->TileMap;
|
||||||
|
|
||||||
int TileSideInPixels = 60;
|
TileSideInPixels = 60;
|
||||||
float MetersToPixels =
|
MetersToPixels = (float)TileSideInPixels / TileMap->TileSideInMeters;
|
||||||
(float)TileSideInPixels / TileMap->TileSideInMeters;
|
|
||||||
|
|
||||||
for(unsigned int ControllerIndex = 0;
|
for(ControllerIndex = 0;
|
||||||
ControllerIndex < ARRAY_SIZE(Input->Controllers);
|
ControllerIndex < ARRAY_SIZE(Input->Controllers);
|
||||||
ControllerIndex++)
|
ControllerIndex++)
|
||||||
{
|
{
|
||||||
struct game_controller_input *Controller =
|
struct game_controller_input *Controller;
|
||||||
GetController(Input, ControllerIndex);
|
struct entity *ControllingEntity;
|
||||||
struct entity *ControllingEntity =
|
|
||||||
GetEntity(GameState,
|
Controller = GetController(Input, ControllerIndex);
|
||||||
|
ControllingEntity = GetEntity(GameState,
|
||||||
GameState->PlayerIndexForController[ControllerIndex]);
|
GameState->PlayerIndexForController[ControllerIndex]);
|
||||||
if(ControllingEntity) {
|
if(ControllingEntity) {
|
||||||
struct v2 ddPlayer; /* accerlation */
|
struct v2 ddPlayer; /* accerlation */
|
||||||
memset(&ddPlayer, 0, sizeof(ddPlayer));
|
memset(&ddPlayer, 0, sizeof(ddPlayer));
|
||||||
|
|
||||||
if(Controller->IsAnalog) {
|
if(Controller->IsAnalog) {
|
||||||
ddPlayer = (struct v2){ Controller->StickAverageX,
|
ddPlayer.X = Controller->StickAverageX;
|
||||||
Controller->StickAverageY };
|
ddPlayer.Y = -Controller->StickAverageY;
|
||||||
} else {
|
} else {
|
||||||
|
if(Controller->u.s.MoveUp.EndedDown) {
|
||||||
if(Controller->MoveUp.EndedDown) {
|
|
||||||
GameState->rect_pos.Y -= 1.0f;
|
GameState->rect_pos.Y -= 1.0f;
|
||||||
|
|
||||||
ddPlayer.Y = 1.0f;
|
ddPlayer.Y = 1.0f;
|
||||||
}
|
}
|
||||||
if(Controller->MoveDown.EndedDown) {
|
if(Controller->u.s.MoveDown.EndedDown) {
|
||||||
GameState->rect_pos.Y += 1.0f;
|
GameState->rect_pos.Y += 1.0f;
|
||||||
|
|
||||||
ddPlayer.Y = -1.0f;
|
ddPlayer.Y = -1.0f;
|
||||||
}
|
}
|
||||||
if(Controller->MoveLeft.EndedDown) {
|
if(Controller->u.s.MoveLeft.EndedDown) {
|
||||||
GameState->rect_pos.X -= 1.0f;
|
GameState->rect_pos.X -= 1.0f;
|
||||||
|
|
||||||
ddPlayer.X = -1.0f;
|
ddPlayer.X = -1.0f;
|
||||||
}
|
}
|
||||||
if(Controller->MoveRight.EndedDown) {
|
if(Controller->u.s.MoveRight.EndedDown) {
|
||||||
GameState->rect_pos.X += 1.0f;
|
GameState->rect_pos.X += 1.0f;
|
||||||
|
|
||||||
ddPlayer.X = 1.0f;
|
ddPlayer.X = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MovePlayer(GameState, ControllingEntity, Input->dtForFrame,
|
MovePlayer(GameState, ControllingEntity, Input->dtForFrame,
|
||||||
ddPlayer);
|
ddPlayer);
|
||||||
} else {
|
} else {
|
||||||
if(Controller->Start.EndedDown) {
|
if(Controller->u.s.Start.EndedDown) {
|
||||||
unsigned int EntityIndex = AddEntity(GameState);
|
unsigned int EntityIndex = AddEntity(GameState);
|
||||||
ControllingEntity = GetEntity(GameState, EntityIndex);
|
ControllingEntity = GetEntity(GameState, EntityIndex);
|
||||||
InitializePlayer(ControllingEntity);
|
InitializePlayer(ControllingEntity);
|
||||||
@@ -730,13 +807,14 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct entity *CameraFollowingEntity =
|
CameraFollowingEntity =
|
||||||
GetEntity(GameState, GameState->CameraFollowingEntityIndex);
|
GetEntity(GameState, GameState->CameraFollowingEntityIndex);
|
||||||
if(CameraFollowingEntity) {
|
if(CameraFollowingEntity) {
|
||||||
|
struct tile_map_difference Diff;
|
||||||
|
|
||||||
GameState->CameraP.AbsTileZ = CameraFollowingEntity->P.AbsTileZ;
|
GameState->CameraP.AbsTileZ = CameraFollowingEntity->P.AbsTileZ;
|
||||||
|
|
||||||
struct tile_map_difference Diff =
|
Diff = SubtractInFloat(TileMap, &CameraFollowingEntity->P,
|
||||||
SubtractInFloat(TileMap, &CameraFollowingEntity->P,
|
|
||||||
&GameState->CameraP);
|
&GameState->CameraP);
|
||||||
if(Diff.dXY.X > (9.0f*TileMap->TileSideInMeters)) {
|
if(Diff.dXY.X > (9.0f*TileMap->TileSideInMeters)) {
|
||||||
GameState->CameraP.AbsTileX += 17;
|
GameState->CameraP.AbsTileX += 17;
|
||||||
@@ -758,11 +836,11 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
|
|
||||||
DrawBitmap(Buffer, &GameState->Backdrop, 0.0f, 0.0f, 0, 0);
|
DrawBitmap(Buffer, &GameState->Backdrop, 0.0f, 0.0f, 0, 0);
|
||||||
|
|
||||||
float ScreenCenterX = 0.5f * (float)Buffer->Width;
|
ScreenCenterX = 0.5f * (float)Buffer->Width;
|
||||||
float ScreenCenterY = 0.5f * (float)Buffer->Height;
|
ScreenCenterY = 0.5f * (float)Buffer->Height;
|
||||||
|
|
||||||
for(int RelRow = -10; RelRow < 10; RelRow++) {
|
for(RelRow = -10; RelRow < 10; RelRow++) {
|
||||||
for(int RelColumn = -20; RelColumn < 20; RelColumn++) {
|
for(RelColumn = -20; RelColumn < 20; RelColumn++) {
|
||||||
unsigned int Column = GameState->CameraP.AbsTileX + RelColumn;
|
unsigned int Column = GameState->CameraP.AbsTileX + RelColumn;
|
||||||
unsigned int Row = GameState->CameraP.AbsTileY + RelRow;
|
unsigned int Row = GameState->CameraP.AbsTileY + RelRow;
|
||||||
|
|
||||||
@@ -770,7 +848,12 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
GameState->CameraP.AbsTileZ);
|
GameState->CameraP.AbsTileZ);
|
||||||
|
|
||||||
if(TileID > 1) {
|
if(TileID > 1) {
|
||||||
|
struct v2 TileSide, Center;
|
||||||
|
|
||||||
|
struct v2 Min, Max;
|
||||||
|
|
||||||
float Gray = 0.5f;
|
float Gray = 0.5f;
|
||||||
|
|
||||||
if(TileID == 2) {
|
if(TileID == 2) {
|
||||||
Gray = 1.0f;
|
Gray = 1.0f;
|
||||||
}
|
}
|
||||||
@@ -785,48 +868,58 @@ void UpdateAndRender(struct thread_context *Thread,
|
|||||||
Gray = 0.0f;
|
Gray = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct v2 TileSide = { 0.5f*(float)TileSideInPixels,
|
TileSide.X = 0.5f*(float)TileSideInPixels;
|
||||||
0.5f*(float)TileSideInPixels };
|
TileSide.Y = 0.5f*(float)TileSideInPixels;
|
||||||
struct v2 Center = { ScreenCenterX -
|
Center.X = ScreenCenterX -
|
||||||
MetersToPixels*GameState->CameraP.Offset.X +
|
MetersToPixels*GameState->CameraP.Offset.X +
|
||||||
(float)RelColumn*(float)TileSideInPixels,
|
(float)RelColumn*(float)TileSideInPixels;
|
||||||
ScreenCenterY + MetersToPixels *
|
Center.Y = ScreenCenterY + MetersToPixels *
|
||||||
GameState->CameraP.Offset.Y -
|
GameState->CameraP.Offset.Y -
|
||||||
(float)RelRow*(float)TileSideInPixels };
|
(float)RelRow*(float)TileSideInPixels;
|
||||||
struct v2 Min = V2Subtract(Center, TileSide);
|
Min = V2Subtract(Center, TileSide);
|
||||||
struct v2 Max = V2Add(Center, TileSide);
|
Max = V2Add(Center, TileSide);
|
||||||
DrawRectangle(Buffer, Min, Max, Gray, Gray, Gray);
|
DrawRectangle(Buffer, Min, Max, Gray, Gray, Gray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct entity *Entity = GameState->Entities;
|
Entity = GameState->Entities;
|
||||||
for(unsigned int EntityIndex = 0;
|
|
||||||
|
for(EntityIndex = 0;
|
||||||
EntityIndex < GameState->EntityCount;
|
EntityIndex < GameState->EntityCount;
|
||||||
EntityIndex++, Entity++)
|
EntityIndex++, Entity++)
|
||||||
{
|
{
|
||||||
if(Entity->Exists) {
|
if(Entity->Exists) {
|
||||||
struct tile_map_difference Diff =
|
struct tile_map_difference Diff;
|
||||||
SubtractInFloat(TileMap, &Entity->P, &GameState->CameraP);
|
|
||||||
|
float PlayerR, PlayerG, PlayerB;
|
||||||
|
float PlayerGroundPointX, PlayerGroundPointY;
|
||||||
|
struct v2 PlayerLeftTop, PlayerWidthHeight;
|
||||||
|
|
||||||
|
struct hero_bitmaps *Bitmap;
|
||||||
|
|
||||||
|
Diff = SubtractInFloat(TileMap, &Entity->P, &GameState->CameraP);
|
||||||
|
|
||||||
|
PlayerR = 1.0f;
|
||||||
|
PlayerG = 0.0f;
|
||||||
|
PlayerB = 0.0f;
|
||||||
|
PlayerGroundPointX = ScreenCenterX + MetersToPixels*Diff.dXY.X;
|
||||||
|
PlayerGroundPointY = ScreenCenterY - MetersToPixels*Diff.dXY.Y;
|
||||||
|
|
||||||
|
PlayerLeftTop.X =
|
||||||
|
PlayerGroundPointX - 0.5f * MetersToPixels*Entity->Width;
|
||||||
|
PlayerLeftTop.Y =
|
||||||
|
PlayerGroundPointY - MetersToPixels*Entity->Height;
|
||||||
|
|
||||||
|
PlayerWidthHeight.X = Entity->Width;
|
||||||
|
PlayerWidthHeight.X = Entity->Height;
|
||||||
|
|
||||||
float PlayerR = 1.0f;
|
|
||||||
float PlayerG = 0.0f;
|
|
||||||
float PlayerB = 0.0f;
|
|
||||||
float PlayerGroundPointX =
|
|
||||||
ScreenCenterX + MetersToPixels*Diff.dXY.X;
|
|
||||||
float PlayerGroundPointY =
|
|
||||||
ScreenCenterY - MetersToPixels*Diff.dXY.Y;
|
|
||||||
struct v2 PlayerLeftTop =
|
|
||||||
{ PlayerGroundPointX - 0.5f * MetersToPixels*Entity->Width,
|
|
||||||
PlayerGroundPointY - MetersToPixels*Entity->Height };
|
|
||||||
struct v2 PlayerWidthHeight = { Entity->Width, Entity->Height };
|
|
||||||
DrawRectangle(Buffer, PlayerLeftTop,
|
DrawRectangle(Buffer, PlayerLeftTop,
|
||||||
V2Add(PlayerLeftTop, V2Multiply(MetersToPixels,
|
V2Add(PlayerLeftTop, V2Multiply(MetersToPixels,
|
||||||
PlayerWidthHeight)),
|
PlayerWidthHeight)),
|
||||||
PlayerR, PlayerG, PlayerB);
|
PlayerR, PlayerG, PlayerB);
|
||||||
|
|
||||||
struct hero_bitmaps *Bitmap =
|
Bitmap = &GameState->HeroBitmaps[Entity->FacingDirection];
|
||||||
&GameState->HeroBitmaps[Entity->FacingDirection];
|
|
||||||
DrawBitmap(Buffer, &Bitmap->Torso,
|
DrawBitmap(Buffer, &Bitmap->Torso,
|
||||||
PlayerGroundPointX, PlayerGroundPointY,
|
PlayerGroundPointX, PlayerGroundPointY,
|
||||||
Bitmap->AlignX, Bitmap->AlignY);
|
Bitmap->AlignX, Bitmap->AlignY);
|
||||||
|
|||||||
+3
-3
@@ -83,8 +83,8 @@ struct game_controller_input {
|
|||||||
/* NOTE: All buttons must be added above this line. */
|
/* NOTE: All buttons must be added above this line. */
|
||||||
|
|
||||||
struct game_button_state Terminator;
|
struct game_button_state Terminator;
|
||||||
};
|
} s;
|
||||||
};
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct game_input {
|
struct game_input {
|
||||||
@@ -197,7 +197,7 @@ struct hero_bitmaps {
|
|||||||
struct entity {
|
struct entity {
|
||||||
int Exists;
|
int Exists;
|
||||||
struct tile_map_position P;
|
struct tile_map_position P;
|
||||||
struct v2 dP; // velocity
|
struct v2 dP; /* velocity */
|
||||||
unsigned int FacingDirection;
|
unsigned int FacingDirection;
|
||||||
float Height, Width;
|
float Height, Width;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
math.h. */
|
math.h. */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h> // memset
|
#include <string.h> /* memset */
|
||||||
|
|
||||||
float AbsoluteValue(float Real32)
|
float AbsoluteValue(float Real32)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#ifndef HANDMADE_MATH_H
|
#ifndef HANDMADE_MATH_H
|
||||||
#define HANDMADE_MATH_H
|
#define HANDMADE_MATH_H
|
||||||
|
|
||||||
// TODO: Make these static.
|
/* TODO: Make these static. */
|
||||||
struct v2 {
|
struct v2 {
|
||||||
float X, Y;
|
float X, Y;
|
||||||
float E[2];
|
float E[2];
|
||||||
|
|||||||
+17
-12
@@ -41,12 +41,13 @@ GetTileValueUnchecked(struct tile_map *TileMap,
|
|||||||
struct tile_chunk *TileChunk,
|
struct tile_chunk *TileChunk,
|
||||||
unsigned int TileX, unsigned int TileY)
|
unsigned int TileX, unsigned int TileY)
|
||||||
{
|
{
|
||||||
|
unsigned int TileChunkValue;
|
||||||
|
|
||||||
ASSERT(TileChunk);
|
ASSERT(TileChunk);
|
||||||
ASSERT(TileX < TileMap->ChunkDim);
|
ASSERT(TileX < TileMap->ChunkDim);
|
||||||
ASSERT(TileY < TileMap->ChunkDim);
|
ASSERT(TileY < TileMap->ChunkDim);
|
||||||
|
|
||||||
unsigned int TileChunkValue =
|
TileChunkValue = TileChunk->Tiles[TileY * TileMap->ChunkDim + TileX];
|
||||||
TileChunk->Tiles[TileY * TileMap->ChunkDim + TileX];
|
|
||||||
return TileChunkValue;
|
return TileChunkValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,9 +141,10 @@ static void SetTileValue(struct memory_arena *Arena,
|
|||||||
ASSERT(TileChunk);
|
ASSERT(TileChunk);
|
||||||
if(!TileChunk->Tiles) {
|
if(!TileChunk->Tiles) {
|
||||||
unsigned int TileCount = TileMap->ChunkDim*TileMap->ChunkDim;
|
unsigned int TileCount = TileMap->ChunkDim*TileMap->ChunkDim;
|
||||||
|
unsigned int TileIndex;
|
||||||
|
|
||||||
TileChunk->Tiles = PUSH_ARRAY(Arena, TileCount, unsigned int);
|
TileChunk->Tiles = PUSH_ARRAY(Arena, TileCount, unsigned int);
|
||||||
for(unsigned int TileIndex = 0;
|
for(TileIndex = 0;
|
||||||
TileIndex < TileCount;
|
TileIndex < TileCount;
|
||||||
TileIndex++)
|
TileIndex++)
|
||||||
{
|
{
|
||||||
@@ -154,15 +156,13 @@ static void SetTileValue(struct memory_arena *Arena,
|
|||||||
ChunkPos.RelTileY, TileValue);
|
ChunkPos.RelTileY, TileValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* TODO: Do these belong more in a "positioning" or "geometry" file? */
|
||||||
// TODO: Do these belong more in a "positioning" or "geometry" file?
|
|
||||||
//
|
|
||||||
|
|
||||||
static void CannonicalizeCoord(struct tile_map *TileMap, unsigned int *Tile,
|
static void CannonicalizeCoord(struct tile_map *TileMap, unsigned int *Tile,
|
||||||
float *TileRel)
|
float *TileRel)
|
||||||
{
|
{
|
||||||
// NOTE: The world is assumed to be toroidal topology. If you step off
|
/* NOTE: The world is assumed to be toroidal topology. If you step off
|
||||||
// one end, you come back on the other.
|
* one end, you come back on the other.*/
|
||||||
int Offset = RoundFloatToInt(*TileRel / TileMap->TileSideInMeters);
|
int Offset = RoundFloatToInt(*TileRel / TileMap->TileSideInMeters);
|
||||||
*Tile += Offset;
|
*Tile += Offset;
|
||||||
*TileRel -= (float)Offset * TileMap->TileSideInMeters;
|
*TileRel -= (float)Offset * TileMap->TileSideInMeters;
|
||||||
@@ -198,15 +198,20 @@ SubtractInFloat(struct tile_map *TileMap,
|
|||||||
{
|
{
|
||||||
struct tile_map_difference Result;
|
struct tile_map_difference Result;
|
||||||
|
|
||||||
struct v2 dTileXY = { ((float)A->AbsTileX - (float)B->AbsTileX),
|
struct v2 dTileXY;
|
||||||
((float)A->AbsTileY - (float)B->AbsTileY) };
|
|
||||||
float dTileZ = (float)A->AbsTileZ - (float)B->AbsTileZ;
|
float dTileZ;
|
||||||
|
|
||||||
|
dTileXY.X = (float)A->AbsTileX - (float)B->AbsTileX;
|
||||||
|
dTileXY.Y = (float)A->AbsTileY - (float)B->AbsTileY;
|
||||||
|
|
||||||
|
dTileZ = (float)A->AbsTileZ - (float)B->AbsTileZ;
|
||||||
|
|
||||||
Result.dXY = V2Add(V2Multiply(TileMap->TileSideInMeters,
|
Result.dXY = V2Add(V2Multiply(TileMap->TileSideInMeters,
|
||||||
dTileXY),
|
dTileXY),
|
||||||
V2Subtract(A->Offset, B->Offset));
|
V2Subtract(A->Offset, B->Offset));
|
||||||
|
|
||||||
// TODO: Incomplete . . .
|
/* TODO: Incomplete . . . */
|
||||||
Result.dZ = TileMap->TileSideInMeters*dTileZ;
|
Result.dZ = TileMap->TileSideInMeters*dTileZ;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
|
|||||||
+188
-115
@@ -1,7 +1,6 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
// Remove SDL's entry point.
|
#if OS_WINDOWS /* Remove SDL's entry point. */
|
||||||
#if OS_WINDOWS
|
|
||||||
#define SDL_MAIN_HANDLED
|
#define SDL_MAIN_HANDLED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@
|
|||||||
/* NOTE: This is so it compiles on ARM. */
|
/* NOTE: This is so it compiles on ARM. */
|
||||||
#if ARCHITECTURE_X64 || ARCHITECTURE_X86
|
#if ARCHITECTURE_X64 || ARCHITECTURE_X86
|
||||||
#if OS_MACOS || OS_LINUX
|
#if OS_MACOS || OS_LINUX
|
||||||
#include <x86intrin.h> // TODO: What is the equivalent on Windows?
|
#include <x86intrin.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -72,8 +71,12 @@ static int str_len(char *str)
|
|||||||
|
|
||||||
static unsigned int SafeTruncateUInt64(unsigned long long Value)
|
static unsigned int SafeTruncateUInt64(unsigned long long Value)
|
||||||
{
|
{
|
||||||
|
unsigned int Result;
|
||||||
|
|
||||||
ASSERT(Value <= 0xFFFFFFFF);
|
ASSERT(Value <= 0xFFFFFFFF);
|
||||||
unsigned int Result = (unsigned int)Value;
|
|
||||||
|
Result = (unsigned int)Value;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,14 +84,19 @@ struct debug_read_file_result
|
|||||||
DEBUGPlatformReadEntireFile(struct thread_context *Thread,
|
DEBUGPlatformReadEntireFile(struct thread_context *Thread,
|
||||||
const char *Filename)
|
const char *Filename)
|
||||||
{
|
{
|
||||||
(void)Thread;
|
|
||||||
|
|
||||||
struct debug_read_file_result Result;
|
struct debug_read_file_result Result;
|
||||||
|
|
||||||
|
SDL_RWops *FileHandle;
|
||||||
|
|
||||||
memset(&Result, 0, sizeof(Result));
|
memset(&Result, 0, sizeof(Result));
|
||||||
|
|
||||||
SDL_RWops *FileHandle = SDL_RWFromFile(Filename, "r");
|
FileHandle = SDL_RWFromFile(Filename, "r");
|
||||||
if(FileHandle) {
|
if(FileHandle) {
|
||||||
long long FileSize = SDL_RWsize(FileHandle);
|
long long FileSize;
|
||||||
|
unsigned int ObjectsRead;
|
||||||
|
|
||||||
|
FileSize = SDL_RWsize(FileHandle);
|
||||||
|
|
||||||
if(FileSize >= 0) {
|
if(FileSize >= 0) {
|
||||||
Result.ContentsSize = SafeTruncateUInt64(FileSize);
|
Result.ContentsSize = SafeTruncateUInt64(FileSize);
|
||||||
} else {
|
} else {
|
||||||
@@ -104,7 +112,7 @@ DEBUGPlatformReadEntireFile(struct thread_context *Thread,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ObjectsRead = SDL_RWread(FileHandle,
|
ObjectsRead = SDL_RWread(FileHandle,
|
||||||
(void *)Result.Contents, Result.ContentsSize, 1);
|
(void *)Result.Contents, Result.ContentsSize, 1);
|
||||||
if(ObjectsRead == 0) {
|
if(ObjectsRead == 0) {
|
||||||
free(Result.Contents);
|
free(Result.Contents);
|
||||||
@@ -225,13 +233,15 @@ static void
|
|||||||
SDLResizeTexture(struct offscreen_buffer *Buffer,
|
SDLResizeTexture(struct offscreen_buffer *Buffer,
|
||||||
SDL_Renderer *Renderer, int Width, int Height)
|
SDL_Renderer *Renderer, int Width, int Height)
|
||||||
{
|
{
|
||||||
|
int BytesPerPixel;
|
||||||
|
|
||||||
if(Buffer->Texture)
|
if(Buffer->Texture)
|
||||||
SDL_DestroyTexture(Buffer->Texture);
|
SDL_DestroyTexture(Buffer->Texture);
|
||||||
|
|
||||||
if(Buffer->Memory)
|
if(Buffer->Memory)
|
||||||
free(Buffer->Memory);
|
free(Buffer->Memory);
|
||||||
|
|
||||||
int BytesPerPixel = 4;
|
BytesPerPixel = 4;
|
||||||
|
|
||||||
Buffer->Texture = SDL_CreateTexture(Renderer,
|
Buffer->Texture = SDL_CreateTexture(Renderer,
|
||||||
SDL_PIXELFORMAT_ARGB8888,
|
SDL_PIXELFORMAT_ARGB8888,
|
||||||
@@ -248,8 +258,12 @@ static void SDLDisplayBufferInWindow(struct offscreen_buffer *Buffer,
|
|||||||
SDL_Window *Window,
|
SDL_Window *Window,
|
||||||
SDL_Renderer *Renderer)
|
SDL_Renderer *Renderer)
|
||||||
{
|
{
|
||||||
int OffsetX = 10;
|
int OffsetX, OffsetY;
|
||||||
int OffsetY = 10;
|
|
||||||
|
struct sdl_window_size WinSize;
|
||||||
|
|
||||||
|
OffsetX = 10;
|
||||||
|
OffsetY = 10;
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255);
|
||||||
SDL_RenderClear(Renderer);
|
SDL_RenderClear(Renderer);
|
||||||
@@ -261,17 +275,23 @@ static void SDLDisplayBufferInWindow(struct offscreen_buffer *Buffer,
|
|||||||
/* TODO: We temporarily introduce the target rectangle to avoid
|
/* TODO: We temporarily introduce the target rectangle to avoid
|
||||||
* stretching the canvas. */
|
* stretching the canvas. */
|
||||||
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */
|
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */
|
||||||
struct sdl_window_size WinSize = SDLGetBorderedWindowSize(Window);
|
WinSize = SDLGetBorderedWindowSize(Window);
|
||||||
if(WinSize.Width >= Buffer->Width*2 &&
|
if(WinSize.Width >= Buffer->Width*2 &&
|
||||||
WinSize.Height >= Buffer->Height*2)
|
WinSize.Height >= Buffer->Height*2)
|
||||||
{
|
{
|
||||||
SDL_Rect dest_rect =
|
SDL_Rect dest_rect;
|
||||||
{ OffsetX, OffsetY, Buffer->Width*2, Buffer->Height*2 };
|
dest_rect.x = OffsetX;
|
||||||
|
dest_rect.y = OffsetY;
|
||||||
|
dest_rect.w = Buffer->Width*2;
|
||||||
|
dest_rect.h = Buffer->Height*2;
|
||||||
SDL_RenderCopy(Renderer, Buffer->Texture, 0,
|
SDL_RenderCopy(Renderer, Buffer->Texture, 0,
|
||||||
(const SDL_Rect *)(&dest_rect));
|
(const SDL_Rect *)(&dest_rect));
|
||||||
} else {
|
} else {
|
||||||
SDL_Rect dest_rect =
|
SDL_Rect dest_rect;
|
||||||
{ OffsetX, OffsetY, RESOLUTION_WIDTH, RESOLUTION_HEIGHT };
|
dest_rect.x = OffsetX;
|
||||||
|
dest_rect.y = OffsetY;
|
||||||
|
dest_rect.w = RESOLUTION_WIDTH;
|
||||||
|
dest_rect.h = RESOLUTION_HEIGHT;
|
||||||
SDL_RenderCopy(Renderer, Buffer->Texture, 0,
|
SDL_RenderCopy(Renderer, Buffer->Texture, 0,
|
||||||
(const SDL_Rect *)(&dest_rect));
|
(const SDL_Rect *)(&dest_rect));
|
||||||
}
|
}
|
||||||
@@ -282,7 +302,9 @@ static void SDLInitControllers()
|
|||||||
{
|
{
|
||||||
int MaxJoysticks = SDL_NumJoysticks();
|
int MaxJoysticks = SDL_NumJoysticks();
|
||||||
int ControllerIndex = 0;
|
int ControllerIndex = 0;
|
||||||
for(int JoystickIndex = 0; JoystickIndex < MaxJoysticks; JoystickIndex++)
|
|
||||||
|
int JoystickIndex;
|
||||||
|
for(JoystickIndex = 0; JoystickIndex < MaxJoysticks; JoystickIndex++)
|
||||||
{
|
{
|
||||||
if(!SDL_IsGameController(JoystickIndex))
|
if(!SDL_IsGameController(JoystickIndex))
|
||||||
continue;
|
continue;
|
||||||
@@ -460,40 +482,40 @@ static void SDLProcessMessages(struct sdl_state *SDLState,
|
|||||||
if(Event.key.repeat == 0) {
|
if(Event.key.repeat == 0) {
|
||||||
if(KeyCode == SDLK_w) {
|
if(KeyCode == SDLK_w) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->MoveUp, IsDown);
|
&KeyboardController->u.s.MoveUp, IsDown);
|
||||||
} else if(KeyCode == SDLK_s) {
|
} else if(KeyCode == SDLK_s) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->MoveDown, IsDown);
|
&KeyboardController->u.s.MoveDown, IsDown);
|
||||||
} else if(KeyCode == SDLK_a) {
|
} else if(KeyCode == SDLK_a) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->MoveLeft, IsDown);
|
&KeyboardController->u.s.MoveLeft, IsDown);
|
||||||
} else if(KeyCode == SDLK_d) {
|
} else if(KeyCode == SDLK_d) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->MoveRight, IsDown);
|
&KeyboardController->u.s.MoveRight, IsDown);
|
||||||
} else if(KeyCode == SDLK_q) {
|
} else if(KeyCode == SDLK_q) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->LeftShoulder, IsDown);
|
&KeyboardController->u.s.LeftShoulder, IsDown);
|
||||||
} else if(KeyCode == SDLK_e) {
|
} else if(KeyCode == SDLK_e) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->RightShoulder, IsDown);
|
&KeyboardController->u.s.RightShoulder, IsDown);
|
||||||
} else if(KeyCode == SDLK_UP) {
|
} else if(KeyCode == SDLK_UP) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->ActionUp, IsDown);
|
&KeyboardController->u.s.ActionUp, IsDown);
|
||||||
} else if(KeyCode == SDLK_DOWN) {
|
} else if(KeyCode == SDLK_DOWN) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->ActionDown, IsDown);
|
&KeyboardController->u.s.ActionDown, IsDown);
|
||||||
} else if(KeyCode == SDLK_LEFT) {
|
} else if(KeyCode == SDLK_LEFT) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->ActionLeft, IsDown);
|
&KeyboardController->u.s.ActionLeft, IsDown);
|
||||||
} else if(KeyCode == SDLK_RIGHT) {
|
} else if(KeyCode == SDLK_RIGHT) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->ActionRight, IsDown);
|
&KeyboardController->u.s.ActionRight, IsDown);
|
||||||
} else if(KeyCode == SDLK_ESCAPE) {
|
} else if(KeyCode == SDLK_ESCAPE) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->Back, IsDown);
|
&KeyboardController->u.s.Back, IsDown);
|
||||||
} else if(KeyCode == SDLK_SPACE) {
|
} else if(KeyCode == SDLK_SPACE) {
|
||||||
SDLProcessKeyboardMessage(
|
SDLProcessKeyboardMessage(
|
||||||
&KeyboardController->Start, IsDown);
|
&KeyboardController->u.s.Start, IsDown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,10 +711,6 @@ void GetExecutablePath(char *path, size_t path_size)
|
|||||||
|
|
||||||
static void SDLGetEXEDirPath(char *path, size_t path_size)
|
static void SDLGetEXEDirPath(char *path, size_t path_size)
|
||||||
{
|
{
|
||||||
GetExecutablePath(path, path_size);
|
|
||||||
unsigned int len = str_len(path);
|
|
||||||
unsigned int i = len;
|
|
||||||
|
|
||||||
#if OS_MACOS || OS_LINUX
|
#if OS_MACOS || OS_LINUX
|
||||||
char delimeter = '/';
|
char delimeter = '/';
|
||||||
#elif OS_WINDOWS
|
#elif OS_WINDOWS
|
||||||
@@ -701,6 +719,12 @@ static void SDLGetEXEDirPath(char *path, size_t path_size)
|
|||||||
#error Unknown OS: OS uses forward or backward slashes for paths?
|
#error Unknown OS: OS uses forward or backward slashes for paths?
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
unsigned int len, i;
|
||||||
|
|
||||||
|
GetExecutablePath(path, path_size);
|
||||||
|
len = str_len(path);
|
||||||
|
i = len;
|
||||||
|
|
||||||
while(path[i] != delimeter || i == 0) {
|
while(path[i] != delimeter || i == 0) {
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -722,6 +746,9 @@ U64 __rdtsc()
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct sdl_state SDLState;
|
struct sdl_state SDLState;
|
||||||
|
|
||||||
|
SDL_Window *Window;
|
||||||
|
|
||||||
memset(&SDLState, 0, sizeof(SDLState));
|
memset(&SDLState, 0, sizeof(SDLState));
|
||||||
|
|
||||||
SDLGetEXEDirPath(SDLState.EXEDirPath, sizeof(SDLState.EXEDirPath));
|
SDLGetEXEDirPath(SDLState.EXEDirPath, sizeof(SDLState.EXEDirPath));
|
||||||
@@ -738,19 +765,21 @@ int main(int argc, char *argv[])
|
|||||||
* before everything is ready. */
|
* before everything is ready. */
|
||||||
/* TODO: SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, in non-debug
|
/* TODO: SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, in non-debug
|
||||||
* build */
|
* build */
|
||||||
SDL_Window *Window = SDL_CreateWindow("Handmade Hero",
|
Window = SDL_CreateWindow("Handmade Hero",
|
||||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||||
RESOLUTION_WIDTH+20, RESOLUTION_HEIGHT+20,
|
RESOLUTION_WIDTH+20, RESOLUTION_HEIGHT+20,
|
||||||
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE/* |
|
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE/* |
|
||||||
SDL_WINDOW_ALWAYS_ON_TOP*/);
|
SDL_WINDOW_ALWAYS_ON_TOP*/);
|
||||||
if(Window) {
|
if(Window) {
|
||||||
|
SDL_DisplayMode display_mode;
|
||||||
|
|
||||||
|
SDL_Renderer *Renderer;
|
||||||
|
|
||||||
LastWindow = Window;
|
LastWindow = Window;
|
||||||
|
|
||||||
SDL_DisplayMode display_mode;
|
|
||||||
SDL_GetCurrentDisplayMode(0, &display_mode);
|
SDL_GetCurrentDisplayMode(0, &display_mode);
|
||||||
|
|
||||||
SDL_Renderer *Renderer =
|
Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC);
|
||||||
SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC);
|
|
||||||
|
|
||||||
/* NOTE: For future reference, the custom window bar should use
|
/* NOTE: For future reference, the custom window bar should use
|
||||||
* SDL_SetWindowHitTest to define areas that will be used to drag
|
* SDL_SetWindowHitTest to define areas that will be used to drag
|
||||||
@@ -764,11 +793,27 @@ int main(int argc, char *argv[])
|
|||||||
/* SDL_RenderPresent(Renderer) is enough to display the window. */
|
/* SDL_RenderPresent(Renderer) is enough to display the window. */
|
||||||
if(Renderer) {
|
if(Renderer) {
|
||||||
struct thread_context TempContext;
|
struct thread_context TempContext;
|
||||||
|
|
||||||
|
SDL_Cursor *PointerCursor;
|
||||||
|
|
||||||
|
SDL_Rect UsableDisplayRect;
|
||||||
|
|
||||||
|
struct sdl_window_size CurrentWindowSize;
|
||||||
|
|
||||||
|
struct sdl_sound_output SoundOutput;
|
||||||
|
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
void *BaseAddress = (void *)TB(2);
|
||||||
|
#else
|
||||||
|
void *BaseAddress = (void *)(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct game_memory GameMemory;
|
||||||
|
|
||||||
memset(&TempContext, 0, sizeof(TempContext));
|
memset(&TempContext, 0, sizeof(TempContext));
|
||||||
|
|
||||||
/* TODO: Make it a global. */
|
/* TODO: Make it a global. */
|
||||||
SDL_Cursor *PointerCursor =
|
PointerCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||||
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
|
||||||
SDL_SetCursor(PointerCursor);
|
SDL_SetCursor(PointerCursor);
|
||||||
#if !BUILD_INTERNAL
|
#if !BUILD_INTERNAL
|
||||||
if(SDL_ShowCursor(SDL_DISABLE) < 0) {
|
if(SDL_ShowCursor(SDL_DISABLE) < 0) {
|
||||||
@@ -776,10 +821,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_Rect UsableDisplayRect;
|
|
||||||
SDL_GetDisplayUsableBounds(0, &UsableDisplayRect);
|
SDL_GetDisplayUsableBounds(0, &UsableDisplayRect);
|
||||||
struct sdl_window_size CurrentWindowSize =
|
CurrentWindowSize = SDLGetBorderedWindowSize(Window);
|
||||||
SDLGetBorderedWindowSize(Window);
|
|
||||||
SDLSetBorderedWindowPosition(Window,
|
SDLSetBorderedWindowPosition(Window,
|
||||||
(UsableDisplayRect.x + UsableDisplayRect.w -
|
(UsableDisplayRect.x + UsableDisplayRect.w -
|
||||||
CurrentWindowSize.Width),
|
CurrentWindowSize.Width),
|
||||||
@@ -795,7 +838,6 @@ int main(int argc, char *argv[])
|
|||||||
SDLResizeTexture(&GlobalBackbuffer, Renderer,
|
SDLResizeTexture(&GlobalBackbuffer, Renderer,
|
||||||
RESOLUTION_WIDTH, RESOLUTION_HEIGHT);
|
RESOLUTION_WIDTH, RESOLUTION_HEIGHT);
|
||||||
|
|
||||||
struct sdl_sound_output SoundOutput;
|
|
||||||
memset(&SoundOutput, 0, sizeof(SoundOutput));
|
memset(&SoundOutput, 0, sizeof(SoundOutput));
|
||||||
SoundOutput.SamplesPerSecond = 48000;
|
SoundOutput.SamplesPerSecond = 48000;
|
||||||
SoundOutput.BytesPerSample = sizeof(short) * 2;
|
SoundOutput.BytesPerSample = sizeof(short) * 2;
|
||||||
@@ -816,13 +858,6 @@ int main(int argc, char *argv[])
|
|||||||
/* NOTE: calloc auto clears to zero */
|
/* NOTE: calloc auto clears to zero */
|
||||||
/* SDLClearSoundBuffer(&SoundOutput); */
|
/* SDLClearSoundBuffer(&SoundOutput); */
|
||||||
|
|
||||||
#if BUILD_DEBUG
|
|
||||||
void *BaseAddress = (void *)TB(2);
|
|
||||||
#else
|
|
||||||
void *BaseAddress = (void *)(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct game_memory GameMemory;
|
|
||||||
memset(&GameMemory, 0, sizeof(GameMemory));
|
memset(&GameMemory, 0, sizeof(GameMemory));
|
||||||
GameMemory.PermanentStorageSize = MB(64);
|
GameMemory.PermanentStorageSize = MB(64);
|
||||||
GameMemory.TransientStorageSize = GB(1);
|
GameMemory.TransientStorageSize = GB(1);
|
||||||
@@ -863,24 +898,65 @@ int main(int argc, char *argv[])
|
|||||||
unsigned long long LastCounter;
|
unsigned long long LastCounter;
|
||||||
unsigned long long LastCycleCount;
|
unsigned long long LastCycleCount;
|
||||||
|
|
||||||
int MonitorRefreshHz = SDLGetWindowRefreshRate(Window);
|
int MonitorRefreshHz, GameUpdateHz;
|
||||||
/*GameUpdateHz = MonitorRefreshHz;*/
|
float TargetSecondsPerFrame;
|
||||||
int GameUpdateHz = 30; /* NOTE: Temporarily target 30 FPS. */
|
|
||||||
float TargetSecondsPerFrame = 1.0f / (float)GameUpdateHz;
|
|
||||||
|
|
||||||
struct game_input *NewInput = &Input[0];
|
struct game_input *NewInput, *OldInput;
|
||||||
struct game_input *OldInput = &Input[1];
|
|
||||||
|
struct sdl_game_code Game;
|
||||||
|
|
||||||
|
unsigned long long FPSLastCounter;
|
||||||
|
|
||||||
|
MonitorRefreshHz = SDLGetWindowRefreshRate(Window);
|
||||||
|
/*GameUpdateHz = MonitorRefreshHz;*/
|
||||||
|
GameUpdateHz = 30; /* NOTE: Temporarily target 30 FPS. */
|
||||||
|
TargetSecondsPerFrame = 1.0f / (float)GameUpdateHz;
|
||||||
|
|
||||||
|
NewInput = &Input[0];
|
||||||
|
OldInput = &Input[1];
|
||||||
memset(Input, 0, sizeof(Input));
|
memset(Input, 0, sizeof(Input));
|
||||||
|
|
||||||
GlobalPerfCountFrequency = SDL_GetPerformanceFrequency();
|
GlobalPerfCountFrequency = SDL_GetPerformanceFrequency();
|
||||||
|
|
||||||
struct sdl_game_code Game = SDLLoadGameCode(SDLState.DLLPath);
|
Game = SDLLoadGameCode(SDLState.DLLPath);
|
||||||
|
|
||||||
SDL_ShowWindow(Window); // Everything is ready; display the window.
|
SDL_ShowWindow(Window); // Everything is ready; display the window.
|
||||||
|
|
||||||
unsigned long long FPSLastCounter = SDLGetWallClock();
|
FPSLastCounter = SDLGetWallClock();
|
||||||
|
|
||||||
while(GlobalRunning) {
|
while(GlobalRunning) {
|
||||||
|
unsigned int NewDLLWriteTime;
|
||||||
|
|
||||||
|
int MouseX, MouseY;
|
||||||
|
|
||||||
|
int WindowX, WindowY;
|
||||||
|
|
||||||
|
unsigned int SDLMouseButtons;
|
||||||
|
|
||||||
|
struct game_controller_input *OldKeyboardController,
|
||||||
|
*NewKeyboardController;
|
||||||
|
struct game_controller_input ZeroController;
|
||||||
|
|
||||||
|
unsigned int ButtonIndex;
|
||||||
|
unsigned int ControllerIndex;
|
||||||
|
|
||||||
|
int TargetQueueBytes;
|
||||||
|
int BytesToWrite;
|
||||||
|
struct game_sound_output_buffer SoundBuffer;
|
||||||
|
|
||||||
|
struct thread_context Context;
|
||||||
|
|
||||||
|
struct game_offscreen_buffer Buffer;
|
||||||
|
|
||||||
|
unsigned long long WorkCounter;
|
||||||
|
float WorkSecondsElapsed;
|
||||||
|
float SecondsElapsedForFrame;
|
||||||
|
|
||||||
|
unsigned long long EndCounter;
|
||||||
|
|
||||||
|
float MSPerFrame;
|
||||||
|
float FPS;
|
||||||
|
|
||||||
NewInput->dtForFrame = TargetSecondsPerFrame;
|
NewInput->dtForFrame = TargetSecondsPerFrame;
|
||||||
|
|
||||||
LastCounter = SDLGetWallClock();
|
LastCounter = SDLGetWallClock();
|
||||||
@@ -891,24 +967,20 @@ int main(int argc, char *argv[])
|
|||||||
* on MacOS ARM; I have not checked MacOS x64. */
|
* on MacOS ARM; I have not checked MacOS x64. */
|
||||||
LastCycleCount = __rdtsc();
|
LastCycleCount = __rdtsc();
|
||||||
|
|
||||||
unsigned int NewDLLWriteTime =
|
NewDLLWriteTime = GetLastWriteTime(SDLState.DLLPath);
|
||||||
GetLastWriteTime(SDLState.DLLPath);
|
|
||||||
if(NewDLLWriteTime > Game.DLLLastWriteTime) {
|
if(NewDLLWriteTime > Game.DLLLastWriteTime) {
|
||||||
SDLUnloadGameCode(&Game);
|
SDLUnloadGameCode(&Game);
|
||||||
Game = SDLLoadGameCode(SDLState.DLLPath);
|
Game = SDLLoadGameCode(SDLState.DLLPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MouseX, MouseY;
|
|
||||||
SDL_GetGlobalMouseState(&MouseX, &MouseY);
|
SDL_GetGlobalMouseState(&MouseX, &MouseY);
|
||||||
|
|
||||||
int WindowX, WindowY;
|
|
||||||
SDL_GetWindowPosition(Window, &WindowX, &WindowY);
|
SDL_GetWindowPosition(Window, &WindowX, &WindowY);
|
||||||
|
|
||||||
NewInput->MouseX = MouseX - WindowX;
|
NewInput->MouseX = MouseX - WindowX;
|
||||||
NewInput->MouseY = MouseY - WindowY;
|
NewInput->MouseY = MouseY - WindowY;
|
||||||
|
|
||||||
unsigned int SDLMouseButtons =
|
SDLMouseButtons = SDL_GetMouseState(NULL, NULL);
|
||||||
SDL_GetMouseState(NULL, NULL);
|
|
||||||
NewInput->MouseZ = 0; /* TODO: Support mouse wheel? */
|
NewInput->MouseZ = 0; /* TODO: Support mouse wheel? */
|
||||||
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[0]),
|
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[0]),
|
||||||
SDL_BUTTON_LMASK & SDLMouseButtons);
|
SDL_BUTTON_LMASK & SDLMouseButtons);
|
||||||
@@ -923,49 +995,53 @@ int main(int argc, char *argv[])
|
|||||||
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[4]),
|
SDLProcessKeyboardMessage(&(NewInput->MouseButtons[4]),
|
||||||
SDL_BUTTON_X2MASK & SDLMouseButtons);
|
SDL_BUTTON_X2MASK & SDLMouseButtons);
|
||||||
|
|
||||||
struct game_controller_input *OldKeyboardController =
|
OldKeyboardController = GetController(OldInput, 0);
|
||||||
GetController(OldInput, 0);
|
NewKeyboardController = GetController(NewInput, 0);
|
||||||
struct game_controller_input *NewKeyboardController =
|
|
||||||
GetController(NewInput, 0);
|
|
||||||
struct game_controller_input ZeroController;
|
|
||||||
memset(&ZeroController, 0, sizeof(ZeroController));
|
memset(&ZeroController, 0, sizeof(ZeroController));
|
||||||
*NewKeyboardController = ZeroController;
|
*NewKeyboardController = ZeroController;
|
||||||
NewKeyboardController->IsConnected = 1;
|
NewKeyboardController->IsConnected = 1;
|
||||||
|
|
||||||
for(unsigned int ButtonIndex = 0;
|
for(ButtonIndex = 0;
|
||||||
ButtonIndex <
|
ButtonIndex <
|
||||||
ARRAY_SIZE(NewKeyboardController->Buttons);
|
ARRAY_SIZE(NewKeyboardController->u.Buttons);
|
||||||
ButtonIndex++)
|
ButtonIndex++)
|
||||||
{
|
{
|
||||||
NewKeyboardController->
|
NewKeyboardController->u.
|
||||||
Buttons[ButtonIndex].EndedDown =
|
Buttons[ButtonIndex].EndedDown =
|
||||||
OldKeyboardController->
|
OldKeyboardController->u.
|
||||||
Buttons[ButtonIndex].EndedDown;
|
Buttons[ButtonIndex].EndedDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDLProcessMessages(&SDLState, NewKeyboardController);
|
SDLProcessMessages(&SDLState, NewKeyboardController);
|
||||||
|
|
||||||
for(unsigned int ControllerIndex = 0;
|
for(ControllerIndex = 0;
|
||||||
ControllerIndex < MAX_CONTROLLERS;
|
ControllerIndex < MAX_CONTROLLERS;
|
||||||
ControllerIndex++)
|
ControllerIndex++)
|
||||||
{
|
{
|
||||||
struct game_controller_input *OldController =
|
struct game_controller_input *OldController,
|
||||||
|
*NewController;
|
||||||
|
|
||||||
|
OldController =
|
||||||
GetController(OldInput, ControllerIndex+1);
|
GetController(OldInput, ControllerIndex+1);
|
||||||
struct game_controller_input *NewController =
|
NewController =
|
||||||
GetController(NewInput, ControllerIndex+1);
|
GetController(NewInput, ControllerIndex+1);
|
||||||
|
|
||||||
if(ControllerHandles[ControllerIndex] != 0 &&
|
if(ControllerHandles[ControllerIndex] != 0 &&
|
||||||
SDL_GameControllerGetAttached(
|
SDL_GameControllerGetAttached(
|
||||||
ControllerHandles[ControllerIndex]))
|
ControllerHandles[ControllerIndex]))
|
||||||
{
|
{
|
||||||
|
short StickX, StickY;
|
||||||
|
|
||||||
|
float Threshold;
|
||||||
|
|
||||||
NewController->IsAnalog =
|
NewController->IsAnalog =
|
||||||
OldController->IsAnalog;
|
OldController->IsAnalog;
|
||||||
NewController->IsConnected = 1;
|
NewController->IsConnected = 1;
|
||||||
|
|
||||||
short StickX = SDL_GameControllerGetAxis(
|
StickX = SDL_GameControllerGetAxis(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
SDL_CONTROLLER_AXIS_LEFTX);
|
SDL_CONTROLLER_AXIS_LEFTX);
|
||||||
short StickY = SDL_GameControllerGetAxis(
|
StickY = SDL_GameControllerGetAxis(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
SDL_CONTROLLER_AXIS_LEFTY);
|
SDL_CONTROLLER_AXIS_LEFTY);
|
||||||
|
|
||||||
@@ -1015,94 +1091,91 @@ int main(int argc, char *argv[])
|
|||||||
NewController->IsAnalog = 0;
|
NewController->IsAnalog = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Threshold = 0.5f;
|
Threshold = 0.5f;
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[(NewController->
|
ControllerHandles[(NewController->
|
||||||
StickAverageY < -Threshold) ? 1 : 0],
|
StickAverageY < -Threshold) ? 1 : 0],
|
||||||
&OldController->MoveUp,
|
&OldController->u.s.MoveUp,
|
||||||
SDL_CONTROLLER_BUTTON_A,
|
SDL_CONTROLLER_BUTTON_A,
|
||||||
&NewController->MoveUp);
|
&NewController->u.s.MoveUp);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[(NewController->
|
ControllerHandles[(NewController->
|
||||||
StickAverageY > Threshold) ? 1 : 0],
|
StickAverageY > Threshold) ? 1 : 0],
|
||||||
&OldController->MoveDown,
|
&OldController->u.s.MoveDown,
|
||||||
SDL_CONTROLLER_BUTTON_A,
|
SDL_CONTROLLER_BUTTON_A,
|
||||||
&NewController->MoveDown);
|
&NewController->u.s.MoveDown);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[(NewController->
|
ControllerHandles[(NewController->
|
||||||
StickAverageX < -Threshold) ? 1 : 0],
|
StickAverageX < -Threshold) ? 1 : 0],
|
||||||
&OldController->MoveLeft,
|
&OldController->u.s.MoveLeft,
|
||||||
SDL_CONTROLLER_BUTTON_A,
|
SDL_CONTROLLER_BUTTON_A,
|
||||||
&NewController->MoveLeft);
|
&NewController->u.s.MoveLeft);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[(NewController->
|
ControllerHandles[(NewController->
|
||||||
StickAverageX > Threshold) ? 1 : 0],
|
StickAverageX > Threshold) ? 1 : 0],
|
||||||
&OldController->MoveRight,
|
&OldController->u.s.MoveRight,
|
||||||
SDL_CONTROLLER_BUTTON_A,
|
SDL_CONTROLLER_BUTTON_A,
|
||||||
&NewController->MoveRight);
|
&NewController->u.s.MoveRight);
|
||||||
|
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
&OldController->ActionDown,
|
&OldController->u.s.ActionDown,
|
||||||
SDL_CONTROLLER_BUTTON_A,
|
SDL_CONTROLLER_BUTTON_A,
|
||||||
&NewController->ActionDown);
|
&NewController->u.s.ActionDown);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
&OldController->ActionRight,
|
&OldController->u.s.ActionRight,
|
||||||
SDL_CONTROLLER_BUTTON_B,
|
SDL_CONTROLLER_BUTTON_B,
|
||||||
&NewController->ActionRight);
|
&NewController->u.s.ActionRight);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
&OldController->ActionLeft,
|
&OldController->u.s.ActionLeft,
|
||||||
SDL_CONTROLLER_BUTTON_X,
|
SDL_CONTROLLER_BUTTON_X,
|
||||||
&NewController->ActionLeft);
|
&NewController->u.s.ActionLeft);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
&OldController->ActionUp,
|
&OldController->u.s.ActionUp,
|
||||||
SDL_CONTROLLER_BUTTON_Y,
|
SDL_CONTROLLER_BUTTON_Y,
|
||||||
&NewController->ActionUp);
|
&NewController->u.s.ActionUp);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
&OldController->LeftShoulder,
|
&OldController->u.s.LeftShoulder,
|
||||||
SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
|
SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
|
||||||
&NewController->LeftShoulder);
|
&NewController->u.s.LeftShoulder);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
&OldController->RightShoulder,
|
&OldController->u.s.RightShoulder,
|
||||||
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
|
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
|
||||||
&NewController->RightShoulder);
|
&NewController->u.s.RightShoulder);
|
||||||
|
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
&OldController->Start,
|
&OldController->u.s.Start,
|
||||||
SDL_CONTROLLER_BUTTON_START,
|
SDL_CONTROLLER_BUTTON_START,
|
||||||
&NewController->Start);
|
&NewController->u.s.Start);
|
||||||
SDLProcessInputDigitalButton(
|
SDLProcessInputDigitalButton(
|
||||||
ControllerHandles[ControllerIndex],
|
ControllerHandles[ControllerIndex],
|
||||||
&OldController->Back,
|
&OldController->u.s.Back,
|
||||||
SDL_CONTROLLER_BUTTON_BACK,
|
SDL_CONTROLLER_BUTTON_BACK,
|
||||||
&NewController->Back);
|
&NewController->u.s.Back);
|
||||||
} else {
|
} else {
|
||||||
/* NOTE: This controller is not plugged in. */
|
/* NOTE: This controller is not plugged in. */
|
||||||
NewController->IsConnected = 0;
|
NewController->IsConnected = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int TargetQueueBytes = SoundOutput.LatencySampleCount *
|
TargetQueueBytes = SoundOutput.LatencySampleCount *
|
||||||
SoundOutput.BytesPerSample;
|
SoundOutput.BytesPerSample;
|
||||||
int BytesToWrite =
|
BytesToWrite =
|
||||||
TargetQueueBytes - SDL_GetQueuedAudioSize(1);
|
TargetQueueBytes - SDL_GetQueuedAudioSize(1);
|
||||||
struct game_sound_output_buffer SoundBuffer;
|
|
||||||
SoundBuffer.SamplesPerSecond =
|
SoundBuffer.SamplesPerSecond =
|
||||||
SoundOutput.SamplesPerSecond;
|
SoundOutput.SamplesPerSecond;
|
||||||
SoundBuffer.SampleCount =
|
SoundBuffer.SampleCount =
|
||||||
BytesToWrite / SoundOutput.BytesPerSample;
|
BytesToWrite / SoundOutput.BytesPerSample;
|
||||||
SoundBuffer.Samples = (short *)SoundOutput.Samples;
|
SoundBuffer.Samples = (short *)SoundOutput.Samples;
|
||||||
|
|
||||||
struct thread_context Context;
|
|
||||||
memset(&Context, 0, sizeof(Context));
|
memset(&Context, 0, sizeof(Context));
|
||||||
|
|
||||||
struct game_offscreen_buffer Buffer;
|
|
||||||
Buffer.Memory = GlobalBackbuffer.Memory;
|
Buffer.Memory = GlobalBackbuffer.Memory;
|
||||||
Buffer.Width = GlobalBackbuffer.Width;
|
Buffer.Width = GlobalBackbuffer.Width;
|
||||||
Buffer.Height = GlobalBackbuffer.Height;
|
Buffer.Height = GlobalBackbuffer.Height;
|
||||||
@@ -1117,11 +1190,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
SDLFillSoundBuffer(&SoundOutput, BytesToWrite);
|
SDLFillSoundBuffer(&SoundOutput, BytesToWrite);
|
||||||
|
|
||||||
unsigned long long WorkCounter = SDLGetWallClock();
|
WorkCounter = SDLGetWallClock();
|
||||||
float WorkSecondsElapsed =
|
WorkSecondsElapsed =
|
||||||
SDLGetSecondsElapsed(LastCounter, WorkCounter);
|
SDLGetSecondsElapsed(LastCounter, WorkCounter);
|
||||||
|
|
||||||
float SecondsElapsedForFrame = WorkSecondsElapsed;
|
SecondsElapsedForFrame = WorkSecondsElapsed;
|
||||||
if(SecondsElapsedForFrame < TargetSecondsPerFrame) {
|
if(SecondsElapsedForFrame < TargetSecondsPerFrame) {
|
||||||
while(SecondsElapsedForFrame < TargetSecondsPerFrame)
|
while(SecondsElapsedForFrame < TargetSecondsPerFrame)
|
||||||
{
|
{
|
||||||
@@ -1141,15 +1214,15 @@ int main(int argc, char *argv[])
|
|||||||
/* TODO: Logging. */
|
/* TODO: Logging. */
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long EndCounter = SDLGetWallClock();
|
EndCounter = SDLGetWallClock();
|
||||||
|
|
||||||
SDLDisplayBufferInWindow(&GlobalBackbuffer, Window,
|
SDLDisplayBufferInWindow(&GlobalBackbuffer, Window,
|
||||||
Renderer);
|
Renderer);
|
||||||
|
|
||||||
float MSPerFrame =
|
MSPerFrame =
|
||||||
1000.0f *
|
1000.0f *
|
||||||
SDLGetSecondsElapsed(LastCounter, EndCounter);
|
SDLGetSecondsElapsed(LastCounter, EndCounter);
|
||||||
float FPS = 1000.0f / MSPerFrame;
|
FPS = 1000.0f / MSPerFrame;
|
||||||
|
|
||||||
LastCounter = EndCounter;
|
LastCounter = EndCounter;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user