Getting tile data from overworld
This commit is contained in:
@ -9,6 +9,7 @@ target_sources(${DUSK_TARGET_NAME}
|
||||
entity.c
|
||||
overworld.c
|
||||
player.c
|
||||
tile.c
|
||||
)
|
||||
|
||||
# Subdirs
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
@ -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
19
src/dusk/overworld/tile.c
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
@ -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
|
||||
],
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
Reference in New Issue
Block a user