Example rendering
This commit is contained in:
10
src/rpg/world/CMakeLists.txt
Normal file
10
src/rpg/world/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2025 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
worldunit.c
|
||||
)
|
||||
39
src/rpg/world/worldunit.c
Normal file
39
src/rpg/world/worldunit.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "worldunit.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void worldChunkPosAdd(
|
||||
worldchunkpos_t *pos,
|
||||
const worldsubtile_t amt
|
||||
) {
|
||||
int8_t a = pos->subtile; // current signed subtile
|
||||
int8_t b = amt; // signed delta
|
||||
uint8_t unsignedAdded = (uint8_t)a + (uint8_t)b; // well-defined wrap add
|
||||
int8_t r = (int8_t)unsignedAdded; // result in signed domain
|
||||
|
||||
pos->subtile = r;
|
||||
|
||||
// Signed-overflow detection for a + b -> r:
|
||||
// overflow if sign(a) == sign(b) and sign(r) != sign(a)
|
||||
uint8_t ov = (uint8_t)((a ^ r) & (b ^ r)) >> 7; // 1 if overflow, else 0
|
||||
|
||||
// Direction of carry: +1 for b >= 0, -1 for b < 0 (computed branchlessly)
|
||||
uint8_t neg = ((uint8_t)b) >> 7; // 0 if b>=0, 1 if b<0
|
||||
int8_t dir = (int8_t)(1 - (neg << 1)); // +1 or -1
|
||||
|
||||
// Apply tile adjustment (mod-256 via uint8_t arithmetic)
|
||||
pos->tile = (uint8_t)(pos->tile + (uint8_t)(ov * (uint8_t)dir));
|
||||
}
|
||||
|
||||
float_t worldChunkPosToF32(
|
||||
const worldchunkpos_t pos,
|
||||
const uint8_t tileSize
|
||||
) {
|
||||
return (float_t)(pos.tile * tileSize) + ((float_t)pos.subtile / 256.0f);
|
||||
}
|
||||
@@ -8,13 +8,20 @@
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
|
||||
#define WORLD_DIMENSIONS 3
|
||||
#define WORLD_SUBTITLE_MIN -128
|
||||
#define WORLD_SUBTITLE_MAX 127
|
||||
|
||||
/**
|
||||
* Position in SUBTILE space in a world, each unit represents a single subtile.
|
||||
* This is divided by the size of the tile, e.g. if a tile is 16x16 then there
|
||||
* are 256 / tile size = units per pixel of a tile. This means there are always
|
||||
* uint8_t max subtiles in a tile.
|
||||
* are 128 / tile size = units per pixel of a tile. This means there are always
|
||||
* between WORLD_SUBTITLE_MIN and WORLD_SUBTITLE_MAX subtiles in a tile.
|
||||
*
|
||||
* The extra benefit of this is that different tile sizes don't require any game
|
||||
* logic updates!
|
||||
*/
|
||||
typedef uint8_t worldsubtile_t;
|
||||
typedef int8_t worldsubtile_t;
|
||||
|
||||
/**
|
||||
* Position in TILE space in a world, each unit represents a single tile. This
|
||||
@@ -51,4 +58,29 @@ typedef struct worldpos_s {
|
||||
worldsubtile_t subtile;
|
||||
worldtile_t tile;
|
||||
worldchunk_t chunk;
|
||||
} worldpos_t;
|
||||
} worldpos_t;
|
||||
|
||||
/**
|
||||
* Adds a number of subtiles to a world chunk position, rolling over into tiles
|
||||
* and chunks as necessary.
|
||||
*
|
||||
* @param pos Pointer to the world chunk position to modify.
|
||||
* @param amt The amount of subtiles to add (can be negative).
|
||||
*/
|
||||
void worldChunkPosAdd(
|
||||
worldchunkpos_t *pos,
|
||||
const worldsubtile_t amt
|
||||
);
|
||||
|
||||
/**
|
||||
* Converts a world chunk position to a floating point number, given the tile
|
||||
* size in pixels.
|
||||
*
|
||||
* @param pos Pointer to the world chunk position to convert.
|
||||
* @param tileSize The size of a tile in pixels.
|
||||
* @return The position as a floating point number.
|
||||
*/
|
||||
float_t worldChunkPosToF32(
|
||||
const worldchunkpos_t pos,
|
||||
const uint8_t tileSize
|
||||
);
|
||||
Reference in New Issue
Block a user