From ee9f65f01625e2334feaa81d0d4c398ba23d9edc Mon Sep 17 00:00:00 2001 From: Ledda Date: Sun, 8 Dec 2024 21:21:43 +0000 Subject: [PATCH] update --- src/handmade.cpp | 302 ++++++++++++++++---------------------- src/handmade.h | 59 +++----- src/handmade_intrinsics.h | 4 + src/handmade_tile.cpp | 95 ++++++++++++ src/handmade_tile.h | 41 ++++++ 5 files changed, 287 insertions(+), 214 deletions(-) create mode 100644 src/handmade_tile.cpp create mode 100644 src/handmade_tile.h diff --git a/src/handmade.cpp b/src/handmade.cpp index 961e55c..5647971 100644 --- a/src/handmade.cpp +++ b/src/handmade.cpp @@ -1,5 +1,5 @@ #include "handmade.h" -#include "handmade_intrinsics.h" +#include "handmade_tile.cpp" internal void drawRectangle(GameOffscreenBuffer *buffer, real32 realMinX, real32 realMinY, real32 realMaxX, real32 realMaxY, real32 R, real32 G, real32 B) { int32 minX = roundReal32ToInt32(realMinX); @@ -48,163 +48,115 @@ 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]; +internal void initialiseArena(MemoryArena *arena, memory_index size, uint8 *base) { + arena->size = size; + arena->base = base; + arena->used = 0; } -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 void recanonicaliseOrd(World *world, int32 tileCount, int32 *tileMapOrd, int32 *tileOrd, real32* ord) { - int32 offset = floorReal32ToInt32(*ord / world->tileSideInPixels); - *tileOrd += offset; - *ord -= offset*world->tileSideInPixels; - - Assert(*ord >= 0); - Assert(*ord < world->tileSideInPixels); - - if (*tileOrd < 0) { - *tileOrd += tileCount; - *tileMapOrd -= 1; - } - - if (*tileOrd >= tileCount) { - *tileOrd -= tileCount; - *tileMapOrd += 1; - } -} - -inline CanonicalPosition recanonicalisePosition(World* world, CanonicalPosition pos) { - CanonicalPosition result = pos; - - recanonicaliseOrd(world, world->tileCountX, &result.tileMapX, &result.tileX, &result.x); - recanonicaliseOrd(world, world->tileCountY, &result.tileMapY, &result.tileY, &result.y); - // TODO: continue at HH day 32 @ 32:20 - +internal void *_pushSize(MemoryArena *arena, memory_index size) { + Assert((arena->used + size) <= arena->size); + void *result = (void *)(arena->base + arena->used); + arena->used += size; return result; } - -internal bool32 isWorldPointEmpty(World *world, CanonicalPosition testPos) { - bool32 isEmpty = false; - - TileMap *tileMap = getTileMap(world, testPos.tileMapX, testPos.tileMapY); - isEmpty = (getTileValueUnchecked(world, tileMap, testPos.tileX, testPos.tileY) == 0); - - return isEmpty; -} +#define pushStruct(arena, type) (type *)_pushSize(arena, sizeof(type)) +#define pushArray(arena, count, type) (type *)_pushSize(arena, (count)*sizeof(type)) extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { Assert(sizeof(GameState) <= memory->permanentStorageSize); GameState *state = (GameState*)memory->permanentStorage; + const int WORLD_WIDTH = 2; + const int WORLD_HEIGHT = 2; + if (!memory->isInitialised) { - state->playerPos.x = 150.0f; - state->playerPos.y = 150.0f; - state->playerPos.tileMapX = 0; - state->playerPos.tileMapY = 0; + state->playerPos.absTileX = 3; + state->playerPos.absTileY = 3; + state->playerPos.x = 5.0f; + state->playerPos.y = 5.0f; + + initialiseArena( + &state->worldArena, + memory->permanentStorageSize - sizeof(GameState), + (uint8*)memory->permanentStorage + sizeof(GameState) + ); + + state->world = pushStruct(&state->worldArena, World); + World *world = state->world; + + world->tileMap = pushStruct(&state->worldArena, TileMap); + TileMap *tileMap = state->world->tileMap; + + tileMap->chunkShift = 8; + tileMap->chunkMask = 0xFF; + tileMap->chunkDim = 256; + tileMap->tileChunkCountX = 4; + tileMap->tileChunkCountY = 4; + tileMap->tileSideInMeters = 1.4f; + tileMap->tileSideInPixels = 60; + tileMap->metersToPixels = tileMap->tileSideInPixels / tileMap->tileSideInMeters; + + tileMap->tileChunks = pushArray(&state->worldArena, tileMap->tileChunkCountX*tileMap->tileChunkCountY, TileChunk); + + for (uint32 y = 0; y < tileMap->tileChunkCountY; y++) { + for (uint32 x = 0; x < tileMap->tileChunkCountX; x++) { + tileMap->tileChunks[y*tileMap->tileChunkCountX + x].tiles = pushArray(&state->worldArena, tileMap->chunkDim*tileMap->chunkDim, uint32); + } + } - memory->isInitialised = true; - } - const int TILEMAP_WIDTH = 16; - const int TILEMAP_HEIGHT = 9; + uint32 tilesPerWidth = 17; + uint32 tilesPerHeight = 9; - const int WORLD_WIDTH = 2; - const int WORLD_HEIGHT = 2; + for (uint32 screenY = 0; screenY < 32; screenY++) { + for (uint32 screenX = 0; screenX < 32; screenX++) { + for (uint32 tileY = 0; tileY < tilesPerHeight; tileY++) { + for (uint32 tileX = 0; tileX < tilesPerWidth; tileX++) { + uint32 absTileX = screenX*tilesPerWidth + tileX; + uint32 absTileY = screenY*tilesPerHeight + tileY; + setTileMapValue(&state->worldArena, tileMap, absTileX, absTileY, (tileX == tileY && (tileX % 5 == 0))); + } + } + } + } + + memory->isInitialised = true; + } - 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.tileSideInMeters = 1.4f; - world.tileSideInPixels = 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; + real32 screenCenterX = 0.5f*(real32)videoBuf->width; + real32 screenCenterY = 0.5f*(real32)videoBuf->height; + +// uint32 tiles[TILEMAP_WIDTH][TILEMAP_HEIGHT] = { +// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, +// {1, 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, 1, 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, 1, 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, 1}, +// {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 1, 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, 1, 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, 1, 0, 1}, +// {1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1}, +// {1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 0, 0, 0, 0, 0, 1, 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, 1, 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, 1, 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, 1, 0, 1}, +// {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, +// }; + + TileMap *tilemap = state->world->tileMap; // player real32 playerR = 1.0f; real32 playerG = 1.0f; real32 playerB = 0.5f; - real32 playerWidth = 50.0f; - real32 playerHeight = 70.0f; + real32 playerWidth = 0.7f; + real32 playerHeight = 1.4f; for (int controllerIndex = 0; controllerIndex < ArrayCount(input->controllers); controllerIndex++) { GameControllerInput *controller = &input->controllers[controllerIndex]; @@ -213,10 +165,10 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { real32 dPlayerY = 0.0f; if (controller->stickUp.endedDown) { - dPlayerY = -1.0f; + dPlayerY = 1.0f; } if (controller->stickDown.endedDown) { - dPlayerY = 1.0f; + dPlayerY = -1.0f; } if (controller->stickLeft.endedDown) { dPlayerX = -1.0f; @@ -225,37 +177,37 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { dPlayerX = 1.0f; } - dPlayerX *= 96.0f; - dPlayerY *= 96.0f; + dPlayerX *= 6.0f; + dPlayerY *= 6.0f; - CanonicalPosition newPlayerPos = state->playerPos; + TileMapPosition newPlayerPos = state->playerPos; newPlayerPos.x += dPlayerX * input->dtForFrame; newPlayerPos.y += dPlayerY * input->dtForFrame; - newPlayerPos = recanonicalisePosition(&world, newPlayerPos); + newPlayerPos = recanonicalisePosition(tilemap, newPlayerPos); - CanonicalPosition playerBottomLeft = newPlayerPos; + TileMapPosition playerBottomLeft = newPlayerPos; playerBottomLeft.x -= 0.5f * playerWidth; - playerBottomLeft = recanonicalisePosition(&world, playerBottomLeft); + playerBottomLeft = recanonicalisePosition(tilemap, playerBottomLeft); - CanonicalPosition playerTopLeft = newPlayerPos; + TileMapPosition playerTopLeft = newPlayerPos; playerTopLeft.x -= 0.5f * playerWidth; - playerTopLeft.y -= playerWidth; - playerTopLeft = recanonicalisePosition(&world, playerTopLeft); + playerTopLeft.y += playerWidth; + playerTopLeft = recanonicalisePosition(tilemap, playerTopLeft); - CanonicalPosition playerBottomRight = newPlayerPos; + TileMapPosition playerBottomRight = newPlayerPos; playerBottomRight.x += 0.5f * playerWidth; - playerBottomRight = recanonicalisePosition(&world, playerBottomRight); + playerBottomRight = recanonicalisePosition(tilemap, playerBottomRight); - CanonicalPosition playerTopRight = newPlayerPos; + TileMapPosition playerTopRight = newPlayerPos; playerTopRight.x += 0.5f * playerWidth; - playerTopRight.y -= playerWidth; - playerTopRight = recanonicalisePosition(&world, playerTopRight); + playerTopRight.y += playerWidth; + playerTopRight = recanonicalisePosition(tilemap, playerTopRight); if ( - isWorldPointEmpty(&world, playerTopLeft) && - isWorldPointEmpty(&world, playerTopRight) && - isWorldPointEmpty(&world, playerBottomLeft) && - isWorldPointEmpty(&world, playerBottomRight) + isTileMapPointEmpty(tilemap, playerTopLeft) && + isTileMapPointEmpty(tilemap, playerTopRight) && + isTileMapPointEmpty(tilemap, playerBottomLeft) && + isTileMapPointEmpty(tilemap, playerBottomRight) ) { state->playerPos = newPlayerPos; } @@ -264,23 +216,29 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { // clearscreen drawRectangle(videoBuf, 0.0f, 0.0f, (real32)videoBuf->width, (real32)videoBuf->height, 1.0f, 0.0f, 1.0f); - TileMap *currMap = getTileMap(&world, state->playerPos.tileMapX, state->playerPos.tileMapY); - for (int row = 0; row < world.tileCountY; row++) { - for (int col = 0; col < world.tileCountX; col++) { - real32 fill = getTileValueUnchecked(&world, currMap, col, row) == 1 ? 1.0f : 0.5f; - real32 minX = world.upperLeftX + ((real32)col)*world.tileSideInPixels; - real32 minY = world.upperLeftY + ((real32)row)*world.tileSideInPixels; - real32 maxX = minX + world.tileSideInPixels; - real32 maxY = minY + world.tileSideInPixels; - drawRectangle(videoBuf, minX, minY, maxX, maxY, fill, fill, fill); + for (int32 relRow = -10; relRow < 10; relRow++) { + for (int32 relCol = -20; relCol < 20; relCol++) { + uint32 col = state->playerPos.absTileX + relCol; + uint32 row = state->playerPos.absTileY + relRow; + int32 tileId = getTileValue(tilemap, col, row); + real32 fill = 0.5f; + if (tileId == 1) { + fill = 1.0f; + } + if ((row == state->playerPos.absTileY) && (col == state->playerPos.absTileX)) { + fill = 0.0f; + } + real32 minX = screenCenterX - tilemap->metersToPixels*state->playerPos.x + ((real32)relCol)*tilemap->tileSideInPixels; + real32 minY = screenCenterY + tilemap->metersToPixels*state->playerPos.y - ((real32)relRow)*tilemap->tileSideInPixels; + real32 maxX = minX + tilemap->tileSideInPixels; + real32 maxY = minY - tilemap->tileSideInPixels; + drawRectangle(videoBuf, minX, maxY, maxX, minY, fill, fill, fill); } } - real32 playerX = world.upperLeftX + state->playerPos.x + state->playerPos.tileX * world.tileSideInPixels; - real32 playerY = world.upperLeftY + state->playerPos.y + state->playerPos.tileY * world.tileSideInPixels; - real32 playerLeft = playerX - 0.5f * playerWidth; - real32 playerTop = playerY - playerHeight; - drawRectangle(videoBuf, playerLeft, playerTop, playerX + playerWidth*0.5f, playerY, playerR, playerG, playerB); + real32 playerLeft = screenCenterX - 0.5f*tilemap->metersToPixels*playerWidth; + real32 playerTop = screenCenterY - tilemap->metersToPixels*playerHeight; + drawRectangle(videoBuf, playerLeft, playerTop, playerLeft + tilemap->metersToPixels*playerWidth, playerTop + tilemap->metersToPixels*playerHeight, playerR, playerG, playerB); } extern "C" GAME_GET_SOUND_SAMPLES(gameGetSoundSamples) { diff --git a/src/handmade.h b/src/handmade.h index ca1bca9..43d6bc9 100644 --- a/src/handmade.h +++ b/src/handmade.h @@ -1,9 +1,9 @@ +#pragma once + #include #include #include -#pragma once - /* * --------------- * Global flags: @@ -45,11 +45,15 @@ typedef uint16_t uint16; typedef uint32_t uint32; typedef uint64_t uint64; +typedef size_t MemoryIndex; + typedef int8_t int8; typedef int16_t int16; typedef int32_t int32; typedef int64_t int64; +typedef size_t memory_index; + typedef float real32; typedef double real64; @@ -152,52 +156,23 @@ struct GameMemory { 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; -}; +#include "handmade_tile.h" +#include "handmade_intrinsics.h" struct World { - real32 tileSideInMeters; - int32 tileSideInPixels; - - int32 tileMapCountX; - int32 tileMapCountY; - - real32 upperLeftX; - real32 upperLeftY; - - int32 tileCountY; - int32 tileCountX; + TileMap *tileMap; +}; - TileMap *tileMaps; +struct MemoryArena { + memory_index size; + uint8 *base; + memory_index used; }; struct GameState { - CanonicalPosition playerPos; + TileMapPosition playerPos; + World *world; + MemoryArena worldArena; }; // === Game to platform services === diff --git a/src/handmade_intrinsics.h b/src/handmade_intrinsics.h index 073bedd..ef97a8b 100644 --- a/src/handmade_intrinsics.h +++ b/src/handmade_intrinsics.h @@ -31,3 +31,7 @@ inline real32 cos(real32 angle) { inline real32 atan2(real32 y, real32 x) { return atan2f(y, x); } + +inline uint32 absoluteInt32ToUInt32(int32 signedInt32) { + return signedInt32 > 0 ? (uint32)signedInt32 : (uint32)(-1*signedInt32); +} diff --git a/src/handmade_tile.cpp b/src/handmade_tile.cpp new file mode 100644 index 0000000..1fe371f --- /dev/null +++ b/src/handmade_tile.cpp @@ -0,0 +1,95 @@ +#pragma once +#include "handmade.h" + +inline TileChunk *getTileChunk(TileMap *tileMap, uint32 tileChunkX, uint32 tileChunkY) { + TileChunk *tileChunk = NULL; + + if ((tileChunkX >= 0) && (tileChunkX < tileMap->tileChunkCountX) && + (tileChunkY >= 0) && (tileChunkY < tileMap->tileChunkCountY) + ) { + tileChunk = &tileMap->tileChunks[tileChunkY * tileMap->tileChunkCountX + tileChunkX]; + } + + return tileChunk; +} + +inline void recanonicaliseOrd(TileMap *tileMap, uint32 *tileOrd, real32* ord) { + int32 offset = floorReal32ToInt32(*ord / tileMap->tileSideInMeters); + + *tileOrd += offset; + *ord -= offset*tileMap->tileSideInMeters; + + Assert(*ord >= 0.0f); + Assert(*ord < tileMap->tileSideInMeters); +} + +inline TileChunkPosition getChunkPosition(TileMap* tileMap, uint32 absTileX, uint32 absTileY) { + TileChunkPosition result = {}; + result.tileChunkX = absTileX >> tileMap->chunkShift; + result.tileChunkY = absTileY >> tileMap->chunkShift; + result.relTileX = absTileX & tileMap->chunkMask; + result.relTileY = absTileY & tileMap->chunkMask; + return result; +} + +inline uint32 getTileValueUnchecked(TileMap *tileMap, TileChunk *tileChunk, uint32 testTileX, uint32 testTileY) { + Assert(tileChunk); + Assert(testTileX < tileMap->chunkDim); + Assert(testTileY < tileMap->chunkDim); + return tileChunk->tiles[testTileY * tileMap->chunkDim + testTileX]; +} + +inline void setTileValueUnchecked(TileMap *tileMap, TileChunk *tileChunk, uint32 testTileX, uint32 testTileY, uint32 tileValue) { + Assert(tileChunk); + Assert(testTileX < tileMap->chunkDim); + Assert(testTileY < tileMap->chunkDim); + tileChunk->tiles[testTileY * tileMap->chunkDim + testTileX] = tileValue; +} + +inline uint32 getTileValue(TileMap *tileMap, TileChunk* tileChunk, uint32 testTileX, uint32 testTileY) { + uint32 tileValue = 0; + if (tileChunk) { + tileValue = getTileValueUnchecked(tileMap, tileChunk, testTileX, testTileY); + } + return tileValue; +} + +inline void setTileValue(TileMap *tileMap, TileChunk* tileChunk, uint32 testTileX, uint32 testTileY, uint32 tileValue) { + if (tileChunk) { + setTileValueUnchecked(tileMap, tileChunk, testTileX, testTileY, tileValue); + } +} + +inline uint32 getTileValue(TileMap *tileMap, uint32 testTileX, uint32 testTileY) { + uint32 tileValue = 0; + TileChunkPosition chunkPos = getChunkPosition(tileMap, testTileX, testTileY); + TileChunk *tileChunk = getTileChunk(tileMap, chunkPos.tileChunkX, chunkPos.tileChunkY); + tileValue = getTileValue(tileMap, tileChunk, testTileX, testTileY); + return tileValue; +} + +inline TileMapPosition recanonicalisePosition(TileMap *tileMap, TileMapPosition pos) { + TileMapPosition result = pos; + + recanonicaliseOrd(tileMap, &result.absTileX, &result.x); + recanonicaliseOrd(tileMap, &result.absTileY, &result.y); + + return result; +} + +internal bool32 isTileMapPointEmpty(TileMap *tileMap, TileMapPosition testPos) { + bool32 isEmpty = false; + + TileChunkPosition chunkPos = getChunkPosition(tileMap, testPos.absTileX, testPos.absTileY); + TileChunk *tileChunk = getTileChunk(tileMap, chunkPos.tileChunkX, chunkPos.tileChunkY); + isEmpty = (getTileValue(tileMap, tileChunk, chunkPos.relTileX, chunkPos.relTileY) == 0); + + return isEmpty; +} + +internal void setTileMapValue(MemoryArena *arena, TileMap *tileMap, uint32 absTileX, uint32 absTileY, uint32 tileValue) { + TileChunkPosition chunkPos = getChunkPosition(tileMap, absTileX, absTileY); + TileChunk *tileChunk = getTileChunk(tileMap, chunkPos.tileChunkX, chunkPos.tileChunkY); + Assert(tileChunk); + setTileValue(tileMap, tileChunk, chunkPos.relTileX, chunkPos.relTileY, tileValue); +} diff --git a/src/handmade_tile.h b/src/handmade_tile.h new file mode 100644 index 0000000..0c966a1 --- /dev/null +++ b/src/handmade_tile.h @@ -0,0 +1,41 @@ +#pragma once +#include "handmade.h" + +struct TileChunk { + uint32 *tiles; +}; + +struct TileChunkPosition { + uint32 tileChunkX; + uint32 tileChunkY; + + uint32 relTileX; + uint32 relTileY; +}; + +struct TileMapPosition { + // tile map x and y and tile x and y packed, lower 8 bits are tile X,Y and upper 24 bits map X,Y + // ---- ---- ---- ---- ---- ---- : ---- ---- + // TILE MAP ORD : TILE ORD + uint32 absTileX; + uint32 absTileY; + + // Sub-tile position + real32 x; + real32 y; +}; + +struct TileMap { + uint32 chunkShift; + uint32 chunkMask; + uint32 chunkDim; + + real32 tileSideInMeters; + int32 tileSideInPixels; + real32 metersToPixels; + + uint32 tileChunkCountX; + uint32 tileChunkCountY; + + TileChunk *tileChunks; +};