From 38ce7681688d592fd52ca184068d7222a64eddc4 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 6 Mar 2026 13:40:27 -0600 Subject: [PATCH] kms --- CMakeLists.txt | 9 +- cmake/modules/Findpspsdk.cmake | 106 ------------ cmake/targets/dolphin.cmake | 14 +- cmake/targets/gamecube.cmake | 3 + cmake/targets/linux.cmake | 6 +- cmake/targets/psp.cmake | 8 +- cmake/targets/wii.cmake | 4 +- src/CMakeLists.txt | 4 - src/assert/assert.c | 2 +- src/assert/assert.h | 4 +- src/debug/CMakeLists.txt | 4 +- src/debug/debug.c | 72 +------- src/{ => debug}/platform/CMakeLists.txt | 11 +- src/debug/platform/dolphin.c | 70 ++++++++ src/debug/platform/dolphin.h | 22 +++ src/debug/platform/psp.c | 19 +++ src/debug/platform/psp.h | 17 ++ src/display/CMakeLists.txt | 1 + src/display/display.c | 209 +----------------------- src/display/display.h | 16 +- src/display/platform/CMakeLists.txt | 12 ++ src/display/platform/dolphin.c | 92 +++++++++++ src/display/platform/dolphin.h | 27 +++ src/display/platform/psp.c | 12 ++ src/display/platform/psp.h | 13 ++ src/display/platform/sdl2.c | 124 ++++++++++++++ src/display/platform/sdl2.h | 35 ++++ src/dusk.h | 15 +- src/duskdolphin.h | 11 ++ src/duskpsp.h | 13 ++ src/platform/SDL2/CMakeLists.txt | 0 src/platform/linux/CMakeLists.txt | 0 32 files changed, 539 insertions(+), 416 deletions(-) delete mode 100644 cmake/modules/Findpspsdk.cmake rename src/{ => debug}/platform/CMakeLists.txt (57%) create mode 100644 src/debug/platform/dolphin.c create mode 100644 src/debug/platform/dolphin.h create mode 100644 src/debug/platform/psp.c create mode 100644 src/debug/platform/psp.h create mode 100644 src/display/platform/CMakeLists.txt create mode 100644 src/display/platform/dolphin.c create mode 100644 src/display/platform/dolphin.h create mode 100644 src/display/platform/psp.c create mode 100644 src/display/platform/psp.h create mode 100644 src/display/platform/sdl2.c create mode 100644 src/display/platform/sdl2.h create mode 100644 src/duskdolphin.h create mode 100644 src/duskpsp.h delete mode 100644 src/platform/SDL2/CMakeLists.txt delete mode 100644 src/platform/linux/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index aa9d414..d3a44cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,6 @@ set(DUSK_LIBRARY_TARGET_NAME "DuskCore" CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_BINARY_TARGET_NAME "Dusk" CACHE INTERNAL ${DUSK_CACHE_TARGET}) set(DUSK_ASSETS_ZIP "${DUSK_BUILD_DIR}/dusk.dsk" CACHE INTERNAL ${DUSK_CACHE_TARGET}) -# Set default target system if(NOT DEFINED DUSK_TARGET_SYSTEM) set(DUSK_TARGET_SYSTEM "linux") endif() @@ -52,7 +51,7 @@ project(${DUSK_LIBRARY_TARGET_NAME} ) # Either, create library and binary separately (used for tests), or make them -# one in the same so all code is in the binary. +# one in the same so all code is in the binary only. if(ENABLE_TESTS) # MainLibrary add_library(${DUSK_LIBRARY_TARGET_NAME} STATIC) @@ -70,6 +69,12 @@ else() add_executable(${DUSK_BINARY_TARGET_NAME} ${DUSK_SOURCES_DIR}/null.c) endif() +# Definitions +target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} + PUBLIC + DUSK_TARGET_SYSTEM="${DUSK_TARGET_SYSTEM}" +) + # Toolchains include(cmake/targets/${DUSK_TARGET_SYSTEM}.cmake) diff --git a/cmake/modules/Findpspsdk.cmake b/cmake/modules/Findpspsdk.cmake deleted file mode 100644 index e145c35..0000000 --- a/cmake/modules/Findpspsdk.cmake +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) 2025 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -if(NOT TARGET pspsdk) - message(STATUS "Looking for PSPSDK...") - - set(PSPSDK_FOUND FALSE CACHE INTERNAL "PSPSDK found") - set(PSPSDK_DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/_pspsdk") - set(PSPSDK_SEARCH_ROOTS - "${PSPSDK_ROOT}" - "$ENV{PSPDEV}" - "$ENV{HOME}/pspdev" - "/usr/local/pspdev" - "/opt/pspdev" - "/usr/pspdev" - "${PSPSDK_DOWNLOAD_DIR}/pspdev" - ) - - foreach(root IN LISTS PSPSDK_SEARCH_ROOTS) - list(APPEND PSPSDK_BIN_HINTS "${root}/bin") - list(APPEND PSPSDK_INCLUDE_HINTS "${root}/include") - list(APPEND PSPSDK_LIB_HINTS "${root}/lib") - endforeach() - - # Find PSP GCC - find_program(PSPSDK_PSP_GCC NAMES psp-gcc HINTS ${PSPSDK_BIN_HINTS}) - - # If we did not find it, download it. - if(NOT PSPSDK_PSP_GCC) - message(STATUS "psp-gcc not found in system paths. Downloading PSPSDK tarball...") - file(DOWNLOAD - "https://github.com/pspdev/pspdev/releases/download/v20260101/pspdev-ubuntu-latest-x86_64.tar.gz" - "${CMAKE_BINARY_DIR}/pspsdk.tar.gz" - EXPECTED_HASH SHA256=68fb6063323e695a43415a151b3dd9ded61d00605f02d20146cc6933c11830f8 - SHOW_PROGRESS - ) - - # Make output dir - file(MAKE_DIRECTORY "${PSPSDK_DOWNLOAD_DIR}") - - # Extract the tarball - execute_process( - COMMAND - ${CMAKE_COMMAND} -E tar xzf "${CMAKE_BINARY_DIR}/pspsdk.tar.gz" - WORKING_DIRECTORY - "${PSPSDK_DOWNLOAD_DIR}" - RESULT_VARIABLE - tar_result - ) - if(NOT tar_result EQUAL 0) - message(FATAL_ERROR "Failed to extract PSPSDK tarball") - endif() - - # Retry discovery with extracted fallback - find_program(PSPSDK_PSP_GCC NAMES psp-gcc HINTS ${PSPSDK_BIN_HINTS}) - endif() - - if(PSPSDK_PSP_GCC) - get_filename_component(PSPSDK_BIN_ROOT "${PSPSDK_PSP_GCC}" DIRECTORY) - get_filename_component(PSPSDK_ROOT "${PSPSDK_BIN_ROOT}" DIRECTORY) - set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) - set(ENV{PSPDEV} "${PSPSDK_ROOT}") - set(CMAKE_TOOLCHAIN_FILE "${PSPSDK_ROOT}/psp/share/pspdev.cmake") - set(BUILD_PRX ON CACHE BOOL "Build PRX modules") - - include("${PSPSDK_ROOT}/psp/share/pspdev.cmake") - set(CMAKE_C_COMPILER ${PSPSDK_BIN_ROOT}/psp-gcc) - set(CMAKE_CXX_COMPILER ${PSPSDK_BIN_ROOT}/psp-g++) - - if(NOT DEFINED PSP) - message(FATAL_ERROR "PSP environment variable is not set correctly.") - endif() - - add_library(pspsdk INTERFACE IMPORTED) - set_target_properties(pspsdk PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${PSPSDK_INCLUDE_DIR}" - INTERFACE_LINK_DIRECTORIES "${PSPSDK_LIB_DIR}" - ) - target_include_directories(pspsdk - INTERFACE - ${PSPDEV}/psp/include - ${PSPDEV}/psp/sdk/include - ) - target_link_directories(pspsdk - INTERFACE - ${PSPDEV}/lib - ${PSPDEV}/psp/lib - ${PSPDEV}/psp/sdk/lib - ) - target_link_libraries(pspsdk INTERFACE - pspdebug - pspdisplay - pspge - pspctrl - pspgu - pspaudio - pspaudiolib - psputility - pspvfpu - pspvram - psphprm - ) - endif() -endif() \ No newline at end of file diff --git a/cmake/targets/dolphin.cmake b/cmake/targets/dolphin.cmake index 29d893c..58de55d 100644 --- a/cmake/targets/dolphin.cmake +++ b/cmake/targets/dolphin.cmake @@ -1,12 +1,16 @@ set(DUSK_LIBRARY_TARGET_NAME "${DUSK_LIBRARY_TARGET_NAME}.elf" CACHE INTERNAL ${DUSK_CACHE_TARGET}) +# Target definitions +target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC + DUSK_DOLPHIN +) + +# Custom compiler flags set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions") -# configure_file(opengl.pc.in opengl.pc @ONLY) + +# Need PkgConfig find_package(PkgConfig REQUIRED) pkg_check_modules(zip IMPORTED_TARGET libzip) -target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC - DOLPHIN -) # Disable all warnings target_compile_options(${DUSK_LIBRARY_TARGET_NAME} PRIVATE -w) @@ -37,6 +41,7 @@ target_compile_definitions(liblua PRIVATE LUA_USE_C89) add_library(lua::lua ALIAS liblua) set(Lua_FOUND TRUE CACHE BOOL "Lua found" FORCE) +# Link libraries target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE cglm liblua @@ -46,7 +51,6 @@ target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE ) # Postbuild - set(DUSK_BINARY_TARGET_NAME_DOL "${DUSK_BUILD_DIR}/Dusk.dol") add_custom_command(TARGET ${DUSK_BINARY_TARGET_NAME} POST_BUILD COMMAND elf2dol diff --git a/cmake/targets/gamecube.cmake b/cmake/targets/gamecube.cmake index e69de29..0d2d449 100644 --- a/cmake/targets/gamecube.cmake +++ b/cmake/targets/gamecube.cmake @@ -0,0 +1,3 @@ +include(./dolphin.cmake) + +target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DUSK_GAMECUBE) \ No newline at end of file diff --git a/cmake/targets/linux.cmake b/cmake/targets/linux.cmake index c786eca..bc78a13 100644 --- a/cmake/targets/linux.cmake +++ b/cmake/targets/linux.cmake @@ -10,4 +10,8 @@ target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC m ) -# TEST +target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC + DUSK_SDL2 + DUSK_OPENGL + DUSK_LINUX +) \ No newline at end of file diff --git a/cmake/targets/psp.cmake b/cmake/targets/psp.cmake index d024b5e..e67e085 100644 --- a/cmake/targets/psp.cmake +++ b/cmake/targets/psp.cmake @@ -1,4 +1,3 @@ -# find_package(pspsdk REQUIRED) find_package(SDL2 REQUIRED) find_package(OpenGL REQUIRED) target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC @@ -14,10 +13,17 @@ target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC lzma m ) + target_include_directories(${DUSK_LIBRARY_TARGET_NAME} PRIVATE ${SDL2_INCLUDE_DIRS} ) +target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC + DUSK_SDL2 + DUSK_OPENGL + DUSK_PSP +) + # Postbuild, create .pbp file for PSP. create_pbp_file( TARGET "${DUSK_BINARY_TARGET_NAME}" diff --git a/cmake/targets/wii.cmake b/cmake/targets/wii.cmake index 4f4f75c..d493819 100644 --- a/cmake/targets/wii.cmake +++ b/cmake/targets/wii.cmake @@ -1 +1,3 @@ -include(./dolphin.cmake) \ No newline at end of file +include(./dolphin.cmake) + +target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DUSK_WII) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a9e09c8..504800c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,10 +42,6 @@ target_sources(${DUSK_BINARY_TARGET_NAME} # Defs dusk_env_to_h(duskdefs.env duskdefs.h) -target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} - PUBLIC - DUSK_TARGET_SYSTEM="${DUSK_TARGET_SYSTEM}" -) # Subdirs add_subdirectory(assert) diff --git a/src/assert/assert.c b/src/assert/assert.c index 8c83996..b3c334c 100644 --- a/src/assert/assert.c +++ b/src/assert/assert.c @@ -8,7 +8,7 @@ #include "assert.h" #include "debug/debug.h" -#ifndef ASSERTIONS_FAKED +#ifndef DUSK_ASSERTIONS_FAKED #ifdef DUSK_TEST_ASSERT void assertTrueImpl( const char *file, diff --git a/src/assert/assert.h b/src/assert/assert.h index d6acfa1..c50dd9c 100644 --- a/src/assert/assert.h +++ b/src/assert/assert.h @@ -11,12 +11,12 @@ #ifdef DUSK_TEST_ASSERT #include - #ifdef ASSERTIONS_FAKED + #ifdef DUSK_ASSERTIONS_FAKED #error "Cannot fake assertions when DUSK_TEST_ASSERT is set." #endif #endif -#ifndef ASSERTIONS_FAKED +#ifndef DUSK_ASSERTIONS_FAKED /** * Assert a given value to be true. * diff --git a/src/debug/CMakeLists.txt b/src/debug/CMakeLists.txt index a01ae13..2b0f4b7 100644 --- a/src/debug/CMakeLists.txt +++ b/src/debug/CMakeLists.txt @@ -7,4 +7,6 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} PUBLIC debug.c -) \ No newline at end of file +) + +add_subdirectory(platform) \ No newline at end of file diff --git a/src/debug/debug.c b/src/debug/debug.c index 12f4dcc..f856306 100644 --- a/src/debug/debug.c +++ b/src/debug/debug.c @@ -6,10 +6,11 @@ */ #include "debug.h" -#if DOLPHIN - #include "display/display.h" - static char_t DEBUG_ERROR_BUFFER[16*1024] = {0}; +#if PSP + #include "platform/psp.h" +#elif DOLPHIN + #include "platform/dolphin.h" #endif void debugPrint(const char_t *message, ...) { @@ -19,26 +20,9 @@ void debugPrint(const char_t *message, ...) { va_end(args); #if PSP - FILE *file = fopen("ms0:/PSP/GAME/Dusk/debug.log", "a"); - if(file) { - va_start(args, message); - vfprintf(file, message, args); - va_end(args); - fclose(file); - } - + debugPrintPSP(message, args); #elif DOLPHIN - // append to error buffer - size_t start = strlen(DEBUG_ERROR_BUFFER); - va_start(args, message); - vsnprintf( - DEBUG_ERROR_BUFFER + start, - sizeof(DEBUG_ERROR_BUFFER) - start, - message, - args - ); - va_end(args); - + debugPrintDolphin(message, args); #endif } @@ -46,50 +30,8 @@ void debugFlush() { #if PSP // No buffering, so nothing to flush #elif DOLPHIN - // Either create graphics, or hijack the displays' graphics. - void *xfb = NULL; - GXRModeObj *rmode = NULL; - void *framebuffer; - - if(DISPLAY.frameBuffer[0]) { - console_init( - DISPLAY.frameBuffer[0], - 20, - 20, - DISPLAY.screenMode->fbWidth, - DISPLAY.screenMode->xfbHeight, - DISPLAY.screenMode->fbWidth * VI_DISPLAY_PIX_SZ - ); - } else { - VIDEO_Init(); - rmode = VIDEO_GetPreferredMode(NULL); - framebuffer = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); - console_init( - framebuffer, - 20, - 20, - rmode->fbWidth, - rmode->xfbHeight, - rmode->fbWidth*VI_DISPLAY_PIX_SZ - ); - VIDEO_Configure(rmode); - VIDEO_SetNextFramebuffer(framebuffer); - VIDEO_SetBlack(FALSE); - VIDEO_Flush(); - VIDEO_WaitVSync(); - if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); - } - - // Printf - printf("SOB\n"); - printf(DEBUG_ERROR_BUFFER); - printf("\nEOB."); - - while(SYS_MainLoop()) { - VIDEO_WaitVSync(); - } + debugFlushDolphin(); #else fflush(stdout); - #endif } \ No newline at end of file diff --git a/src/platform/CMakeLists.txt b/src/debug/platform/CMakeLists.txt similarity index 57% rename from src/platform/CMakeLists.txt rename to src/debug/platform/CMakeLists.txt index 6a6c334..544b265 100644 --- a/src/platform/CMakeLists.txt +++ b/src/debug/platform/CMakeLists.txt @@ -3,7 +3,10 @@ # This software is released under the MIT License. # https://opensource.org/licenses/MIT -if(DUSK_TARGET_SYSTEM STREQUAL "linux") - add_subdirectory(linux) - add_subdirectory(SDL2) -endif() \ No newline at end of file +# Sources + +target_sources(${DUSK_LIBRARY_TARGET_NAME} + PUBLIC + psp.c + dolphin.c +) \ No newline at end of file diff --git a/src/debug/platform/dolphin.c b/src/debug/platform/dolphin.c new file mode 100644 index 0000000..c19c2ed --- /dev/null +++ b/src/debug/platform/dolphin.c @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "dolphin.h" +#include "display/display.h" + +static char_t DEBUG_ERROR_BUFFER[16*1024] = {0}; + +void debugPrintDolphin(const char_t *message, ...) { + // append to error buffer + size_t start = strlen(DEBUG_ERROR_BUFFER); + va_list args; + va_start(args, message); + vsnprintf( + DEBUG_ERROR_BUFFER + start, + sizeof(DEBUG_ERROR_BUFFER) - start, + message, + args + ); + va_end(args); +} + +void debugFlushDolphin() { + // Either create graphics, or hijack the displays' graphics. + void *xfb = NULL; + GXRModeObj *rmode = NULL; + void *framebuffer; + + if(DISPLAY.frameBuffer[0]) { + console_init( + DISPLAY.frameBuffer[0], + 20, + 20, + DISPLAY.screenMode->fbWidth, + DISPLAY.screenMode->xfbHeight, + DISPLAY.screenMode->fbWidth * VI_DISPLAY_PIX_SZ + ); + } else { + VIDEO_Init(); + rmode = VIDEO_GetPreferredMode(NULL); + framebuffer = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + console_init( + framebuffer, + 20, + 20, + rmode->fbWidth, + rmode->xfbHeight, + rmode->fbWidth*VI_DISPLAY_PIX_SZ + ); + VIDEO_Configure(rmode); + VIDEO_SetNextFramebuffer(framebuffer); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); + } + + // Printf + printf("SOB\n"); + printf(DEBUG_ERROR_BUFFER); + printf("\nEOB."); + + while(SYS_MainLoop()) { + VIDEO_WaitVSync(); + } +} \ No newline at end of file diff --git a/src/debug/platform/dolphin.h b/src/debug/platform/dolphin.h new file mode 100644 index 0000000..5380e27 --- /dev/null +++ b/src/debug/platform/dolphin.h @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "debug/debug.h" + +/** + * Platform-specific debug print function for Dolphin. + * + * @param message The message format string. + * @param ... Additional arguments for the format string. + */ +void debugPrintDolphin(const char_t *message, ...); + +/** + * Flushes the Dolphin debug output buffer. + */ +void debugFlushDolphin(); \ No newline at end of file diff --git a/src/debug/platform/psp.c b/src/debug/platform/psp.c new file mode 100644 index 0000000..6ee191d --- /dev/null +++ b/src/debug/platform/psp.c @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "psp.h" + +void debugPrintPSP(const char_t *message, ...) { + FILE *file = fopen("ms0:/PSP/GAME/Dusk/debug.log", "a"); + if(!file) return; + + va_list args; + va_start(args, message); + vfprintf(file, message, args); + va_end(args); + fclose(file); +} \ No newline at end of file diff --git a/src/debug/platform/psp.h b/src/debug/platform/psp.h new file mode 100644 index 0000000..9af40db --- /dev/null +++ b/src/debug/platform/psp.h @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "debug/debug.h" + +/** + * Platform-specific debug print function for PSP. + * + * @param message The message format string. + * @param ... Additional arguments for the format string. + */ +void debugPrintPSP(const char_t *message, ...); \ No newline at end of file diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt index 08af9fc..08e7eb8 100644 --- a/src/display/CMakeLists.txt +++ b/src/display/CMakeLists.txt @@ -17,6 +17,7 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} add_subdirectory(camera) add_subdirectory(mesh) add_subdirectory(texture) +add_subdirectory(platform) # Color definitions dusk_run_python( diff --git a/src/display/display.c b/src/display/display.c index 7844114..a61d6a6 100644 --- a/src/display/display.c +++ b/src/display/display.c @@ -26,157 +26,9 @@ errorret_t displayInit(void) { memoryZero(&DISPLAY, sizeof(DISPLAY)); #if DISPLAY_SDL2 - uint32_t flags = SDL_INIT_VIDEO; - #if INPUT_GAMEPAD == 1 - flags |= SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK; - #endif - if(SDL_Init(flags) != 0) { - errorThrow("SDL Failed to Initialize: %s", SDL_GetError()); - } - - // Set OpenGL attributes (Needs to be done now or later?) - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - // Create window with OpenGL flag. - DISPLAY.window = SDL_CreateWindow( - "Dusk", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - DISPLAY_WINDOW_WIDTH_DEFAULT, - DISPLAY_WINDOW_HEIGHT_DEFAULT, - SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | - SDL_WINDOW_OPENGL - ); - if(!DISPLAY.window) { - errorThrow("SDL_CreateWindow failed: %s", SDL_GetError()); - } - - // Create OpenGL context - DISPLAY.glContext = SDL_GL_CreateContext(DISPLAY.window); - if(!DISPLAY.glContext) { - errorThrow("SDL_GL_CreateContext failed: %s", SDL_GetError()); - } - - SDL_GL_SetSwapInterval(1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING);// PSP defaults this on? - glShadeModel(GL_SMOOTH); // Fixes color on PSP? - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glClearDepth(1.0f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glEnableClientState(GL_COLOR_ARRAY);// To confirm: every frame on PSP? - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - - // Get and validate GL state. - GLenum err = glGetError(); - if(err != GL_NO_ERROR) { - assertUnreachable("GL Error before checking support"); - } - - // Check if paletted textures are supported. - #if PSP - DISPLAY.usingShaderedPalettes = false; - #else - GLint mask = 0; - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); - DISPLAY.usingShaderedPalettes = true; - if(mask & GL_CONTEXT_CORE_PROFILE_BIT) { - GLint numExtens = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &numExtens); - for(GLint i = 0; i < numExtens; ++i) { - const char* e = (const char*)glGetStringi(GL_EXTENSIONS, i); - if(!e) continue; - if(stringCompare(e, "GL_EXT_paletted_texture") != 0) continue; - DISPLAY.usingShaderedPalettes = false; - break; - } - } else { - const char* ext = (const char*)glGetString(GL_EXTENSIONS); - DISPLAY.usingShaderedPalettes = !( - ext && strstr(ext, "GL_EXT_paletted_texture") - ); - } - #endif - + displaySDL2Init(); #elif DOLPHIN - VIDEO_Init(); - DISPLAY.screenMode = VIDEO_GetPreferredMode(NULL); - DISPLAY.frameBuffer[0] = MEM_K0_TO_K1( - SYS_AllocateFramebuffer(DISPLAY.screenMode) - ); - DISPLAY.frameBuffer[1] = MEM_K0_TO_K1( - SYS_AllocateFramebuffer(DISPLAY.screenMode) - ); - VIDEO_Configure(DISPLAY.screenMode); - - VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]); - // VIDEO_SetPostRetraceCallback(copy_buffers); - VIDEO_SetBlack(FALSE); - VIDEO_Flush(); - VIDEO_WaitVSync(); - if(DISPLAY.screenMode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); - - DISPLAY.fifoBuffer = memalign(32, DISPLAY_FIFO_SIZE); - memoryZero(DISPLAY.fifoBuffer, DISPLAY_FIFO_SIZE); - - GX_Init(DISPLAY.fifoBuffer, DISPLAY_FIFO_SIZE); - - // This seems to be mostly related to interlacing vs progressive - GX_SetViewport( - 0, 0, - DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight, - 0, 1 - ); - float_t yscale = GX_GetYScaleFactor( - DISPLAY.screenMode->efbHeight, DISPLAY.screenMode->xfbHeight - ); - uint32_t xfbHeight = GX_SetDispCopyYScale(yscale); - GX_SetScissor( - 0, 0, - DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight - ); - GX_SetDispCopySrc( - 0, 0, - DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight - ); - GX_SetDispCopyDst(DISPLAY.screenMode->fbWidth, xfbHeight); - GX_SetCopyFilter( - DISPLAY.screenMode->aa, - DISPLAY.screenMode->sample_pattern, - GX_TRUE, - DISPLAY.screenMode->vfilter - ); - GX_SetFieldMode( - DISPLAY.screenMode->field_rendering, - ( - (DISPLAY.screenMode->viHeight == 2 * DISPLAY.screenMode->xfbHeight) ? - GX_ENABLE : - GX_DISABLE - ) - ); - - // Setup cull modes - GX_SetCullMode(GX_CULL_NONE); - GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE); - GX_SetDispCopyGamma(GX_GM_1_0); - - GX_ClearVtxDesc(); - GX_SetVtxDesc(GX_VA_POS, GX_INDEX16); - GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX16); - GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16); - GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); - GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_U8, 0); - GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + displayDolphinInit(); #endif quadInit(); @@ -191,35 +43,7 @@ errorret_t displayInit(void) { errorret_t displayUpdate(void) { #if DISPLAY_SDL2 - SDL_Event event; - while(SDL_PollEvent(&event)) { - switch(event.type) { - case SDL_QUIT: { - ENGINE.running = false; - break; - } - - case SDL_WINDOWEVENT: { - switch(event.window.event) { - case SDL_WINDOWEVENT_CLOSE: { - ENGINE.running = false; - break; - } - - default: { - break; - } - } - } - - default: { - break; - } - } - } - - SDL_GL_MakeCurrent(DISPLAY.window, DISPLAY.glContext); - + displaySDL2Update(); #endif // Reset state @@ -243,22 +67,9 @@ errorret_t displayUpdate(void) { screenRender(); #if DISPLAY_SDL2 - SDL_GL_SwapWindow(DISPLAY.window); - - GLenum err; - while((err = glGetError()) != GL_NO_ERROR) { - debugPrint("GL Error: %d\n", err); - } + displaySDL2Swap(); #elif DOLPHIN - GX_DrawDone(); - - DISPLAY.whichFrameBuffer ^= 1; - GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); - GX_SetColorUpdate(GX_TRUE); - GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE); - VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]); - VIDEO_Flush(); - VIDEO_WaitVSync(); + displayDolphinSwap(); #endif // For now, we just return an OK error. @@ -271,15 +82,7 @@ errorret_t displayDispose(void) { textDispose(); #if DISPLAY_SDL2 - if(DISPLAY.glContext) { - SDL_GL_DeleteContext(DISPLAY.glContext); - DISPLAY.glContext = NULL; - } - if(DISPLAY.window) { - SDL_DestroyWindow(DISPLAY.window); - DISPLAY.window = NULL; - } - SDL_Quit(); + displaySDL2Dispose(); #endif // For now, we just return an OK error. diff --git a/src/display/display.h b/src/display/display.h index f62b7c8..968e4af 100644 --- a/src/display/display.h +++ b/src/display/display.h @@ -10,19 +10,17 @@ #include "error/error.h" #include "display/camera/camera.h" #include "display/framebuffer.h" +#if DISPLAY_SDL2 + #include "display/platform/sdl2.h" +#elif DOLPHIN + #include "display/platform/dolphin.h" +#endif typedef struct { #if DISPLAY_SDL2 - SDL_Window *window; - SDL_GLContext glContext; - bool_t usingShaderedPalettes; - + displaysdl2_t sdl2; #elif DOLPHIN - void *frameBuffer[2];// Double-Bufferred - int whichFrameBuffer; - GXRModeObj *screenMode; - void *fifoBuffer; - + displaydolphin_t dolphin; #endif } display_t; diff --git a/src/display/platform/CMakeLists.txt b/src/display/platform/CMakeLists.txt new file mode 100644 index 0000000..b156355 --- /dev/null +++ b/src/display/platform/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_LIBRARY_TARGET_NAME} + PUBLIC + sdl2.c + psp.c + dolphin.c +) \ No newline at end of file diff --git a/src/display/platform/dolphin.c b/src/display/platform/dolphin.c new file mode 100644 index 0000000..b21593b --- /dev/null +++ b/src/display/platform/dolphin.c @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "dolphin.h" + +void displayInitDolphin(void) { + VIDEO_Init(); + DISPLAY.screenMode = VIDEO_GetPreferredMode(NULL); + DISPLAY.frameBuffer[0] = MEM_K0_TO_K1( + SYS_AllocateFramebuffer(DISPLAY.screenMode) + ); + DISPLAY.frameBuffer[1] = MEM_K0_TO_K1( + SYS_AllocateFramebuffer(DISPLAY.screenMode) + ); + VIDEO_Configure(DISPLAY.screenMode); + + VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]); + // VIDEO_SetPostRetraceCallback(copy_buffers); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if(DISPLAY.screenMode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); + + DISPLAY.fifoBuffer = memalign(32, DISPLAY_FIFO_SIZE); + memoryZero(DISPLAY.fifoBuffer, DISPLAY_FIFO_SIZE); + + GX_Init(DISPLAY.fifoBuffer, DISPLAY_FIFO_SIZE); + + // This seems to be mostly related to interlacing vs progressive + GX_SetViewport( + 0, 0, + DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight, + 0, 1 + ); + float_t yscale = GX_GetYScaleFactor( + DISPLAY.screenMode->efbHeight, DISPLAY.screenMode->xfbHeight + ); + uint32_t xfbHeight = GX_SetDispCopyYScale(yscale); + GX_SetScissor( + 0, 0, + DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight + ); + GX_SetDispCopySrc( + 0, 0, + DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight + ); + GX_SetDispCopyDst(DISPLAY.screenMode->fbWidth, xfbHeight); + GX_SetCopyFilter( + DISPLAY.screenMode->aa, + DISPLAY.screenMode->sample_pattern, + GX_TRUE, + DISPLAY.screenMode->vfilter + ); + GX_SetFieldMode( + DISPLAY.screenMode->field_rendering, + ( + (DISPLAY.screenMode->viHeight == 2 * DISPLAY.screenMode->xfbHeight) ? + GX_ENABLE : + GX_DISABLE + ) + ); + + // Setup cull modes + GX_SetCullMode(GX_CULL_NONE); + GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); + GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE); + GX_SetDispCopyGamma(GX_GM_1_0); + + GX_ClearVtxDesc(); + GX_SetVtxDesc(GX_VA_POS, GX_INDEX16); + GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX16); + GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_U8, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); +} + +void displayDolphinSwap(void) { + GX_DrawDone(); + + DISPLAY.whichFrameBuffer ^= 1; + GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + GX_SetColorUpdate(GX_TRUE); + GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE); + VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]); + VIDEO_Flush(); + VIDEO_WaitVSync(); +} \ No newline at end of file diff --git a/src/display/platform/dolphin.h b/src/display/platform/dolphin.h new file mode 100644 index 0000000..c62fa28 --- /dev/null +++ b/src/display/platform/dolphin.h @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" +#include "display/displaydefs.h" + +typedef struct { + void *frameBuffer[2];// Double-Bufferred + int whichFrameBuffer; + GXRModeObj *screenMode; + void *fifoBuffer; +} displaydolphin_t; + +/** + * Initializes the display for Dolphin. + */ +void displayDolphinInit(void); + +/** + * Swaps the back buffer to the front for Dolphin. + */ +void displayDolphinSwap(void); \ No newline at end of file diff --git a/src/display/platform/psp.c b/src/display/platform/psp.c new file mode 100644 index 0000000..8fe9e21 --- /dev/null +++ b/src/display/platform/psp.c @@ -0,0 +1,12 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "psp.h" + +void displayInitPSP(void) { + DISPLAY.usingShaderedPalettes = false; +} \ No newline at end of file diff --git a/src/display/platform/psp.h b/src/display/platform/psp.h new file mode 100644 index 0000000..d822b2f --- /dev/null +++ b/src/display/platform/psp.h @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once + +/** + * Initializes the display for PSP. + */ +void displayInitPSP(void); \ No newline at end of file diff --git a/src/display/platform/sdl2.c b/src/display/platform/sdl2.c new file mode 100644 index 0000000..3cbc3e6 --- /dev/null +++ b/src/display/platform/sdl2.c @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "sdl2.h" + +void displaySDL2Init(void) { + uint32_t flags = SDL_INIT_VIDEO; + #if INPUT_GAMEPAD == 1 + flags |= SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK; + #endif + if(SDL_Init(flags) != 0) { + errorThrow("SDL Failed to Initialize: %s", SDL_GetError()); + } + + // Set OpenGL attributes (Needs to be done now or later?) + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + // Create window with OpenGL flag. + DISPLAY.window = SDL_CreateWindow( + "Dusk", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + DISPLAY_WINDOW_WIDTH_DEFAULT, + DISPLAY_WINDOW_HEIGHT_DEFAULT, + SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | + SDL_WINDOW_OPENGL + ); + if(!DISPLAY.window) { + errorThrow("SDL_CreateWindow failed: %s", SDL_GetError()); + } + + // Create OpenGL context + DISPLAY.glContext = SDL_GL_CreateContext(DISPLAY.window); + if(!DISPLAY.glContext) { + errorThrow("SDL_GL_CreateContext failed: %s", SDL_GetError()); + } + + SDL_GL_SetSwapInterval(1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING);// PSP defaults this on? + glShadeModel(GL_SMOOTH); // Fixes color on PSP? + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glClearDepth(1.0f); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glEnableClientState(GL_COLOR_ARRAY);// To confirm: every frame on PSP? + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + + // Get and validate GL state. + GLenum err = glGetError(); + if(err != GL_NO_ERROR) { + assertUnreachable("GL Error before checking support"); + } + + #if PSP + displayInitPSP(); + #else + + #endif +} + +void displaySDL2Update(void) { + SDL_Event event; + while(SDL_PollEvent(&event)) { + switch(event.type) { + case SDL_QUIT: { + ENGINE.running = false; + break; + } + + case SDL_WINDOWEVENT: { + switch(event.window.event) { + case SDL_WINDOWEVENT_CLOSE: { + ENGINE.running = false; + break; + } + + default: { + break; + } + } + } + + default: { + break; + } + } + } + + SDL_GL_MakeCurrent(DISPLAY.window, DISPLAY.glContext); +} + +void displaySDL2Swap(void) { + SDL_GL_SwapWindow(DISPLAY.window); + + GLenum err; + while((err = glGetError()) != GL_NO_ERROR) { + debugPrint("GL Error: %d\n", err); + } +} + +void displaySDL2Dispose(void) { + if(DISPLAY.glContext) { + SDL_GL_DeleteContext(DISPLAY.glContext); + DISPLAY.glContext = NULL; + } + if(DISPLAY.window) { + SDL_DestroyWindow(DISPLAY.window); + DISPLAY.window = NULL; + } + SDL_Quit(); +} \ No newline at end of file diff --git a/src/display/platform/sdl2.h b/src/display/platform/sdl2.h new file mode 100644 index 0000000..83ec571 --- /dev/null +++ b/src/display/platform/sdl2.h @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +typedef struct { + SDL_Window *window; + SDL_GLContext glContext; + bool_t usingShaderedPalettes; +} displaysdl2_t; + +/** + * Initializes the display for SDL2. + */ +void displaySDL2Init(void); + +/** + * Updates the display for SDL2. + */ +void displaySDL2Update(void); + +/** + * Swaps the display buffers for SDL2. + */ +void displaySDL2Swap(void); + +/** + * Disposes of the display for SDL2. + */ +void displaySDL2Dispose(void); \ No newline at end of file diff --git a/src/dusk.h b/src/dusk.h index 0352c83..3739db9 100644 --- a/src/dusk.h +++ b/src/dusk.h @@ -6,6 +6,7 @@ */ #pragma once + #include #include #include @@ -22,17 +23,9 @@ #include #if PSP - #include - #include - #include - #include - #include -#endif - -#if DOLPHIN - #include - #include - #include + #include "duskpsp.h" +#elif DOLPHIN + #include "duskdolphin.h" #endif typedef bool bool_t; diff --git a/src/duskdolphin.h b/src/duskdolphin.h new file mode 100644 index 0000000..4d1660a --- /dev/null +++ b/src/duskdolphin.h @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include +#include +#include \ No newline at end of file diff --git a/src/duskpsp.h b/src/duskpsp.h new file mode 100644 index 0000000..4a0dde2 --- /dev/null +++ b/src/duskpsp.h @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/src/platform/SDL2/CMakeLists.txt b/src/platform/SDL2/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/platform/linux/CMakeLists.txt b/src/platform/linux/CMakeLists.txt deleted file mode 100644 index e69de29..0000000