From af5bf987c8464e2e427e2914f06a9709b08bbc6f Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 6 Jan 2026 07:47:16 -0600 Subject: [PATCH] Add inventory. --- CMakeLists.txt | 4 +- {src/asset/type => archive}/assetchunk.c | 0 {src/asset/type => archive}/assetchunk.h | 2 +- {src/asset/type => archive}/assetmap.c | 0 {src/asset/type => archive}/assetmap.h | 2 +- {src/script/module => archive}/modulemap.h | 2 +- {src => archive}/rpg/CMakeLists.txt | 2 +- {src => archive}/rpg/cutscene/CMakeLists.txt | 0 {src => archive}/rpg/cutscene/cutscene.h | 0 {src => archive}/rpg/cutscene/cutscenemode.c | 0 {src => archive}/rpg/cutscene/cutscenemode.h | 0 .../rpg/cutscene/cutscenesystem.c | 0 .../rpg/cutscene/cutscenesystem.h | 0 .../rpg/cutscene/item/CMakeLists.txt | 0 .../rpg/cutscene/item/cutscenecallback.h | 0 .../rpg/cutscene/item/cutsceneitem.c | 0 .../rpg/cutscene/item/cutsceneitem.h | 0 .../rpg/cutscene/item/cutscenetext.h | 0 .../rpg/cutscene/item/cutscenewait.h | 0 .../rpg/cutscene/scene/testcutscene.h | 0 {src => archive}/rpg/entity/CMakeLists.txt | 0 {src => archive}/rpg/entity/entity.c | 2 +- {src => archive}/rpg/entity/entity.h | 0 {src => archive}/rpg/entity/entityanim.c | 0 {src => archive}/rpg/entity/entityanim.h | 0 {src => archive}/rpg/entity/entitydir.c | 0 {src => archive}/rpg/entity/entitydir.h | 2 +- {src => archive}/rpg/entity/entitytype.h | 0 {src => archive}/rpg/entity/npc.c | 0 {src => archive}/rpg/entity/npc.h | 0 {src => archive}/rpg/entity/player.c | 0 {src => archive}/rpg/entity/player.h | 0 {src => archive}/rpg/item/inventory.h | 0 .../rpg/overworld}/CMakeLists.txt | 0 .../world => archive/rpg/overworld}/chunk.c | 0 .../world => archive/rpg/overworld}/chunk.h | 2 +- .../rpg/world => archive/rpg/overworld}/map.c | 0 .../rpg/world => archive/rpg/overworld}/map.h | 2 +- .../world => archive/rpg/overworld}/tile.c | 0 .../world => archive/rpg/overworld}/tile.h | 0 .../rpg/overworld}/worldpos.c | 0 .../rpg/overworld}/worldpos.h | 0 {src => archive}/rpg/rpg.c | 2 +- {src => archive}/rpg/rpg.h | 0 {src => archive}/rpg/rpgcamera.c | 2 +- {src => archive}/rpg/rpgcamera.h | 2 +- {src => archive}/rpg/rpgtextbox.c | 0 {src => archive}/rpg/rpgtextbox.h | 0 archive/scene/CMakeLists.txt | 13 + archive/scene/scene.h | 24 ++ {src => archive}/scene/scene/CMakeLists.txt | 0 {src => archive}/scene/scene/scenemap.c | 2 +- {src => archive}/scene/scene/scenemap.h | 0 {src => archive}/scene/scene/scenetest.c | 0 {src => archive}/scene/scene/scenetest.h | 0 {src => archive}/scene/scenedata.h | 9 +- {src => archive}/scene/scenemanager.c | 0 {src => archive}/scene/scenemanager.h | 1 - .../module => archive}/scriptfuncentity.h | 0 assets/init.lua | 3 +- src/CMakeLists.txt | 3 +- src/asset/assettype.h | 17 - src/asset/type/CMakeLists.txt | 2 - src/display/color.h | 2 +- src/display/display.c | 6 +- src/engine/engine.c | 16 +- src/item/CMakeLists.txt | 11 + src/item/inventory.c | 165 +++++++++ src/item/inventory.h | 103 ++++++ src/item/item.c | 19 + src/item/item.h | 21 ++ src/item/itemtype.h | 19 + src/scene/CMakeLists.txt | 7 +- src/scene/scene.c | 84 +++++ src/scene/scene.h | 65 +++- src/script/module/modulescene.h | 6 +- src/script/scriptmodule.c | 2 - src/time/time.c | 4 +- src/time/time.h | 1 + src/ui/ui.c | 6 +- src/ui/uidebug.c | 54 +-- src/ui/uitextbox.c | 50 +-- test/CMakeLists.txt | 3 + test/display/CMakeLists.txt | 9 + test/display/test_color.c | 98 +++++ test/item/CMakeLists.txt | 9 + test/item/test_inventory.c | 341 ++++++++++++++++++ test/rpg/CMakeLists.txt | 12 + test/rpg/overworld/CMakeLists.txt | 10 + test/rpg/test_rpg.c | 16 + test/time/test_time.c | 8 +- 91 files changed, 1108 insertions(+), 139 deletions(-) rename {src/asset/type => archive}/assetchunk.c (100%) rename {src/asset/type => archive}/assetchunk.h (92%) rename {src/asset/type => archive}/assetmap.c (100%) rename {src/asset/type => archive}/assetmap.h (94%) rename {src/script/module => archive}/modulemap.h (97%) rename {src => archive}/rpg/CMakeLists.txt (91%) rename {src => archive}/rpg/cutscene/CMakeLists.txt (100%) rename {src => archive}/rpg/cutscene/cutscene.h (100%) rename {src => archive}/rpg/cutscene/cutscenemode.c (100%) rename {src => archive}/rpg/cutscene/cutscenemode.h (100%) rename {src => archive}/rpg/cutscene/cutscenesystem.c (100%) rename {src => archive}/rpg/cutscene/cutscenesystem.h (100%) rename {src => archive}/rpg/cutscene/item/CMakeLists.txt (100%) rename {src => archive}/rpg/cutscene/item/cutscenecallback.h (100%) rename {src => archive}/rpg/cutscene/item/cutsceneitem.c (100%) rename {src => archive}/rpg/cutscene/item/cutsceneitem.h (100%) rename {src => archive}/rpg/cutscene/item/cutscenetext.h (100%) rename {src => archive}/rpg/cutscene/item/cutscenewait.h (100%) rename {src => archive}/rpg/cutscene/scene/testcutscene.h (100%) rename {src => archive}/rpg/entity/CMakeLists.txt (100%) rename {src => archive}/rpg/entity/entity.c (99%) rename {src => archive}/rpg/entity/entity.h (100%) rename {src => archive}/rpg/entity/entityanim.c (100%) rename {src => archive}/rpg/entity/entityanim.h (100%) rename {src => archive}/rpg/entity/entitydir.c (100%) rename {src => archive}/rpg/entity/entitydir.h (97%) rename {src => archive}/rpg/entity/entitytype.h (100%) rename {src => archive}/rpg/entity/npc.c (100%) rename {src => archive}/rpg/entity/npc.h (100%) rename {src => archive}/rpg/entity/player.c (100%) rename {src => archive}/rpg/entity/player.h (100%) rename {src => archive}/rpg/item/inventory.h (100%) rename {src/rpg/world => archive/rpg/overworld}/CMakeLists.txt (100%) rename {src/rpg/world => archive/rpg/overworld}/chunk.c (100%) rename {src/rpg/world => archive/rpg/overworld}/chunk.h (96%) rename {src/rpg/world => archive/rpg/overworld}/map.c (100%) rename {src/rpg/world => archive/rpg/overworld}/map.h (98%) rename {src/rpg/world => archive/rpg/overworld}/tile.c (100%) rename {src/rpg/world => archive/rpg/overworld}/tile.h (100%) rename {src/rpg/world => archive/rpg/overworld}/worldpos.c (100%) rename {src/rpg/world => archive/rpg/overworld}/worldpos.h (100%) rename {src => archive}/rpg/rpg.c (97%) rename {src => archive}/rpg/rpg.h (100%) rename {src => archive}/rpg/rpgcamera.c (97%) rename {src => archive}/rpg/rpgcamera.h (94%) rename {src => archive}/rpg/rpgtextbox.c (100%) rename {src => archive}/rpg/rpgtextbox.h (100%) create mode 100644 archive/scene/CMakeLists.txt create mode 100644 archive/scene/scene.h rename {src => archive}/scene/scene/CMakeLists.txt (100%) rename {src => archive}/scene/scene/scenemap.c (99%) rename {src => archive}/scene/scene/scenemap.h (100%) rename {src => archive}/scene/scene/scenetest.c (100%) rename {src => archive}/scene/scene/scenetest.h (100%) rename {src => archive}/scene/scenedata.h (59%) rename {src => archive}/scene/scenemanager.c (100%) rename {src => archive}/scene/scenemanager.h (98%) rename {src/script/module => archive}/scriptfuncentity.h (100%) create mode 100644 src/item/CMakeLists.txt create mode 100644 src/item/inventory.c create mode 100644 src/item/inventory.h create mode 100644 src/item/item.c create mode 100644 src/item/item.h create mode 100644 src/item/itemtype.h create mode 100644 src/scene/scene.c create mode 100644 test/display/CMakeLists.txt create mode 100644 test/display/test_color.c create mode 100644 test/item/CMakeLists.txt create mode 100644 test/item/test_inventory.c create mode 100644 test/rpg/CMakeLists.txt create mode 100644 test/rpg/overworld/CMakeLists.txt create mode 100644 test/rpg/test_rpg.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 61945a0..2e026e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,8 @@ option(ENABLE_TESTS "Enable tests" ON) # Set target system if(NOT DEFINED DUSK_TARGET_SYSTEM) - # set(DUSK_TARGET_SYSTEM "linux") - set(DUSK_TARGET_SYSTEM "psp") + set(DUSK_TARGET_SYSTEM "linux") + # set(DUSK_TARGET_SYSTEM "psp") endif() # Prep cache diff --git a/src/asset/type/assetchunk.c b/archive/assetchunk.c similarity index 100% rename from src/asset/type/assetchunk.c rename to archive/assetchunk.c diff --git a/src/asset/type/assetchunk.h b/archive/assetchunk.h similarity index 92% rename from src/asset/type/assetchunk.h rename to archive/assetchunk.h index 98c94ee..a474bda 100644 --- a/src/asset/type/assetchunk.h +++ b/archive/assetchunk.h @@ -7,7 +7,7 @@ #pragma once #include "error/error.h" -#include "rpg/world/chunk.h" +#include "rpg/overworld/chunk.h" typedef struct assetcustom_s assetcustom_t; diff --git a/src/asset/type/assetmap.c b/archive/assetmap.c similarity index 100% rename from src/asset/type/assetmap.c rename to archive/assetmap.c diff --git a/src/asset/type/assetmap.h b/archive/assetmap.h similarity index 94% rename from src/asset/type/assetmap.h rename to archive/assetmap.h index 7411ce3..f3a6262 100644 --- a/src/asset/type/assetmap.h +++ b/archive/assetmap.h @@ -7,7 +7,7 @@ #pragma once #include "error/error.h" -#include "rpg/world/map.h" +#include "rpg/overworld/map.h" #include "display/mesh/mesh.h" /** diff --git a/src/script/module/modulemap.h b/archive/modulemap.h similarity index 97% rename from src/script/module/modulemap.h rename to archive/modulemap.h index 928ab33..5b70729 100644 --- a/src/script/module/modulemap.h +++ b/archive/modulemap.h @@ -9,7 +9,7 @@ #include "script/scriptcontext.h" #include "debug/debug.h" #include "assert/assert.h" -#include "rpg/world/map.h" +#include "rpg/overworld/map.h" int moduleMapLoad(lua_State *L) { assertNotNull(L, "Lua state cannot be NULL"); diff --git a/src/rpg/CMakeLists.txt b/archive/rpg/CMakeLists.txt similarity index 91% rename from src/rpg/CMakeLists.txt rename to archive/rpg/CMakeLists.txt index 515af3b..cb964fd 100644 --- a/src/rpg/CMakeLists.txt +++ b/archive/rpg/CMakeLists.txt @@ -14,4 +14,4 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} # Subdirs add_subdirectory(cutscene) add_subdirectory(entity) -add_subdirectory(world) \ No newline at end of file +add_subdirectory(overworld) \ No newline at end of file diff --git a/src/rpg/cutscene/CMakeLists.txt b/archive/rpg/cutscene/CMakeLists.txt similarity index 100% rename from src/rpg/cutscene/CMakeLists.txt rename to archive/rpg/cutscene/CMakeLists.txt diff --git a/src/rpg/cutscene/cutscene.h b/archive/rpg/cutscene/cutscene.h similarity index 100% rename from src/rpg/cutscene/cutscene.h rename to archive/rpg/cutscene/cutscene.h diff --git a/src/rpg/cutscene/cutscenemode.c b/archive/rpg/cutscene/cutscenemode.c similarity index 100% rename from src/rpg/cutscene/cutscenemode.c rename to archive/rpg/cutscene/cutscenemode.c diff --git a/src/rpg/cutscene/cutscenemode.h b/archive/rpg/cutscene/cutscenemode.h similarity index 100% rename from src/rpg/cutscene/cutscenemode.h rename to archive/rpg/cutscene/cutscenemode.h diff --git a/src/rpg/cutscene/cutscenesystem.c b/archive/rpg/cutscene/cutscenesystem.c similarity index 100% rename from src/rpg/cutscene/cutscenesystem.c rename to archive/rpg/cutscene/cutscenesystem.c diff --git a/src/rpg/cutscene/cutscenesystem.h b/archive/rpg/cutscene/cutscenesystem.h similarity index 100% rename from src/rpg/cutscene/cutscenesystem.h rename to archive/rpg/cutscene/cutscenesystem.h diff --git a/src/rpg/cutscene/item/CMakeLists.txt b/archive/rpg/cutscene/item/CMakeLists.txt similarity index 100% rename from src/rpg/cutscene/item/CMakeLists.txt rename to archive/rpg/cutscene/item/CMakeLists.txt diff --git a/src/rpg/cutscene/item/cutscenecallback.h b/archive/rpg/cutscene/item/cutscenecallback.h similarity index 100% rename from src/rpg/cutscene/item/cutscenecallback.h rename to archive/rpg/cutscene/item/cutscenecallback.h diff --git a/src/rpg/cutscene/item/cutsceneitem.c b/archive/rpg/cutscene/item/cutsceneitem.c similarity index 100% rename from src/rpg/cutscene/item/cutsceneitem.c rename to archive/rpg/cutscene/item/cutsceneitem.c diff --git a/src/rpg/cutscene/item/cutsceneitem.h b/archive/rpg/cutscene/item/cutsceneitem.h similarity index 100% rename from src/rpg/cutscene/item/cutsceneitem.h rename to archive/rpg/cutscene/item/cutsceneitem.h diff --git a/src/rpg/cutscene/item/cutscenetext.h b/archive/rpg/cutscene/item/cutscenetext.h similarity index 100% rename from src/rpg/cutscene/item/cutscenetext.h rename to archive/rpg/cutscene/item/cutscenetext.h diff --git a/src/rpg/cutscene/item/cutscenewait.h b/archive/rpg/cutscene/item/cutscenewait.h similarity index 100% rename from src/rpg/cutscene/item/cutscenewait.h rename to archive/rpg/cutscene/item/cutscenewait.h diff --git a/src/rpg/cutscene/scene/testcutscene.h b/archive/rpg/cutscene/scene/testcutscene.h similarity index 100% rename from src/rpg/cutscene/scene/testcutscene.h rename to archive/rpg/cutscene/scene/testcutscene.h diff --git a/src/rpg/entity/CMakeLists.txt b/archive/rpg/entity/CMakeLists.txt similarity index 100% rename from src/rpg/entity/CMakeLists.txt rename to archive/rpg/entity/CMakeLists.txt diff --git a/src/rpg/entity/entity.c b/archive/rpg/entity/entity.c similarity index 99% rename from src/rpg/entity/entity.c rename to archive/rpg/entity/entity.c index 6bda94e..194c413 100644 --- a/src/rpg/entity/entity.c +++ b/archive/rpg/entity/entity.c @@ -11,7 +11,7 @@ #include "time/time.h" #include "util/math.h" #include "rpg/cutscene/cutscenemode.h" -#include "rpg/world/map.h" +#include "rpg/overworld/map.h" entity_t ENTITIES[ENTITY_COUNT]; diff --git a/src/rpg/entity/entity.h b/archive/rpg/entity/entity.h similarity index 100% rename from src/rpg/entity/entity.h rename to archive/rpg/entity/entity.h diff --git a/src/rpg/entity/entityanim.c b/archive/rpg/entity/entityanim.c similarity index 100% rename from src/rpg/entity/entityanim.c rename to archive/rpg/entity/entityanim.c diff --git a/src/rpg/entity/entityanim.h b/archive/rpg/entity/entityanim.h similarity index 100% rename from src/rpg/entity/entityanim.h rename to archive/rpg/entity/entityanim.h diff --git a/src/rpg/entity/entitydir.c b/archive/rpg/entity/entitydir.c similarity index 100% rename from src/rpg/entity/entitydir.c rename to archive/rpg/entity/entitydir.c diff --git a/src/rpg/entity/entitydir.h b/archive/rpg/entity/entitydir.h similarity index 97% rename from src/rpg/entity/entitydir.h rename to archive/rpg/entity/entitydir.h index 3b34b6e..b132efb 100644 --- a/src/rpg/entity/entitydir.h +++ b/archive/rpg/entity/entitydir.h @@ -6,7 +6,7 @@ */ #pragma once -#include "rpg/world/worldpos.h" +#include "rpg/overworld/worldpos.h" typedef enum { ENTITY_DIR_UP = ENTITY_DIR_NORTH, diff --git a/src/rpg/entity/entitytype.h b/archive/rpg/entity/entitytype.h similarity index 100% rename from src/rpg/entity/entitytype.h rename to archive/rpg/entity/entitytype.h diff --git a/src/rpg/entity/npc.c b/archive/rpg/entity/npc.c similarity index 100% rename from src/rpg/entity/npc.c rename to archive/rpg/entity/npc.c diff --git a/src/rpg/entity/npc.h b/archive/rpg/entity/npc.h similarity index 100% rename from src/rpg/entity/npc.h rename to archive/rpg/entity/npc.h diff --git a/src/rpg/entity/player.c b/archive/rpg/entity/player.c similarity index 100% rename from src/rpg/entity/player.c rename to archive/rpg/entity/player.c diff --git a/src/rpg/entity/player.h b/archive/rpg/entity/player.h similarity index 100% rename from src/rpg/entity/player.h rename to archive/rpg/entity/player.h diff --git a/src/rpg/item/inventory.h b/archive/rpg/item/inventory.h similarity index 100% rename from src/rpg/item/inventory.h rename to archive/rpg/item/inventory.h diff --git a/src/rpg/world/CMakeLists.txt b/archive/rpg/overworld/CMakeLists.txt similarity index 100% rename from src/rpg/world/CMakeLists.txt rename to archive/rpg/overworld/CMakeLists.txt diff --git a/src/rpg/world/chunk.c b/archive/rpg/overworld/chunk.c similarity index 100% rename from src/rpg/world/chunk.c rename to archive/rpg/overworld/chunk.c diff --git a/src/rpg/world/chunk.h b/archive/rpg/overworld/chunk.h similarity index 96% rename from src/rpg/world/chunk.h rename to archive/rpg/overworld/chunk.h index 7f1079b..508b15f 100644 --- a/src/rpg/world/chunk.h +++ b/archive/rpg/overworld/chunk.h @@ -6,7 +6,7 @@ */ #pragma once -#include "rpg/world/tile.h" +#include "rpg/overworld/tile.h" #include "worldpos.h" #include "display/mesh/quad.h" diff --git a/src/rpg/world/map.c b/archive/rpg/overworld/map.c similarity index 100% rename from src/rpg/world/map.c rename to archive/rpg/overworld/map.c diff --git a/src/rpg/world/map.h b/archive/rpg/overworld/map.h similarity index 98% rename from src/rpg/world/map.h rename to archive/rpg/overworld/map.h index 29137da..8373fca 100644 --- a/src/rpg/world/map.h +++ b/archive/rpg/overworld/map.h @@ -6,7 +6,7 @@ */ #pragma once -#include "rpg/world/chunk.h" +#include "rpg/overworld/chunk.h" #define MAP_FILE_PATH_MAX 128 diff --git a/src/rpg/world/tile.c b/archive/rpg/overworld/tile.c similarity index 100% rename from src/rpg/world/tile.c rename to archive/rpg/overworld/tile.c diff --git a/src/rpg/world/tile.h b/archive/rpg/overworld/tile.h similarity index 100% rename from src/rpg/world/tile.h rename to archive/rpg/overworld/tile.h diff --git a/src/rpg/world/worldpos.c b/archive/rpg/overworld/worldpos.c similarity index 100% rename from src/rpg/world/worldpos.c rename to archive/rpg/overworld/worldpos.c diff --git a/src/rpg/world/worldpos.h b/archive/rpg/overworld/worldpos.h similarity index 100% rename from src/rpg/world/worldpos.h rename to archive/rpg/overworld/worldpos.h diff --git a/src/rpg/rpg.c b/archive/rpg/rpg.c similarity index 97% rename from src/rpg/rpg.c rename to archive/rpg/rpg.c index e97368d..ead5c87 100644 --- a/src/rpg/rpg.c +++ b/archive/rpg/rpg.c @@ -7,7 +7,7 @@ #include "rpg.h" #include "entity/entity.h" -#include "rpg/world/map.h" +#include "rpg/overworld/map.h" #include "rpg/cutscene/cutscenesystem.h" #include "time/time.h" #include "rpgcamera.h" diff --git a/src/rpg/rpg.h b/archive/rpg/rpg.h similarity index 100% rename from src/rpg/rpg.h rename to archive/rpg/rpg.h diff --git a/src/rpg/rpgcamera.c b/archive/rpg/rpgcamera.c similarity index 97% rename from src/rpg/rpgcamera.c rename to archive/rpg/rpgcamera.c index 0955506..b32c017 100644 --- a/src/rpg/rpgcamera.c +++ b/archive/rpg/rpgcamera.c @@ -8,7 +8,7 @@ #include "rpgcamera.h" #include "util/memory.h" #include "rpg/entity/entity.h" -#include "rpg/world/map.h" +#include "rpg/overworld/map.h" #include "assert/assert.h" rpgcamera_t RPG_CAMERA; diff --git a/src/rpg/rpgcamera.h b/archive/rpg/rpgcamera.h similarity index 94% rename from src/rpg/rpgcamera.h rename to archive/rpg/rpgcamera.h index 07cf991..920a9a2 100644 --- a/src/rpg/rpgcamera.h +++ b/archive/rpg/rpgcamera.h @@ -6,7 +6,7 @@ */ #pragma once -#include "rpg/world/worldpos.h" +#include "rpg/overworld/worldpos.h" #include "error/error.h" typedef enum { diff --git a/src/rpg/rpgtextbox.c b/archive/rpg/rpgtextbox.c similarity index 100% rename from src/rpg/rpgtextbox.c rename to archive/rpg/rpgtextbox.c diff --git a/src/rpg/rpgtextbox.h b/archive/rpg/rpgtextbox.h similarity index 100% rename from src/rpg/rpgtextbox.h rename to archive/rpg/rpgtextbox.h diff --git a/archive/scene/CMakeLists.txt b/archive/scene/CMakeLists.txt new file mode 100644 index 0000000..94aaa08 --- /dev/null +++ b/archive/scene/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DUSK_LIBRARY_TARGET_NAME} + PUBLIC + scenemanager.c +) + +# Subdirs +add_subdirectory(scene) \ No newline at end of file diff --git a/archive/scene/scene.h b/archive/scene/scene.h new file mode 100644 index 0000000..39c89a4 --- /dev/null +++ b/archive/scene/scene.h @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" +#include "error/error.h" +#include "display/color.h" + +#define SCENE_FLAG_INITIALIZED (1 << 0) + +typedef struct scenedata_s scenedata_t; + +typedef struct { + const char_t *name; + errorret_t (*init)(scenedata_t *data); + void (*update)(scenedata_t *data); + void (*render)(scenedata_t *data); + void (*dispose)(scenedata_t *data); + uint8_t flags; +} scene_t; \ No newline at end of file diff --git a/src/scene/scene/CMakeLists.txt b/archive/scene/scene/CMakeLists.txt similarity index 100% rename from src/scene/scene/CMakeLists.txt rename to archive/scene/scene/CMakeLists.txt diff --git a/src/scene/scene/scenemap.c b/archive/scene/scene/scenemap.c similarity index 99% rename from src/scene/scene/scenemap.c rename to archive/scene/scene/scenemap.c index e1739a0..7699116 100644 --- a/src/scene/scene/scenemap.c +++ b/archive/scene/scene/scenemap.c @@ -11,7 +11,7 @@ #include "assert/assert.h" #include "asset/asset.h" #include "rpg/entity/entity.h" -#include "rpg/world/map.h" +#include "rpg/overworld/map.h" #include "display/screen.h" #include "rpg/rpgcamera.h" #include "util/memory.h" diff --git a/src/scene/scene/scenemap.h b/archive/scene/scene/scenemap.h similarity index 100% rename from src/scene/scene/scenemap.h rename to archive/scene/scene/scenemap.h diff --git a/src/scene/scene/scenetest.c b/archive/scene/scene/scenetest.c similarity index 100% rename from src/scene/scene/scenetest.c rename to archive/scene/scene/scenetest.c diff --git a/src/scene/scene/scenetest.h b/archive/scene/scene/scenetest.h similarity index 100% rename from src/scene/scene/scenetest.h rename to archive/scene/scene/scenetest.h diff --git a/src/scene/scenedata.h b/archive/scene/scenedata.h similarity index 59% rename from src/scene/scenedata.h rename to archive/scene/scenedata.h index 4122c42..948bed6 100644 --- a/src/scene/scenedata.h +++ b/archive/scene/scenedata.h @@ -9,11 +9,4 @@ #include "scene/scene.h" #include "scene/scene/scenetest.h" -#include "scene/scene/scenemap.h" - -typedef struct scenedata_s { - union { - scenetest_t sceneTest; - scenemap_t sceneMap; - }; -} scenedata_t; +#include "scene/scene/scenemap.h" \ No newline at end of file diff --git a/src/scene/scenemanager.c b/archive/scene/scenemanager.c similarity index 100% rename from src/scene/scenemanager.c rename to archive/scene/scenemanager.c diff --git a/src/scene/scenemanager.h b/archive/scene/scenemanager.h similarity index 98% rename from src/scene/scenemanager.h rename to archive/scene/scenemanager.h index 9919144..d31a96f 100644 --- a/src/scene/scenemanager.h +++ b/archive/scene/scenemanager.h @@ -15,7 +15,6 @@ typedef struct { scene_t *current; scene_t *scenes[SCENE_MANAGER_SCENE_COUNT_MAX]; uint8_t sceneCount; - scenedata_t sceneData; } scenemanager_t; extern scenemanager_t SCENE_MANAGER; diff --git a/src/script/module/scriptfuncentity.h b/archive/scriptfuncentity.h similarity index 100% rename from src/script/module/scriptfuncentity.h rename to archive/scriptfuncentity.h diff --git a/assets/init.lua b/assets/init.lua index 049cafc..38c7b72 100644 --- a/assets/init.lua +++ b/assets/init.lua @@ -1,7 +1,6 @@ module('platform') module('input') module('scene') -module('map') -- Default Input bindings. if PLATFORM == "psp" then @@ -39,4 +38,4 @@ else end sceneSet('map') -mapLoad('map/testmap/testmap.dmf') \ No newline at end of file +-- mapLoad('map/testmap/testmap.dmf') \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d2d5491..ddf93fa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,8 +56,9 @@ add_subdirectory(display) add_subdirectory(engine) add_subdirectory(error) add_subdirectory(input) +add_subdirectory(item) add_subdirectory(locale) -add_subdirectory(rpg) +# add_subdirectory(rpg) add_subdirectory(scene) add_subdirectory(script) add_subdirectory(thread) diff --git a/src/asset/assettype.h b/src/asset/assettype.h index a419e8a..90b392c 100644 --- a/src/asset/assettype.h +++ b/src/asset/assettype.h @@ -9,8 +9,6 @@ #include "type/assetpaletteimage.h" #include "type/assetalphaimage.h" #include "type/assetlanguage.h" -#include "type/assetmap.h" -#include "type/assetchunk.h" #include "type/assetscript.h" #include @@ -20,8 +18,6 @@ typedef enum { ASSET_TYPE_PALETTE_IMAGE, ASSET_TYPE_ALPHA_IMAGE, ASSET_TYPE_LANGUAGE, - ASSET_TYPE_MAP, - ASSET_TYPE_CHUNK, ASSET_TYPE_SCRIPT, ASSET_TYPE_COUNT, @@ -72,19 +68,6 @@ static const assettypedef_t ASSET_TYPE_DEFINITIONS[ASSET_TYPE_COUNT] = { .custom = assetLanguageHandler }, - [ASSET_TYPE_MAP] = { - .header = "DMF", - .loadStrategy = ASSET_LOAD_STRAT_ENTIRE, - .dataSize = sizeof(1), - .entire = assetMapLoad - }, - - [ASSET_TYPE_CHUNK] = { - .header = "DCF", - .loadStrategy = ASSET_LOAD_STRAT_CUSTOM, - .custom = assetChunkLoad - }, - [ASSET_TYPE_SCRIPT] = { .header = "DSF", .loadStrategy = ASSET_LOAD_STRAT_CUSTOM, diff --git a/src/asset/type/CMakeLists.txt b/src/asset/type/CMakeLists.txt index cb4aafb..1a60a2f 100644 --- a/src/asset/type/CMakeLists.txt +++ b/src/asset/type/CMakeLists.txt @@ -9,7 +9,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} assetalphaimage.c assetpaletteimage.c assetlanguage.c - assetmap.c - assetchunk.c assetscript.c ) \ No newline at end of file diff --git a/src/display/color.h b/src/display/color.h index 4f9daeb..380c182 100644 --- a/src/display/color.h +++ b/src/display/color.h @@ -45,7 +45,7 @@ typedef color4b_t color_t; #define color4b(r, g, b, a) ((color4b_t){r, g, b, a}) #define color(r, g, b, a) ((color_t){r, g, b, a}) -#define color_hex(hex) color( \ +#define colorHex(hex) color( \ ((hex >> 24) & 0xFF), \ ((hex >> 16) & 0xFF), \ ((hex >> 8) & 0xFF), \ diff --git a/src/display/display.c b/src/display/display.c index 26a9cd1..26f2024 100644 --- a/src/display/display.c +++ b/src/display/display.c @@ -8,7 +8,7 @@ #include "display/display.h" #include "engine/engine.h" #include "display/framebuffer.h" -#include "scene/scenemanager.h" +#include "scene/scene.h" #include "display/spritebatch.h" #include "display/mesh/quad.h" #include "display/screen.h" @@ -120,7 +120,9 @@ errorret_t displayUpdate(void) { FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH, COLOR_CORNFLOWER_BLUE ); - sceneManagerRender(); + sceneRender(); + + // Render UI uiRender(); // Finish up diff --git a/src/engine/engine.c b/src/engine/engine.c index 5d4514f..066a1f2 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -11,10 +11,10 @@ #include "input/input.h" #include "locale/localemanager.h" #include "display/display.h" -#include "scene/scenemanager.h" +#include "scene/scene.h" #include "asset/asset.h" #include "ui/ui.h" -#include "rpg/rpg.h" +// #include "rpg/rpg.h" #include "script/scriptmanager.h" #include "debug/debug.h" @@ -35,8 +35,8 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { errorChain(scriptManagerInit()); errorChain(displayInit()); errorChain(uiInit()); - errorChain(rpgInit()); - errorChain(sceneManagerInit()); + // errorChain(rpgInit()); + errorChain(sceneInit()); // Run the initial script. scriptcontext_t ctx; @@ -51,9 +51,9 @@ errorret_t engineUpdate(void) { timeUpdate(); inputUpdate(); - errorChain(rpgUpdate()); + // errorChain(rpgUpdate()); uiUpdate(); - sceneManagerUpdate(); + sceneUpdate(); errorChain(displayUpdate()); if(inputPressed(INPUT_ACTION_RAGEQUIT)) ENGINE.running = false; @@ -67,8 +67,8 @@ void engineExit(void) { errorret_t engineDispose(void) { localeManagerDispose(); - sceneManagerDispose(); - rpgDispose(); + // sceneManagerDispose(); + // rpgDispose(); uiDispose(); errorChain(displayDispose()); assetDispose(); diff --git a/src/item/CMakeLists.txt b/src/item/CMakeLists.txt new file mode 100644 index 0000000..3a44978 --- /dev/null +++ b/src/item/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DUSK_LIBRARY_TARGET_NAME} + PUBLIC + item.c + inventory.c +) \ No newline at end of file diff --git a/src/item/inventory.c b/src/item/inventory.c new file mode 100644 index 0000000..daae2d6 --- /dev/null +++ b/src/item/inventory.c @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "inventory.h" +#include "util/memory.h" +#include "assert/assert.h" + +void inventoryInit( + inventory_t* inventory, + inventorystack_t* storage, + uint8_t storageSize +) { + assertNotNull(inventory, "Inventory pointer is NULL."); + assertNotNull(storage, "Storage pointer is NULL."); + assertTrue(storageSize > 0, "Storage size must be greater than zero."); + + inventory->storage = storage; + inventory->storageSize = storageSize; + + // Zero item ids. + memoryZero(inventory->storage, sizeof(inventorystack_t) * storageSize); +} + +bool_t inventoryItemExists(const inventory_t *inventory, const itemid_t item) { + assertNotNull(inventory, "Inventory pointer is NULL."); + assertNotNull(inventory->storage, "Storage pointer is NULL."); + assertTrue(inventory->storageSize > 0, "Storage too small."); + assertTrue(item != ITEM_ID_NULL, "Item ID cannot be ITEM_ID_NULL."); + + inventorystack_t *stack = inventory->storage; + inventorystack_t *end = stack + inventory->storageSize; + do { + if(stack->item == ITEM_ID_NULL) break; + if(stack->item != item) continue; + assertTrue(stack->quantity > 0, "Item has quantity zero."); + return true; + } while(++stack < end); + + return false; +} + +void inventorySet( + inventory_t *inventory, + const itemid_t item, + const uint8_t quantity +) { + assertNotNull(inventory, "Inventory pointer is NULL."); + assertNotNull(inventory->storage, "Storage pointer is NULL."); + assertTrue(inventory->storageSize > 0, "Storage too small."); + assertTrue(item != ITEM_ID_NULL, "Item ID cannot be ITEM_ID_NULL."); + + // If quantity 0, remove. + if(quantity == 0) return inventoryRemove(inventory, item); + + // Search for existing stack. + inventorystack_t *stack = inventory->storage; + inventorystack_t *end = stack + inventory->storageSize; + do { + // Not in inventory yet, add as new stack. + if(stack->item == ITEM_ID_NULL) { + stack->item = item; + stack->quantity = quantity; + return; + } + + // Not the stack we're looking for. + if(stack->item != item) continue; + + // Update existing stack. + stack->quantity = quantity; + return; + } while(++stack < end); + + // No space in the inventory. + assertUnreachable("Inventory is full, cannot set more items."); +} + +void inventoryAdd( + inventory_t *inventory, + const itemid_t item, + const uint8_t quantity +) { + uint8_t current = inventoryGetCount(inventory, item); + uint16_t newQuantity = (uint16_t)current + (uint16_t)quantity; + + assertTrue( + newQuantity <= UINT8_MAX, + "Cannot add item, would overflow maximum quantity." + ); + + inventorySet(inventory, item, (uint8_t)newQuantity); +} + +void inventoryRemove(inventory_t *inventory, const itemid_t item) { + assertNotNull(inventory, "Inventory pointer is NULL."); + assertNotNull(inventory->storage, "Storage pointer is NULL."); + assertTrue(inventory->storageSize > 0, "Storage too small."); + assertTrue(item != ITEM_ID_NULL, "Item ID cannot be ITEM_ID_NULL."); + + inventorystack_t *stack = inventory->storage; + inventorystack_t *end = stack + inventory->storageSize; + + // Search for existing stack. + do { + // End of inventory, item not present. + if(stack->item == ITEM_ID_NULL) break; + + // Not matching stack. + if(stack->item != item) continue; + + // Match found, shift everything else down + memoryMove(stack, stack + 1, end - (stack + 1)); + + // Clear last stack. + inventorystack_t *last = end - 1; + last->item = ITEM_ID_NULL; + + break; + } while(++stack < end); +} + +uint8_t inventoryGetCount(const inventory_t *inventory, const itemid_t item) { + assertNotNull(inventory, "Inventory pointer is NULL."); + assertNotNull(inventory->storage, "Storage pointer is NULL."); + assertTrue(inventory->storageSize > 0, "Storage too small."); + assertTrue(item != ITEM_ID_NULL, "Item ID cannot be ITEM_ID_NULL."); + + inventorystack_t *stack = inventory->storage; + inventorystack_t *end = stack + inventory->storageSize; + do { + // End of inventory, item not present. + if(stack->item == ITEM_ID_NULL) break; + + // Not matching stack. + if(stack->item != item) continue; + + // Match found, return quantity. + return stack->quantity; + } while(++stack < end); + + return 0; +} + +bool_t inventoryIsFull(const inventory_t *inventory) { + assertNotNull(inventory, "Inventory pointer is NULL."); + assertNotNull(inventory->storage, "Storage pointer is NULL."); + assertTrue(inventory->storageSize > 0, "Storage too small."); + + inventorystack_t *stack = inventory->storage; + inventorystack_t *end = stack + inventory->storageSize; + do { + // Found empty stack, not full. + if(stack->item == ITEM_ID_NULL) return false; + } while(++stack < end); + + return true; +} + +bool_t inventoryItemFull(const inventory_t *inventory, const itemid_t item) { + return inventoryGetCount(inventory, item) == ITEM_STACK_QUANTITY_MAX; +} \ No newline at end of file diff --git a/src/item/inventory.h b/src/item/inventory.h new file mode 100644 index 0000000..bd939f9 --- /dev/null +++ b/src/item/inventory.h @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "item.h" + +#define ITEM_STACK_QUANTITY_MAX UINT8_MAX + +typedef struct { + itemid_t item; + uint8_t quantity; +} inventorystack_t; + +typedef struct { + inventorystack_t *storage; + uint8_t storageSize; +} inventory_t; + +/** + * Initializes an inventory. + * + * @param inventory The inventory to initialize. + * @param storage The storage array for the inventory. + * @param storageSize The size of the storage array. + */ +void inventoryInit( + inventory_t* inventory, + inventorystack_t* storage, + uint8_t storageSize +); + +/** + * Checks if a specific item exists in the inventory (and has quantity > 0). + * + * @param inventory The inventory to check. + * @param item The item ID to check. + * @return true if the item exists, false otherwise. + */ +bool_t inventoryItemExists(const inventory_t *inventory, const itemid_t item); + +/** + * Sets the quantity of a specific item in the inventory. + * + * @param inventory The inventory to modify. + * @param item The item ID to set. + * @param quantity The quantity to set. + */ +void inventorySet( + inventory_t *inventory, + const itemid_t item, + const uint8_t quantity +); + +/** + * Adds a specific quantity of an item to the inventory. + * + * @param inventory The inventory to modify. + * @param item The item ID to add. + * @param quantity The quantity to add. + */ +void inventoryAdd( + inventory_t *inventory, + const itemid_t item, + const uint8_t quantity +); + +/** + * Removes an item from the inventory. + * + * @param inventory The inventory to modify. + * @param item The item ID to remove. + */ +void inventoryRemove(inventory_t *inventory, const itemid_t item); + +/** + * Gets the count of a specific item in the inventory. + * + * @param inventory The inventory to check. + * @param item The item ID to check. + * @return The count of the item in the inventory. + */ +uint8_t inventoryGetCount(const inventory_t *inventory, const itemid_t item); + +/** + * Checks if the inventory is full. + * + * @param inventory The inventory to check. + * @return true if full, false otherwise. + */ +bool_t inventoryIsFull(const inventory_t *inventory); + +/** + * Checks if a specific item stack is full in the inventory. + * + * @param inventory The inventory to check. + * @param item The item ID to check. + * @return true if the item stack is full, false otherwise. + */ +bool_t inventoryItemFull(const inventory_t *inventory, const itemid_t item); \ No newline at end of file diff --git a/src/item/item.c b/src/item/item.c new file mode 100644 index 0000000..2a06839 --- /dev/null +++ b/src/item/item.c @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "item.h" + +const item_t ITEMS[] = { + [ITEM_ID_NULL] = { + .type = ITEM_TYPE_NULL + }, + + // Potion + [ITEM_ID_POTION] = { + .type = ITEM_TYPE_MEDICINE + }, +}; \ No newline at end of file diff --git a/src/item/item.h b/src/item/item.h new file mode 100644 index 0000000..6df27be --- /dev/null +++ b/src/item/item.h @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "itemtype.h" + +typedef struct { + itemtype_t type; +} item_t; + +typedef uint8_t itemid_t; + +#define ITEM_ID_NULL 0 +#define ITEM_ID_POTION 1 +#define ITEM_ID_POTATO 2 + +extern const item_t ITEMS[]; \ No newline at end of file diff --git a/src/item/itemtype.h b/src/item/itemtype.h new file mode 100644 index 0000000..cde6d3e --- /dev/null +++ b/src/item/itemtype.h @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +typedef enum { + ITEM_TYPE_NULL, + + ITEM_TYPE_MEDICINE, + ITEM_TYPE_INGREDIENT, + ITEM_TYPE_KEYITEM, + + ITEM_TYPE_COUNT +} itemtype_t; \ No newline at end of file diff --git a/src/scene/CMakeLists.txt b/src/scene/CMakeLists.txt index 94aaa08..5a9fe3d 100644 --- a/src/scene/CMakeLists.txt +++ b/src/scene/CMakeLists.txt @@ -6,8 +6,5 @@ # Sources target_sources(${DUSK_LIBRARY_TARGET_NAME} PUBLIC - scenemanager.c -) - -# Subdirs -add_subdirectory(scene) \ No newline at end of file + scene.c +) \ No newline at end of file diff --git a/src/scene/scene.c b/src/scene/scene.c new file mode 100644 index 0000000..7e4edde --- /dev/null +++ b/src/scene/scene.c @@ -0,0 +1,84 @@ +// Copyright (c) 2026 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "scene.h" +#include "assert/assert.h" +#include "util/string.h" + +const scene_t SCENES[] = { +}; + +uint_fast8_t SCENE_CURRENT = 0xFF; + +errorret_t sceneInit(void) { + // Initialize the scene subsystem here + errorOk(); +} + +void sceneUpdate(void) { + const scene_t *current = sceneGetCurrent(); + if(current && current->update) { + current->update(); + } +} + +void sceneRender(void) { + const scene_t *current = sceneGetCurrent(); + + if(current && current->render) { + current->render(); + } +} + +void sceneDispose(void) { + const scene_t *current = sceneGetCurrent(); + + if(current && current->dispose) { + current->dispose(); + } +} + +errorret_t sceneSet(const scene_t *scene) { + sceneDispose(); + + if(scene) { + SCENE_CURRENT = (uint_fast8_t)(scene - SCENES); + + assertTrue( + SCENE_CURRENT < sizeof(SCENES) / sizeof(scene_t), + "Invalid scene index." + ); + + if(scene->init) { + errorret_t err = scene->init(); + if(err.code != ERROR_OK) SCENE_CURRENT = 0xFF; + errorChain(err); + } + } else { + SCENE_CURRENT = 0xFF; + } + + errorOk(); +} + +const scene_t* sceneGetCurrent(void) { + if(SCENE_CURRENT == 0xFF) return NULL; + + assertTrue( + SCENE_CURRENT < sizeof(SCENES) / sizeof(scene_t), + "Invalid current scene index." + ); + + return &SCENES[SCENE_CURRENT]; +} + +const scene_t* sceneGetByName(const char_t *name) { + for(uint_fast8_t i = 0; i < sizeof(SCENES) / sizeof(scene_t); i++) { + if(stringCompare(SCENES[i].name, name) == 0) { + return &SCENES[i]; + } + } + return NULL; +} \ No newline at end of file diff --git a/src/scene/scene.h b/src/scene/scene.h index 39c89a4..412df8b 100644 --- a/src/scene/scene.h +++ b/src/scene/scene.h @@ -1,24 +1,63 @@ /** - * Copyright (c) 2025 Dominic Masters + * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #pragma once -#include "dusk.h" #include "error/error.h" -#include "display/color.h" - -#define SCENE_FLAG_INITIALIZED (1 << 0) - -typedef struct scenedata_s scenedata_t; typedef struct { const char_t *name; - errorret_t (*init)(scenedata_t *data); - void (*update)(scenedata_t *data); - void (*render)(scenedata_t *data); - void (*dispose)(scenedata_t *data); - uint8_t flags; -} scene_t; \ No newline at end of file + errorret_t (*init)(void); + void (*update)(void); + void (*render)(void); + void (*dispose)(void); +} scene_t; + +extern const scene_t SCENES[]; +extern uint_fast8_t SCENE_CURRENT; + +/** + * Initialize the scene subsystem. + */ +errorret_t sceneInit(void); + +/** + * Update the current scene. + */ +void sceneUpdate(void); + +/** + * Render the current scene. + */ +void sceneRender(void); + +/** + * Dispose of the scene subsystem. + */ +void sceneDispose(void); + +/** + * Set the current scene. + * + * @param sceneIndex The index of the scene to set. + * @return An error code indicating success or failure. + */ +errorret_t sceneSet(const scene_t *scene); + +/** + * Get the current scene. + * + * @return The current scene. + */ +const scene_t* sceneGetCurrent(void); + +/** + * Get a scene by its name. + * + * @param name The name of the scene. + * @return The scene with the given name, or NULL if not found. + */ +const scene_t* sceneGetByName(const char_t *name); \ No newline at end of file diff --git a/src/script/module/modulescene.h b/src/script/module/modulescene.h index 25879ce..6172698 100644 --- a/src/script/module/modulescene.h +++ b/src/script/module/modulescene.h @@ -7,7 +7,7 @@ #pragma once #include "script/scriptcontext.h" -#include "scene/scenemanager.h" +#include "scene/scene.h" int moduleSceneSetScene(lua_State *L) { assertNotNull(L, "Lua state cannot be NULL"); @@ -20,13 +20,13 @@ int moduleSceneSetScene(lua_State *L) { return 0; } - scene_t *scene = sceneManagerGetSceneByName(sceneName); + const scene_t *scene = sceneGetByName(sceneName); if(scene == NULL) { luaL_error(L, "Scene '%s' not found", sceneName); return 0; } - errorret_t err = sceneManagerSetScene(scene); + errorret_t err = sceneSet(scene); if(err.code != ERROR_OK) { luaL_error(L, "Failed to set scene '%s'", sceneName); return 0; diff --git a/src/script/scriptmodule.c b/src/script/scriptmodule.c index aaf204d..3ff670f 100644 --- a/src/script/scriptmodule.c +++ b/src/script/scriptmodule.c @@ -10,14 +10,12 @@ #include "script/module/moduleinput.h" #include "script/module/moduleplatform.h" #include "script/module/modulescene.h" -#include "script/module/modulemap.h" const scriptmodule_t SCRIPT_MODULE_LIST[] = { { .name = "system", .callback = moduleSystem }, { .name = "input", .callback = moduleInput }, { .name = "platform", .callback = modulePlatform }, { .name = "scene", .callback = moduleScene }, - { .name = "map", .callback = moduleMapSystem }, }; #define SCRIPT_MODULE_COUNT ( \ diff --git a/src/time/time.c b/src/time/time.c index 5a0bbc1..15a150c 100644 --- a/src/time/time.c +++ b/src/time/time.c @@ -26,6 +26,7 @@ void timeInit(void) { TIME.dynamicTime = TIME_STEP; TIME.dynamicDelta = TIME_STEP; TIME.dynamicUpdate = false; + TIME.lastNonDynamic = TIME.dynamicTime; #endif } @@ -44,8 +45,9 @@ void timeUpdate(void) { assertTrue(TIME.dynamicDelta >= 0.0f, "Time delta is negative"); // Is within 1ms of a full step? - if(TIME.dynamicTime - TIME.time >= TIME_STEP * 0.999f) { + if(TIME.dynamicTime - TIME.lastNonDynamic >= TIME_STEP * 0.999f) { TIME.dynamicUpdate = false; + TIME.lastNonDynamic = TIME.dynamicTime; TIME.delta = TIME_STEP; TIME.time += TIME_STEP; } diff --git a/src/time/time.h b/src/time/time.h index e56178f..52bfc1b 100644 --- a/src/time/time.h +++ b/src/time/time.h @@ -18,6 +18,7 @@ typedef struct { float_t time; #if TIME_FIXED == 0 + float_t lastNonDynamic; bool_t dynamicUpdate; float_t dynamicDelta; float_t dynamicTime; diff --git a/src/ui/ui.c b/src/ui/ui.c index d575ea5..1faba12 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -11,7 +11,7 @@ #include "util/memory.h" #include "display/tileset/tileset_minogram.h" #include "display/screen.h" -#include "ui/uitextbox.h" +// #include "ui/uitextbox.h" ui_t UI; @@ -33,7 +33,7 @@ void uiUpdate(void) { UI.camera.orthographic.top = 0; UI.camera.orthographic.bottom = SCREEN.height; - uiTextboxUpdate(); + // uiTextboxUpdate(); } void uiRender(void) { @@ -42,7 +42,7 @@ void uiRender(void) { // Render UI elements here if(UI.fontTexture.width > 0) { uiDebugRender(UI.fontTileset, &UI.fontTexture); - uiTextboxRender(); + // uiTextboxRender(); } cameraPopMatrix(); } diff --git a/src/ui/uidebug.c b/src/ui/uidebug.c index abe1588..56e7db5 100644 --- a/src/ui/uidebug.c +++ b/src/ui/uidebug.c @@ -11,7 +11,7 @@ #include "ui/uitext.h" #include "display/screen.h" #include "display/spritebatch.h" -#include "rpg/entity/entity.h" +// #include "rpg/entity/entity.h" bool_t UI_DEBUG_DRAW = true; @@ -67,32 +67,32 @@ void uiDebugRender(const tileset_t *tileset, texture_t *texture) { // Player position - entity_t *player = NULL; - for(uint8_t i = 0; i < ENTITY_COUNT; i++) { - if(ENTITIES[i].type != ENTITY_TYPE_PLAYER) continue; - player = &ENTITIES[i]; - break; - } - if(player == NULL) { - snprintf(buffer, sizeof(buffer), "Player: N/A"); - } else { - snprintf( - buffer, - sizeof(buffer), - "%d,%d,%d/%d/%d", - player->position.x, - player->position.y, - player->position.z, - (int32_t)player->direction, - (int32_t)player->animation - ); - } - uiTextMeasure(buffer, tileset, &w, &h); - uiTextDraw( - SCREEN.width - w, hOffset, - buffer, COLOR_GREEN, tileset, texture - ); - hOffset += h; + // entity_t *player = NULL; + // for(uint8_t i = 0; i < ENTITY_COUNT; i++) { + // if(ENTITIES[i].type != ENTITY_TYPE_PLAYER) continue; + // player = &ENTITIES[i]; + // break; + // } + // if(player == NULL) { + // snprintf(buffer, sizeof(buffer), "Player: N/A"); + // } else { + // snprintf( + // buffer, + // sizeof(buffer), + // "%d,%d,%d/%d/%d", + // player->position.x, + // player->position.y, + // player->position.z, + // (int32_t)player->direction, + // (int32_t)player->animation + // ); + // } + // uiTextMeasure(buffer, tileset, &w, &h); + // uiTextDraw( + // SCREEN.width - w, hOffset, + // buffer, COLOR_GREEN, tileset, texture + // ); + // hOffset += h; spriteBatchFlush(); } \ No newline at end of file diff --git a/src/ui/uitextbox.c b/src/ui/uitextbox.c index 47b0a87..3aecfa8 100644 --- a/src/ui/uitextbox.c +++ b/src/ui/uitextbox.c @@ -8,38 +8,38 @@ #include "uitextbox.h" #include "ui/ui.h" #include "ui/uitext.h" -#include "rpg/rpgtextbox.h" +// #include "rpg/rpgtextbox.h" #include "display/screen.h" #include "display/spritebatch.h" #include "input/input.h" -void uiTextboxUpdate() { - if(!rpgTextboxIsVisible()) return; +// void uiTextboxUpdate() { +// if(!rpgTextboxIsVisible()) return; - if(inputPressed(INPUT_ACTION_ACCEPT)) { - rpgTextboxHide(); - } -} +// if(inputPressed(INPUT_ACTION_ACCEPT)) { +// rpgTextboxHide(); +// } +// } -void uiTextboxRender() { - if(!rpgTextboxIsVisible()) return; +// void uiTextboxRender() { +// if(!rpgTextboxIsVisible()) return; - const char_t *text = RPG_TEXTBOX.text; - int32_t textWidth, textHeight; +// const char_t *text = RPG_TEXTBOX.text; +// int32_t textWidth, textHeight; - uiTextMeasure(text, UI.fontTileset, &textWidth, &textHeight); +// uiTextMeasure(text, UI.fontTileset, &textWidth, &textHeight); - float_t y = 0; - if(RPG_TEXTBOX.position == RPG_TEXTBOX_POS_BOTTOM) { - y = SCREEN.height - (float_t)textHeight; - } +// float_t y = 0; +// if(RPG_TEXTBOX.position == RPG_TEXTBOX_POS_BOTTOM) { +// y = SCREEN.height - (float_t)textHeight; +// } - spriteBatchPush( - NULL, - 0.0f, y, - (float_t)SCREEN.width, (float_t)(y + textHeight), - COLOR_BLACK, - 0.0f, 0.0f, 1.0f, 1.0f - ); - uiTextDraw(0, y, text, COLOR_RED, UI.fontTileset, &UI.fontTexture); -} \ No newline at end of file +// spriteBatchPush( +// NULL, +// 0.0f, y, +// (float_t)SCREEN.width, (float_t)(y + textHeight), +// COLOR_BLACK, +// 0.0f, 0.0f, 1.0f, 1.0f +// ); +// uiTextDraw(0, y, text, COLOR_RED, UI.fontTileset, &UI.fontTexture); +// } \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0f39308..67fbe2b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,5 +3,8 @@ # This software is released under the MIT License. # https://opensource.org/licenses/MIT +add_subdirectory(display) +# add_subdirectory(rpg) +add_subdirectory(item) add_subdirectory(time) add_subdirectory(util) \ No newline at end of file diff --git a/test/display/CMakeLists.txt b/test/display/CMakeLists.txt new file mode 100644 index 0000000..47bf362 --- /dev/null +++ b/test/display/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2026 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +include(dusktest) + +# Tests +dusktest(test_color.c) \ No newline at end of file diff --git a/test/display/test_color.c b/test/display/test_color.c new file mode 100644 index 0000000..3f07a58 --- /dev/null +++ b/test/display/test_color.c @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "dusktest.h" +#include "display/color.h" + +static void test_color3f_create(void **state) { + (void)state; + + color3f_t color = color3f(0.1f, 0.2f, 0.3f); + assert_float_equal(color.r, 0.1f, 0.0001f); + assert_float_equal(color.g, 0.2f, 0.0001f); + assert_float_equal(color.b, 0.3f, 0.0001f); +} + +static void test_color4f_create(void **state) { + (void)state; + + color4f_t color = color4f(0.1f, 0.2f, 0.3f, 0.4f); + assert_float_equal(color.r, 0.1f, 0.0001f); + assert_float_equal(color.g, 0.2f, 0.0001f); + assert_float_equal(color.b, 0.3f, 0.0001f); + assert_float_equal(color.a, 0.4f, 0.0001f); +} + +static void test_color3b_create(void **state) { + (void)state; + + color3b_t color = color3b(10, 20, 30); + assert_int_equal(color.r, 10); + assert_int_equal(color.g, 20); + assert_int_equal(color.b, 30); +} + +static void test_color4b_create(void **state) { + (void)state; + + color4b_t color = color4b(10, 20, 30, 40); + assert_int_equal(color.r, 10); + assert_int_equal(color.g, 20); + assert_int_equal(color.b, 30); + assert_int_equal(color.a, 40); +} + +static void test_color_create(void **state) { + (void)state; + + color_t color = color(10, 20, 30, 40); + assert_int_equal(color.r, 10); + assert_int_equal(color.g, 20); + assert_int_equal(color.b, 30); + assert_int_equal(color.a, 40); +} + +static void test_colorHex_create(void **state) { + (void)state; + + color_t color = colorHex(0x11223344); + assert_int_equal(color.r, 0x11); + assert_int_equal(color.g, 0x22); + assert_int_equal(color.b, 0x33); + assert_int_equal(color.a, 0x44); + + color = colorHex(0xFF00FF00); + assert_int_equal(color.r, 0xFF); + assert_int_equal(color.g, 0x00); + assert_int_equal(color.b, 0xFF); + assert_int_equal(color.a, 0x00); + + color_t comp = color(255, 0, 255, 0); + assert_int_equal(color.r, comp.r); + assert_int_equal(color.g, comp.g); + assert_int_equal(color.b, comp.b); + assert_int_equal(color.a, comp.a); + + color = colorHex(0xFFFFFFFF); + assert_int_equal(color.r, COLOR_WHITE.r); + assert_int_equal(color.g, COLOR_WHITE.g); + assert_int_equal(color.b, COLOR_WHITE.b); + assert_int_equal(color.a, COLOR_WHITE.a); +} + +int main(int argc, char **argv) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_color3f_create), + cmocka_unit_test(test_color4f_create), + cmocka_unit_test(test_color3b_create), + cmocka_unit_test(test_color4b_create), + cmocka_unit_test(test_color_create), + cmocka_unit_test(test_colorHex_create), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} \ No newline at end of file diff --git a/test/item/CMakeLists.txt b/test/item/CMakeLists.txt new file mode 100644 index 0000000..ee72333 --- /dev/null +++ b/test/item/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2026 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +include(dusktest) + +# Tests +dusktest(test_inventory.c) \ No newline at end of file diff --git a/test/item/test_inventory.c b/test/item/test_inventory.c new file mode 100644 index 0000000..d8fb81e --- /dev/null +++ b/test/item/test_inventory.c @@ -0,0 +1,341 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "dusktest.h" +#include "item/inventory.h" + +static void test_inventoryInit(void **state) { + (void)state; + + inventorystack_t storage[5]; + inventory_t inventory; + + inventoryInit(&inventory, storage, 5); + + // Should setup struct + assert_non_null(inventory.storage); + assert_int_equal(inventory.storageSize, 5); + + // Should zero the item ids. + for(size_t i = 0; i < inventory.storageSize; i++) { + assert_int_equal(inventory.storage[i].item, ITEM_ID_NULL); + assert_int_equal(inventory.storage[i].quantity, 0); + } + + // Should fail when given NULL inventory pointer + expect_assert_failure(inventoryInit(NULL, storage, 5)); + + // Should fail when given NULL storage pointer + expect_assert_failure(inventoryInit(&inventory, NULL, 5)); + + // Should fail when given zero storage size + expect_assert_failure(inventoryInit(&inventory, storage, 0)); +} + +static void test_inventoryItemExists(void **state) { + (void)state; + + inventorystack_t storage[5]; + inventory_t inventory; + inventoryInit(&inventory, storage, 5); + + // Initially should not exist + assert_false(inventoryItemExists(&inventory, ITEM_ID_POTION)); + + // Add item + inventorySet(&inventory, ITEM_ID_POTION, 3); + assert_true(inventoryItemExists(&inventory, ITEM_ID_POTION)); + + // Remove item + inventorySet(&inventory, ITEM_ID_POTION, 0); + assert_false(inventoryItemExists(&inventory, ITEM_ID_POTION)); + + // Should fail when given NULL inventory pointer + expect_assert_failure(inventoryItemExists(NULL, ITEM_ID_POTION)); + + // Should fail when given NULL storage pointer + inventory.storage = NULL; + expect_assert_failure(inventoryItemExists(&inventory, ITEM_ID_POTION)); + inventory.storage = storage; + + // Should fail when given zero storage size + inventory.storageSize = 0; + expect_assert_failure(inventoryItemExists(&inventory, ITEM_ID_POTION)); + inventory.storageSize = 5; + + // Should fail when given ITEM_ID_NULL + expect_assert_failure(inventoryItemExists(&inventory, ITEM_ID_NULL)); + + // Should fail if item has zero quantity somehow + inventorySet(&inventory, ITEM_ID_POTION, 3); + inventory.storage[0].quantity = 0; + expect_assert_failure(inventoryItemExists(&inventory, ITEM_ID_POTION)); +} + +static void test_inventorySet(void **state) { + (void)state; + + inventorystack_t storage[5]; + inventory_t inventory; + inventoryInit(&inventory, storage, 5); + + // Set item quantity + inventorySet(&inventory, ITEM_ID_POTION, 4); + assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION); + assert_int_equal(inventory.storage[0].quantity, 4); + + // Update item quantity + inventorySet(&inventory, ITEM_ID_POTION, 2); + assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION); + assert_int_equal(inventory.storage[0].quantity, 2); + + // Remove item by setting quantity to 0 + inventorySet(&inventory, ITEM_ID_POTION, 0); + assert_int_equal(inventory.storage[0].item, ITEM_ID_NULL); + + // Setting multiple items should not cause issues + inventorySet(&inventory, ITEM_ID_POTION, 1); + inventorySet(&inventory, ITEM_ID_POTATO, 5); + assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION); + assert_int_equal(inventory.storage[0].quantity, 1); + assert_int_equal(inventory.storage[1].item, ITEM_ID_POTATO); + assert_int_equal(inventory.storage[1].quantity, 5); + + // Setting early item to 0 should shift others down + inventorySet(&inventory, ITEM_ID_POTION, 0); + assert_int_equal(inventory.storage[0].item, ITEM_ID_POTATO); + assert_int_equal(inventory.storage[0].quantity, 5); + assert_int_equal(inventory.storage[1].item, ITEM_ID_NULL); + + // Setting non-existing item should add it + inventorySet(&inventory, ITEM_ID_POTION, 3); + assert_int_equal(inventory.storage[1].item, ITEM_ID_POTION); + assert_int_equal(inventory.storage[1].quantity, 3); + + // Should fail when given NULL inventory pointer + expect_assert_failure(inventorySet(NULL, ITEM_ID_POTION, 3)); + + // Should fail when given NULL storage pointer + inventory.storage = NULL; + expect_assert_failure(inventorySet(&inventory, ITEM_ID_POTION, 3)); + inventory.storage = storage; + + // Should fail when given zero storage size + inventory.storageSize = 0; + expect_assert_failure(inventorySet(&inventory, ITEM_ID_POTION, 3)); + inventory.storageSize = 5; + + // Should fail when given ITEM_ID_NULL + expect_assert_failure(inventorySet(&inventory, ITEM_ID_NULL, 3)); +} + +static void test_inventoryAdd(void **state) { + (void)state; + + inventorystack_t storage[5]; + inventory_t inventory; + inventoryInit(&inventory, storage, 5); + + // Add item quantity + inventoryAdd(&inventory, ITEM_ID_POTION, 4); + assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION); + assert_int_equal(inventory.storage[0].quantity, 4); + + // Add more to existing item + inventoryAdd(&inventory, ITEM_ID_POTION, 3); + assert_int_equal(inventory.storage[0].item, ITEM_ID_POTION); + assert_int_equal(inventory.storage[0].quantity, 7); + + // Adding item that would overflow should assert + expect_assert_failure(inventoryAdd(&inventory, ITEM_ID_POTION, 250)); + + // Should fail when given NULL inventory pointer + expect_assert_failure(inventoryAdd(NULL, ITEM_ID_POTION, 3)); + + // Should fail when given NULL storage pointer + inventory.storage = NULL; + expect_assert_failure(inventoryAdd(&inventory, ITEM_ID_POTION, 3)); + inventory.storage = storage; + + // Should fail when given zero storage size + inventory.storageSize = 0; + expect_assert_failure(inventoryAdd(&inventory, ITEM_ID_POTION, 3)); + inventory.storageSize = 5; + + // Should fail when given ITEM_ID_NULL + expect_assert_failure(inventoryAdd(&inventory, ITEM_ID_NULL, 3)); +} + +static void test_inventoryRemove(void **state) { + (void)state; + + inventorystack_t storage[5]; + inventory_t inventory; + inventoryInit(&inventory, storage, 5); + + // Add item and then remove it + inventorySet(&inventory, ITEM_ID_POTION, 5); + inventoryRemove(&inventory, ITEM_ID_POTION); + assert_int_equal(inventory.storage[0].item, ITEM_ID_NULL); + + // Removing non-existing item should do nothing + inventoryRemove(&inventory, ITEM_ID_POTION); + assert_int_equal(inventory.storage[0].item, ITEM_ID_NULL); + + // Should fail when given NULL inventory pointer + expect_assert_failure(inventoryRemove(NULL, ITEM_ID_POTION)); + + // Should fail when given NULL storage pointer + inventory.storage = NULL; + expect_assert_failure(inventoryRemove(&inventory, ITEM_ID_POTION)); + inventory.storage = storage; + + // Should fail when given zero storage size + inventory.storageSize = 0; + expect_assert_failure(inventoryRemove(&inventory, ITEM_ID_POTION)); + inventory.storageSize = 5; + + // Should fail when given ITEM_ID_NULL + expect_assert_failure(inventoryRemove(&inventory, ITEM_ID_NULL)); +} + +static void test_inventoryGetCount(void **state) { + (void)state; + + inventorystack_t storage[5]; + inventory_t inventory; + inventoryInit(&inventory, storage, 5); + + // Initially should be zero + assert_int_equal(inventoryGetCount(&inventory, ITEM_ID_POTION), 0); + + // Add item and check count + inventorySet(&inventory, ITEM_ID_POTION, 4); + assert_int_equal(inventoryGetCount(&inventory, ITEM_ID_POTION), 4); + + // Update item quantity and check count + inventorySet(&inventory, ITEM_ID_POTION, 2); + assert_int_equal(inventoryGetCount(&inventory, ITEM_ID_POTION), 2); + + // Remove item and check count + inventorySet(&inventory, ITEM_ID_POTION, 0); + assert_int_equal(inventoryGetCount(&inventory, ITEM_ID_POTION), 0); + + // Should fail when given NULL inventory pointer + expect_assert_failure(inventoryGetCount(NULL, ITEM_ID_POTION)); + + // Should fail when given NULL storage pointer + inventory.storage = NULL; + expect_assert_failure(inventoryGetCount(&inventory, ITEM_ID_POTION)); + inventory.storage = storage; + + // Should fail when given zero storage size + inventory.storageSize = 0; + expect_assert_failure(inventoryGetCount(&inventory, ITEM_ID_POTION)); + inventory.storageSize = 5; + + // Should fail when given ITEM_ID_NULL + expect_assert_failure(inventoryGetCount(&inventory, ITEM_ID_NULL)); +} + +static void test_inventoryIsFull(void **state) { + (void)state; + + inventorystack_t storage[2]; + inventory_t inventory; + inventoryInit(&inventory, storage, 2); + + // Initially should not be full + assert_false(inventoryIsFull(&inventory)); + + // Fill inventory + inventorySet(&inventory, ITEM_ID_POTION, 1); + inventorySet(&inventory, ITEM_ID_POTATO, 1); + assert_true(inventoryIsFull(&inventory)); + + // Remove one item + inventoryRemove(&inventory, ITEM_ID_POTION); + assert_false(inventoryIsFull(&inventory)); + + // Add one item back + inventorySet(&inventory, ITEM_ID_POTION, 1); + assert_true(inventoryIsFull(&inventory)); + + // Should fail when given NULL inventory pointer + expect_assert_failure(inventoryIsFull(NULL)); + + // Should fail when given NULL storage pointer + inventory.storage = NULL; + expect_assert_failure(inventoryIsFull(&inventory)); + inventory.storage = storage; + + // Should fail when given zero storage size + inventory.storageSize = 0; + expect_assert_failure(inventoryIsFull(&inventory)); + inventory.storageSize = 2; +} + +static void test_inventoryItemFull(void **state) { + (void)state; + + inventorystack_t storage[2]; + inventory_t inventory; + inventoryInit(&inventory, storage, 2); + + // Initially should not be full + assert_false(inventoryItemFull(&inventory, ITEM_ID_POTION)); + + // Add some potions, but not too many. + inventorySet(&inventory, ITEM_ID_POTION, 100); + assert_false(inventoryItemFull(&inventory, ITEM_ID_POTION)); + + // Fill with potions + inventorySet(&inventory, ITEM_ID_POTION, ITEM_STACK_QUANTITY_MAX); + assert_true(inventoryItemFull(&inventory, ITEM_ID_POTION)); + + // Add potatoes, should not affect potions + inventorySet(&inventory, ITEM_ID_POTATO, 50); + assert_true(inventoryItemFull(&inventory, ITEM_ID_POTION)); + assert_false(inventoryItemFull(&inventory, ITEM_ID_POTATO)); + + // Remove some potions + inventorySet(&inventory, ITEM_ID_POTION, 200); + assert_false(inventoryItemFull(&inventory, ITEM_ID_POTION)); + + // Fill with potatoes + inventorySet(&inventory, ITEM_ID_POTATO, ITEM_STACK_QUANTITY_MAX); + assert_false(inventoryItemFull(&inventory, ITEM_ID_POTION)); + assert_true(inventoryItemFull(&inventory, ITEM_ID_POTATO)); + + // Should fail when given NULL inventory pointer + expect_assert_failure(inventoryItemFull(NULL, ITEM_ID_POTION)); + + // Should fail when given NULL storage pointer + inventory.storage = NULL; + expect_assert_failure(inventoryItemFull(&inventory, ITEM_ID_POTION)); + inventory.storage = storage; + + // Should fail when given zero storage size + inventory.storageSize = 0; + expect_assert_failure(inventoryItemFull(&inventory, ITEM_ID_POTION)); + inventory.storageSize = 2; +} + +int main(int argc, char** argv) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_inventoryInit), + cmocka_unit_test(test_inventoryItemExists), + cmocka_unit_test(test_inventorySet), + cmocka_unit_test(test_inventoryAdd), + cmocka_unit_test(test_inventoryRemove), + cmocka_unit_test(test_inventoryGetCount), + cmocka_unit_test(test_inventoryIsFull), + cmocka_unit_test(test_inventoryItemFull), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} \ No newline at end of file diff --git a/test/rpg/CMakeLists.txt b/test/rpg/CMakeLists.txt new file mode 100644 index 0000000..5a1133c --- /dev/null +++ b/test/rpg/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (c) 2026 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +include(dusktest) + +# Tests +dusktest(test_rpg.c) + +# Subdirs +add_subdirectory(overworld) \ No newline at end of file diff --git a/test/rpg/overworld/CMakeLists.txt b/test/rpg/overworld/CMakeLists.txt new file mode 100644 index 0000000..a888f72 --- /dev/null +++ b/test/rpg/overworld/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2026 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +include(dusktest) + +# Tests + +# Subdirs \ No newline at end of file diff --git a/test/rpg/test_rpg.c b/test/rpg/test_rpg.c new file mode 100644 index 0000000..7a5e36d --- /dev/null +++ b/test/rpg/test_rpg.c @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "dusktest.h" + +int main(int argc, char** argv) { + const struct CMUnitTest tests[] = { + // Add RPG tests here in the future + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} \ No newline at end of file diff --git a/test/time/test_time.c b/test/time/test_time.c index f5df52e..746f249 100644 --- a/test/time/test_time.c +++ b/test/time/test_time.c @@ -100,17 +100,17 @@ static void test_timeUpdate(void **state) { assert_float_equal(TIME.delta, TIME_STEP, 0.0001f); assert_float_equal(TIME.time, TIME_STEP * 4, 0.0001f); - // Fifth test, despite a small time passing the game should be trying to catch - // and running extra ticks + // Fifth test, despite a small time passing the game should not start + // trying to run ahead SDL_GETTICKS_TICKS = 104; // Simulate 4ms elapsed SDL_GETTICKS_CALLED = false; timeUpdate(); assert_true(SDL_GETTICKS_CALLED); - assert_false(TIME.dynamicUpdate); + assert_true(TIME.dynamicUpdate); assert_float_equal(TIME.dynamicDelta, 0.004f, 0.0001f); assert_float_equal(TIME.dynamicTime, TIME_STEP + 0.104f, 0.0001f); assert_float_equal(TIME.delta, TIME_STEP, 0.0001f); - assert_float_equal(TIME.time, TIME_STEP * 5, 0.0001f); + assert_float_equal(TIME.time, TIME_STEP * 4, 0.0001f); // Time can stand still if needed SDL_GETTICKS_CALLED = false;