Half of day 39 complete.
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
@@ -84,8 +84,11 @@ static void DrawRectangle(game_offscreen_buffer *Buffer, F32 RealMinX, F32 RealM
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawBitmap(game_offscreen_buffer *Buffer, loaded_bitmap *Bitmap, F32 RelX, F32 RelY)
|
||||
static void DrawBitmap(game_offscreen_buffer *Buffer, loaded_bitmap *Bitmap, F32 RelX, F32 RelY, S32 AlignX, S32 AlignY)
|
||||
{
|
||||
RelX -= (F32)AlignX;
|
||||
RelY -= (F32)AlignY;
|
||||
|
||||
S32 MinX = RoundF32toS32(RelX);
|
||||
S32 MinY = RoundF32toS32(RelY);
|
||||
S32 MaxX = RoundF32toS32(RelX + (F32)Bitmap->Width);
|
||||
@@ -112,12 +115,12 @@ static void DrawBitmap(game_offscreen_buffer *Buffer, loaded_bitmap *Bitmap, F32
|
||||
for(S32 X = MinX; X < MaxX; X++) {
|
||||
F32 A = (F32)((*Source >> 24) & 0xFF) / 255.0f;
|
||||
F32 SR = (F32)((*Source >> 16) & 0xFF);
|
||||
F32 SG = (F32)((*Source >> 8) & 0xFF);
|
||||
F32 SB = (F32)((*Source >> 0) & 0xFF);
|
||||
F32 SG = (F32)((*Source >> 8) & 0xFF);
|
||||
F32 SB = (F32)((*Source >> 0) & 0xFF);
|
||||
|
||||
F32 DR = (F32)((*Dest >> 16) & 0xFF);
|
||||
F32 DG = (F32)((*Dest >> 8) & 0xFF);
|
||||
F32 DB = (F32)((*Dest >> 0) & 0xFF);
|
||||
F32 DG = (F32)((*Dest >> 8) & 0xFF);
|
||||
F32 DB = (F32)((*Dest >> 0) & 0xFF);
|
||||
|
||||
// TODO: This should be replaced by premultiplied alpha.
|
||||
F32 R = (1.0f-A)*DR + A*SR;
|
||||
@@ -186,7 +189,7 @@ static loaded_bitmap DEBUGLoadBMP(thread_context *Thread, debug_read_file_result
|
||||
bit_scan_result GreenShift = FindLeastSignificantSetBit(GreenMask);
|
||||
bit_scan_result BlueShift = FindLeastSignificantSetBit(BlueMask);
|
||||
bit_scan_result AlphaShift = FindLeastSignificantSetBit(AlphaMask);
|
||||
|
||||
|
||||
ASSERT(RedShift.Found);
|
||||
ASSERT(GreenShift.Found);
|
||||
ASSERT(BlueShift.Found);
|
||||
@@ -200,7 +203,8 @@ static loaded_bitmap DEBUGLoadBMP(thread_context *Thread, debug_read_file_result
|
||||
*SourceDest = ((((C >> AlphaShift.Index) & 0xFF) << 24) |
|
||||
(((C >> RedShift.Index ) & 0xFF) << 16) |
|
||||
(((C >> GreenShift.Index) & 0xFF) << 8) |
|
||||
(((C >> BlueShift.Index ) & 0xFF) << 8));
|
||||
(((C >> BlueShift.Index ) & 0xFF) << 0));
|
||||
SourceDest++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,10 +228,40 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In
|
||||
|
||||
GameState = (game_state *)Memory->PermanentStorage;
|
||||
if(!Memory->IsInitialized) {
|
||||
GameState->Backdrop = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/background.bmp");
|
||||
GameState->HeroHead = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/hero_head_front.bmp");;
|
||||
GameState->HeroCape = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/hero_cape_front.bmp");;
|
||||
GameState->HeroTorso = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/hero_torso_front.bmp");;
|
||||
GameState->Backdrop = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_background.bmp");
|
||||
|
||||
hero_bitmaps *Bitmap;
|
||||
|
||||
Bitmap = &GameState->HeroBitmaps[0];
|
||||
Bitmap->AlignX = 72;
|
||||
Bitmap->AlignY = 182;
|
||||
Bitmap->Head = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_right_head.bmp");
|
||||
Bitmap->Cape = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_right_cape.bmp");
|
||||
Bitmap->Torso = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_right_torso.bmp");
|
||||
Bitmap++;
|
||||
|
||||
Bitmap->AlignX = 72;
|
||||
Bitmap->AlignY = 182;
|
||||
Bitmap->Head = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_back_head.bmp");
|
||||
Bitmap->Cape = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_back_cape.bmp");
|
||||
Bitmap->Torso = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_back_torso.bmp");
|
||||
Bitmap++;
|
||||
|
||||
Bitmap->AlignX = 72;
|
||||
Bitmap->AlignY = 182;
|
||||
Bitmap->Head = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_left_head.bmp");
|
||||
Bitmap->Cape = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_left_cape.bmp");
|
||||
Bitmap->Torso = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_left_torso.bmp");
|
||||
Bitmap++;
|
||||
|
||||
Bitmap->AlignX = 72;
|
||||
Bitmap->AlignY = 182;
|
||||
Bitmap->Head = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_front_head.bmp");
|
||||
Bitmap->Cape = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_front_cape.bmp");
|
||||
Bitmap->Torso = DEBUGLoadBMP(Thread, Memory->DEBUGPlatformReadEntireFile, "data/test_hero_front_torso.bmp");
|
||||
|
||||
GameState->CameraP.AbsTileX = 17 / 2;
|
||||
GameState->CameraP.AbsTileY = 9 / 2;
|
||||
|
||||
GameState->PlayerP.AbsTileX = 2;
|
||||
GameState->PlayerP.AbsTileY = 3;
|
||||
@@ -376,15 +410,19 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In
|
||||
|
||||
if(Controller->MoveUp.EndedDown) {
|
||||
dPlayerY = 1.0f;
|
||||
GameState->FacingDirection = 1;
|
||||
}
|
||||
if(Controller->MoveDown.EndedDown) {
|
||||
dPlayerY = -1.0f;
|
||||
GameState->FacingDirection = 3;
|
||||
}
|
||||
if(Controller->MoveLeft.EndedDown) {
|
||||
dPlayerX = -1.0f;
|
||||
GameState->FacingDirection = 2;
|
||||
}
|
||||
if(Controller->MoveRight.EndedDown) {
|
||||
dPlayerX = 1.0f;
|
||||
GameState->FacingDirection = 0;
|
||||
}
|
||||
|
||||
F32 PlayerSpeed = 2.0f;
|
||||
@@ -428,17 +466,17 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In
|
||||
|
||||
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);
|
||||
DrawBitmap(Buffer, &GameState->Backdrop, 0.0f, 0.0f, 0, 0);
|
||||
|
||||
F32 ScreenCenterX = 0.5f * (F32)Buffer->Width;
|
||||
F32 ScreenCenterY = 0.5f * (F32)Buffer->Height;
|
||||
|
||||
for(S32 RelRow = -10; RelRow < 10; RelRow++) {
|
||||
for(S32 RelColumn = -20; RelColumn < 20; RelColumn++) {
|
||||
U32 Column = GameState->PlayerP.AbsTileX + RelColumn;
|
||||
U32 Row = GameState->PlayerP.AbsTileY + RelRow;
|
||||
U32 Column = GameState->CameraP.AbsTileX + RelColumn;
|
||||
U32 Row = GameState->CameraP.AbsTileY + RelRow;
|
||||
|
||||
U32 TileID = GetTileValue(TileMap, Column, Row, GameState->PlayerP.AbsTileZ);
|
||||
U32 TileID = GetTileValue(TileMap, Column, Row, GameState->CameraP.AbsTileZ);
|
||||
|
||||
if(TileID > 1) {
|
||||
F32 Gray = 0.5f;
|
||||
@@ -450,13 +488,13 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In
|
||||
Gray = 0.25f;
|
||||
}
|
||||
|
||||
if((Column == GameState->PlayerP.AbsTileX) && (Row == GameState->PlayerP.AbsTileY)) {
|
||||
if((Column == GameState->CameraP.AbsTileX) && (Row == GameState->CameraP.AbsTileY)) {
|
||||
Gray = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
F32 CenterX = ScreenCenterX - MetersToPixels*GameState->PlayerP.OffsetX + (F32)RelColumn*(F32)TileSideInPixels;
|
||||
F32 CenterY = ScreenCenterY + MetersToPixels*GameState->PlayerP.OffsetY - (F32)RelRow*(F32)TileSideInPixels;
|
||||
F32 CenterX = ScreenCenterX - MetersToPixels*GameState->CameraP.OffsetX + (F32)RelColumn*(F32)TileSideInPixels;
|
||||
F32 CenterY = ScreenCenterY + MetersToPixels*GameState->CameraP.OffsetY - (F32)RelRow*(F32)TileSideInPixels;
|
||||
F32 MinX = CenterX - 0.5f*(F32)TileSideInPixels;
|
||||
F32 MinY = CenterY - 0.5f*(F32)TileSideInPixels;
|
||||
F32 MaxX = CenterX + 0.5f*(F32)TileSideInPixels;
|
||||
@@ -466,13 +504,21 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In
|
||||
}
|
||||
}
|
||||
|
||||
tile_map_difference Diff = SubtractInF32(TileMap, &GameState->PlayerP, &GameState->CameraP);
|
||||
|
||||
F32 PlayerR = 1.0f;
|
||||
F32 PlayerG = 0.0f;
|
||||
F32 PlayerB = 0.0f;
|
||||
F32 PlayerLeft = ScreenCenterX - 0.5f * MetersToPixels*PlayerWidth;
|
||||
F32 PlayerTop = ScreenCenterY - MetersToPixels*PlayerHeight;
|
||||
F32 PlayerGroundPointX = ScreenCenterX + MetersToPixels*Diff.dX;
|
||||
F32 PlayerGroundPointY = ScreenCenterY + MetersToPixels*Diff.dY;
|
||||
F32 PlayerLeft = PlayerGroundPointX - 0.5f * MetersToPixels*PlayerWidth;
|
||||
F32 PlayerTop = PlayerGroundPointY - MetersToPixels*PlayerHeight;
|
||||
DrawRectangle(Buffer, PlayerLeft, PlayerTop, PlayerLeft + MetersToPixels*PlayerWidth, PlayerTop + MetersToPixels*PlayerHeight, PlayerR, PlayerG, PlayerB);
|
||||
DrawBitmap(Buffer, &GameState->HeroHead, PlayerLeft, PlayerTop);
|
||||
|
||||
hero_bitmaps *Bitmap = &GameState->HeroBitmaps[GameState->FacingDirection];
|
||||
DrawBitmap(Buffer, &Bitmap->Torso, PlayerGroundPointX, PlayerGroundPointY, Bitmap->AlignX, Bitmap->AlignY);
|
||||
DrawBitmap(Buffer, &Bitmap->Cape, PlayerGroundPointX, PlayerGroundPointY, Bitmap->AlignX, Bitmap->AlignY);
|
||||
DrawBitmap(Buffer, &Bitmap->Head, PlayerGroundPointX, PlayerGroundPointY, Bitmap->AlignX, Bitmap->AlignY);
|
||||
|
||||
GameOutputSound(GameState, SoundBuffer, 400);
|
||||
}
|
||||
|
||||
@@ -18,11 +18,8 @@ typedef struct debug_read_file_result {
|
||||
void *Contents;
|
||||
} debug_read_file_result;
|
||||
|
||||
debug_read_file_result DEBUGPlatformReadEntireFile(thread_context *Thread,
|
||||
const char *Filename);
|
||||
B32 DEBUGPlatformWriteEntireFile(thread_context *Thread,
|
||||
const char *Filename, U32 MemorySize,
|
||||
void *Memory);
|
||||
debug_read_file_result DEBUGPlatformReadEntireFile(thread_context *Thread, const char *Filename);
|
||||
B32 DEBUGPlatformWriteEntireFile(thread_context *Thread, const char *Filename, U32 MemorySize, void *Memory);
|
||||
void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory);
|
||||
#endif
|
||||
|
||||
@@ -171,17 +168,26 @@ typedef struct loaded_bitmap {
|
||||
U32 *Pixels;
|
||||
} loaded_bitmap;
|
||||
|
||||
typedef struct hero_bitmaps {
|
||||
S32 AlignX;
|
||||
S32 AlignY;
|
||||
|
||||
loaded_bitmap Head;
|
||||
loaded_bitmap Cape;
|
||||
loaded_bitmap Torso;
|
||||
} hero_bitmaps;
|
||||
|
||||
typedef struct game_state {
|
||||
memory_arena WorldArena;
|
||||
world *World;
|
||||
|
||||
tile_map_position CameraP;
|
||||
tile_map_position PlayerP;
|
||||
|
||||
loaded_bitmap Backdrop;
|
||||
|
||||
loaded_bitmap HeroHead;
|
||||
loaded_bitmap HeroCape;
|
||||
loaded_bitmap HeroTorso;
|
||||
U32 FacingDirection;
|
||||
hero_bitmaps HeroBitmaps[4];
|
||||
} game_state;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -135,3 +135,20 @@ static B32 AreOnSameTile(tile_map_position *A, tile_map_position *B)
|
||||
B32 Result = ((A->AbsTileX == B->AbsTileX) && (A->AbsTileY == B->AbsTileY) && (A->AbsTileZ == B->AbsTileZ));
|
||||
return Result;
|
||||
}
|
||||
|
||||
static tile_map_difference SubtractInF32(tile_map *TileMap, tile_map_position *A, tile_map_position *B)
|
||||
{
|
||||
tile_map_difference Result;
|
||||
|
||||
F32 dTileX = (F32)A->AbsTileX - (F32)B->AbsTileY;
|
||||
F32 dTileY = (F32)A->AbsTileX - (F32)B->AbsTileY;
|
||||
F32 dTileZ = (F32)A->AbsTileX - (F32)B->AbsTileY;
|
||||
|
||||
Result.dX = TileMap->TileSideInMeters*dTileX + (A->OffsetX - B->OffsetX);
|
||||
Result.dY = TileMap->TileSideInMeters*dTileY + (A->OffsetY - B->OffsetY);
|
||||
|
||||
// TODO: Incomplete . . .
|
||||
Result.dZ = TileMap->TileSideInMeters*dTileZ;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#ifndef HANDMADE_TILE_H_SENTRY
|
||||
#define HANDMADE_TILE_H_SENTRY
|
||||
|
||||
typedef struct tile_map_difference {
|
||||
F32 dX;
|
||||
F32 dY;
|
||||
F32 dZ;
|
||||
} tile_map_difference;
|
||||
|
||||
typedef struct tile_map_position {
|
||||
U32 AbsTileX;
|
||||
U32 AbsTileY;
|
||||
|
||||