Getting tile data from overworld

This commit is contained in:
2025-03-03 00:57:36 -06:00
parent d81775054d
commit d53b5eab49
10 changed files with 176 additions and 23 deletions

View File

@ -9,6 +9,7 @@ target_sources(${DUSK_TARGET_NAME}
entity.c
overworld.c
player.c
tile.c
)
# Subdirs

View File

@ -8,7 +8,7 @@
#include "entity.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "overworlddefs.h"
#include "overworld.h"
entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
{ NULL, NULL },
@ -68,27 +68,58 @@ void entityMove(entity_t *ent, const facingdir_t dir) {
entityTurn(ent, dir);
// Move
uint8_t targetX = ent->x, targetY = ent->y;
switch(dir) {
case FACING_DIRECTION_EAST:
ent->x++;
ent->subX = -OVERWORLD_ENTITY_WIDTH;
if(ent->x >= OVERWORLD.mapWidth - 1) return;
targetX++;
break;
case FACING_DIRECTION_WEST:
ent->x--;
ent->subX = OVERWORLD_ENTITY_WIDTH;
if(ent->x == 0) return;
targetX--;
break;
case FACING_DIRECTION_NORTH:
ent->y++;
ent->subY = -OVERWORLD_ENTITY_HEIGHT;
if(ent->y >= OVERWORLD.mapHeight - 1) return;
targetY++;
break;
case FACING_DIRECTION_SOUTH:
ent->y--;
ent->subY = OVERWORLD_ENTITY_HEIGHT;
if(ent->y == 0) return;
targetY--;
break;
default:
assertUnreachable("Invalid facing direction");
}
// Check tile at target
uint8_t i = 0;
tileid_t tileId;
for(i = 0; i < OVERWORLD.mapLayerCount; i++) {
tileId = overworldTileGet(0, targetX, targetY);
if(tileIsSolid(tileId)) return;
}
// Check for entity at target
entity_t *atPos = overworldEntityGetAtPosition(targetX, targetY);
if(atPos != NULL) return;
// Commit to move
ent->x = targetX;
ent->y = targetY;
switch(dir) {
case FACING_DIRECTION_EAST:
ent->subX = -OVERWORLD_ENTITY_WIDTH;
break;
case FACING_DIRECTION_WEST:
ent->subX = OVERWORLD_ENTITY_WIDTH;
break;
case FACING_DIRECTION_NORTH:
ent->subY = -OVERWORLD_ENTITY_HEIGHT;
break;
case FACING_DIRECTION_SOUTH:
ent->subY = OVERWORLD_ENTITY_HEIGHT;
break;
}
}
bool entityIsMoving(const entity_t *ent) {

View File

@ -17,7 +17,7 @@ void overworldInit() {
// Test
OVERWORLD.mapWidth = 16;
OVERWORLD.mapHeight = 16;
OVERWORLD.mapLayerCount = 2;
OVERWORLD.mapLayerCount = 1;
memset(&OVERWORLD.tileIds, 0x01, sizeof(OVERWORLD.tileIds));
@ -44,4 +44,33 @@ void overworldUpdate() {
while(i < OVERWORLD.entityCount) {
entityUpdate(OVERWORLD.entities + i++);
}
}
uint32_t overworldTileGetIndex(
const uint8_t layer,
const uint8_t x,
const uint8_t y
) {
return (
(layer * OVERWORLD.mapWidth * OVERWORLD.mapHeight) +
(y * OVERWORLD.mapWidth) +
x
);
}
tileid_t overworldTileGet(
const uint8_t layer,
const uint8_t x,
const uint8_t y
) {
return OVERWORLD.tileIds[overworldTileGetIndex(layer, x, y)];
}
entity_t * overworldEntityGetAtPosition(const uint8_t x, const uint8_t y) {
uint8_t i = 0;
while(i < OVERWORLD.entityCount) {
entity_t * entity = OVERWORLD.entities + i++;
if(entity->x == x && entity->y == y) return entity;
}
return NULL;
}

View File

@ -45,4 +45,44 @@ void overworldUpdate();
/**
* Platform level render method. Refer to sceneRender for information.
*/
void overworldRender();
void overworldRender();
/**
* Returns the index of the tile at the given position.
*
* @param layer The layer to get the tile from.
* @param x The x position of the tile.
* @param y The y position of the tile.
* @return The index of the tile at the given position.
*/
uint32_t overworldTileGetIndex(
const uint8_t layer,
const uint8_t x,
const uint8_t y
);
/**
* Returns the tile at the given position.
*
* @param layer The layer to get the tile from.
* @param x The x position of the tile.
* @param y The y position of the tile.
* @return The tile id at the given position.
*/
tileid_t overworldTileGet(
const uint8_t layer,
const uint8_t x,
const uint8_t y
);
/**
* Returns the entity at the given position.
*
* @param x The x position of the entity.
* @param y The y position of the entity.
* @return The entity at the given position.
*/
entity_t * overworldEntityGetAtPosition(
const uint8_t x,
const uint8_t y
);

19
src/dusk/overworld/tile.c Normal file
View File

@ -0,0 +1,19 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "tile.h"
bool_t tileIsSolid(const tileid_t id) {
switch(id) {
case TILE_ID_NULL:
case TILE_ID_GRASS:
return false;
default:
return true;
}
}

View File

@ -14,4 +14,13 @@ typedef struct {
uint32_t nothing;
} tiledata_t;
#define TILE_ID_NULL 0
#define TILE_ID_NULL 0
#define TILE_ID_GRASS 1
/**
* Returns whether or not the tile is solid.
*
* @param id The tile id to check.
* @return Whether or not the tile is solid.
*/
bool_t tileIsSolid(const tileid_t id);

View File

@ -25,8 +25,8 @@ void mapInit() {
void mapUpdate() {
// Copy tile ids.
memoryCopyRangeSafe(
&MAP_DATA.tileIds,
&OVERWORLD.tileIds[0],
MAP_DATA.tileIds,
OVERWORLD.tileIds,
&OVERWORLD.tileIds[
OVERWORLD.mapWidth * OVERWORLD.mapHeight * OVERWORLD.mapLayerCount
],

View File

@ -7,8 +7,10 @@
#include "../fragments/packed.glsl"
#include "../fragments/quad.glsl"
#define MAP_TILE_PACKED_SIZE 16
layout(std140) uniform b_Map {
uvec4 mapTileIds[OVERWORLD_TILE_COUNT_MAX / PACKED_U8_PER_UVEC4];
uvec4 mapTileIds[OVERWORLD_TILE_COUNT_MAX / MAP_TILE_PACKED_SIZE];
uint mapSize;
uvec3 _padding0;
};
@ -42,5 +44,6 @@ uint mapGetLayer(uint instanceIndex) {
}
uint mapGetTileId(uint instanceIndex) {
uvec4 v4 = mapTileIds[packedArrayGetU8IndexFromUVEC4Array(instanceIndex)];
return packedArrayGetU8FromUVEC4ArrayValue(instanceIndex, v4);
}

View File

@ -4,13 +4,33 @@
// https://opensource.org/licenses/MIT
#define PACKED_U8_PER_UI 4
#define PACKED_U8_PER_UVEC4 PACKED_U8_PER_UI / 4
#define PACKED_U8_PER_UVEC4 PACKED_U8_PER_UI * 4
uint packedGetU8(uint position, uint data) {
return (data >> (position * 8u)) & 0xFFu;
}
uint packedGetU8FromVEC4(uint position, vec4 data) {
return packedGetU8(position, uint(data[position / 4u]));
}
int packedGetI8(uint position, uint data) {
int shift = int(position * 8u);
return int(data << (24 - shift)) >> 24;
}
uint packedArrayGetU8IndexFromUVEC4Array(uint u8ArrayIndex) {
// Given a uint8_t array is uploaded, this will return the index to get the
// appropriate uvec4 from a uvec4 array that will be at the right index.
return u8ArrayIndex / uint(PACKED_U8_PER_UVEC4);
}
uint packedArrayGetU8FromUVEC4ArrayValue(uint u8ArrayIndex, uvec4 data) {
// Given a value from a uint8_t array, this will return the value at the
// appropriate index. You must first get the uvec4 from the array using
// packedArrayGetU8IndexFromUVEC4Array.
uint subIndex = (u8ArrayIndex % uint(PACKED_U8_PER_UVEC4)) / uint(PACKED_U8_PER_UI);
uint shiftAmount = (u8ArrayIndex % uint(PACKED_U8_PER_UI)) * 8u;
uint value = (data[subIndex] >> shiftAmount) & 0xFFu;
return value;
}

View File

@ -16,12 +16,13 @@ out vec4 FragColor;
void main() {
uint layer = mapGetLayer(v_InstanceIndex);
uint tileId = mapGetTileId(v_InstanceIndex);
if(layer == 0u) {
FragColor = vec4(1, 0, 0, 0.5);
if(tileId == 0u) {
FragColor = vec4(1, 0, 0, 1);
} else if(tileId == 1u) {
FragColor = vec4(0, 1, 0, 1);
} else {
FragColor = vec4(0, 1, 0, 0.5);
FragColor = vec4(0, 0, 1, 1);
}
// FragColor = vec4(1, 0, 0, 1);
}