From 78837b321244a974c30de9dad50037ba0c0bd5b5 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 19 Jun 2025 09:55:56 -0500 Subject: [PATCH] hot entity on entity action --- data/map.tmj | 20 ++- src/dusk/CMakeLists.txt | 1 + src/dusk/entity/entity.c | 50 ++++++- src/dusk/entity/player.c | 1 + src/dusk/physics/CMakeLists.txt | 10 ++ src/dusk/physics/physics.c | 52 ++++++++ src/dusk/physics/physics.h | 31 +++++ src/dusk/util/fixed.c | 119 +++++++++++++---- src/dusk/util/fixed.h | 139 +++++++++++++++++--- src/dusk/world/chunk.c | 12 +- src/dusk/world/overworld.c | 8 +- src/dusk/world/tile.h | 3 +- src/duskraylib/display/draw/drawoverworld.c | 32 ++--- tools/mapcompile/mapcompile.py | 22 ++-- 14 files changed, 414 insertions(+), 86 deletions(-) create mode 100644 src/dusk/physics/CMakeLists.txt create mode 100644 src/dusk/physics/physics.c create mode 100644 src/dusk/physics/physics.h diff --git a/data/map.tmj b/data/map.tmj index 0a5dc76..7218b5b 100644 --- a/data/map.tmj +++ b/data/map.tmj @@ -440,6 +440,24 @@ "template":"templates\/NPC.tx", "x":6627, "y":6828.33333333333 + }, + { + "id":8, + "template":"templates\/NPC.tx", + "x":6640, + "y":6817 + }, + { + "id":9, + "template":"templates\/NPC.tx", + "x":6639.66666666667, + "y":6839 + }, + { + "id":10, + "template":"templates\/NPC.tx", + "x":6653.66666666667, + "y":6832 }], "opacity":1, "type":"objectgroup", @@ -448,7 +466,7 @@ "y":0 }], "nextlayerid":6, - "nextobjectid":8, + "nextobjectid":11, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.11.1", diff --git a/src/dusk/CMakeLists.txt b/src/dusk/CMakeLists.txt index ac89f59..3cbbb57 100644 --- a/src/dusk/CMakeLists.txt +++ b/src/dusk/CMakeLists.txt @@ -25,5 +25,6 @@ target_sources(${DUSK_TARGET_NAME} add_subdirectory(assert) add_subdirectory(display) add_subdirectory(entity) +add_subdirectory(physics) add_subdirectory(util) add_subdirectory(world) \ No newline at end of file diff --git a/src/dusk/entity/entity.c b/src/dusk/entity/entity.c index 4f19683..18ef933 100644 --- a/src/dusk/entity/entity.c +++ b/src/dusk/entity/entity.c @@ -8,6 +8,8 @@ #include "entity.h" #include "assert/assert.h" #include "util/memory.h" +#include "world/world.h" +#include "physics/physics.h" entity_t ENTITIES[ENTITY_COUNT_MAX] = {0}; @@ -43,6 +45,50 @@ void entityUpdate(entity_t *entity) { ENTITY_CALLBACKS[entity->type].update(entity); - entity->x += entity->vx; - entity->y += entity->vy; + if( + entity->vx == FIXED248(0, 0) && + entity->vy == FIXED248(0, 0) + ) return; + + fixed248_t newX = entity->x + entity->vx; + fixed248_t newY = entity->y + entity->vy; + + // Check for collisions with the world boundaries + + // Check for collisions with tiles + + // Check for collisions with other entities + fixed248_t halfTileW = FIXED248(TILE_WIDTH_HEIGHT / 2, 0); + fixed248_t halfTileH = FIXED248(TILE_WIDTH_HEIGHT / 2, 0); + fixed248_t selfCircR = halfTileW; + fixed248_t selfCircX = newX - halfTileW; + fixed248_t selfCircY = newY - halfTileH; + + for(entity_t *otherEntity = ENTITIES; otherEntity < ENTITIES + ENTITY_COUNT_MAX; ++otherEntity) { + // Skip self and null entities + if(otherEntity == entity || otherEntity->type == ENTITY_TYPE_NULL) continue; + + fixed248_t otherCircX = otherEntity->x - halfTileW; + fixed248_t otherCircY = otherEntity->y - halfTileH; + fixed248_t otherCircR = halfTileW; + + collisionresult_t collision = physicsCheckCircleCircle( + selfCircX, selfCircY, selfCircR, + otherCircX, otherCircY, otherCircR + ); + if(!collision.hit) continue; + + // Collision with entity detected. Slide out of collision. + fixed248_t slideX = fx248Mulf32(collision.normalX, fx248Tof32(collision.depth)); + fixed248_t slideY = fx248Mulf32(collision.normalY, fx248Tof32(collision.depth)); + newX -= slideX; + newY -= slideY; + + // Update selfCircX/Y for next collision check + selfCircX = newX - halfTileW; + selfCircY = newY - halfTileH; + } + + entity->x = newX; + entity->y = newY; } \ No newline at end of file diff --git a/src/dusk/entity/player.c b/src/dusk/entity/player.c index e137610..b39e073 100644 --- a/src/dusk/entity/player.c +++ b/src/dusk/entity/player.c @@ -10,6 +10,7 @@ #include "input.h" #include "display/render.h" #include "world/world.h" +#include "physics/physics.h" void playerInit() { entity_t *ent = &ENTITIES[0]; diff --git a/src/dusk/physics/CMakeLists.txt b/src/dusk/physics/CMakeLists.txt new file mode 100644 index 0000000..0f79ab8 --- /dev/null +++ b/src/dusk/physics/CMakeLists.txt @@ -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 + physics.c +) \ No newline at end of file diff --git a/src/dusk/physics/physics.c b/src/dusk/physics/physics.c new file mode 100644 index 0000000..59a5e57 --- /dev/null +++ b/src/dusk/physics/physics.c @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "physics.h" + +collisionresult_t physicsCheckCircleCircle( + fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r, + fixed248_t circle1x, fixed248_t circle1y, fixed248_t circle1r +) { + collisionresult_t result; + // Compute vector between centers + fixed248_t dx = fx248Subfx248(circle1x, circle0x); + fixed248_t dy = fx248Subfx248(circle1y, circle0y); + + // Distance squared between centers + fixed248_t distSq = fx248Addfx248( + fx248Mulfx248(dx, dx), + fx248Mulfx248(dy, dy) + ); + + // Sum of radii + fixed248_t rSum = fx248Addfx248(circle0r, circle1r); + fixed248_t rSumSq = fx248Mulfx248(rSum, rSum); + + if(distSq > rSumSq) { + // No collision + result.hit = false; + return result; + } + + // Collision: calculate normal and penetration depth + fixed248_t dist = fx248Sqrt(distSq); + + // If centers are the same, pick arbitrary normal (1,0) + if(dist == 0) { + result.normalX = FIXED248(1,0); + result.normalY = 0; + result.depth = rSum; + } else { + // Normalized direction from circle0 to circle1 + result.normalX = fx248Divfx248(dx, dist); + result.normalY = fx248Divfx248(dy, dist); + // Penetration depth = sum of radii - distance + result.depth = fx248Subfx248(rSum, dist); + } + result.hit = true; + return result; +} \ No newline at end of file diff --git a/src/dusk/physics/physics.h b/src/dusk/physics/physics.h new file mode 100644 index 0000000..3432819 --- /dev/null +++ b/src/dusk/physics/physics.h @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "util/fixed.h" + +typedef struct { + bool_t hit; + fixed248_t normalX, normalY; + fixed248_t depth; +} collisionresult_t; + +/** + * Check for collision between two circles. + * + * @param circle0x X coordinate of the first circle's center. + * @param circle0y Y coordinate of the first circle's center. + * @param circle0r Radius of the first circle. + * @param circle1x X coordinate of the second circle's center. + * @param circle1y Y coordinate of the second circle's center. + * @param circle1r Radius of the second circle. + * @return A collisionresult_t structure containing collision information. + */ +collisionresult_t physicsCheckCircleCircle( + fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r, + fixed248_t circle1x, fixed248_t circle1y, fixed248_t circle1r +); \ No newline at end of file diff --git a/src/dusk/util/fixed.c b/src/dusk/util/fixed.c index d925d02..b8d3adf 100644 --- a/src/dusk/util/fixed.c +++ b/src/dusk/util/fixed.c @@ -6,59 +6,118 @@ */ #include "fixed.h" +#include "assert/assert.h" fixed248_t fx248Fromi32(const int32_t b) { return (fixed248_t)b << FIXED248_FRACTION_BITS; } -fixed248_t fx248Fromui32(const uint32_t b) { - return (fixed248_t)b << FIXED248_FRACTION_BITS; +fixed248_t fx248Fromu32(const uint32_t b) { + return (fixed248_t)((int32_t)b << FIXED248_FRACTION_BITS); } fixed248_t fx248Fromf32(const float_t b) { return (fixed248_t)(b * (1 << FIXED248_FRACTION_BITS)); } + int32_t fx248Toi32(const fixed248_t a) { return (int32_t)(a >> FIXED248_FRACTION_BITS); } uint32_t fx248Tou32(const fixed248_t a) { - return (uint32_t)(a >> FIXED248_FRACTION_BITS); + return (uint32_t)((a >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); } float_t fx248Tof32(const fixed248_t a) { - return (float_t)(a / (1 << FIXED248_FRACTION_BITS)); + return (float_t)(a / (float_t)(1 << FIXED248_FRACTION_BITS)); } -void fx248Addfx248(fixed248_t *a, const fixed248_t b) { - *a += b; + +fixed248_t fx248Addfx248(const fixed248_t a, const fixed248_t b) { + return a + b; } -void fx248Addi32(fixed248_t *a, const int32_t b) { - *a += (fixed248_t)b << FIXED248_FRACTION_BITS; +fixed248_t fx248Addi32(const fixed248_t a, const int32_t b) { + return fx248Addfx248(a, fx248Fromi32(b)); } -void fx248Addui32(fixed248_t *a, const uint32_t b) { - *a += (fixed248_t)b << FIXED248_FRACTION_BITS; +fixed248_t fx248Addu32(const fixed248_t a, const uint32_t b) { + return fx248Addfx248(a, fx248Fromu32(b)); } -void fx248Subfx248(fixed248_t *a, const fixed248_t b) { - *a -= b; +fixed248_t fx248Addf32(const fixed248_t a, const float_t b) { + return fx248Addfx248(a, fx248Fromf32(b)); } -void fx248Subi32(fixed248_t *a, const int32_t b) { - *a -= (fixed248_t)b << FIXED248_FRACTION_BITS; + + +fixed248_t fx248Subfx248(const fixed248_t a, const fixed248_t b) { + return a - b; } -void fx248Subui32(fixed248_t *a, const uint32_t b) { - *a -= (fixed248_t)b << FIXED248_FRACTION_BITS; +fixed248_t fx248Subi32(const fixed248_t a, const int32_t b) { + return fx248Subfx248(a, fx248Fromi32(b)); } -void fx248Subf32(fixed248_t *a, const float_t b) { - *a -= (fixed248_t)(b * (1 << FIXED248_FRACTION_BITS)); +fixed248_t fx248Subu32(const fixed248_t a, const uint32_t b) { + return fx248Subfx248(a, fx248Fromu32(b)); } +fixed248_t fx248Subf32(const fixed248_t a, const float_t b) { + return fx248Subfx248(a, fx248Fromf32(b)); +} + + + +fixed248_t fx248Mulfx248(const fixed248_t a, const fixed248_t b) { + return (fixed248_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS); +} + +fixed248_t fx248Muli32(const fixed248_t a, const int32_t b) { + return (fixed248_t)(((int64_t)a * (int64_t)b) >> FIXED248_FRACTION_BITS); +} + +fixed248_t fx248Mulu32(const fixed248_t a, const uint32_t b) { + return (fixed248_t)( + ((int64_t)a * (int64_t)(int32_t)b + ) >> FIXED248_FRACTION_BITS); +} + +fixed248_t fx248Mulf32(const fixed248_t a, const float_t b) { + return (fixed248_t)(( + (int64_t)a * (int64_t)(b * (1 << FIXED248_FRACTION_BITS)) + ) >> FIXED248_FRACTION_BITS); +} + + + +fixed248_t fx248Divfx248(const fixed248_t a, const fixed248_t b) { + assertFalse(b == 0, "Division by zero in fx248Divfx248"); + return (fixed248_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b); +} + +fixed248_t fx248Divi32(const fixed248_t a, const int32_t b) { + assertFalse(b == 0, "Division by zero in fx248Divi32"); + return (fixed248_t)(((int64_t)a << FIXED248_FRACTION_BITS) / (int64_t)b); +} + +fixed248_t fx248Divu32(const fixed248_t a, const uint32_t b) { + assertFalse(b == 0, "Division by zero in fx248Divu32"); + return (fixed248_t)( + ((int64_t)a << FIXED248_FRACTION_BITS + ) / (int64_t)(int32_t)b); +} + +fixed248_t fx248Divf32(const fixed248_t a, const float_t b) { + assertFalse(b == 0, "Division by zero in fx248Divf32"); + return (fixed248_t)(( + (int64_t)a << FIXED248_FRACTION_BITS + ) / (int64_t)(b * (1 << FIXED248_FRACTION_BITS))); +} + + + int32_t fx248Floor(const fixed248_t a) { return (int32_t)(a >> FIXED248_FRACTION_BITS); } @@ -76,17 +135,27 @@ int32_t fx248Round(const fixed248_t a) { } uint32_t fx248Flooru32(const fixed248_t a) { - return (uint32_t)(a >> FIXED248_FRACTION_BITS); + return (uint32_t)((a >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); } uint32_t fx248Ceilu32(const fixed248_t a) { - return (uint32_t)(( - a + ((1 << FIXED248_FRACTION_BITS) - 1) - ) >> FIXED248_FRACTION_BITS); + return (uint32_t)(((a + ((1 << FIXED248_FRACTION_BITS) - 1)) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); } uint32_t fx248Roundu32(const fixed248_t a) { - return (uint32_t)( - (a + (1 << (FIXED248_FRACTION_BITS - 1)) - ) >> FIXED248_FRACTION_BITS); + return (uint32_t)(((a + (1 << (FIXED248_FRACTION_BITS - 1))) >> FIXED248_FRACTION_BITS) & 0xFFFFFFFF); +} + +fixed248_t fx248Sqrt(const fixed248_t a) { + if(a == 0) return 0; + + fixed248_t y = a > FIXED248(1, 0) ? a : FIXED248(1, 0); + fixed248_t last = 0; + int max_iter = 16; + while(y != last && max_iter-- > 0) { + last = y; + int32_t div = (int32_t)(((int64_t)a << FIXED248_FRACTION_BITS) / y); + y = (y + div) >> 1; + } + return y; } \ No newline at end of file diff --git a/src/dusk/util/fixed.h b/src/dusk/util/fixed.h index eb73a4d..d7cdfea 100644 --- a/src/dusk/util/fixed.h +++ b/src/dusk/util/fixed.h @@ -8,10 +8,12 @@ #pragma once #include "dusk.h" -typedef uint32_t fixed248_t; +typedef int32_t fixed248_t; #define FIXED248_FRACTION_BITS 8 #define FIXED248_HIGH_MULTIPLIER (1 << FIXED248_FRACTION_BITS) +#define FIXED248_MIN INT32_MIN +#define FIXED248_MAX INT32_MAX #define FIXED248(i, f) ((fixed248_t)( \ ((i) << FIXED248_FRACTION_BITS) + \ (((f) * FIXED248_HIGH_MULTIPLIER) / 100) \ @@ -31,7 +33,7 @@ fixed248_t fx248Fromi32(const int32_t b); * @param b The uint32_t value to convert. * @return The converted fixed248_t value. */ -fixed248_t fx248Fromui32(const uint32_t b); +fixed248_t fx248Fromu32(const uint32_t b); /** * Convert a float_t value to a fixed248_t value. @@ -41,6 +43,8 @@ fixed248_t fx248Fromui32(const uint32_t b); */ fixed248_t fx248Fromf32(const float_t b); + + /** * Convert a fixed248_t value to an int32_t value. * @@ -65,69 +69,159 @@ uint32_t fx248Tou32(const fixed248_t a); */ float_t fx248Tof32(const fixed248_t a); + + /** * Add a fixed248_t value to another fixed248_t value. * - * @param a Pointer to the first fixed248_t value (will be modified). - * @param b The fixed248_t value to add to the first value. + * @param a First fixed248_t value. + * @param b Second fixed248_t value to add to the first value. + * @return The result of the addition as a fixed248_t value. */ -void fx248Addfx248(fixed248_t *a, const fixed248_t b); +fixed248_t fx248Addfx248(const fixed248_t a, const fixed248_t b); /** * Add an int32_t value to a fixed248_t value. * - * @param a Pointer to the fixed248_t value (will be modified). + * @param a The fixed248_t value to which the int32_t will be added. * @param b The int32_t value to add to the fixed248_t value. + * @return The result of the addition as a fixed248_t value. */ -void fx248Addi32(fixed248_t *a, const int32_t b); +fixed248_t fx248Addi32(const fixed248_t a, const int32_t b); /** * Add a uint32_t value to a fixed248_t value. * - * @param a Pointer to the fixed248_t value (will be modified). + * @param a The fixed248_t value to which the uint32_t will be added. * @param b The uint32_t value to add to the fixed248_t value. + * @return The result of the addition as a fixed248_t value. */ -void fx248Addui32(fixed248_t *a, const uint32_t b); +fixed248_t fx248Addu32(const fixed248_t a, const uint32_t b); /** * Add a float_t value to a fixed248_t value. * * @param a Pointer to the fixed248_t value (will be modified). * @param b The float_t value to add to the fixed248_t value. + * @return The result of the addition as a fixed248_t value. */ -void fx248Addf32(fixed248_t *a, const float_t b); +fixed248_t fx248Addf32(const fixed248_t a, const float_t b); + + /** * Subtract a fixed248_t value from another fixed248_t value. * - * @param a Pointer to the first fixed248_t value (will be modified). + * @param a First fixed248_t value. * @param b The fixed248_t value to subtract from the first value. + * @return The result of the subtraction as a fixed248_t value. */ -void fx248Subfx248(fixed248_t *a, const fixed248_t b); +fixed248_t fx248Subfx248(const fixed248_t a, const fixed248_t b); /** * Subtract an int32_t value from a fixed248_t value. * - * @param a Pointer to the fixed248_t value (will be modified). + * @param a The fixed248_t value from which the int32_t will be subtracted. * @param b The int32_t value to subtract from the fixed248_t value. + * @return The result of the subtraction as a fixed248_t value. */ -void fx248Subi32(fixed248_t *a, const int32_t b); +fixed248_t fx248Subi32(const fixed248_t a, const int32_t b); /** * Subtract a uint32_t value from a fixed248_t value. * - * @param a Pointer to the fixed248_t value (will be modified). + * @param a The fixed248_t value from which the uint32_t will be subtracted. * @param b The uint32_t value to subtract from the fixed248_t value. + * @return The result of the subtraction as a fixed248_t value. */ -void fx248Subui32(fixed248_t *a, const uint32_t b); +fixed248_t fx248Subu32(const fixed248_t a, const uint32_t b); /** * Subtract a float_t value from a fixed248_t value. * - * @param a Pointer to the fixed248_t value (will be modified). + * @param a The fixed248_t value from which the float_t will be subtracted. * @param b The float_t value to subtract from the fixed248_t value. + * @return The result of the subtraction as a fixed248_t value. */ -void fx248Subf32(fixed248_t *a, const float_t b); +fixed248_t fx248Subf32(const fixed248_t a, const float_t b); + + + +/** + * Multiply two fixed248_t values. + * + * @param a First fixed248_t value. + * @param b Second fixed248_t value to multiply with the first value. + * @return The result of the multiplication as a fixed248_t value. + */ +fixed248_t fx248Mulfx248(const fixed248_t a, const fixed248_t b); + +/** + * Multiply a fixed248_t value by an int32_t value. + * + * @param a The fixed248_t value to multiply. + * @param b The int32_t value to multiply with the fixed248_t value. + * @return The result of the multiplication as a fixed248_t value. + */ +fixed248_t fx248Muli32(const fixed248_t a, const int32_t b); + +/** + * Multiply a fixed248_t value by a uint32_t value. + * + * @param a The fixed248_t value to multiply. + * @param b The uint32_t value to multiply with the fixed248_t value. + * @return The result of the multiplication as a fixed248_t value. + */ +fixed248_t fx248Mulu32(const fixed248_t a, const uint32_t b); + +/** + * Multiply a fixed248_t value by a float_t value. + * + * @param a The fixed248_t value to multiply. + * @param b The float_t value to multiply with the fixed248_t value. + * @return The result of the multiplication as a fixed248_t value. + */ +fixed248_t fx248Mulf32(const fixed248_t a, const float_t b); + + + +/** + * Divide two fixed248_t values. + * + * @param a The fixed248_t value to be divided. + * @param b The fixed248_t value to divide by. + * @return The result of the division as a fixed248_t value. + */ +fixed248_t fx248Divfx248(const fixed248_t a, const fixed248_t b); + +/** + * Divide a fixed248_t value by an int32_t value. + * + * @param a The fixed248_t value to be divided. + * @param b The int32_t value to divide by. + * @return The result of the division as a fixed248_t value. + */ +fixed248_t fx248Divi32(const fixed248_t a, const int32_t b); + +/** + * Divide a fixed248_t value by a uint32_t value. + * + * @param a The fixed248_t value to be divided. + * @param b The uint32_t value to divide by. + * @return The result of the division as a fixed248_t value. + */ +fixed248_t fx248Divu32(const fixed248_t a, const uint32_t b); + +/** + * Divide a fixed248_t value by a float_t value. + * + * @param a The fixed248_t value to be divided. + * @param b The float_t value to divide by. + * @return The result of the division as a fixed248_t value. + */ +fixed248_t fx248Divf32(const fixed248_t a, const float_t b); + + /** * Convert a fixed248_t value to an int32_t value, rounding towards zero. @@ -179,4 +273,11 @@ uint32_t fx248Ceilu32(const fixed248_t a); * @param a The fixed248_t value to convert. * @return The converted uint32_t value. */ -uint32_t fx248Roundu32(const fixed248_t a); \ No newline at end of file +uint32_t fx248Roundu32(const fixed248_t a); + +/** + * Returns the square root of a fixed248_t value. + * + * @param a The fixed248_t value to calculate the square root of. + */ +fixed248_t fx248Sqrt(const fixed248_t a); \ No newline at end of file diff --git a/src/dusk/world/chunk.c b/src/dusk/world/chunk.c index 15271bd..a7cc100 100644 --- a/src/dusk/world/chunk.c +++ b/src/dusk/world/chunk.c @@ -248,8 +248,8 @@ void chunkLoad(chunk_t *chunk, const uint16_t x, const uint16_t y) { entity->id = data->id; // Positions are chunk-relative. - entity->x = fx248Fromui32((chunk->x * CHUNK_WIDTH * TILE_WIDTH) + data->x); - entity->y = fx248Fromui32((chunk->y * CHUNK_HEIGHT * TILE_HEIGHT)+data->y); + entity->x = fx248Fromu32((chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT) + data->x); + entity->y = fx248Fromu32((chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT)+data->y); // Next entity data++; @@ -285,10 +285,10 @@ void chunkUnload(chunk_t *chunk) { // If the entity is still within our chunk bounds, it's getting unloaded if( - fx248Flooru32(entity->x) >= chunk->x * CHUNK_WIDTH * TILE_WIDTH && - fx248Ceilu32(entity->x) < (chunk->x + 1) * CHUNK_WIDTH * TILE_WIDTH && - fx248Flooru32(entity->y) >= chunk->y * CHUNK_HEIGHT * TILE_HEIGHT && - fx248Ceilu32(entity->y) < (chunk->y + 1) * CHUNK_HEIGHT * TILE_HEIGHT + fx248Flooru32(entity->x) >= chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT && + fx248Ceilu32(entity->x) < (chunk->x + 1) * CHUNK_WIDTH * TILE_WIDTH_HEIGHT && + fx248Flooru32(entity->y) >= chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT && + fx248Ceilu32(entity->y) < (chunk->y + 1) * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT ) { shouldUnload = true; } else { diff --git a/src/dusk/world/overworld.c b/src/dusk/world/overworld.c index fcbf907..b028077 100644 --- a/src/dusk/world/overworld.c +++ b/src/dusk/world/overworld.c @@ -52,20 +52,20 @@ void overworldUpdate() { uint16_t x, y; uint16_t halfWidth, halfHeight; - halfWidth = ((CHUNK_MAP_WIDTH - 1) * CHUNK_WIDTH * TILE_WIDTH) / 2; - halfHeight = ((CHUNK_MAP_HEIGHT - 1) * CHUNK_HEIGHT * TILE_HEIGHT) / 2; + halfWidth = ((CHUNK_MAP_WIDTH - 1) * CHUNK_WIDTH * TILE_WIDTH_HEIGHT) / 2; + halfHeight = ((CHUNK_MAP_HEIGHT - 1) * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT) / 2; // Calculate the chunk map position based on the camera position. if(OVERWORLD_CAMERA_X < halfWidth) { x = 0; } else { - x = (OVERWORLD_CAMERA_X - halfWidth) / (CHUNK_WIDTH*TILE_WIDTH); + x = (OVERWORLD_CAMERA_X - halfWidth) / (CHUNK_WIDTH*TILE_WIDTH_HEIGHT); } if(OVERWORLD_CAMERA_Y < halfHeight) { y = 0; } else { - y = (OVERWORLD_CAMERA_Y - halfHeight) / (CHUNK_HEIGHT*TILE_HEIGHT); + y = (OVERWORLD_CAMERA_Y - halfHeight) / (CHUNK_HEIGHT*TILE_WIDTH_HEIGHT); } chunkMapSetPosition(x, y); diff --git a/src/dusk/world/tile.h b/src/dusk/world/tile.h index 8aea9f4..5663921 100644 --- a/src/dusk/world/tile.h +++ b/src/dusk/world/tile.h @@ -8,7 +8,6 @@ #pragma once #include "dusk.h" -#define TILE_WIDTH 16 -#define TILE_HEIGHT 16 +#define TILE_WIDTH_HEIGHT 16 typedef uint8_t tile_t; \ No newline at end of file diff --git a/src/duskraylib/display/draw/drawoverworld.c b/src/duskraylib/display/draw/drawoverworld.c index 07593c0..be55c38 100644 --- a/src/duskraylib/display/draw/drawoverworld.c +++ b/src/duskraylib/display/draw/drawoverworld.c @@ -55,18 +55,18 @@ void drawOverworldDraw(void) { if(tile == 0) continue; // Skip empty tiles uint32_t tilemapIndex = tile - 1; // Convert to zero-based index - uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH + (i % CHUNK_WIDTH) * TILE_WIDTH; - uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_HEIGHT + (i / CHUNK_WIDTH) * TILE_HEIGHT; - uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_WIDTH; - uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_HEIGHT; + uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT + (i % CHUNK_WIDTH) * TILE_WIDTH_HEIGHT; + uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT + (i / CHUNK_WIDTH) * TILE_WIDTH_HEIGHT; + uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT; + uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT; DrawTextureRec( RENDER_TILEMAP_TEXTURE, (Rectangle){ tilemapX, tilemapY, - TILE_WIDTH, - TILE_HEIGHT + TILE_WIDTH_HEIGHT, + TILE_WIDTH_HEIGHT }, (Vector2){ x, y }, WHITE @@ -79,18 +79,18 @@ void drawOverworldDraw(void) { if(tile == 0) continue; // Skip empty tiles uint32_t tilemapIndex = tile - 1; // Convert to zero-based index - uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH + (i % CHUNK_WIDTH) * TILE_WIDTH; - uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_HEIGHT + (i / CHUNK_WIDTH) * TILE_HEIGHT; - uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_WIDTH; - uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH)) * TILE_HEIGHT; + uint32_t x = (uint32_t)chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT + (i % CHUNK_WIDTH) * TILE_WIDTH_HEIGHT; + uint32_t y = (uint32_t)chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT + (i / CHUNK_WIDTH) * TILE_WIDTH_HEIGHT; + uint32_t tilemapX = (tilemapIndex % (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT; + uint32_t tilemapY = (tilemapIndex / (RENDER_TILEMAP_TEXTURE.width / TILE_WIDTH_HEIGHT)) * TILE_WIDTH_HEIGHT; DrawTextureRec( RENDER_TILEMAP_TEXTURE, (Rectangle){ tilemapX, tilemapY, - TILE_WIDTH, - TILE_HEIGHT + TILE_WIDTH_HEIGHT, + TILE_WIDTH_HEIGHT }, (Vector2){ x, y }, WHITE @@ -123,10 +123,10 @@ void drawOverworldDrawEntity(const entity_t *entity) { DrawTextureRec( RENDER_ENTITIES_TEXTURE, (Rectangle){ - col * TILE_WIDTH, - row * TILE_HEIGHT, - TILE_WIDTH, - TILE_HEIGHT + col * TILE_WIDTH_HEIGHT, + row * TILE_WIDTH_HEIGHT, + TILE_WIDTH_HEIGHT, + TILE_WIDTH_HEIGHT }, (Vector2){ x, y }, WHITE diff --git a/tools/mapcompile/mapcompile.py b/tools/mapcompile/mapcompile.py index b0463de..37102b1 100644 --- a/tools/mapcompile/mapcompile.py +++ b/tools/mapcompile/mapcompile.py @@ -9,8 +9,8 @@ CHUNK_WIDTH = 8 CHUNK_HEIGHT = 8 CHUNK_TILE_COUNT = CHUNK_WIDTH * CHUNK_HEIGHT CHUNK_ENTITY_COUNT_MAX = 8 -TILE_WIDTH = 16 -TILE_HEIGHT = 16 +TILE_WIDTH_HEIGHT = 16 +TILE_WIDTH_HEIGHT = 16 ENTITY_TYPE_MAP = { "npc": "ENTITY_TYPE_NPC", @@ -194,11 +194,11 @@ for obIndex, ob in enumerate(objectLayer['objects']): print(f"Error: Object in object layer does not contain 'x' or 'y' key.") sys.exit(1) - ob['x'] -= inputMapLowestX * TILE_WIDTH - ob['y'] -= inputMapLowestY * TILE_HEIGHT + ob['x'] -= inputMapLowestX * TILE_WIDTH_HEIGHT + ob['y'] -= inputMapLowestY * TILE_WIDTH_HEIGHT # Objects are bottom aligned in tiled, so we need to adjust the Y coordinate. - ob['y'] -= TILE_HEIGHT + ob['y'] -= TILE_WIDTH_HEIGHT # Round off the coordinates ob['x'] = round(ob['x']) @@ -281,13 +281,13 @@ for chunkY in range(mapHeightInRealChunks): sys.exit(1) # Is this object within the chunk? - if ob['x'] < topLeftTileX * TILE_WIDTH: + if ob['x'] < topLeftTileX * TILE_WIDTH_HEIGHT: continue - if ob['x'] >= (topLeftTileX + CHUNK_WIDTH) * TILE_WIDTH: + if ob['x'] >= (topLeftTileX + CHUNK_WIDTH) * TILE_WIDTH_HEIGHT: continue - if ob['y'] < topLeftTileY * TILE_HEIGHT: + if ob['y'] < topLeftTileY * TILE_WIDTH_HEIGHT: continue - if ob['y'] >= (topLeftTileY + CHUNK_HEIGHT) * TILE_HEIGHT: + if ob['y'] >= (topLeftTileY + CHUNK_HEIGHT) * TILE_WIDTH_HEIGHT: continue entities.append(ob) @@ -372,8 +372,8 @@ for chunkY in range(mapHeightInRealChunks): f.write(f" .entities = {{\n") for entity in entities: # Entities are center aligned in tiled. - localX = round(entity['x'] - (topLeftTileX * TILE_WIDTH)) - localY = round(entity['y'] - (topLeftTileY * TILE_HEIGHT)) + localX = round(entity['x'] - (topLeftTileX * TILE_WIDTH_HEIGHT)) + localY = round(entity['y'] - (topLeftTileY * TILE_WIDTH_HEIGHT)) if 'type' in entity and entity['type'] not in ENTITY_TYPE_MAP: continue