From 7d8e1051fe72262f56195fdcfe0e30f1c8c60142 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 11 Jun 2025 16:42:00 -0500 Subject: [PATCH] BG implemented --- CMakeLists.txt | 13 +- Dusk.gb | Bin 0 -> 32768 bytes cmake/toolchains/gbdk.cmake | 49 ++++ src/CMakeLists.txt | 7 +- src/dusk/CMakeLists.txt | 6 +- src/dusk/assert/assert.c | 177 ++++++-------- src/dusk/assert/assert.h | 224 +++++++++--------- src/dusk/display/CMakeLists.txt | 3 +- .../{rpg/quest/quest.c => display/render.c} | 2 +- src/dusk/display/render.h | 33 ++- src/dusk/dusk.h | 20 +- src/dusk/input.c | 29 --- src/dusk/input.h | 74 ------ src/dusk/main.c | 138 +++++++++-- src/dusk/rpg/CMakeLists.txt | 16 -- src/dusk/rpg/entity/CMakeLists.txt | 12 - src/dusk/rpg/entity/entity.c | 192 --------------- src/dusk/rpg/entity/entity.h | 158 ------------ src/dusk/rpg/entity/npc.c | 34 --- src/dusk/rpg/entity/npc.h | 37 --- src/dusk/rpg/entity/player.c | 58 ----- src/dusk/rpg/entity/player.h | 29 --- src/dusk/rpg/event/event.c | 33 --- src/dusk/rpg/event/event.h | 47 ---- src/dusk/rpg/item/CMakeLists.txt | 11 - src/dusk/rpg/item/inventory.c | 16 -- src/dusk/rpg/item/inventory.h | 23 -- src/dusk/rpg/item/itemstack.h | 14 -- src/dusk/rpg/item/itemtype.c | 28 --- src/dusk/rpg/item/itemtype.h | 38 --- src/dusk/rpg/quest/CMakeLists.txt | 10 - src/dusk/rpg/world/CMakeLists.txt | 13 - src/dusk/rpg/world/map.c | 45 ---- src/dusk/rpg/world/map.h | 59 ----- src/dusk/rpg/world/maps/CMakeLists.txt | 9 - src/dusk/rpg/world/maps/testmap.h | 43 ---- src/dusk/ui/CMakeLists.txt | 13 - src/dusk/ui/ui.c | 21 -- src/dusk/ui/ui.h | 30 --- src/dusk/ui/uitextbox.c | 43 ---- src/dusk/ui/uitextbox.h | 49 ---- src/dusk/util/CMakeLists.txt | 3 - src/dusk/util/math.c | 12 - src/dusk/util/math.h | 17 -- src/dusk/util/memory.c | 2 +- src/dusk/util/memory.h | 2 +- src/dusk/util/random.c | 12 - src/dusk/util/random.h | 18 -- src/dusk/util/string.c | 127 ---------- src/dusk/util/string.h | 109 --------- src/duskgb/CMakeLists.txt | 31 +++ .../event => duskgb/display}/CMakeLists.txt | 4 +- src/duskgb/display/renderimpl.c | 23 ++ .../display/renderimpl.h} | 6 +- .../rpg/quest/quest.h => duskgb/duskgb.h} | 5 +- src/duskraylib/CMakeLists.txt | 1 - src/duskraylib/display/CMakeLists.txt | 9 +- src/duskraylib/display/draw/CMakeLists.txt | 11 - src/duskraylib/display/draw/drawentity.c | 63 ----- src/duskraylib/display/draw/drawentity.h | 14 -- src/duskraylib/display/draw/drawui.c | 27 --- src/duskraylib/display/draw/drawui.h | 14 -- src/duskraylib/display/renderimpl.c | 209 ++++++++++++++++ src/duskraylib/display/renderimpl.h | 56 +++++ src/duskraylib/display/renderraylib.c | 49 ---- .../eventtext.h => duskraylib/duskraylib.h} | 3 +- src/duskraylib/input.c | 60 ----- tools/CMakeLists.txt | 3 +- 68 files changed, 733 insertions(+), 2013 deletions(-) create mode 100644 Dusk.gb create mode 100644 cmake/toolchains/gbdk.cmake rename src/dusk/{rpg/quest/quest.c => display/render.c} (88%) delete mode 100644 src/dusk/input.c delete mode 100644 src/dusk/input.h delete mode 100644 src/dusk/rpg/CMakeLists.txt delete mode 100644 src/dusk/rpg/entity/CMakeLists.txt delete mode 100644 src/dusk/rpg/entity/entity.c delete mode 100644 src/dusk/rpg/entity/entity.h delete mode 100644 src/dusk/rpg/entity/npc.c delete mode 100644 src/dusk/rpg/entity/npc.h delete mode 100644 src/dusk/rpg/entity/player.c delete mode 100644 src/dusk/rpg/entity/player.h delete mode 100644 src/dusk/rpg/event/event.c delete mode 100644 src/dusk/rpg/event/event.h delete mode 100644 src/dusk/rpg/item/CMakeLists.txt delete mode 100644 src/dusk/rpg/item/inventory.c delete mode 100644 src/dusk/rpg/item/inventory.h delete mode 100644 src/dusk/rpg/item/itemstack.h delete mode 100644 src/dusk/rpg/item/itemtype.c delete mode 100644 src/dusk/rpg/item/itemtype.h delete mode 100644 src/dusk/rpg/quest/CMakeLists.txt delete mode 100644 src/dusk/rpg/world/CMakeLists.txt delete mode 100644 src/dusk/rpg/world/map.c delete mode 100644 src/dusk/rpg/world/map.h delete mode 100644 src/dusk/rpg/world/maps/CMakeLists.txt delete mode 100644 src/dusk/rpg/world/maps/testmap.h delete mode 100644 src/dusk/ui/CMakeLists.txt delete mode 100644 src/dusk/ui/ui.c delete mode 100644 src/dusk/ui/ui.h delete mode 100644 src/dusk/ui/uitextbox.c delete mode 100644 src/dusk/ui/uitextbox.h delete mode 100644 src/dusk/util/math.c delete mode 100644 src/dusk/util/math.h delete mode 100644 src/dusk/util/random.c delete mode 100644 src/dusk/util/random.h delete mode 100644 src/dusk/util/string.c delete mode 100644 src/dusk/util/string.h create mode 100644 src/duskgb/CMakeLists.txt rename src/{dusk/rpg/event => duskgb/display}/CMakeLists.txt (90%) create mode 100644 src/duskgb/display/renderimpl.c rename src/{duskraylib/display/renderraylib.h => duskgb/display/renderimpl.h} (63%) rename src/{dusk/rpg/quest/quest.h => duskgb/duskgb.h} (85%) delete mode 100644 src/duskraylib/display/draw/CMakeLists.txt delete mode 100644 src/duskraylib/display/draw/drawentity.c delete mode 100644 src/duskraylib/display/draw/drawentity.h delete mode 100644 src/duskraylib/display/draw/drawui.c delete mode 100644 src/duskraylib/display/draw/drawui.h create mode 100644 src/duskraylib/display/renderimpl.c create mode 100644 src/duskraylib/display/renderimpl.h delete mode 100644 src/duskraylib/display/renderraylib.c rename src/{dusk/rpg/event/eventtext.h => duskraylib/duskraylib.h} (80%) delete mode 100644 src/duskraylib/input.c diff --git a/CMakeLists.txt b/CMakeLists.txt index eaaafb5..3eeeb2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,11 +8,13 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) +if(NOT DEFINED DUSK_TARGET_SYSTEM) + set(DUSK_TARGET_SYSTEM "raylib") +endif() + # Prep cache set(DUSK_CACHE_TARGET "dusk-target") -# Platform configs - # Build variables set(DUSK_ROOT_DIR "${CMAKE_SOURCE_DIR}") set(DUSK_BUILD_DIR "${CMAKE_BINARY_DIR}") @@ -26,6 +28,11 @@ set(DUSK_TARGET_NAME "Dusk" CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_BUILD_BINARY ${DUSK_BUILD_DIR}/Dusk CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_ASSETS "" CACHE INTERNAL ${DUSK_CACHE_TARGET}) +# Toolchain +if(DUSK_TARGET_SYSTEM STREQUAL "gb") + include(${CMAKE_SOURCE_DIR}/cmake/toolchains/gbdk.cmake) +endif() + # Create directories file(MAKE_DIRECTORY ${DUSK_GENERATED_HEADERS_DIR}) file(MAKE_DIRECTORY ${DUSK_ASSETS_BUILD_DIR}) @@ -36,7 +43,7 @@ project(${DUSK_TARGET_NAME} LANGUAGES C ) -# Executable +# Executable add_executable(${DUSK_TARGET_NAME}) # Add tools diff --git a/Dusk.gb b/Dusk.gb new file mode 100644 index 0000000000000000000000000000000000000000..a2c2711da22490c4376187e3dcba59228ccfe55d GIT binary patch literal 32768 zcmeI!Z%7+=7zglQ?#`&yL{rx;({)}hqlENLR?CpAJ5pQBwlcC8)og<{g@IBA3KJS@ zR?WIH?7J$gtRSmh84TY9Tj(F8kPreM@wy2MTS4IhOBTyIqE>sR&f6~+t(&+)8SKrz z54k_T-#yRWb004kHSO6kw|-bK@v9QuuNUe}e4)5kilvP0+h{yYHpb7pO{APR9aR~3 zSLd&3yLBt5I)ZG`i@2|23kd z%x3`0_~djTawWjYgCf<*;%{c}FZ)j#_>swyirizqeJLI^5*4=NYs3l&dfGjp0)SM#21crv04ohJFATaFcp{wbV3 zr+0iZbcbK=yUi~gdAF*{$*_L9T<4ed<2N0w-MZ4Zzo#VOGm_q+9};o{8{@1?xu|Sr zRT2?|Z9ih0AUty!6Sjn?(TaawUe_$+(UgspXXGnfjoq`-cxrteXYIY zd<8A?wZ$~#=1`>{VEq!4gIvdR8g;g8C0X5r5g27 zF*&Wbl&hfqr_?fc*Gcc$Q_1E=pNnQ|Hj8+7C$0vKL zjvcR~+hVR>#8q#koA}3N{3A(!(DFythFt}^9%?Soi2+Kamb<-fpWE*a&@XVYs{RsR zU1u*AK_9eeNZiI-hhW8(aoK-!Ovk!pl~!_~h*2S9bBs^nL>E zl4@+X?$~{iUa8i>><%Z22=wXh=uS3;vNh-Yp=>^o{LsN9zcJR9UJdm2XtO4ME+!ST z{U_8)y}gcZ`4JbBGW1j)N2Rs8xKqKG*~nK`)<#AW$)+S5%ChIZqH^t=FFl<~6c*xN z1WG3jG4?ZAC2;0ow(*8<7oUku@0m>XW>*6u|Cw)aD9hgPCam9Yc_WauHG>{&Yqff8 zjxBl&421O<7#P%}jf|1ME*s~gZ>=$n9@z{{qwm_yA@;TxU`zh`n%O=@pZ$;Xj2rQ{ z>uyYLZn^(i5MpRyZQe5ab0Al8TYsdV_n!*nLjVF0fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## oAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1pcMKpRo0>%m4rY literal 0 HcmV?d00001 diff --git a/cmake/toolchains/gbdk.cmake b/cmake/toolchains/gbdk.cmake new file mode 100644 index 0000000..18631b5 --- /dev/null +++ b/cmake/toolchains/gbdk.cmake @@ -0,0 +1,49 @@ +set(GBDK_HOME "$ENV{GBDK_HOME}") +if(NOT GBDK_HOME) + set(GBDK_HOME "/opt/gbdk") + message(STATUS "GBDK_HOME not set, using default: ${GBDK_HOME}") +endif() + +# Use Linux to omit any unwanted file extension in the created ROM file +set(CMAKE_SYSTEM_NAME Generic) + +set(CMAKE_C_COMPILER lcc) +set(CMAKE_C_COMPILER_FORCED TRUE) + +set(GBDK_INCLUDE_DIR ${GBDK_HOME}/include) +set(GBDK_LIB_DIR ${GBDK_HOME}/lib) + +set(CMAKE_PROGRAM_PATH ${GBDK_HOME}/bin) +set(CMAKE_INCLUDE_PATH ${GBDK_INCLUDE_DIR}) +set(CMAKE_LIBRARY_PATH ${GBDK_LIB_DIR}) + + +set(CMAKE_SYSTEM_INCLUDE_PATH ${GBDK_INCLUDE_DIR}) +set(CMAKE_SYSTEM_LIBRARY_PATH ${GBDK_LIB_DIR}) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) + +function(add_gb_rom target) + set(GB_MBC_TYPE 0) + if(ARGC GREATER_EQUAL 2) + set(GB_MBC_TYPE ${ARGV1}) + endif() + set(GB_ROM_BANKS 2) + if(ARGC GREATER_EQUAL 3) + set(GB_ROM_BANKS ${ARGV2}) + endif() + set(GB_RAM_BANKS 0) + if(ARGC GREATER_EQUAL 4) + set(GB_RAM_BANKS ${ARGV3}) + endif() + + + set_target_properties(${target} PROPERTIES OUTPUT_NAME ${target} SUFFIX ".gb") + target_compile_options(${target} PRIVATE -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG) + target_link_options(${target} PRIVATE "-Wl-yt${GB_MBC_TYPE}" "-Wl-yo${GB_ROM_BANKS}" "-Wl-ya${GB_RAM_BANKS}") +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fe911e6..126e6e2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,4 +4,9 @@ # https://opensource.org/licenses/MIT add_subdirectory(dusk) -add_subdirectory(duskraylib) \ No newline at end of file + +if(DUSK_TARGET_SYSTEM STREQUAL "gb") + add_subdirectory(duskgb) +elseif(DUSK_TARGET_SYSTEM STREQUAL "raylib") + add_subdirectory(duskraylib) +endif() \ No newline at end of file diff --git a/src/dusk/CMakeLists.txt b/src/dusk/CMakeLists.txt index c736552..f78afd4 100644 --- a/src/dusk/CMakeLists.txt +++ b/src/dusk/CMakeLists.txt @@ -6,7 +6,6 @@ # Libs target_link_libraries(${DUSK_TARGET_NAME} PUBLIC - m ) # Includes @@ -19,12 +18,9 @@ target_include_directories(${DUSK_TARGET_NAME} target_sources(${DUSK_TARGET_NAME} PRIVATE main.c - input.c ) # Subdirs add_subdirectory(assert) add_subdirectory(display) -add_subdirectory(rpg) -add_subdirectory(util) -add_subdirectory(ui) \ No newline at end of file +add_subdirectory(util) \ No newline at end of file diff --git a/src/dusk/assert/assert.c b/src/dusk/assert/assert.c index 77bade8..2f02a16 100644 --- a/src/dusk/assert/assert.c +++ b/src/dusk/assert/assert.c @@ -7,118 +7,79 @@ #include "assert.h" -void assertTrueImpl( - const char *file, - const int32_t line, - const bool x, - const char *message -) { - if(x != true) { - fprintf( - stderr, - "Assertion Failed in %s:%i\n\n%s\n", +#ifndef ASSERTIONS_FAKED + void assertTrueImpl( + const char *file, + const int32_t line, + const bool x, + const char *message + ) { + if(x != true) { + fprintf( + stderr, + "Assertion Failed in %s:%i\n\n%s\n", + file, + line, + message + ); + abort(); + } + } + + void assertFalseImpl( + const char *file, + const int32_t line, + bool x, + const char *message + ) { + assertTrueImpl(file, line, !x, message); + } + + void assertUnreachableImpl( + const char *file, + const int32_t line, + const char *message + ) { + assertTrueImpl(file, line, false, message); + } + + void assertNotNullImpl( + const char *file, + const int32_t line, + const void *pointer, + const char *message + ) { + assertTrueImpl( file, line, + pointer != NULL, message ); - abort(); + + // Ensure we can touch it + volatile char temp; + temp = *((char*)pointer); } -} -void assertFalseImpl( - const char *file, - const int32_t line, - bool x, - const char *message -) { - assertTrueImpl(file, line, !x, message); -} + void assertNullImpl( + const char *file, + const int32_t line, + const void *pointer, + const char *message + ) { + assertTrueImpl( + file, + line, + pointer == NULL, + message + ); + } -void assertUnreachableImpl( - const char *file, - const int32_t line, - const char *message -) { - assertTrueImpl(file, line, false, message); -} - -void assertNotNullImpl( - const char *file, - const int32_t line, - const void *pointer, - const char *message -) { - assertTrueImpl( - file, - line, - pointer != NULL, - message - ); - - // Ensure we can touch it - volatile char temp; - temp = *((char*)pointer); -} - -void assertNullImpl( - const char *file, - const int32_t line, - const void *pointer, - const char *message -) { - assertTrueImpl( - file, - line, - pointer == NULL, - message - ); -} - -void assertDeprecatedImpl( - const char *file, - const int32_t line, - const char *message -) { - assertUnreachableImpl(file, line, message); -} - -// void assertMemoryRangeMatchesImpl( -// const char *file, -// const int32_t line, -// const void *start, -// const void *end, -// const size_t size, -// const char *message -// ) { -// assertTrueImpl( -// file, -// line, -// start != NULL, -// "Start pointer is NULL" -// ); -// assertTrueImpl( -// file, -// line, -// end != NULL, -// "End pointer is NULL" -// ); -// assertTrueImpl( -// file, -// line, -// size > 0, -// "Size is 0" -// ); -// assertTrueImpl( -// file, -// line, -// start < end, -// "Start pointer is not before end pointer" -// ); - -// assertTrueImpl( -// file, -// line, -// ((uintptr_t)end - (uintptr_t)start) == size, -// message -// ); -// } \ No newline at end of file + void assertDeprecatedImpl( + const char *file, + const int32_t line, + const char *message + ) { + assertUnreachableImpl(file, line, message); + } +#endif \ No newline at end of file diff --git a/src/dusk/assert/assert.h b/src/dusk/assert/assert.h index 56b8668..03e401e 100644 --- a/src/dusk/assert/assert.h +++ b/src/dusk/assert/assert.h @@ -8,124 +8,136 @@ #pragma once #include "dusk.h" -/** - * Assert a given value to be true. - * - * @param file File that the assertion is being made from. - * @param line Line that the assertion is being made from. - * @param x Value to assert as true. - * @param message Message to throw against assertion failure. - */ -void assertTrueImpl( - const char *file, - const int32_t line, - const bool x, - const char *message -); +#ifndef ASSERTIONS_FAKED + /** + * Assert a given value to be true. + * + * @param file File that the assertion is being made from. + * @param line Line that the assertion is being made from. + * @param x Value to assert as true. + * @param message Message to throw against assertion failure. + */ + void assertTrueImpl( + const char *file, + const int32_t line, + const bool_t x, + const char *message + ); -/** - * Asserts a given statement to be false. - * - * @param file File that the assertion is being made from. - * @param line Line that the assertion is being made from. - * @param x Value to assert as false. - * @param message Message to throw against assertion failure. - */ -void assertFalseImpl( - const char *file, - const int32_t line, - const bool x, - const char *message -); + /** + * Asserts a given statement to be false. + * + * @param file File that the assertion is being made from. + * @param line Line that the assertion is being made from. + * @param x Value to assert as false. + * @param message Message to throw against assertion failure. + */ + void assertFalseImpl( + const char *file, + const int32_t line, + const bool_t x, + const char *message + ); -/** - * Asserts that a given line of code is unreachable. Essentially a forced - * assertion failure, good for "edge cases" - * - * @param file File that the assertion is being made from. - * @param line Line that the assertion is being made from. - * @param message Message to throw against assertion failure. - */ -void assertUnreachableImpl( - const char *file, - const int32_t line, - const char *message -); + /** + * Asserts that a given line of code is unreachable. Essentially a forced + * assertion failure, good for "edge cases" + * + * @param file File that the assertion is being made from. + * @param line Line that the assertion is being made from. + * @param message Message to throw against assertion failure. + */ + void assertUnreachableImpl( + const char *file, + const int32_t line, + const char *message + ); -/** - * Assert a given pointer to not point to a null pointer. - * - * @param file File that the assertion is being made from. - * @param line Line that the assertion is being made from. - * @param pointer Pointer to assert is not a null pointer. - * @param message Message to throw against assertion failure. - */ -void assertNotNullImpl( - const char *file, - const int32_t line, - const void *pointer, - const char *message -); + /** + * Assert a given pointer to not point to a null pointer. + * + * @param file File that the assertion is being made from. + * @param line Line that the assertion is being made from. + * @param pointer Pointer to assert is not a null pointer. + * @param message Message to throw against assertion failure. + */ + void assertNotNullImpl( + const char *file, + const int32_t line, + const void *pointer, + const char *message + ); -/** - * Asserts a given pointer to be a nullptr. - * - * @param file File that the assertion is being made from. - * @param line Line that the assertion is being made from. - * @param pointer Pointer to assert is nullptr. - * @param message Message to throw against assertion failure. - */ -void assertNullImpl( - const char *file, - const int32_t line, - const void *pointer, - const char *message -); + /** + * Asserts a given pointer to be a nullptr. + * + * @param file File that the assertion is being made from. + * @param line Line that the assertion is being made from. + * @param pointer Pointer to assert is nullptr. + * @param message Message to throw against assertion failure. + */ + void assertNullImpl( + const char *file, + const int32_t line, + const void *pointer, + const char *message + ); -/** - * Asserts a function as being deprecated. - * - * @param file File that the assertion is being made from. - * @param line Line that the assertion is being made from. - * @param message Message to throw against assertion failure. - */ -void assertDeprecatedImpl( - const char *file, - const int32_t line, - const char *message -); + /** + * Asserts a function as being deprecated. + * + * @param file File that the assertion is being made from. + * @param line Line that the assertion is being made from. + * @param message Message to throw against assertion failure. + */ + void assertDeprecatedImpl( + const char *file, + const int32_t line, + const char *message + ); -void assertMemoryRangeMatchesImpl( - const char *file, - const int32_t line, - const void *start, - const void *end, - const size_t size, - const char *message -); + void assertMemoryRangeMatchesImpl( + const char *file, + const int32_t line, + const void *start, + const void *end, + const size_t size, + const char *message + ); -#define assertTrue(x, message) \ - assertTrueImpl(__FILE__, __LINE__, x, message) + #define assertTrue(x, message) \ + assertTrueImpl(__FILE__, __LINE__, x, message) -#define assertFalse(x, message) \ - assertFalseImpl(__FILE__, __LINE__, x, message) + #define assertFalse(x, message) \ + assertFalseImpl(__FILE__, __LINE__, x, message) -#define assertUnreachable(message) \ - assertUnreachableImpl(__FILE__, __LINE__, message) + #define assertUnreachable(message) \ + assertUnreachableImpl(__FILE__, __LINE__, message) -#define assertNotNull(pointer, message) \ - assertNotNullImpl(__FILE__, __LINE__, pointer, message) + #define assertNotNull(pointer, message) \ + assertNotNullImpl(__FILE__, __LINE__, pointer, message) -#define assertNull(pointer, message) \ - assertNullImpl(__FILE__, __LINE__, pointer, message) + #define assertNull(pointer, message) \ + assertNullImpl(__FILE__, __LINE__, pointer, message) -#define assertDeprecated(message) \ - assertDeprecatedImpl(__FILE__, __LINE__, message) + #define assertDeprecated(message) \ + assertDeprecatedImpl(__FILE__, __LINE__, message) -#define assertStrLenMax(str, len, message) \ - assertTrue(strlen(str) < len, message) + #define assertStrLenMax(str, len, message) \ + assertTrue(strlen(str) < len, message) -#define assertStrLenMin(str, len, message) \ - assertTrue(strlen(str) >= len, message) + #define assertStrLenMin(str, len, message) \ + assertTrue(strlen(str) >= len, message) -// EOF \ No newline at end of file +#else + // If assertions are faked, we define the macros to do nothing. + #define assertTrue(x, message) ((void)0) + #define assertFalse(x, message) ((void)0) + #define assertUnreachable(message) ((void)0) + #define assertNotNull(pointer, message) ((void)0) + #define assertNull(pointer, message) ((void)0) + #define assertDeprecated(message) ((void)0) + #define assertStrLenMax(str, len, message) ((void)0) + #define assertStrLenMin(str, len, message) ((void)0) + +#endif \ No newline at end of file diff --git a/src/dusk/display/CMakeLists.txt b/src/dusk/display/CMakeLists.txt index fb0e252..46c5dbd 100644 --- a/src/dusk/display/CMakeLists.txt +++ b/src/dusk/display/CMakeLists.txt @@ -1,9 +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 + render.c ) \ No newline at end of file diff --git a/src/dusk/rpg/quest/quest.c b/src/dusk/display/render.c similarity index 88% rename from src/dusk/rpg/quest/quest.c rename to src/dusk/display/render.c index aeeb9f6..4a61745 100644 --- a/src/dusk/rpg/quest/quest.c +++ b/src/dusk/display/render.c @@ -5,4 +5,4 @@ * https://opensource.org/licenses/MIT */ -#include "quest.h" \ No newline at end of file +#include "render.h" \ No newline at end of file diff --git a/src/dusk/display/render.h b/src/dusk/display/render.h index a57ccf9..46d3b86 100644 --- a/src/dusk/display/render.h +++ b/src/dusk/display/render.h @@ -6,22 +6,37 @@ */ #pragma once -#include "dusk.h" +#include "display/renderimpl.h" -extern const uint16_t RENDER_WIDTH; -extern const uint16_t RENDER_HEIGHT; +#define RENDER_WIDTH_PIXELS 160 +#define RENDER_HEIGHT_PIXELS 144 +#define RENDER_WIDTH_TILES 20 +#define RENDER_HEIGHT_TILES 18 + +extern uint8_t RENDER_STATUS; +#define RENDER_SHOULD_EXIT (1 << 0) /** - * Init the render system. + * Initializes the rendering system. */ -void renderInit(); +void renderInit(void); /** - * Update the render system. + * Vsyncs the frame. */ -bool_t renderUpdate(); +void renderVsync(void); /** - * Dispose of the render system. + * Disposes of the rendering system. */ -void renderDispose(); \ No newline at end of file +void renderDispose(void); + +/** + * Turns off the display. + */ +void renderDisplayOff(void); + +/** + * Turns on the display. + */ +void renderDisplayOn(void); \ No newline at end of file diff --git a/src/dusk/dusk.h b/src/dusk/dusk.h index 4761ff8..9a40d66 100644 --- a/src/dusk/dusk.h +++ b/src/dusk/dusk.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024 Dominic Masters + * Copyright (c) 2025 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT @@ -7,20 +7,10 @@ #pragma once #include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include +#include +#include +#include typedef bool bool_t; -typedef char char_t; - -#define DUSK_NAME "Dusk" -#define DUSK_VERSION "1.0.0" \ No newline at end of file +typedef int int_t; \ No newline at end of file diff --git a/src/dusk/input.c b/src/dusk/input.c deleted file mode 100644 index 8a2b98e..0000000 --- a/src/dusk/input.c +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "input.h" -#include "assert/assert.h" - -input_t INPUT; - -bool_t inputIsDown(const uint8_t key) { - assertTrue(key < INPUT_COUNT, "Invalid input key"); - return (INPUT.current & key) != 0; -} - -bool_t inputWasDown(const uint8_t key) { - assertTrue(key < INPUT_COUNT, "Invalid input key"); - return (INPUT.previous & key) != 0; -} - -bool_t inputWasPressed(const uint8_t key) { - return inputIsDown(key) && !inputWasDown(key); -} - -bool_t inputWasReleased(const uint8_t key) { - return !inputIsDown(key) && inputWasDown(key); -} \ No newline at end of file diff --git a/src/dusk/input.h b/src/dusk/input.h deleted file mode 100644 index 7c45fb3..0000000 --- a/src/dusk/input.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" -#include - -#define INPUT_UP (1 << 0) -#define INPUT_DOWN (1 << 1) -#define INPUT_LEFT (1 << 2) -#define INPUT_RIGHT (1 << 3) -#define INPUT_ACTION (1 << 4) -#define INPUT_CANCEL (1 << 5) -#define INPUT_COUNT (INPUT_CANCEL + 1) - -#define INPUT_BUFFER_SIZE 128 - -typedef struct { - uint8_t current; - uint8_t previous; -} input_t; - -extern input_t INPUT; - -/** - * Initializes the input system. - */ -void inputInit(); - -/** - * Updates the input system. - */ -void inputUpdate(); - -/** - * Disposes of the input system, restoring terminal settings. - */ -void inputDispose(); - -/** - * Returns true if the specified key is currently pressed down. - * - * @param key The key to check. - * @return True if the key is down, false otherwise. - */ -bool_t inputIsDown(const uint8_t key); - -/** - * Returns true if the specified key was pressed down in the previous frame. - * - * @param key The key to check. - * @return True if the key was down in the previous frame, false otherwise. - */ -bool_t inputWasDown(const uint8_t key); - -/** - * Returns true if the specified key was pressed in the current frame. - * - * @param key The key to check. - * @return True if the key was pressed, false otherwise. - */ -bool_t inputWasPressed(const uint8_t key); - -/** - * Returns true if the specified key was released in the current frame. - * - * @param key The key to check. - * @return True if the key was released, false otherwise. - */ -bool_t inputWasReleased(const uint8_t key); \ No newline at end of file diff --git a/src/dusk/main.c b/src/dusk/main.c index 48d0669..4463b5f 100644 --- a/src/dusk/main.c +++ b/src/dusk/main.c @@ -1,32 +1,124 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ -#include "input.h" -#include "util/random.h" #include "display/render.h" -#include "ui/ui.h" -#include "rpg/entity/entity.h" -#include "rpg/world/maps/testmap.h" +uint8_t backgroundtiles[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0xFE, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0xFE, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0xFE, 0xFE, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x7F, 0x7F, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7F, 0x7F, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, + 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xAA, 0xFF, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 +}; -int32_t main(const int32_t argc, const char **argv) { - renderInit(); - inputInit(); - randomInit(); +#define backgroundmapWidth 40 +#define backgroundmapHeight 18 +#define backgroundmapBank 0 - uiInit(); - mapSet(TEST_MAP); +uint8_t backgroundmap[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x03, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x02,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, + 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 +}; - while(1) { - inputUpdate(); - uiUpdate(); - mapUpdate(); - if(!renderUpdate()) break; +void pdelay(uint8_t numVbls) { + uint8_t i; + for (i = 0; i < numVbls; i++) { + renderVsync(); } +} - return EXIT_SUCCESS; +// Press F5 to compile and run the compiled game.gb in the Emulicous Emulator/Debugger +void main(void) { + renderInit(); + + set_bkg_data(0, 7, backgroundtiles); + set_bkg_tiles(0, 0, backgroundmapWidth, backgroundmapHeight, backgroundmap); + + renderDisplayOn(); + + while (1) { + RENDER_BACKGROUND_X++; + pdelay(3); + + if((RENDER_STATUS & RENDER_SHOULD_EXIT) != 0) break; + } + + renderDispose(); } \ No newline at end of file diff --git a/src/dusk/rpg/CMakeLists.txt b/src/dusk/rpg/CMakeLists.txt deleted file mode 100644 index 8cabe87..0000000 --- a/src/dusk/rpg/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# 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 -) - -# Subdirs -add_subdirectory(entity) -add_subdirectory(event) -add_subdirectory(item) -add_subdirectory(quest) -add_subdirectory(world) \ No newline at end of file diff --git a/src/dusk/rpg/entity/CMakeLists.txt b/src/dusk/rpg/entity/CMakeLists.txt deleted file mode 100644 index db1c540..0000000 --- a/src/dusk/rpg/entity/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# 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 - entity.c - player.c - npc.c -) \ No newline at end of file diff --git a/src/dusk/rpg/entity/entity.c b/src/dusk/rpg/entity/entity.c deleted file mode 100644 index 7bbcee2..0000000 --- a/src/dusk/rpg/entity/entity.c +++ /dev/null @@ -1,192 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "assert/assert.h" -#include "util/memory.h" -#include "entity.h" -#include "rpg/world/map.h" -#include "util/math.h" - -entitycallbacks_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = { - [ENTITY_TYPE_NULL] = { 0 }, - - [ENTITY_TYPE_PLAYER] = { - .init = playerInit, - .update = playerUpdate, - .interact = NULL, - }, - - [ENTITY_TYPE_NPC] = { - .init = npcInit, - .update = npcUpdate, - .interact = npcInteract, - } -}; - -void entityInit(entity_t *entity, const entitytype_t type) { - assertNotNull(entity, "Entity is NULL"); - assertTrue(type < ENTITY_TYPE_COUNT, "Invalid entity type"); - assertNotNull(ENTITY_CALLBACKS[type].init, "Entity type has no init"); - - memoryZero(entity, sizeof(entity_t)); - entity->type = type; - ENTITY_CALLBACKS[type].init(entity); -} - -void entityUpdate(entity_t *entity) { - assertNotNull(entity, "Entity cannot be NULL"); - assertNotNull( - ENTITY_CALLBACKS[entity->type].update, - "Entity type has no update" - ); - - // Handle subpixel movement - if(entity->subX < 0) { - entity->subX++; - } else if(entity->subY < 0) { - entity->subY++; - } else if(entity->subX > 0) { - entity->subX--; - } else if(entity->subY > 0) { - entity->subY--; - } - - // Entity-Type handling - ENTITY_CALLBACKS[entity->type].update(entity); -} - -void entityTurn(entity_t *entity, const entitydir_t dir) { - assertNotNull(entity, "Entity cannot be NULL"); - assertFalse(entityIsWalking(entity), "Entity is currently walking"); - entity->dir = dir; -} - -void entityDirGetPosition( - const entitydir_t dir, - const uint8_t distance, - int8_t *outX, - int8_t *outY -) { - assertTrue(dir < ENTITY_DIR_COUNT, "Invalid entity direction"); - assertNotNull(outX, "Output X cannot be NULL"); - assertNotNull(outY, "Output Y cannot be NULL"); - - switch(dir) { - case ENTITY_DIR_UP: - *outX = 0; - *outY = -distance; - break; - case ENTITY_DIR_DOWN: - *outX = 0; - *outY = distance; - break; - case ENTITY_DIR_LEFT: - *outX = -distance; - *outY = 0; - break; - case ENTITY_DIR_RIGHT: - *outX = distance; - *outY = 0; - break; - default: - assertUnreachable("Invalid entity direction"); - } -} - -entitydir_t entityGetLookDirection( - const entity_t *entity, - const uint8_t x, - const uint8_t y -) { - assertNotNull(entity, "Entity cannot be NULL"); - assertTrue(x < MAP.width, "X coordinate out of bounds"); - assertTrue(y < MAP.height, "Y coordinate out of bounds"); - - int8_t dX = x - entity->x; - int8_t dY = y - entity->y; - - // More horizontal movement or more vertical movement? - if(mathAbsI8(dX) > mathAbsI8(dY)) { - // More horizontal movement - if(dX < 0) return ENTITY_DIR_LEFT; - return ENTITY_DIR_RIGHT; - } - - if(dY < 0) { - return ENTITY_DIR_UP; - } - return ENTITY_DIR_DOWN; -} - -void entityWalk(entity_t *entity) { - assertNotNull(entity, "Entity cannot be NULL"); - assertFalse(entityIsWalking(entity), "Entity is already walking"); - assertTrue(entityCanWalk(entity, entity->dir, NULL), "Entity cannot walk"); - - int8_t tX, tY; - entityDirGetPosition(entity->dir, 1, &tX, &tY); - - entity->y += tY; - entity->x += tX; - entity->subX = ENTITY_MOVE_SUBPIXEL * -tX; - entity->subY = ENTITY_MOVE_SUBPIXEL * -tY; -} - -bool_t entityIsWalking(const entity_t *entity) { - assertNotNull(entity, "Entity cannot be NULL"); - return (entity->subX != 0 || entity->subY != 0); -} - -bool_t entityCanWalk( - const entity_t *entity, - const entitydir_t dir, - entity_t **entityInWay -) { - assertNotNull(entity, "Entity cannot be NULL"); - assertTrue(dir < ENTITY_DIR_COUNT, "Invalid entity direction"); - - int8_t dX, dY; - entityDirGetPosition(dir, 1, &dX, &dY); - - uint8_t tX = entity->x + dX; - if(tX < 0 || tX >= MAP.width) return false; - - uint8_t tY = entity->y + dY; - if(tY < 0 || tY >= MAP.height) return false; - - if(entityInWay == NULL) { - if(mapGetEntityAt(tX, tY) != NULL) return false; - } else { - *entityInWay = mapGetEntityAt(tX, tY); - if(*entityInWay != NULL) return false; - } - - return true; -} - -void entityPositionSet(entity_t *entity, const uint8_t x, const uint8_t y) { - assertNotNull(entity, "Entity cannot be NULL"); - assertTrue(x < MAP.width, "X coordinate out of bounds"); - assertTrue(y < MAP.height, "Y coordinate out of bounds"); - entity->x = x; - entity->y = y; - entity->subX = 0; - entity->subY = 0; -} - -bool_t entityInteract(entity_t *interacted, entity_t *player) { - assertNotNull(interacted, "Interacted entity cannot be NULL"); - assertNotNull(player, "Player entity cannot be NULL"); - assertTrue(interacted->type != ENTITY_TYPE_NULL, "Interacted entity invalid"); - assertTrue(player->type == ENTITY_TYPE_PLAYER, "Entity is not a player"); - - if(ENTITY_CALLBACKS[interacted->type].interact != NULL) { - return ENTITY_CALLBACKS[interacted->type].interact(interacted, player); - } - - return false; -} \ No newline at end of file diff --git a/src/dusk/rpg/entity/entity.h b/src/dusk/rpg/entity/entity.h deleted file mode 100644 index 31dbff7..0000000 --- a/src/dusk/rpg/entity/entity.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "player.h" -#include "npc.h" - -#define ENTITY_WIDTH 16 -#define ENTITY_HEIGHT 16 -#define ENTITY_MOVE_SUBPIXEL ENTITY_WIDTH - -typedef enum { - ENTITY_DIR_UP = 0, - ENTITY_DIR_DOWN = 1, - ENTITY_DIR_LEFT = 2, - ENTITY_DIR_RIGHT = 3, - - ENTITY_DIR_NORTH = ENTITY_DIR_UP, - ENTITY_DIR_SOUTH = ENTITY_DIR_DOWN, - ENTITY_DIR_WEST = ENTITY_DIR_LEFT, - ENTITY_DIR_EAST = ENTITY_DIR_RIGHT -} entitydir_t; - -#define ENTITY_DIR_COUNT (ENTITY_DIR_RIGHT + 1) - -typedef enum { - ENTITY_TYPE_NULL = 0, - ENTITY_TYPE_PLAYER = 1, - ENTITY_TYPE_NPC = 2, -} entitytype_t; -#define ENTITY_TYPE_COUNT (ENTITY_TYPE_NPC + 1) - -typedef struct _entity_t { - entitytype_t type; - uint8_t x, y; - int8_t subX, subY; - entitydir_t dir; - - // Per type data - union { - player_t player; - npc_t npc; - }; -} entity_t; - -typedef struct { - void (*init)(entity_t *entity); - void (*update)(entity_t *entity); - bool_t (*interact)(entity_t *self, entity_t *player); -} entitycallbacks_t; -extern entitycallbacks_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT]; - -/** - * Initializes an entity with the given type. - * - * @param entity Pointer to the entity to initialize. - * @param type The type of the entity to initialize. - */ -void entityInit(entity_t *entity, const entitytype_t type); - -/** - * Updates the entity's state based on its type. - * - * @param entity Pointer to the entity to update. - */ -void entityUpdate(entity_t *entity); - -/** - * Turns the entity to face a specific direction. - * - * @param entity Pointer to the entity to turn. - * @param dir The direction to turn the entity towards. - */ -void entityTurn(entity_t *entity, const entitydir_t dir); - -/** - * Gets the position of a specific direction at a given distance. - * - * @param dir The direction to get the position in. - * @param distance The distance to move in that direction. - * @param outX Pointer to store the resulting x-coordinate. - * @param outY Pointer to store the resulting y-coordinate. - */ -void entityDirGetPosition( - const entitydir_t dir, - const uint8_t distance, - int8_t *outX, - int8_t *outY -); - -/** - * Gets the look direction for a given entity to be looking at the specified - * coordinates. - * - * @param entity Pointer to the entity to get the look direction for. - * @param x The x-coordinate to look at. - * @param Y The y-coordinate to look at. - * @return The direction the entity should look towards. - */ -entitydir_t entityGetLookDirection( - const entity_t *entity, - const uint8_t x, - const uint8_t Y -); - -/** - * Makes the entity walk in the current direction. - * - * @param entity Pointer to the entity to make walk. - */ -void entityWalk(entity_t *entity); - -/** - * Checks if the entity is currently mid-walking. - * - * @param entity Pointer to the entity to check. - * @return true if the entity is walking, false otherwise. - */ -bool_t entityIsWalking(const entity_t *entity); - -/** - * Checks if the entity can walk in a specific direction. - * - * @param entity Pointer to the entity to check. - * @param dir The direction to check for walking capability. - * @param inWay Pointer to store any entity in the way, if applicable. - * @return true if the entity can walk in the specified direction, false otherwise. - */ -bool_t entityCanWalk( - const entity_t *entity, - const entitydir_t dir, - entity_t **inWay -); - -/** - * Sets the position of the entity. - * - * @param entity Pointer to the entity to set the position for. - * @param x The x-coordinate to set. - * @param y The y-coordinate to set. - */ -void entityPositionSet(entity_t *entity, const uint8_t x, const uint8_t y); - -/** - * Handles interaction between an entity and a player. - * - * @param self Pointer to the entity that is being interacted with. - * @param player Pointer to the player entity interacting with the entity. - * @return true if interaction happened. - */ -bool_t entityInteract( - entity_t *self, - entity_t *player -); \ No newline at end of file diff --git a/src/dusk/rpg/entity/npc.c b/src/dusk/rpg/entity/npc.c deleted file mode 100644 index 7ddda17..0000000 --- a/src/dusk/rpg/entity/npc.c +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "entity.h" -#include "assert/assert.h" - -#include "ui/uitextbox.h" - -void npcInit(entity_t *ent) { - assertNotNull(ent, "NPC entity is NULL"); - assertTrue(ent->type == ENTITY_TYPE_NPC, "Entity is not an NPC"); -} - -void npcUpdate(entity_t *ent) { - assertNotNull(ent, "Entity is NULL"); - assertTrue(ent->type == ENTITY_TYPE_NPC, "Entity is not an NPC"); -} - -bool_t npcInteract(entity_t *self, entity_t *player) { - assertNotNull(self, "NPC entity cannot be NULL"); - assertNotNull(player, "Player entity cannot be NULL"); - assertTrue(self->type == ENTITY_TYPE_NPC, "Entity is not an NPC"); - assertTrue(player->type == ENTITY_TYPE_PLAYER, "Entity is not a player"); - - // Look at the player - entityTurn(self, entityGetLookDirection(self, player->x, player->y)); - eventStart(self->npc.event); - - return true; -} \ No newline at end of file diff --git a/src/dusk/rpg/entity/npc.h b/src/dusk/rpg/entity/npc.h deleted file mode 100644 index 14310d2..0000000 --- a/src/dusk/rpg/entity/npc.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "rpg/event/event.h" - -typedef struct _entity_t entity_t; - -typedef struct { - const event_t *event; -} npc_t; - -/** - * Initializes an NPC entity. - * - * @param ent Pointer to the NPC entity to initialize. - */ -void npcInit(entity_t *ent); - -/** - * Updates an NPC entity. - * - * @param ent Entity to update. - */ -void npcUpdate(entity_t *ent); - -/** - * Handles interaction between an NPC and a player. - * - * @param self Pointer to the NPC entity. - * @param player Pointer to the player entity interacting with the NPC. - */ -bool_t npcInteract(entity_t *self, entity_t *player); \ No newline at end of file diff --git a/src/dusk/rpg/entity/player.c b/src/dusk/rpg/entity/player.c deleted file mode 100644 index 2d374c9..0000000 --- a/src/dusk/rpg/entity/player.c +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "entity.h" -#include "assert/assert.h" -#include "input.h" -#include "rpg/world/map.h" - -void playerInit(entity_t *player) { - assertNotNull(player, "Player entity is NULL"); - assertTrue(player->type == ENTITY_TYPE_PLAYER, "Entity is not a player"); -} - -void playerUpdate(entity_t *entity) { - entity_t *other; - assertNotNull(entity, "Entity is NULL"); - assertTrue(entity->type == ENTITY_TYPE_PLAYER, "Entity is not a player"); - - // Handle movement - if(entityIsWalking(entity)) { - return; - } - - entitydir_t dir = 0xFF; - if(inputIsDown(INPUT_UP)) { - dir = ENTITY_DIR_UP; - } else if(inputIsDown(INPUT_DOWN)) { - dir = ENTITY_DIR_DOWN; - } else if(inputIsDown(INPUT_LEFT)) { - dir = ENTITY_DIR_LEFT; - } else if(inputIsDown(INPUT_RIGHT)) { - dir = ENTITY_DIR_RIGHT; - } - - if(dir != 0xFF) { - if(dir != entity->dir) { - entityTurn(entity, dir); - } else { - if(!entityCanWalk(entity, dir, &other)) return; - entityWalk(entity); - } - return; - } - - // Handle interaction - if(inputWasPressed(INPUT_ACTION)) { - int8_t dX, dY; - entityDirGetPosition(entity->dir, 1, &dX, &dY); - other = mapGetEntityAt(entity->x + dX, entity->y + dY); - - assertTrue(other != entity, "Player trying to interact with itself?"); - if(other != NULL && entityInteract(other, entity)) return; - } -} \ No newline at end of file diff --git a/src/dusk/rpg/entity/player.h b/src/dusk/rpg/entity/player.h deleted file mode 100644 index 14fd5dd..0000000 --- a/src/dusk/rpg/entity/player.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -typedef struct _entity_t entity_t; - -typedef struct { - uint8_t nothing; -} player_t; - -/** - * Initializes a player entity. - * - * @param ent Pointer to the player entity to initialize. - */ -void playerInit(entity_t *ent); - -/** - * Updates a player entity. - * - * @param ent Entity to update. - */ -void playerUpdate(entity_t *ent); \ No newline at end of file diff --git a/src/dusk/rpg/event/event.c b/src/dusk/rpg/event/event.c deleted file mode 100644 index b850a97..0000000 --- a/src/dusk/rpg/event/event.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "event.h" -#include "assert/assert.h" -#include "ui/uitextbox.h" -#include "util/memory.h" - -event_t eventCreate() { - event_t event; - return event; -} - -void eventStart(const event_t *event) { - assertNotNull(event, "Event cannot be NULL"); - assertTrue(event->count <= EVENT_ITEMS_MAX, "Event count exceeds maximum items"); - assertTrue(event->count > 0, "Event must have at least one item"); - - switch(event->type) { - case EVENT_TYPE_CONVERSATION: { - assertTrue(event->items[0].type == EVENT_ITEM_TYPE_TEXT, "First item in conversation must be text"); - uiTextboxSetText(event->items[0].text.text); - uiTextboxShow(); - break; - } - default: - assertFalse(true, "Unknown event type"); - } -} \ No newline at end of file diff --git a/src/dusk/rpg/event/event.h b/src/dusk/rpg/event/event.h deleted file mode 100644 index 048a225..0000000 --- a/src/dusk/rpg/event/event.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -typedef enum { - EVENT_TYPE_CONVERSATION, -} eventtype_t; - -typedef enum { - EVENT_ITEM_TYPE_TEXT -} eventitemtype_t; - -typedef struct { - const char_t *text; -} eventtext_t; - -typedef struct { - eventitemtype_t type; - - union { - eventtext_t text; - }; -} eventitem_t; - -#define EVENT_ITEMS_MAX 16 - -typedef struct { - eventtype_t type; - uint8_t count; - eventitem_t items[EVENT_ITEMS_MAX]; -} event_t; - -/** - * Creates a new event. - */ -event_t eventCreate(); - -/** - * Starts a given event. - */ -void eventStart(const event_t *event); \ No newline at end of file diff --git a/src/dusk/rpg/item/CMakeLists.txt b/src/dusk/rpg/item/CMakeLists.txt deleted file mode 100644 index e1d291d..0000000 --- a/src/dusk/rpg/item/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# 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 - itemtype.c - inventory.c -) \ No newline at end of file diff --git a/src/dusk/rpg/item/inventory.c b/src/dusk/rpg/item/inventory.c deleted file mode 100644 index 1c6de8d..0000000 --- a/src/dusk/rpg/item/inventory.c +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "assert/assert.h" -#include "inventory.h" -#include "util/memory.h" - -void inventoryInit(inventory_t *inventory) { - assertNotNull(inventory, "Inventory pointer cannot be NULL"); - - memoryZero(inventory, sizeof(inventory_t)); -} \ No newline at end of file diff --git a/src/dusk/rpg/item/inventory.h b/src/dusk/rpg/item/inventory.h deleted file mode 100644 index 0b47c0c..0000000 --- a/src/dusk/rpg/item/inventory.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "itemstack.h" - -#define INVENTORY_ITEM_COUNT 32 - -typedef struct { - itemstack_t items[INVENTORY_ITEM_COUNT]; - uint8_t itemCount; -} inventory_t; - -/** - * Initializes the inventory. - * - * @param inventory Pointer to the inventory to initialize. - */ -void inventoryInit(inventory_t *inventory); \ No newline at end of file diff --git a/src/dusk/rpg/item/itemstack.h b/src/dusk/rpg/item/itemstack.h deleted file mode 100644 index b691d5d..0000000 --- a/src/dusk/rpg/item/itemstack.h +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) 2025 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; - uint8_t count; -} itemstack_t; \ No newline at end of file diff --git a/src/dusk/rpg/item/itemtype.c b/src/dusk/rpg/item/itemtype.c deleted file mode 100644 index a6d6a5d..0000000 --- a/src/dusk/rpg/item/itemtype.c +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "assert/assert.h" -#include "itemtype.h" - -iteminfo_t ITEM_INFO[ITEM_TYPE_COUNT] = { - [ITEM_TYPE_NULL] = { 0 }, - - // Consumables - [ITEM_TYPE_POTION] = { .stackable = true }, - - // Ingredients - [ITEM_TYPE_ONION] = { .stackable = true }, - [ITEM_TYPE_SWEET_POTATO] = { .stackable = true }, - - // Cooked Items - [ITEM_TYPE_BAKED_SWEET_POTATO] = { .stackable = true }, -}; - -static inline bool_t itemTypeIsStackable(const itemtype_t type) { - assertTrue(type < ITEM_TYPE_COUNT, "Invalid item type"); - return ITEM_INFO[type].stackable; -} \ No newline at end of file diff --git a/src/dusk/rpg/item/itemtype.h b/src/dusk/rpg/item/itemtype.h deleted file mode 100644 index 22cbb91..0000000 --- a/src/dusk/rpg/item/itemtype.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2025 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, - - // Consumables - ITEM_TYPE_POTION, - - // Ingredients - ITEM_TYPE_ONION, - ITEM_TYPE_SWEET_POTATO, - - // Cooked Items - ITEM_TYPE_BAKED_SWEET_POTATO, -} itemtype_t; - -#define ITEM_TYPE_COUNT (ITEM_TYPE_BAKED_SWEET_POTATO + 1) - -typedef struct { - bool_t stackable; -} iteminfo_t; -extern iteminfo_t ITEM_INFO[ITEM_TYPE_COUNT]; - -/** - * Returns true if the item type is stackable. - * - * @param type The item type to check. - * @return true if the item type is stackable, false otherwise. - */ -static inline bool_t itemTypeIsStackable(const itemtype_t type); \ No newline at end of file diff --git a/src/dusk/rpg/quest/CMakeLists.txt b/src/dusk/rpg/quest/CMakeLists.txt deleted file mode 100644 index 785cca9..0000000 --- a/src/dusk/rpg/quest/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# 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 - quest.c -) \ No newline at end of file diff --git a/src/dusk/rpg/world/CMakeLists.txt b/src/dusk/rpg/world/CMakeLists.txt deleted file mode 100644 index 642760b..0000000 --- a/src/dusk/rpg/world/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# 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 - map.c -) - -# Subdirs -add_subdirectory(maps) \ No newline at end of file diff --git a/src/dusk/rpg/world/map.c b/src/dusk/rpg/world/map.c deleted file mode 100644 index d1ddd08..0000000 --- a/src/dusk/rpg/world/map.c +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "map.h" -#include "util/memory.h" -#include "assert/assert.h" - -map_t MAP; - -void mapSet(const mapinfo_t mapInfo) { - assertTrue(mapInfo.init != NULL, "Map initialization function cannot be NULL"); - mapInfo.init(); -} - -void mapInit(const uint8_t width, const uint8_t height) { - memoryZero(&MAP, sizeof(map_t)); - - MAP.width = width; - MAP.height = height; -} - -void mapUpdate() { - entity_t *ent = MAP.entities; - do { - if(ent->type != ENTITY_TYPE_NULL) { - entityUpdate(ent); - } - ent++; - } while(ent < MAP.entities + MAP_ENTITY_COUNT); -} - -entity_t * mapGetEntityAt(const uint8_t x, const uint8_t y) { - if(x >= MAP.width || y >= MAP.height) return NULL; - entity_t *ent = MAP.entities; - do { - if(ent->type != ENTITY_TYPE_NULL && ent->x == x && ent->y == y) return ent; - ent++; - } while(ent < MAP.entities + MAP_ENTITY_COUNT); - - return NULL; -} \ No newline at end of file diff --git a/src/dusk/rpg/world/map.h b/src/dusk/rpg/world/map.h deleted file mode 100644 index c7c3e60..0000000 --- a/src/dusk/rpg/world/map.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "rpg/entity/entity.h" - -#define MAP_ENTITY_COUNT 16 - -typedef struct { - uint8_t width; - uint8_t height; - entity_t entities[MAP_ENTITY_COUNT]; -} map_t; - -typedef struct { - const char *name; - void (*init)(void); -} mapinfo_t; - -extern map_t MAP; - -/** - * Sets the current map to the specified map information. - * - * This function initializes the map with the provided map information, - * including its name and initialization function. - * - * @param mapInfo Map information containing the name and initialization function. - */ -void mapSet(const mapinfo_t mapInfo); - -/** - * Initializes the map with the given width and height. - * - * @param width Width of the map. - * @param height Height of the map. - */ -void mapInit(const uint8_t width, const uint8_t height); - -/** - * Updates the map, processing all entities. - * - * This function should be called every frame to update the state of the map - * and its entities. - */ -void mapUpdate(); - -/** - * Gets the entity at the specified coordinates. - * - * @param x X coordinate of the entity. - * @param y Y coordinate of the entity. - * @return Pointer to the entity at the specified coordinates or NULL. - */ -entity_t * mapGetEntityAt(const uint8_t x, const uint8_t y); \ No newline at end of file diff --git a/src/dusk/rpg/world/maps/CMakeLists.txt b/src/dusk/rpg/world/maps/CMakeLists.txt deleted file mode 100644 index fb0e252..0000000 --- a/src/dusk/rpg/world/maps/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# 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 -) \ No newline at end of file diff --git a/src/dusk/rpg/world/maps/testmap.h b/src/dusk/rpg/world/maps/testmap.h deleted file mode 100644 index 59050eb..0000000 --- a/src/dusk/rpg/world/maps/testmap.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "rpg/entity/entity.h" -#include "rpg/world/map.h" -#include "rpg/event/event.h" - -const event_t TEST_MAP_NPC_TEST = { - .type = EVENT_TYPE_CONVERSATION, - .count = 1, - .items = { - { - .type = EVENT_ITEM_TYPE_TEXT, - .text = { .text = "Hello, player! How can I help you today?" } - } - }, -}; - -/** - * Initializes the test map. - * This function sets up a test map with predefined dimensions. - */ -void testMapInit() { - mapInit(10, 10); - - entity_t *ent = MAP.entities; - entityInit(ent, ENTITY_TYPE_PLAYER); - - ent++; - entityInit(ent, ENTITY_TYPE_NPC); - entityPositionSet(ent, 5, 5); - ent->npc.event = &TEST_MAP_NPC_TEST; -} - -mapinfo_t TEST_MAP = { - .name = "Test Map", - .init = testMapInit -}; \ No newline at end of file diff --git a/src/dusk/ui/CMakeLists.txt b/src/dusk/ui/CMakeLists.txt deleted file mode 100644 index cdd7163..0000000 --- a/src/dusk/ui/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# 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 - ui.c - uitextbox.c -) - -# Subdirs \ No newline at end of file diff --git a/src/dusk/ui/ui.c b/src/dusk/ui/ui.c deleted file mode 100644 index 4d1539d..0000000 --- a/src/dusk/ui/ui.c +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "ui.h" -#include "util/memory.h" -#include "ui/uitextbox.h" - -ui_t UI; - -void uiInit() { - memoryZero(&UI, sizeof(ui_t)); - uiTextboxInit(); -} - -void uiUpdate() { - uiTextboxUpdate(); -} \ No newline at end of file diff --git a/src/dusk/ui/ui.h b/src/dusk/ui/ui.h deleted file mode 100644 index 0f38901..0000000 --- a/src/dusk/ui/ui.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -typedef enum { - UI_FOCUS_TEXTBOX -} uifocus_t; - -typedef struct { - uint8_t nothing; -} ui_t; - -extern ui_t UI; - -/** - * Initializes the UI system. - */ -void uiInit(); - -/** - * Updates the UI system. - * This function should be called every frame to update the UI state. - */ -void uiUpdate(); \ No newline at end of file diff --git a/src/dusk/ui/uitextbox.c b/src/dusk/ui/uitextbox.c deleted file mode 100644 index d31a3ed..0000000 --- a/src/dusk/ui/uitextbox.c +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "uitextbox.h" -#include "assert/assert.h" -#include "util/memory.h" -#include "display/render.h" -#include "input.h" - -uitextbox_t UI_TEXTBOX; - -void uiTextboxInit() { - memoryZero(&UI_TEXTBOX, sizeof(uitextbox_t)); - - UI_TEXTBOX.width = RENDER_WIDTH; - UI_TEXTBOX.height = 58; - UI_TEXTBOX.x = 0; - UI_TEXTBOX.y = RENDER_HEIGHT - UI_TEXTBOX.height; -} - -void uiTextboxUpdate() { - if(!UI_TEXTBOX.visible) return; - - if(inputWasPressed(INPUT_ACTION)) { - UI_TEXTBOX.visible = false; - } -} - -void uiTextboxSetText(const char_t *text) { - sprintf(UI_TEXTBOX.text, "%s", text); -} - -void uiTextboxShow() { - UI_TEXTBOX.visible = true; -} - -void uiTextboxHide() { - UI_TEXTBOX.visible = false; -} \ No newline at end of file diff --git a/src/dusk/ui/uitextbox.h b/src/dusk/ui/uitextbox.h deleted file mode 100644 index 6e62e3e..0000000 --- a/src/dusk/ui/uitextbox.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -#define UI_TEXTBOX_TEXT_MAX_LENGTH 1024 - -typedef struct { - bool_t visible; - - char_t text[UI_TEXTBOX_TEXT_MAX_LENGTH]; - - uint16_t width, height; - uint16_t x, y; -} uitextbox_t; - -extern uitextbox_t UI_TEXTBOX; - -/** - * Initializes the UI textbox. - */ -void uiTextboxInit(); - -/** - * Updates the UI textbox. - */ -void uiTextboxUpdate(); - -/** - * Sets the text of the UI textbox. - * - * @param text The text to set in the textbox. - */ -void uiTextboxSetText(const char_t *text); - -/** - * Shows the UI textbox. - */ -void uiTextboxShow(); - -/** - * Hides the UI textbox. - */ -void uiTextboxHide(); \ No newline at end of file diff --git a/src/dusk/util/CMakeLists.txt b/src/dusk/util/CMakeLists.txt index b626d7f..59462e2 100644 --- a/src/dusk/util/CMakeLists.txt +++ b/src/dusk/util/CMakeLists.txt @@ -7,7 +7,4 @@ target_sources(${DUSK_TARGET_NAME} PRIVATE memory.c - string.c - random.c - math.c ) \ No newline at end of file diff --git a/src/dusk/util/math.c b/src/dusk/util/math.c deleted file mode 100644 index 636930e..0000000 --- a/src/dusk/util/math.c +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "math.h" - -int8_t mathAbsI8(const int8_t val) { - return (val > 0) ? val : -val; -} diff --git a/src/dusk/util/math.h b/src/dusk/util/math.h deleted file mode 100644 index 8166d32..0000000 --- a/src/dusk/util/math.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -/** - * Returns the absolute (ignoring sign) value of an 8-bit integer. - * - * @param val The 8-bit integer value to get the absolute value of. - * @return The absolute value of the input integer. - */ -int8_t mathAbsI8(const int8_t val); \ No newline at end of file diff --git a/src/dusk/util/memory.c b/src/dusk/util/memory.c index 97bf35a..265e8cd 100644 --- a/src/dusk/util/memory.c +++ b/src/dusk/util/memory.c @@ -48,7 +48,7 @@ void memoryMove(void *dest, const void *src, const size_t size) { memmove(dest, src, size); } -ssize_t memoryCompare( +int_t memoryCompare( const void *a, const void *b, const size_t size diff --git a/src/dusk/util/memory.h b/src/dusk/util/memory.h index ee50d3d..e227a89 100644 --- a/src/dusk/util/memory.h +++ b/src/dusk/util/memory.h @@ -83,7 +83,7 @@ void memoryMove(void *dest, const void *src, const size_t size); * @param size The size of the memory to compare. * @return 0 if the memory is equal, < 0 if a < b, > 0 if a > b. */ -ssize_t memoryCompare( +int_t memoryCompare( const void *a, const void *b, const size_t size diff --git a/src/dusk/util/random.c b/src/dusk/util/random.c deleted file mode 100644 index 0f28ba7..0000000 --- a/src/dusk/util/random.c +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "random.h" -#include "assert/assert.h" - -void randomInit() { -} \ No newline at end of file diff --git a/src/dusk/util/random.h b/src/dusk/util/random.h deleted file mode 100644 index a738425..0000000 --- a/src/dusk/util/random.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -/** - * Initializes the random number generator with a random seed. - * - * This function should be called once at the start of the program to - * initialize the random number generator with a random seed. It uses - * the current time to generate a seed. - */ -void randomInit(); \ No newline at end of file diff --git a/src/dusk/util/string.c b/src/dusk/util/string.c deleted file mode 100644 index 8bbc6ea..0000000 --- a/src/dusk/util/string.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "string.h" -#include "assert/assert.h" -#include "util/memory.h" - -bool_t stringIsWhitespace(const char_t c) { - return isspace(c); -} - -void stringCopy(char_t *dest, const char_t *src, const size_t destSize) { - assertNotNull(dest, "dest must not be NULL"); - assertNotNull(src, "src must not be NULL"); - assertTrue(destSize > 0, "destSize must be greater than 0"); - assertStrLenMax(src, destSize, "src is too long"); - memoryCopy(dest, src, strlen(src) + 1); -} - -int stringCompare(const char_t *str1, const char_t *str2) { - assertNotNull(str1, "str1 must not be NULL"); - assertNotNull(str2, "str2 must not be NULL"); - return strcmp(str1, str2); -} - -void stringTrim(char_t *str) { - assertNotNull(str, "str must not be NULL"); - - // Trim leading whitespace - char_t *start = str; - while(stringIsWhitespace(*start)) start++; - - // Trim trailing whitespace - char_t *end = start + strlen(start) - 1; - while (end >= start && stringIsWhitespace(*end)) end--; - - // Null-terminate the string - *(end + 1) = '\0'; - - // Move trimmed string to the original buffer - if (start != str) memmove(str, start, end - start + 2); -} - -char_t * stringToken(char_t *str, const char_t *delim) { - assertNotNull(str, "str must not be NULL"); - assertNotNull(delim, "delim must not be NULL"); - return strtok(str, delim); -} - -int32_t stringFormat( - char_t *dest, - const size_t destSize, - char_t *format, - ... -) { - assertNotNull(dest, "dest must not be NULL"); - assertNotNull(format, "format must not be NULL"); - assertTrue(destSize > 0, "destSize must be greater than 0"); - - va_list args; - va_start(args, format); - int32_t result = stringFormatVA(dest, destSize, format, args); - va_end(args); - - return result; -} - -int32_t stringFormatVA( - char_t *dest, - const size_t destSize, - const char_t *format, - va_list args -) { - assertNotNull(dest, "dest must not be NULL"); - assertNotNull(format, "format must not be NULL"); - assertTrue(destSize > 0, "destSize must be greater than 0"); - int32_t ret = vsnprintf(dest, destSize, format, args); - assertTrue(ret >= 0, "Failed to format string."); - assertTrue(ret < destSize, "Formatted string is too long."); - return ret; -} - -bool_t stringToI32(const char_t *str, int32_t *out) { - assertNotNull(str, "str must not be NULL"); - assertNotNull(out, "out must not be NULL"); - - char_t *endptr; - errno = 0; - long int result = strtol(str, &endptr, 10); - if (errno != 0 || *endptr != '\0') { - return false; - } - *out = (int32_t)result; - return true; -} - -bool_t stringToI64(const char_t *str, int64_t *out) { - assertNotNull(str, "str must not be NULL"); - assertNotNull(out, "out must not be NULL"); - - char_t *endptr; - errno = 0; - long long int result = strtoll(str, &endptr, 10); - if (errno != 0 || *endptr != '\0') { - return false; - } - *out = (int64_t)result; - return true; -} - -bool_t stringToU16(const char_t *str, uint16_t *out) { - assertNotNull(str, "str must not be NULL"); - assertNotNull(out, "out must not be NULL"); - - char_t *endptr; - errno = 0; - unsigned long int result = strtoul(str, &endptr, 10); - if (errno != 0 || *endptr != '\0' || result > UINT16_MAX) { - return false; - } - *out = (uint16_t)result; - return true; -} \ No newline at end of file diff --git a/src/dusk/util/string.h b/src/dusk/util/string.h deleted file mode 100644 index 1028ca3..0000000 --- a/src/dusk/util/string.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -/** - * Determines if a character is whitespace. - * - * @param c The character to check. - * @return TRUE if the character is whitespace, FALSE otherwise. - */ -bool_t stringIsWhitespace(const char_t c); - -/** - * Copies a string from src to dest, ensuring the dest string is null-terminated - * and does not exceed the specified size. - * - * @param dest The destination string. - * @param src The source string. - * @param destSize The size of the destination string exc. null terminator. - */ -void stringCopy(char_t *dest, const char_t *src, const size_t destSize); - -/** - * Compares two strings. - * - * @param str1 The first string. - * @param str2 The second string. - * @return 0 if the strings are equal, -1 if str1 is less than str2, 1 if str1 - * is greater than str2. - */ -int stringCompare(const char_t *str1, const char_t *str2); - -/** - * Trims whitespace from the beginning and end of a string. - * - * @param str The string to trim. - */ -void stringTrim(char_t *str); - -/** - * Gets the next token in a string using a delimiter. - * e.g. input: "Hello, World, Happy Monday!" with stringToken(input, ",") will - * return "Hello" then " World" then " Happy Monday!" on each subsequent call. - * - * @param str The string to split. - * @param delim The delimiter to split by. - * @return A pointer to the next token in the string. - */ -char_t * stringToken(char_t *str, const char_t *delim); - -/** - * Formats a string. - * - * @param dest The destination string. - * @param destSize The size of the destination string exc. null terminator. - * @param format The format string. - * @param ... The arguments to format. - * @return The number of characters written. - */ -int32_t stringFormat(char_t *dest, const size_t destSize, char_t *format, ...); - -/** - * Formats a string using a va_list. - * - * @param dest The destination string. - * @param destSize The size of the destination string exc. null terminator. - * @param format The format string. - * @param args The va_list of arguments. - * @return The number of characters written. - */ -int32_t stringFormatVA( - char_t *dest, - const size_t destSize, - const char_t *format, - va_list args -); - -/** - * Converts a string to an integer. - * - * @param str The string to convert. - * @param out The output integer. - * @return TRUE if the conversion was successful, FALSE otherwise. - */ -bool_t stringToI32(const char_t *str, int32_t *out); - -/** - * Converts a string to a signed 16-bit integer. - * - * @param str The string to convert. - * @param out The output signed integer. - * @return TRUE if the conversion was successful, FALSE otherwise. - */ -bool_t stringToI16(const char_t *str, int16_t *out); - -/** - * Converts a string to an unsigned 16-bit integer. - * - * @param str The string to convert. - * @param out The output unsigned integer. - * @return TRUE if the conversion was successful, FALSE otherwise. - */ -bool_t stringToU16(const char_t *str, uint16_t *out); \ No newline at end of file diff --git a/src/duskgb/CMakeLists.txt b/src/duskgb/CMakeLists.txt new file mode 100644 index 0000000..3121693 --- /dev/null +++ b/src/duskgb/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright (c) 2025 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Definitions +target_compile_definitions(${DUSK_TARGET_NAME} + PUBLIC + ASSERTIONS_FAKED=1 +) + +# Libs +target_link_libraries(${DUSK_TARGET_NAME} + PUBLIC +) + +# Includes +target_include_directories(${DUSK_TARGET_NAME} + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} +) + +# Sources +target_sources(${DUSK_TARGET_NAME} + PRIVATE +) + +# Subdirs +add_subdirectory(display) + +add_gb_rom(${DUSK_TARGET_NAME} 0x10 2 4) \ No newline at end of file diff --git a/src/dusk/rpg/event/CMakeLists.txt b/src/duskgb/display/CMakeLists.txt similarity index 90% rename from src/dusk/rpg/event/CMakeLists.txt rename to src/duskgb/display/CMakeLists.txt index fd0702c..3aa6f61 100644 --- a/src/dusk/rpg/event/CMakeLists.txt +++ b/src/duskgb/display/CMakeLists.txt @@ -1,10 +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 - event.c + renderimpl.c ) \ No newline at end of file diff --git a/src/duskgb/display/renderimpl.c b/src/duskgb/display/renderimpl.c new file mode 100644 index 0000000..c92954e --- /dev/null +++ b/src/duskgb/display/renderimpl.c @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "display/render.h" + +uint8_t RENDER_STATUS = 0; + +void renderInit(void) { + SHOW_BKG; + DISPLAY_ON; +} + +void renderVsync(void) { + vsync(); +} + +void renderDispose(void) { + +} \ No newline at end of file diff --git a/src/duskraylib/display/renderraylib.h b/src/duskgb/display/renderimpl.h similarity index 63% rename from src/duskraylib/display/renderraylib.h rename to src/duskgb/display/renderimpl.h index 19b06b8..4e77795 100644 --- a/src/duskraylib/display/renderraylib.h +++ b/src/duskgb/display/renderimpl.h @@ -6,7 +6,7 @@ */ #pragma once -#include "display/render.h" -#include +#include "duskgb.h" -extern Font FONT; \ No newline at end of file +#define RENDER_BACKGROUND_X SCX_REG +#define RENDER_BACKGROUND_Y SCY_REG \ No newline at end of file diff --git a/src/dusk/rpg/quest/quest.h b/src/duskgb/duskgb.h similarity index 85% rename from src/dusk/rpg/quest/quest.h rename to src/duskgb/duskgb.h index 52b433b..cf8fb96 100644 --- a/src/dusk/rpg/quest/quest.h +++ b/src/duskgb/duskgb.h @@ -7,7 +7,4 @@ #pragma once #include "dusk.h" - -typedef struct { - -} quest_t; \ No newline at end of file +#include \ No newline at end of file diff --git a/src/duskraylib/CMakeLists.txt b/src/duskraylib/CMakeLists.txt index 0dbe76c..3df503d 100644 --- a/src/duskraylib/CMakeLists.txt +++ b/src/duskraylib/CMakeLists.txt @@ -27,7 +27,6 @@ target_include_directories(${DUSK_TARGET_NAME} # Sources target_sources(${DUSK_TARGET_NAME} PRIVATE - input.c ) # Subdirs diff --git a/src/duskraylib/display/CMakeLists.txt b/src/duskraylib/display/CMakeLists.txt index 6187a93..3aa6f61 100644 --- a/src/duskraylib/display/CMakeLists.txt +++ b/src/duskraylib/display/CMakeLists.txt @@ -1,13 +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 - renderraylib.c -) - -# Subdirs -add_subdirectory(draw) \ No newline at end of file + renderimpl.c +) \ No newline at end of file diff --git a/src/duskraylib/display/draw/CMakeLists.txt b/src/duskraylib/display/draw/CMakeLists.txt deleted file mode 100644 index a2e73b7..0000000 --- a/src/duskraylib/display/draw/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# 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 - drawentity.c - drawui.c -) \ No newline at end of file diff --git a/src/duskraylib/display/draw/drawentity.c b/src/duskraylib/display/draw/drawentity.c deleted file mode 100644 index e2fcade..0000000 --- a/src/duskraylib/display/draw/drawentity.c +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "drawentity.h" -#include "rpg/world/map.h" - -void drawEntities() { - uint8_t x, y; - entity_t *ent = MAP.entities; - - do { - if(ent->type == ENTITY_TYPE_NULL) { - ent++; - continue; - } - - x = ent->x * ENTITY_WIDTH + ent->subX; - y = ent->y * ENTITY_HEIGHT + ent->subY; - - switch(ent->dir) { - case ENTITY_DIR_UP: - DrawTriangle( - (Vector2){ x, y + ENTITY_HEIGHT }, - (Vector2){ x + ENTITY_WIDTH, y + ENTITY_HEIGHT }, - (Vector2){ x + ENTITY_WIDTH / 2, y }, - RED - ); - break; - case ENTITY_DIR_DOWN: - DrawTriangle( - (Vector2){ x, y }, - (Vector2){ x + ENTITY_WIDTH / 2, y + ENTITY_HEIGHT }, - (Vector2){ x + ENTITY_WIDTH, y }, - RED - ); - break; - case ENTITY_DIR_LEFT: - DrawTriangle( - (Vector2){ x + ENTITY_WIDTH, y }, - (Vector2){ x, y + ENTITY_HEIGHT / 2 }, - (Vector2){ x + ENTITY_WIDTH, y + ENTITY_HEIGHT }, - RED - ); - break; - case ENTITY_DIR_RIGHT: - DrawTriangle( - (Vector2){ x, y }, - (Vector2){ x, y + ENTITY_HEIGHT }, - (Vector2){ x + ENTITY_WIDTH, y + ENTITY_HEIGHT / 2 }, - RED - ); - break; - default: - break; - } - - ent++; - } while(ent->type != ENTITY_TYPE_NULL); -} \ No newline at end of file diff --git a/src/duskraylib/display/draw/drawentity.h b/src/duskraylib/display/draw/drawentity.h deleted file mode 100644 index 0974cac..0000000 --- a/src/duskraylib/display/draw/drawentity.h +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "display/renderraylib.h" - -/** - * Draws all entities on the map. - */ -void drawEntities(); \ No newline at end of file diff --git a/src/duskraylib/display/draw/drawui.c b/src/duskraylib/display/draw/drawui.c deleted file mode 100644 index 41f4c48..0000000 --- a/src/duskraylib/display/draw/drawui.c +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "drawui.h" -#include "ui/ui.h" -#include "ui/uitextbox.h" - -void drawUITextbox() { - if(!UI_TEXTBOX.visible) return; - - DrawRectangle( - UI_TEXTBOX.x, UI_TEXTBOX.y, - UI_TEXTBOX.width, UI_TEXTBOX.height, - Fade(SKYBLUE, 0.5f) - ); - - DrawTextEx( - FONT, - UI_TEXTBOX.text, - (Vector2){ UI_TEXTBOX.x + 2, UI_TEXTBOX.y + 2 }, - FONT.baseSize, 0, BLACK - ); -} \ No newline at end of file diff --git a/src/duskraylib/display/draw/drawui.h b/src/duskraylib/display/draw/drawui.h deleted file mode 100644 index 5eedd99..0000000 --- a/src/duskraylib/display/draw/drawui.h +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "display/renderraylib.h" - -/** - * Draws the UI textbox. - */ -void drawUITextbox(); \ No newline at end of file diff --git a/src/duskraylib/display/renderimpl.c b/src/duskraylib/display/renderimpl.c new file mode 100644 index 0000000..e9d0d2a --- /dev/null +++ b/src/duskraylib/display/renderimpl.c @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "display/render.h" +#include "assert/assert.h" +#include "util/memory.h" + +uint8_t RENDER_BACKGROUND_X = 0; +uint8_t RENDER_BACKGROUND_Y = 0; +uint8_t RENDER_STATUS = 0; + +uint8_t RENDER_TILES[RENDER_TILE_COUNT] = { 0 }; +uint8_t RENDER_BACKGROUND_TILEMAP[RENDER_BACKGROUND_TILE_COUNT] = { 0 }; + +Color RENDER_PALETTE[RENDER_PALETTE_COLOR_COUNT] = { + { 102, 191, 47, 255 }, + { 78, 146, 35, 255 }, + { 48, 89, 22, 255 }, + { 18, 33, 8, 255 } +}; +bool_t RENDER_DISPLAY_ON = false; + +RenderTexture2D RENDER_BACKBUFFER; +RenderTexture2D RENDER_TILES_TEXTURE; + +void renderInit(void) { + InitWindow(RENDER_WIDTH_PIXELS * 4, RENDER_HEIGHT_PIXELS * 4, "Dusk"); + SetTargetFPS(60); + SetWindowState( + FLAG_WINDOW_RESIZABLE | + FLAG_WINDOW_HIGHDPI | + FLAG_VSYNC_HINT + ); + + // Create back buffer for rendering. + RENDER_BACKBUFFER = LoadRenderTexture( + RENDER_WIDTH_PIXELS, + RENDER_HEIGHT_PIXELS + ); + + // Create texture to hold the tile data. + RENDER_TILES_TEXTURE = LoadRenderTexture( + RENDER_TILE_COUNT * RENDER_TILE_WIDTH, + RENDER_TILE_HEIGHT + ); +} + +void renderVsync() { + int32_t x, y, i; + BeginDrawing(); + + if(RENDER_DISPLAY_ON) { + // Update the texture with the new tile data + BeginTextureMode(RENDER_TILES_TEXTURE); + i = 0; + for(i = 0; i < RENDER_TILE_COUNT; i++) { + uint8_t *tile = RENDER_TILES + (i * RENDER_TILE_BYTES_PER_TILE); + + // For each pixel in the tile... + for(y = 0; y < RENDER_TILE_HEIGHT; y++) { + uint8_t low = tile[y * RENDER_TILE_BYTES_PER_ROW]; + uint8_t high = tile[y * RENDER_TILE_BYTES_PER_ROW + 1]; + + for(x = 0; x < RENDER_TILE_WIDTH; x++) { + uint8_t loBit = (low >> (7 - x)) & 1; + uint8_t hiBit = (high >> (7 - x)) & 1; + uint8_t paletteIndex = (hiBit << 1) | loBit; + + // Draw the pixel to the texture + DrawPixel( + (i * RENDER_TILE_WIDTH) + x, + y, + RENDER_PALETTE[paletteIndex] + ); + } + } + } + EndTextureMode(); + + // Clear the back buffer + BeginTextureMode(RENDER_BACKBUFFER); + ClearBackground(RENDER_PALETTE[0]); + + // Render background tiles + i = 0; + for(y = 0; y < RENDER_BACKGROUND_ROWS; y++) { + for(x = 0; x < RENDER_BACKGROUND_COLUMNS; x++) { + // Get the tile index from the tilemap + uint8_t tileIndex = RENDER_BACKGROUND_TILEMAP[i++]; + + DrawTexturePro( + RENDER_TILES_TEXTURE.texture, + (Rectangle){ + .x = ((int32_t)tileIndex) * RENDER_TILE_WIDTH, + .y = 0, + .width = RENDER_TILE_WIDTH, + .height = -RENDER_TILE_HEIGHT + }, + (Rectangle){ + ((int32_t)x * RENDER_TILE_WIDTH) - RENDER_BACKGROUND_X, + ((int32_t)y * RENDER_TILE_HEIGHT) - RENDER_BACKGROUND_Y, + RENDER_TILE_WIDTH, + RENDER_TILE_HEIGHT + }, + (Vector2){ 0, 0 }, + 0.0f, + WHITE + ); + } + } + + // Render the back buffer to the screen + EndTextureMode(); + ClearBackground(WHITE); + + // Keep aspect and center the render + int32_t renderWidth, renderHeight, renderX, renderY; + const int32_t width = GetScreenWidth(); + const int32_t height = GetScreenHeight(); + if (RENDER_WIDTH_PIXELS * height > RENDER_HEIGHT_PIXELS * width) { + renderWidth = width; + renderHeight = (RENDER_HEIGHT_PIXELS * width) / RENDER_WIDTH_PIXELS; + renderX = 0; + renderY = (height - renderHeight) / 2; + } else { + renderWidth = (RENDER_WIDTH_PIXELS * height) / RENDER_HEIGHT_PIXELS; + renderHeight = height; + renderX = (width - renderWidth) / 2; + renderY = 0; + } + DrawTexturePro( + RENDER_BACKBUFFER.texture, + (Rectangle) { 0, 0, RENDER_WIDTH_PIXELS, -RENDER_HEIGHT_PIXELS }, + (Rectangle) { renderX, renderY, renderWidth, renderHeight }, + (Vector2) { 0, 0 }, + 0.0f, + WHITE + ); + } + + EndDrawing(); + if(WindowShouldClose()) RENDER_STATUS |= RENDER_SHOULD_EXIT; +} + +void renderDispose() { + UnloadRenderTexture(RENDER_TILES_TEXTURE); + CloseWindow(); +} + +void renderDisplayOn(void) { + RENDER_DISPLAY_ON = true; +} + +void renderDisplayOff(void) { + RENDER_DISPLAY_ON = false; +} + +void set_bkg_data( + const uint8_t index, + const uint8_t count, + const uint8_t *tiles +) { + assertTrue(count > 0, "Count must be greater than zero"); + assertNotNull(tiles, "Tiles pointer must not be null"); + + // Copy data to fake vram + memoryCopy( + &RENDER_TILES[index * RENDER_TILE_BYTES_PER_TILE], + tiles, + count * RENDER_TILE_BYTES_PER_TILE + ); +} + +void set_bkg_tiles( + const uint8_t xPos, + const uint8_t yPos, + const uint8_t width, + const uint8_t height, + const uint8_t *tiles +) { + uint8_t w = width, h = height, x = xPos, y = yPos; + assertNotNull(tiles, "Tiles pointer must not be null"); + + // Clamp x and y to tilemap bounds + if (x >= RENDER_BACKGROUND_COLUMNS) x = RENDER_BACKGROUND_COLUMNS - 1; + if (y >= RENDER_BACKGROUND_ROWS) y = RENDER_BACKGROUND_ROWS - 1; + + // Clamp width and height so we don't overflow past edges + if (x + w > RENDER_BACKGROUND_COLUMNS) { + w = RENDER_BACKGROUND_COLUMNS - x; + } + if (y + h > RENDER_BACKGROUND_ROWS) { + h = RENDER_BACKGROUND_ROWS - y; + } + + if (w == 0 || h == 0) return; + + for (uint8_t row = 0; row < h; row++) { + memoryCopy( + &RENDER_BACKGROUND_TILEMAP[(y + row) * RENDER_BACKGROUND_COLUMNS + x], + &tiles[row * width], + w + ); + } +} diff --git a/src/duskraylib/display/renderimpl.h b/src/duskraylib/display/renderimpl.h new file mode 100644 index 0000000..f957d25 --- /dev/null +++ b/src/duskraylib/display/renderimpl.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "duskraylib.h" + +#define RENDER_TILE_COUNT 384 +#define RENDER_TILE_WIDTH 8 +#define RENDER_TILE_BYTES_PER_ROW 2 +#define RENDER_TILE_HEIGHT 8 +#define RENDER_TILE_BYTES_PER_TILE (RENDER_TILE_BYTES_PER_ROW * RENDER_TILE_HEIGHT) +#define RENDER_BACKGROUND_COLUMNS 32 +#define RENDER_BACKGROUND_ROWS 32 +#define RENDER_BACKGROUND_TILE_COUNT (RENDER_BACKGROUND_COLUMNS * RENDER_BACKGROUND_ROWS) + +extern uint8_t RENDER_BACKGROUND_X; +extern uint8_t RENDER_BACKGROUND_Y; +extern uint8_t RENDER_TILES[RENDER_TILE_COUNT]; + +#define RENDER_PALETTE_COLOR_COUNT 4 +extern Color RENDER_PALETTE[RENDER_PALETTE_COLOR_COUNT]; +extern bool_t RENDER_DISPLAY_ON; + +/** + * Sets the background tile data. + * + * @param index The starting index of the tile data. + * @param count The number of tiles to set. + * @param tiles Pointer to the tile data array. + */ +void set_bkg_data( + const uint8_t index, + const uint8_t count, + const uint8_t *tiles +); + +/** + * Sets the background tiles. + * + * @param x The x-coordinate of the top-left corner of the background. + * @param y The y-coordinate of the top-left corner of the background. + * @param width The width of the background in tiles. + * @param height The height of the background in tiles. + * @param tiles Pointer to the tile map data. + */ +void set_bkg_tiles( + const uint8_t x, + const uint8_t y, + const uint8_t width, + const uint8_t height, + const uint8_t *tiles +); \ No newline at end of file diff --git a/src/duskraylib/display/renderraylib.c b/src/duskraylib/display/renderraylib.c deleted file mode 100644 index 674b78f..0000000 --- a/src/duskraylib/display/renderraylib.c +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "assert/assert.h" -#include "display/render.h" -#include - -#include "display/draw/drawentity.h" -#include "display/draw/drawui.h" - -const uint16_t RENDER_WIDTH = 480; -const uint16_t RENDER_HEIGHT = 270; -Font FONT; - -void renderInit() { - InitWindow(RENDER_WIDTH, RENDER_HEIGHT, "Dusk"); - SetTargetFPS(60); - - FONT = LoadFontEx( - "../assets/ark-pixel-font/12px/monospaced/ark-pixel-12px-monospaced-latin.otf", - 12, NULL, 0 - ); -} - -bool_t renderUpdate() { - uint8_t x, y; - char_t buffer[64]; - - // End rendering? - if(WindowShouldClose()) return false; - - BeginDrawing(); - ClearBackground(RAYWHITE); - - drawEntities(); - drawUITextbox(); - - EndDrawing(); - - return true; -} - -void renderDispose() { - CloseWindow(); -} \ No newline at end of file diff --git a/src/dusk/rpg/event/eventtext.h b/src/duskraylib/duskraylib.h similarity index 80% rename from src/dusk/rpg/event/eventtext.h rename to src/duskraylib/duskraylib.h index 1e6be71..846c48c 100644 --- a/src/dusk/rpg/event/eventtext.h +++ b/src/duskraylib/duskraylib.h @@ -6,4 +6,5 @@ */ #pragma once -#include "dusk.h" \ No newline at end of file +#include "dusk.h" +#include \ No newline at end of file diff --git a/src/duskraylib/input.c b/src/duskraylib/input.c deleted file mode 100644 index b5e60ba..0000000 --- a/src/duskraylib/input.c +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "input.h" -#include "raylib.h" - -typedef struct { - int32_t key; - uint8_t flag; -} inputmap_t; - -const inputmap_t INPUT_MAP[] = { - { KEY_W, INPUT_UP }, - { KEY_S, INPUT_DOWN }, - { KEY_A, INPUT_LEFT }, - { KEY_D, INPUT_RIGHT }, - - { KEY_SPACE, INPUT_ACTION }, - { KEY_E, INPUT_ACTION }, - { KEY_ENTER, INPUT_ACTION }, - - { KEY_ESCAPE, INPUT_CANCEL }, - { KEY_Q, INPUT_CANCEL }, - { KEY_BACKSPACE, INPUT_CANCEL }, - - { KEY_UP, INPUT_UP }, - { KEY_DOWN, INPUT_DOWN }, - { KEY_LEFT, INPUT_LEFT }, - { KEY_RIGHT, INPUT_RIGHT }, - { KEY_ENTER, INPUT_ACTION }, - { KEY_BACKSPACE, INPUT_CANCEL }, - { 0, 0 } -}; - -void inputInit() { - -} - -void inputUpdate() { - uint8_t state = 0; - inputmap_t *map = INPUT_MAP; - - do { - if(IsKeyDown(map->key)) { - state |= map->flag; - } - map++; - } while(map->key != 0); - - INPUT.previous = INPUT.current; - INPUT.current = state; -} - -void inputDispose() { - -} diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 496a55d..c080a69 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -5,5 +5,4 @@ # Tools add_subdirectory(assetstool) -add_subdirectory(copytool) -add_subdirectory(glsltool) \ No newline at end of file +add_subdirectory(copytool) \ No newline at end of file