diff --git a/src/dusk/CMakeLists.txt b/src/dusk/CMakeLists.txt index ef552d1..b9bd045 100644 --- a/src/dusk/CMakeLists.txt +++ b/src/dusk/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources(${DUSK_TARGET_NAME} PRIVATE game.c input.c + time.c ) # Subdirs diff --git a/src/dusk/game.c b/src/dusk/game.c index 91a17b1..9f00400 100644 --- a/src/dusk/game.c +++ b/src/dusk/game.c @@ -14,12 +14,16 @@ #include "event/event.h" #include "ui/uitextbox.h" #include "console/console.h" +#include "util/memory.h" +#include "time.h" game_t GAME; void gameInit(void) { + memoryZero(&GAME, sizeof(game_t)); GAME.running = true; + timeInit(); consoleInit(); inputInit(); eventInit(); @@ -28,12 +32,15 @@ void gameInit(void) { } void gameUpdate(void) { + timeUpdate(); sceneUpdate(); uiTextboxUpdate(); eventUpdate(); consoleUpdate(); inputUpdate(); + + if(inputPressed(INPUT_BIND_QUIT)) consoleExec("quit"); } void gameDispose(void) { diff --git a/src/dusk/time.c b/src/dusk/time.c new file mode 100644 index 0000000..f58e472 --- /dev/null +++ b/src/dusk/time.c @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "time.h" +#include "util/memory.h" +#include "assert/assert.h" + +dusktime_t TIME; + +void timeInit(void) { + memoryZero(&TIME, sizeof(TIME)); +} + +void timeUpdate(void) { + #if DUSK_DYNAMIC_TIME + TIME.delta = timeDeltaGet(); + #else + TIME.delta = DUSK_TIME_STEP; + #endif + + TIME.time += TIME.delta; + assertTrue(TIME.delta >= 0.0f, "Time delta is negative"); +} \ No newline at end of file diff --git a/src/dusk/time.h b/src/dusk/time.h new file mode 100644 index 0000000..2e5a03f --- /dev/null +++ b/src/dusk/time.h @@ -0,0 +1,47 @@ +/** + * 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 { + float_t delta; + float_t time; +} dusktime_t; + +extern dusktime_t TIME; + +#ifndef DUSK_DYNAMIC_TIME + #define DUSK_DYNAMIC_TIME 1 +#endif + +#if DUSK_DYNAMIC_TIME == 0 + #ifndef DUSK_TIME_STEP + #define DUSK_TIME_STEP (1.0f / 60.0f) + #endif +#endif + +/** + * Initializes the time system. + */ +void timeInit(void); + +/** + * Updates the time system + */ +void timeUpdate(void); + +#if DUSK_DYNAMIC_TIME == 1 + /** + * Gets the time delta since the last frame, in seconds. Tied to the + * platform. + * + * This will only get called once per gameUpdate. + */ + float_t timeDeltaGet(void); +#endif + diff --git a/src/dusk/world/chunk.h b/src/dusk/world/chunk.h index b389fc2..c2bcf36 100644 --- a/src/dusk/world/chunk.h +++ b/src/dusk/world/chunk.h @@ -7,16 +7,17 @@ #pragma once #include "tile.h" - -#define CHUNK_MAP_WIDTH 4 -#define CHUNK_MAP_HEIGHT 3 -#define CHUNK_MAP_COUNT (CHUNK_MAP_WIDTH * CHUNK_MAP_HEIGHT) +#include "display/render.h" #define CHUNK_WIDTH 8 #define CHUNK_HEIGHT 8 #define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT) #define CHUNK_ENTITY_COUNT_MAX 8 +#define CHUNK_MAP_WIDTH (((RENDER_WIDTH / TILE_WIDTH_HEIGHT)/CHUNK_WIDTH)+2) +#define CHUNK_MAP_HEIGHT (((RENDER_HEIGHT / TILE_WIDTH_HEIGHT)/CHUNK_HEIGHT)+2) +#define CHUNK_MAP_COUNT (CHUNK_MAP_WIDTH * CHUNK_MAP_HEIGHT) + typedef struct { uint16_t x, y; tile_t tilesBase[CHUNK_TILE_COUNT]; diff --git a/src/duskpsp/CMakeLists.txt b/src/duskpsp/CMakeLists.txt index 2db134f..f9f5efc 100644 --- a/src/duskpsp/CMakeLists.txt +++ b/src/duskpsp/CMakeLists.txt @@ -20,6 +20,7 @@ target_compile_definitions(${DUSK_TARGET_NAME} RENDER_HEIGHT=272 RENDER_WINDOW_WIDTH_DEFAULT=480 RENDER_WINDOW_HEIGHT_DEFAULT=272 + DUSK_DYNAMIC_TIME=0 ) # Includes diff --git a/src/dusksdl2/CMakeLists.txt b/src/dusksdl2/CMakeLists.txt index b2b90b2..407a27a 100644 --- a/src/dusksdl2/CMakeLists.txt +++ b/src/dusksdl2/CMakeLists.txt @@ -32,6 +32,7 @@ target_sources(${DUSK_TARGET_NAME} PRIVATE dusksdl2input.c main.c + time.c ) # Subdirs diff --git a/src/dusksdl2/display/CMakeLists.txt b/src/dusksdl2/display/CMakeLists.txt index 765f28c..f705193 100644 --- a/src/dusksdl2/display/CMakeLists.txt +++ b/src/dusksdl2/display/CMakeLists.txt @@ -8,8 +8,6 @@ target_sources(${DUSK_TARGET_NAME} PRIVATE render.c renderbackbuffer.c - rendertext.c - renderconsole.c ) # Subdirs @@ -19,4 +17,5 @@ add_subdirectory(mesh) add_subdirectory(overworld) add_subdirectory(texture) add_subdirectory(spritebatch) -add_subdirectory(scene) \ No newline at end of file +add_subdirectory(scene) +add_subdirectory(ui) \ No newline at end of file diff --git a/src/dusksdl2/display/overworld/renderoverworld.c b/src/dusksdl2/display/overworld/renderoverworld.c index b068c1a..c308558 100644 --- a/src/dusksdl2/display/overworld/renderoverworld.c +++ b/src/dusksdl2/display/overworld/renderoverworld.c @@ -41,7 +41,6 @@ void renderOverworldDraw(void) { for(uint8_t i = 0; i < CHUNK_MAP_COUNT; i++) { renderchunk_t *chunk = &RENDER_OVERWORLD.chunks[i]; - // meshDraw(&chunk->meshBase, 0, CHUNK_TILE_COUNT * QUAD_VERTEX_COUNT); meshDraw(&chunk->meshBase, -1, -1); } @@ -53,8 +52,8 @@ void renderOverworldDraw(void) { // Draw the entity spriteBatchPush( NULL, - entity->x, entity->y, - entity->x + TILE_WIDTH_HEIGHT, entity->y + TILE_WIDTH_HEIGHT, + floorf(entity->x), floorf(entity->y), + floorf(entity->x + TILE_WIDTH_HEIGHT), floorf(entity->y + TILE_WIDTH_HEIGHT), 0xFF, 0x00, 0xFF, 0XFF, 0.0f, 0.0f, 1.0f, 1.0f ); diff --git a/src/dusksdl2/display/render.c b/src/dusksdl2/display/render.c index ada3fbc..1a36e98 100644 --- a/src/dusksdl2/display/render.c +++ b/src/dusksdl2/display/render.c @@ -5,11 +5,13 @@ * https://opensource.org/licenses/MIT */ +#include "dusksdl2input.h" #include "render.h" #include "assert/assert.h" #include "renderbackbuffer.h" -#include "rendertext.h" -#include "renderconsole.h" +#include "display/ui/rendertext.h" +#include "display/ui/renderconsole.h" +#include "display/ui/renderfps.h" #include "console/console.h" #include "display/scene/renderscene.h" #include "display/spritebatch/spritebatch.h" @@ -23,6 +25,7 @@ errorret_t renderInit(void) { // Init SDL uint32_t flags = SDL_INIT_VIDEO; #if INPUT_SUPPORT_GAMEPAD + printf("Gamepad support enabled.\n"); flags |= SDL_INIT_GAMECONTROLLER; #endif @@ -100,6 +103,7 @@ errorret_t renderDraw(void) { // Draw UI cameraUIPush(); renderConsoleDraw(); + renderFPSDraw(); spriteBatchFlush(); cameraUIPop(); diff --git a/src/dusksdl2/display/ui/CMakeLists.txt b/src/dusksdl2/display/ui/CMakeLists.txt new file mode 100644 index 0000000..7b13424 --- /dev/null +++ b/src/dusksdl2/display/ui/CMakeLists.txt @@ -0,0 +1,12 @@ +# 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 + renderconsole.c + renderfps.c + rendertext.c +) \ No newline at end of file diff --git a/src/dusksdl2/display/renderconsole.c b/src/dusksdl2/display/ui/renderconsole.c similarity index 94% rename from src/dusksdl2/display/renderconsole.c rename to src/dusksdl2/display/ui/renderconsole.c index 6b4df19..0c6b0c5 100644 --- a/src/dusksdl2/display/renderconsole.c +++ b/src/dusksdl2/display/ui/renderconsole.c @@ -7,7 +7,7 @@ #include "renderconsole.h" #include "console/console.h" -#include "rendertext.h" +#include "display/ui/rendertext.h" void renderConsoleDraw(void) { if(!CONSOLE.visible) return; diff --git a/src/dusksdl2/display/renderconsole.h b/src/dusksdl2/display/ui/renderconsole.h similarity index 100% rename from src/dusksdl2/display/renderconsole.h rename to src/dusksdl2/display/ui/renderconsole.h diff --git a/src/dusksdl2/display/ui/renderfps.c b/src/dusksdl2/display/ui/renderfps.c new file mode 100644 index 0000000..078f21f --- /dev/null +++ b/src/dusksdl2/display/ui/renderfps.c @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "renderfps.h" +#include "display/ui/rendertext.h" +#include "time.h" + +void renderFPSDraw(void) { + float_t fps = 1.0f / TIME.delta; + + char_t buffer[32]; + snprintf(buffer, sizeof(buffer), "FPS: %.1f", fps); + + if(fps >= 50.0f) { + // Green + renderTextDraw(0, 0, buffer, 0x00, 0xFF, 0x00); + } else if(fps >= 30.0f) { + // Yellow + renderTextDraw(0, 0, buffer, 0xFF, 0xFF, 0x00); + } else { + // Red + renderTextDraw(0, 0, buffer, 0xFF, 0x00, 0x00); + } +} \ No newline at end of file diff --git a/src/dusksdl2/display/ui/renderfps.h b/src/dusksdl2/display/ui/renderfps.h new file mode 100644 index 0000000..739256c --- /dev/null +++ b/src/dusksdl2/display/ui/renderfps.h @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once + +/** + * Draws the FPS overlay. + */ +void renderFPSDraw(void); \ No newline at end of file diff --git a/src/dusksdl2/display/rendertext.c b/src/dusksdl2/display/ui/rendertext.c similarity index 99% rename from src/dusksdl2/display/rendertext.c rename to src/dusksdl2/display/ui/rendertext.c index c3d3152..6488211 100644 --- a/src/dusksdl2/display/rendertext.c +++ b/src/dusksdl2/display/ui/rendertext.c @@ -6,7 +6,7 @@ */ #include "rendertext.h" -#include "render.h" +#include "display/render.h" #include "assert/assert.h" #include "display/spritebatch/spritebatch.h" #include "util/memory.h" diff --git a/src/dusksdl2/display/rendertext.h b/src/dusksdl2/display/ui/rendertext.h similarity index 100% rename from src/dusksdl2/display/rendertext.h rename to src/dusksdl2/display/ui/rendertext.h diff --git a/src/dusksdl2/dusksdl2input.h b/src/dusksdl2/dusksdl2input.h index 8eb6d90..179243c 100644 --- a/src/dusksdl2/dusksdl2input.h +++ b/src/dusksdl2/dusksdl2input.h @@ -30,7 +30,7 @@ { SDL_CONTROLLER_BUTTON_DPAD_RIGHT, INPUT_BIND_RIGHT }, { SDL_CONTROLLER_BUTTON_A, INPUT_BIND_ACTION }, { SDL_CONTROLLER_BUTTON_B, INPUT_BIND_CANCEL }, - { SDL_CONTROLLER_BUTTON_MISC1, INPUT_BIND_CONSOLE }, + { SDL_CONTROLLER_BUTTON_BACK, INPUT_BIND_CONSOLE }, { 0, 0 } }; #endif diff --git a/src/dusksdl2/main.c b/src/dusksdl2/main.c index 91a3e23..6018ead 100644 --- a/src/dusksdl2/main.c +++ b/src/dusksdl2/main.c @@ -7,7 +7,6 @@ #include "display/render.h" #include "game.h" -#include "console/console.h" #include "input.h" #define mainError(ret) \ @@ -26,7 +25,6 @@ int main(int argc, char *argv[]) { gameUpdate(); mainError(renderDraw()); - if(inputPressed(INPUT_BIND_QUIT)) consoleExec("quit"); if(!GAME.running) break; } diff --git a/src/dusksdl2/time.c b/src/dusksdl2/time.c new file mode 100644 index 0000000..55cab73 --- /dev/null +++ b/src/dusksdl2/time.c @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "time.h" +#include "dusksdl2.h" + +#if DUSK_DYNAMIC_TIME + uint32_t TIME_LAST = 0; + + float_t timeDeltaGet(void) { + // Get the current time in milliseconds + uint32_t currentTime = SDL_GetTicks(); + float_t delta = (currentTime - TIME_LAST) / 1000.0f; + TIME_LAST = currentTime; + return delta; + } +#endif \ No newline at end of file