ソースを参照

update

master
Ledda 1ヶ月前
コミット
ee9f65f016
5個のファイルの変更287行の追加214行の削除
  1. +130
    -172
      src/handmade.cpp
  2. +17
    -42
      src/handmade.h
  3. +4
    -0
      src/handmade_intrinsics.h
  4. +95
    -0
      src/handmade_tile.cpp
  5. +41
    -0
      src/handmade_tile.h

+ 130
- 172
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) {


+ 17
- 42
src/handmade.h ファイルの表示

@@ -1,9 +1,9 @@
#pragma once

#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>

#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 ===


+ 4
- 0
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);
}

+ 95
- 0
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);
}

+ 41
- 0
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;
};

読み込み中…
キャンセル
保存