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 entity.c
overworld.c overworld.c
player.c player.c
tile.c
) )
# Subdirs # Subdirs

View File

@ -8,7 +8,7 @@
#include "entity.h" #include "entity.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "util/memory.h" #include "util/memory.h"
#include "overworlddefs.h" #include "overworld.h"
entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = { entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
{ NULL, NULL }, { NULL, NULL },
@ -68,27 +68,58 @@ void entityMove(entity_t *ent, const facingdir_t dir) {
entityTurn(ent, dir); entityTurn(ent, dir);
// Move uint8_t targetX = ent->x, targetY = ent->y;
switch(dir) { switch(dir) {
case FACING_DIRECTION_EAST: case FACING_DIRECTION_EAST:
ent->x++; if(ent->x >= OVERWORLD.mapWidth - 1) return;
ent->subX = -OVERWORLD_ENTITY_WIDTH; targetX++;
break; break;
case FACING_DIRECTION_WEST: case FACING_DIRECTION_WEST:
ent->x--; if(ent->x == 0) return;
ent->subX = OVERWORLD_ENTITY_WIDTH; targetX--;
break; break;
case FACING_DIRECTION_NORTH: case FACING_DIRECTION_NORTH:
ent->y++; if(ent->y >= OVERWORLD.mapHeight - 1) return;
ent->subY = -OVERWORLD_ENTITY_HEIGHT; targetY++;
break; break;
case FACING_DIRECTION_SOUTH: case FACING_DIRECTION_SOUTH:
ent->y--; if(ent->y == 0) return;
ent->subY = OVERWORLD_ENTITY_HEIGHT; targetY--;
break; break;
default: default:
assertUnreachable("Invalid facing direction"); 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) { bool entityIsMoving(const entity_t *ent) {

View File

@ -17,7 +17,7 @@ void overworldInit() {
// Test // Test
OVERWORLD.mapWidth = 16; OVERWORLD.mapWidth = 16;
OVERWORLD.mapHeight = 16; OVERWORLD.mapHeight = 16;
OVERWORLD.mapLayerCount = 2; OVERWORLD.mapLayerCount = 1;
memset(&OVERWORLD.tileIds, 0x01, sizeof(OVERWORLD.tileIds)); memset(&OVERWORLD.tileIds, 0x01, sizeof(OVERWORLD.tileIds));
@ -44,4 +44,33 @@ void overworldUpdate() {
while(i < OVERWORLD.entityCount) { while(i < OVERWORLD.entityCount) {
entityUpdate(OVERWORLD.entities + i++); 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. * 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; uint32_t nothing;
} tiledata_t; } 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() { void mapUpdate() {
// Copy tile ids. // Copy tile ids.
memoryCopyRangeSafe( memoryCopyRangeSafe(
&MAP_DATA.tileIds, MAP_DATA.tileIds,
&OVERWORLD.tileIds[0], OVERWORLD.tileIds,
&OVERWORLD.tileIds[ &OVERWORLD.tileIds[
OVERWORLD.mapWidth * OVERWORLD.mapHeight * OVERWORLD.mapLayerCount OVERWORLD.mapWidth * OVERWORLD.mapHeight * OVERWORLD.mapLayerCount
], ],

View File

@ -7,8 +7,10 @@
#include "../fragments/packed.glsl" #include "../fragments/packed.glsl"
#include "../fragments/quad.glsl" #include "../fragments/quad.glsl"
#define MAP_TILE_PACKED_SIZE 16
layout(std140) uniform b_Map { 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; uint mapSize;
uvec3 _padding0; uvec3 _padding0;
}; };
@ -42,5 +44,6 @@ uint mapGetLayer(uint instanceIndex) {
} }
uint mapGetTileId(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 // https://opensource.org/licenses/MIT
#define PACKED_U8_PER_UI 4 #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) { uint packedGetU8(uint position, uint data) {
return (data >> (position * 8u)) & 0xFFu; 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 packedGetI8(uint position, uint data) {
int shift = int(position * 8u); int shift = int(position * 8u);
return int(data << (24 - shift)) >> 24; 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() { void main() {
uint layer = mapGetLayer(v_InstanceIndex); uint layer = mapGetLayer(v_InstanceIndex);
uint tileId = mapGetTileId(v_InstanceIndex);
if(layer == 0u) { if(tileId == 0u) {
FragColor = vec4(1, 0, 0, 0.5); FragColor = vec4(1, 0, 0, 1);
} else if(tileId == 1u) {
FragColor = vec4(0, 1, 0, 1);
} else { } else {
FragColor = vec4(0, 1, 0, 0.5); FragColor = vec4(0, 0, 1, 1);
} }
// FragColor = vec4(1, 0, 0, 1);
} }