feat: day 31

This commit is contained in:
2024-11-24 11:17:17 +00:00
parent 5ddc837101
commit 2a1b24af1f
3 changed files with 282 additions and 50 deletions

View File

@@ -2,14 +2,23 @@
#define PI32 3.141592653589f #define PI32 3.141592653589f
internal int32 roundReal32ToUInt32(real32 realNum) { inline int32 roundReal32ToUInt32(real32 realNum) {
return (uint32)(realNum + 0.5f); return (uint32)(realNum + 0.5f);
} }
internal int32 roundReal32ToInt32(real32 realNum) { inline int32 roundReal32ToInt32(real32 realNum) {
return (int32)(realNum + 0.5f); return (int32)(realNum + 0.5f);
} }
#include "math.h"
inline int32 floorReal32ToInt32(real32 realNum) {
return (int32)floorf(realNum);
}
inline int32 truncateReal32ToInt32(real32 realNum) {
return (int32)realNum;
}
internal void drawRectangle(GameOffscreenBuffer *buffer, real32 realMinX, real32 realMinY, real32 realMaxX, real32 realMaxY, real32 R, real32 G, real32 B) { internal void drawRectangle(GameOffscreenBuffer *buffer, real32 realMinX, real32 realMinY, real32 realMaxX, real32 realMaxY, real32 R, real32 G, real32 B) {
int32 minX = roundReal32ToInt32(realMinX); int32 minX = roundReal32ToInt32(realMinX);
int32 minY = roundReal32ToInt32(realMinY); int32 minY = roundReal32ToInt32(realMinY);
@@ -57,6 +66,76 @@ internal void outputSound(GameSoundOutputBuffer *soundBuffer, GameState *state)
} }
} }
inline uint32 getTileValueUnchecked(World *world, TileMap *tileMap, int32 testTileX, int32 testTileY) {
Assert(tileMap);
Assert(
(testTileX >= 0) && (testTileX < world->tileCountX) &&
(testTileY >= 0) && (testTileY < world->tileCountY)
);
return tileMap->tiles[testTileY * world->tileCountX + testTileX];
}
inline TileMap *getTileMap(World *world, int32 tileMapX, int32 tileMapY) {
TileMap *tileMap = NULL;
if ((tileMapX >= 0) && (tileMapX < world->tileMapCountX) &&
(tileMapY >= 0) && (tileMapY < world->tileMapCountY)
) {
tileMap = &world->tileMaps[tileMapY * world->tileMapCountX + tileMapX];
}
return tileMap;
}
inline CanonicalPosition getCanonicalPosition(World* world, RawPosition pos) {
CanonicalPosition result = {};
result.tileMapX = pos.tileMapX;
result.tileMapY = pos.tileMapY;
real32 x = pos.x - world->upperLeftX;
real32 y = pos.y - world->upperLeftY;
result.tileX = floorReal32ToInt32(x / world->tileWidth);
result.tileY = floorReal32ToInt32(y / world->tileHeight);
result.x = pos.x - result.tileX*world->tileWidth;
result.y = pos.y - result.tileY*world->tileHeight;
if (result.tileX < 0) {
result.tileX += world->tileCountX;
result.tileMapX -= 1;
}
if (result.tileY < 0) {
result.tileY += world->tileCountY;
result.tileMapY -= 1;
}
if (result.tileX >= world->tileCountX) {
result.tileX -= world->tileCountX;
result.tileMapX += 1;
}
if (result.tileY >= world->tileCountY) {
result.tileY -= world->tileCountY;
result.tileMapY += 1;
}
return result;
}
internal bool32 isWorldPointEmpty(World *world, RawPosition testPos) {
bool32 isEmpty = false;
CanonicalPosition canPos = getCanonicalPosition(world, testPos);
TileMap *tileMap = getTileMap(world, canPos.tileMapX, canPos.tileMapY);
isEmpty = (getTileValueUnchecked(world, tileMap, canPos.tileX, canPos.tileY) == 0);
return isEmpty;
}
extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) {
Assert(sizeof(GameState) <= memory->permanentStorageSize); Assert(sizeof(GameState) <= memory->permanentStorageSize);
@@ -64,10 +143,97 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) {
if (!memory->isInitialised) { if (!memory->isInitialised) {
memory->isInitialised = true; memory->isInitialised = true;
state->playerX = 20.0f; state->playerX = 150.0f;
state->playerY = 20.0f; state->playerY = 150.0f;
state->tileMapX = 0;
state->tileMapY = 0;
} }
const int TILEMAP_WIDTH = 16;
const int TILEMAP_HEIGHT = 9;
const int WORLD_WIDTH = 2;
const int WORLD_HEIGHT = 2;
uint32 tiles00[TILEMAP_HEIGHT][TILEMAP_WIDTH] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1},
};
uint32 tiles01[TILEMAP_HEIGHT][TILEMAP_WIDTH] = {
{1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};
uint32 tiles10[TILEMAP_HEIGHT][TILEMAP_WIDTH] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1},
};
uint32 tiles11[TILEMAP_HEIGHT][TILEMAP_WIDTH] = {
{1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};
World world = {};
world.tileCountX = TILEMAP_WIDTH;
world.tileCountY = TILEMAP_HEIGHT;
world.tileMapCountX = WORLD_WIDTH;
world.tileMapCountY = WORLD_HEIGHT;
world.upperLeftX = 0;
world.upperLeftY = 0;
world.tileWidth = 60;
world.tileHeight = 60;
TileMap maps[WORLD_HEIGHT][WORLD_WIDTH];
maps[0][0].tiles = (uint32*)tiles00;
maps[1][0] = maps[0][0];
maps[1][0].tiles = (uint32*)tiles01;
maps[0][1] = maps[0][0];
maps[0][1].tiles = (uint32*)tiles10;
maps[1][1] = maps[0][0];
maps[1][1].tiles = (uint32*)tiles11;
world.tileMaps = (TileMap*)maps;
// player
real32 playerR = 1.0f;
real32 playerG = 1.0f;
real32 playerB = 0.5f;
real32 playerWidth = 50.0f;
real32 playerHeight = 70.0f;
for (int controllerIndex = 0; controllerIndex < ArrayCount(input->controllers); controllerIndex++) { for (int controllerIndex = 0; controllerIndex < ArrayCount(input->controllers); controllerIndex++) {
GameControllerInput *controller = &input->controllers[controllerIndex]; GameControllerInput *controller = &input->controllers[controllerIndex];
@@ -75,67 +241,79 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) {
real32 dPlayerY = 0.0f; real32 dPlayerY = 0.0f;
if (controller->stickUp.endedDown) { if (controller->stickUp.endedDown) {
dPlayerY = -128.0f; dPlayerY = -1.0f;
} }
if (controller->stickDown.endedDown) { if (controller->stickDown.endedDown) {
dPlayerY = 128.0f; dPlayerY = 1.0f;
} }
if (controller->stickLeft.endedDown) { if (controller->stickLeft.endedDown) {
dPlayerX = -128.0f; dPlayerX = -1.0f;
} }
if (controller->stickRight.endedDown) { if (controller->stickRight.endedDown) {
dPlayerX = 128.0f; dPlayerX = 1.0f;
} }
state->playerX += dPlayerX * input->dtForFrame; dPlayerX *= 96.0f;
state->playerY += dPlayerY * input->dtForFrame; dPlayerY *= 96.0f;
real32 newPlayerX = state->playerX + dPlayerX * input->dtForFrame;
real32 newPlayerY = state->playerY + dPlayerY * input->dtForFrame;
RawPosition playerPos = {
state->tileMapX,
state->tileMapY,
newPlayerX,
newPlayerY,
};
RawPosition playerBottomLeft = playerPos;
playerBottomLeft.x -= 0.5f * playerWidth;
RawPosition playerTopLeft = playerPos;
playerTopLeft.x -= 0.5f * playerWidth;
playerTopLeft.y -= playerWidth;
RawPosition playerBottomRight = playerPos;
playerBottomRight.x += 0.5f * playerWidth;
RawPosition playerTopRight = playerPos;
playerTopRight.x += 0.5f * playerWidth;
playerTopRight.y -= playerWidth;
if (
isWorldPointEmpty(&world, playerTopLeft) &&
isWorldPointEmpty(&world, playerTopRight) &&
isWorldPointEmpty(&world, playerBottomLeft) &&
isWorldPointEmpty(&world, playerBottomRight)
) {
CanonicalPosition canPos = getCanonicalPosition(&world, playerPos);
state->tileMapX = canPos.tileMapX;
state->tileMapY = canPos.tileMapY;
state->playerX = world.upperLeftX + world.tileWidth*canPos.tileX + canPos.x;
state->playerY = world.upperLeftY + world.tileHeight*canPos.tileY + canPos.y;
}
} }
const int TILEMAP_WIDTH = 16;
const int TILEMAP_HEIGHT = 9;
real32 upperLeftX = 0;
real32 upperLeftY = 0;
real32 tileWidth = 60;
real32 tileHeight = 60;
uint32 tileMap[TILEMAP_HEIGHT][TILEMAP_WIDTH] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};
// clearscreen // clearscreen
drawRectangle(videoBuf, 0.0f, 0.0f, (real32)videoBuf->width, (real32)videoBuf->height, 1.0f, 0.0f, 1.0f); drawRectangle(videoBuf, 0.0f, 0.0f, (real32)videoBuf->width, (real32)videoBuf->height, 1.0f, 0.0f, 1.0f);
// tilemap TileMap *currMap = getTileMap(&world, state->tileMapX, state->tileMapY);
for (int row = 0; row < TILEMAP_HEIGHT; row++) { for (int row = 0; row < world.tileCountY; row++) {
for (int col = 0; col < TILEMAP_WIDTH; col++) { for (int col = 0; col < world.tileCountX; col++) {
uint32 tileID = tileMap[row][col]; real32 fill = getTileValueUnchecked(&world, currMap, col, row) == 1 ? 1.0f : 0.5f;
real32 fill = tileID == 1 ? 1.0f : 0.5f; real32 minX = world.upperLeftX + ((real32)col)*world.tileWidth;
real32 minX = upperLeftX + ((real32)col)*tileWidth; real32 minY = world.upperLeftY + ((real32)row)*world.tileHeight;
real32 minY = upperLeftY + ((real32)row)*tileHeight; real32 maxX = minX + world.tileWidth;
real32 maxX = minX + tileWidth; real32 maxY = minY + world.tileHeight;
real32 maxY = minY + tileHeight;
drawRectangle(videoBuf, minX, minY, maxX, maxY, fill, fill, fill); drawRectangle(videoBuf, minX, minY, maxX, maxY, fill, fill, fill);
} }
} }
// player
real32 playerR = 1.0f;
real32 playerG = 0.5f;
real32 playerB = 0.0f;
real32 playerWidth = 25.0f;
real32 playerHeight = 40.0f;
real32 playerLeft = state->playerX - 0.5f * playerWidth; real32 playerLeft = state->playerX - 0.5f * playerWidth;
real32 playerTop = state->playerY - 0.5f * playerHeight; real32 playerTop = state->playerY - playerHeight;
drawRectangle(videoBuf, playerLeft, playerTop, state->playerX + playerWidth*0.5f, state->playerY, playerR, playerG, playerB);
drawRectangle(videoBuf, playerLeft, playerTop, state->playerX + playerWidth, state->playerY + playerHeight, playerR, playerG, playerB);
} }
extern "C" GAME_GET_SOUND_SAMPLES(gameGetSoundSamples) { extern "C" GAME_GET_SOUND_SAMPLES(gameGetSoundSamples) {

View File

@@ -153,7 +153,52 @@ struct GameMemory {
DebugPrintfFn *debug_printf; DebugPrintfFn *debug_printf;
}; };
struct TileMap {
uint32 *tiles;
};
struct CanonicalPosition {
// Which tilemap?
int32 tileMapX;
int32 tileMapY;
// Which tile in tilemap?
int32 tileX;
int32 tileY;
// Sub-tile position
real32 x;
real32 y;
};
struct RawPosition {
// Which tilemap?
int32 tileMapX;
int32 tileMapY;
// Raw tilemap position
real32 x;
real32 y;
};
struct World {
int32 tileMapCountX;
int32 tileMapCountY;
real32 upperLeftX;
real32 upperLeftY;
real32 tileWidth;
real32 tileHeight;
int32 tileCountY;
int32 tileCountX;
TileMap *tileMaps;
};
struct GameState { struct GameState {
int32 tileMapX;
int32 tileMapY;
real32 playerX; real32 playerX;
real32 playerY; real32 playerY;
}; };

View File

@@ -128,9 +128,18 @@ internal Win32WindowDimensions win32GetWindowDimensions(HWND window) {
internal void win32DrawBufferInWindow(Win32OffscreenBuffer *buffer, HWND window) { internal void win32DrawBufferInWindow(Win32OffscreenBuffer *buffer, HWND window) {
Win32WindowDimensions winDims = win32GetWindowDimensions(window); Win32WindowDimensions winDims = win32GetWindowDimensions(window);
StretchDIBits( HDC dc = GetDC(window);
GetDC(window),
0, 0, winDims.width, winDims.height, int offsetX = 10;
int offsetY = 10;
PatBlt(dc, 0, 0, winDims.width, offsetY, BLACKNESS);
PatBlt(dc, 0, offsetY + buffer->height, winDims.width, winDims.height, BLACKNESS);
PatBlt(dc, 0, 0, offsetX, winDims.height, BLACKNESS);
PatBlt(dc, offsetX + buffer->width, 0, winDims.width, winDims.height, BLACKNESS);
StretchDIBits(dc,
offsetX, offsetY, buffer->width, buffer->height,
0, 0, buffer->width, buffer->height, 0, 0, buffer->width, buffer->height,
buffer->memory, buffer->memory,
&buffer->info, &buffer->info,