diff --git a/misc/bdebug.bat b/misc/bdebug.bat deleted file mode 100644 index 26f29d8..0000000 --- a/misc/bdebug.bat +++ /dev/null @@ -1,2 +0,0 @@ -call build || exit /b %errorlevel% -devenv .\build\handmade_win32.exe diff --git a/misc/brun.bat b/misc/brun.bat deleted file mode 100644 index 900435c..0000000 --- a/misc/brun.bat +++ /dev/null @@ -1,2 +0,0 @@ -call build || exit /b %errorlevel% -.\build\handmade_win32.exe diff --git a/misc/build.bat b/misc/cmds/build.bat similarity index 100% rename from misc/build.bat rename to misc/cmds/build.bat diff --git a/misc/cmds/run.bat b/misc/cmds/run.bat new file mode 100644 index 0000000..ed37235 --- /dev/null +++ b/misc/cmds/run.bat @@ -0,0 +1 @@ +.\build\handmade_win32.exe diff --git a/misc/hh.bat b/misc/hh.bat new file mode 100644 index 0000000..baa238d --- /dev/null +++ b/misc/hh.bat @@ -0,0 +1,2 @@ +call .\misc\cmds\%1.bat || exit /b %errorlevel% +.\build\handmade_win32.exe diff --git a/src/handmade.cpp b/src/handmade.cpp index b9ac232..3864130 100644 --- a/src/handmade.cpp +++ b/src/handmade.cpp @@ -1,23 +1,5 @@ #include "handmade.h" - -#define PI32 3.141592653589f - -inline int32 roundReal32ToUInt32(real32 realNum) { - return (uint32)(realNum + 0.5f); -} - -inline int32 roundReal32ToInt32(real32 realNum) { - 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; -} +#include "handmade_intrinsics.h" internal void drawRectangle(GameOffscreenBuffer *buffer, real32 realMinX, real32 realMinY, real32 realMaxX, real32 realMaxY, real32 R, real32 G, real32 B) { int32 minX = roundReal32ToInt32(realMinX); @@ -87,51 +69,39 @@ inline TileMap *getTileMap(World *world, int32 tileMapX, int32 tileMapY) { return tileMap; } -inline CanonicalPosition getCanonicalPosition(World* world, RawPosition pos) { - CanonicalPosition result = {}; - - result.tileMapX = pos.tileMapX; - result.tileMapY = pos.tileMapY; +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; - real32 x = pos.x - world->upperLeftX; - real32 y = pos.y - world->upperLeftY; + Assert(*ord >= 0); + Assert(*ord < world->tileSideInPixels); - 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 (*tileOrd < 0) { + *tileOrd += tileCount; + *tileMapOrd -= 1; } - if (result.tileY < 0) { - result.tileY += world->tileCountY; - result.tileMapY -= 1; + if (*tileOrd >= tileCount) { + *tileOrd -= tileCount; + *tileMapOrd += 1; } +} - if (result.tileX >= world->tileCountX) { - result.tileX -= world->tileCountX; - result.tileMapX += 1; - } +inline CanonicalPosition recanonicalisePosition(World* world, CanonicalPosition pos) { + CanonicalPosition result = pos; - if (result.tileY >= world->tileCountY) { - result.tileY -= world->tileCountY; - result.tileMapY += 1; - } + recanonicaliseOrd(world, world->tileCountX, &result.tileMapX, &result.tileX, &result.x); + recanonicaliseOrd(world, world->tileCountY, &result.tileMapY, &result.tileY, &result.y); return result; } -internal bool32 isWorldPointEmpty(World *world, RawPosition testPos) { +internal bool32 isWorldPointEmpty(World *world, CanonicalPosition 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); + TileMap *tileMap = getTileMap(world, testPos.tileMapX, testPos.tileMapY); + isEmpty = (getTileValueUnchecked(world, tileMap, testPos.tileX, testPos.tileY) == 0); return isEmpty; } @@ -142,11 +112,12 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { GameState *state = (GameState*)memory->permanentStorage; if (!memory->isInitialised) { + state->playerPos.x = 150.0f; + state->playerPos.y = 150.0f; + state->playerPos.tileMapX = 0; + state->playerPos.tileMapY = 0; + memory->isInitialised = true; - state->playerX = 150.0f; - state->playerY = 150.0f; - state->tileMapX = 0; - state->tileMapY = 0; } const int TILEMAP_WIDTH = 16; @@ -210,8 +181,8 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { world.tileMapCountY = WORLD_HEIGHT; world.upperLeftX = 0; world.upperLeftY = 0; - world.tileWidth = 60; - world.tileHeight = 60; + world.tileSideInMeters = 1.4f; + world.tileSideInPixels = 60; TileMap maps[WORLD_HEIGHT][WORLD_WIDTH]; maps[0][0].tiles = (uint32*)tiles00; @@ -256,29 +227,28 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { dPlayerX *= 96.0f; 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, - }; + CanonicalPosition newPlayerPos = state->playerPos; + newPlayerPos.x += dPlayerX * input->dtForFrame; + newPlayerPos.y += dPlayerY * input->dtForFrame; + newPlayerPos = recanonicalisePosition(&world, newPlayerPos); - RawPosition playerBottomLeft = playerPos; + CanonicalPosition playerBottomLeft = newPlayerPos; playerBottomLeft.x -= 0.5f * playerWidth; + playerBottomLeft = recanonicalisePosition(&world, playerBottomLeft); - RawPosition playerTopLeft = playerPos; + CanonicalPosition playerTopLeft = newPlayerPos; playerTopLeft.x -= 0.5f * playerWidth; playerTopLeft.y -= playerWidth; + playerTopLeft = recanonicalisePosition(&world, playerTopLeft); - RawPosition playerBottomRight = playerPos; + CanonicalPosition playerBottomRight = newPlayerPos; playerBottomRight.x += 0.5f * playerWidth; + playerBottomRight = recanonicalisePosition(&world, playerBottomRight); - RawPosition playerTopRight = playerPos; + CanonicalPosition playerTopRight = newPlayerPos; playerTopRight.x += 0.5f * playerWidth; playerTopRight.y -= playerWidth; + playerTopRight = recanonicalisePosition(&world, playerTopRight); if ( isWorldPointEmpty(&world, playerTopLeft) && @@ -286,34 +256,30 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { 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; + state->playerPos = newPlayerPos; } } // clearscreen drawRectangle(videoBuf, 0.0f, 0.0f, (real32)videoBuf->width, (real32)videoBuf->height, 1.0f, 0.0f, 1.0f); - TileMap *currMap = getTileMap(&world, state->tileMapX, state->tileMapY); + 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.tileWidth; - real32 minY = world.upperLeftY + ((real32)row)*world.tileHeight; - real32 maxX = minX + world.tileWidth; - real32 maxY = minY + world.tileHeight; + 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); } } - real32 playerLeft = state->playerX - 0.5f * playerWidth; - real32 playerTop = state->playerY - playerHeight; - drawRectangle(videoBuf, playerLeft, playerTop, state->playerX + playerWidth*0.5f, state->playerY, playerR, playerG, playerB); + 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); } extern "C" GAME_GET_SOUND_SAMPLES(gameGetSoundSamples) { diff --git a/src/handmade.h b/src/handmade.h index e31b11d..ca1bca9 100644 --- a/src/handmade.h +++ b/src/handmade.h @@ -1,7 +1,6 @@ #include #include #include -#include #pragma once @@ -182,13 +181,14 @@ struct RawPosition { }; struct World { + real32 tileSideInMeters; + int32 tileSideInPixels; + int32 tileMapCountX; int32 tileMapCountY; real32 upperLeftX; real32 upperLeftY; - real32 tileWidth; - real32 tileHeight; int32 tileCountY; int32 tileCountX; @@ -197,10 +197,7 @@ struct World { }; struct GameState { - int32 tileMapX; - int32 tileMapY; - real32 playerX; - real32 playerY; + CanonicalPosition playerPos; }; // === Game to platform services === diff --git a/src/handmade_intrinsics.h b/src/handmade_intrinsics.h new file mode 100644 index 0000000..073bedd --- /dev/null +++ b/src/handmade_intrinsics.h @@ -0,0 +1,33 @@ +#pragma once +#include "handmade.h" +#include "math.h" + +#define PI32 3.141592653589f + +inline int32 roundReal32ToUInt32(real32 realNum) { + return (uint32)(realNum + 0.5f); +} + +inline int32 roundReal32ToInt32(real32 realNum) { + return (int32)(realNum + 0.5f); +} + +inline int32 floorReal32ToInt32(real32 realNum) { + return (int32)floorf(realNum); +} + +inline int32 truncateReal32ToInt32(real32 realNum) { + return (int32)realNum; +} + +inline real32 sin(real32 angle) { + return sinf(angle); +} + +inline real32 cos(real32 angle) { + return cosf(angle); +} + +inline real32 atan2(real32 y, real32 x) { + return atan2f(y, x); +}