From 708c4d0ec3493b1f1c0dba66cd999ac99a6dad96 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 4 Feb 2026 15:54:09 -0600 Subject: [PATCH] "Improved" --- .ci/dolphin/Dockerfile | 4 +- .ci/dolphin/build.sh | 2 +- CMakeLists.txt | 161 ++++++------------ opengl.pc.in | 10 ++ src/display/displaydefs.h | 18 +- src/display/framebuffer.c | 10 +- src/display/texture.c | 14 +- src/dusk.h | 1 - src2/CMakeLists.txt | 6 +- src2/{main.cpp => main.c} | 4 +- src2/null.c | 10 ++ ..._assets_loader.cpp => sdl_assets_loader.c} | 27 +-- src2/sdl_assets_loader.h | 3 +- src2/{sdl_starter.cpp => sdl_starter.c} | 21 ++- src2/sdl_starter.h | 13 +- 15 files changed, 150 insertions(+), 154 deletions(-) create mode 100644 opengl.pc.in rename src2/{main.cpp => main.c} (98%) create mode 100644 src2/null.c rename src2/{sdl_assets_loader.cpp => sdl_assets_loader.c} (72%) rename src2/{sdl_starter.cpp => sdl_starter.c} (66%) diff --git a/.ci/dolphin/Dockerfile b/.ci/dolphin/Dockerfile index 0c8a1c4..18be462 100644 --- a/.ci/dolphin/Dockerfile +++ b/.ci/dolphin/Dockerfile @@ -1,5 +1,5 @@ FROM devkitpro/devkitppc RUN apt update && \ - apt install -y cmake git cmake python3 python3-pip python3-polib python3-pil python3-dotenv python3-pyqt5 python3-opengl && \ - dkp-pacman -S --needed --noconfirm gamecube-sdl2 ppc-liblzma ppc-libzip ppc-liblua51 \ No newline at end of file + apt install -y python3 python3-pip python3-polib python3-pil python3-dotenv python3-pyqt5 python3-opengl && \ + dkp-pacman -S --needed --noconfirm gamecube-sdl2 ppc-liblzma ppc-libzip \ No newline at end of file diff --git a/.ci/dolphin/build.sh b/.ci/dolphin/build.sh index 43794df..b169069 100755 --- a/.ci/dolphin/build.sh +++ b/.ci/dolphin/build.sh @@ -4,8 +4,8 @@ docker run -it -v ./:/workdir myapp:latest /bin/bash -c ' \ cd /workdir && \ rm -rf build2 && \ mkdir -p build2 && \ + cmake -S. -Bbuild2 -DDUSK_TARGET_SYSTEM=gamecube -DCMAKE_TOOLCHAIN_FILE="$DEVKITPRO/cmake/GameCube.cmake" cd build2 && \ - cmake .. -DDUSK_TARGET_SYSTEM=gamecube -DCMAKE_C_COMPILER=$DEVKITPPC/bin/powerpc-eabi-gcc -DCMAKE_CXX_COMPILER=$DEVKITPPC/bin/powerpc-eabi-g++ -DBUILD_SHARED_LIBS=OFF && \ make VERBOSE=1 \ ' # docker run -it -v ./:/workdir myapp:latest /bin/bash \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b191681..2a84a8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ set(DUSK_CACHE_TARGET "dusk-target") # Build variables set(DUSK_ROOT_DIR "${CMAKE_SOURCE_DIR}") set(DUSK_BUILD_DIR "${CMAKE_BINARY_DIR}") -set(DUSK_SOURCES_DIR "${DUSK_ROOT_DIR}/src") +set(DUSK_SOURCES_DIR "${DUSK_ROOT_DIR}/src2") set(DUSK_TEST_DIR "${DUSK_ROOT_DIR}/test") set(DUSK_TEMP_DIR "${DUSK_BUILD_DIR}/temp") set(DUSK_TOOLS_DIR "${DUSK_ROOT_DIR}/tools") @@ -117,129 +117,66 @@ elseif(DUSK_TARGET_SYSTEM STREQUAL "psp") ) elseif(DUSK_TARGET_SYSTEM STREQUAL "gamecube" OR DUSK_TARGET_SYSTEM STREQUAL "wii") - if(NOT DEFINED ENV{DEVKITPPC}) - message(FATAL_ERROR "DEVKITPPC environment variable not set!") - endif() - set(DEVKITPPC $ENV{DEVKITPPC}) - if(NOT DEFINED ENV{DEVKITPRO}) - message(FATAL_ERROR "DEVKITPRO environment variable not set!") - endif() - set(DEVKITPRO $ENV{DEVKITPRO}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions") + configure_file(opengl.pc.in opengl.pc @ONLY) + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL2 IMPORTED_TARGET sdl2) + pkg_check_modules(SDL2_ttf IMPORTED_TARGET SDL2_ttf) + pkg_check_modules(SDL2_image IMPORTED_TARGET SDL2_image) + pkg_check_modules(SDL2_mixer IMPORTED_TARGET SDL2_mixer) + pkg_check_modules(OPENGL IMPORTED_TARGET opengl) + pkg_check_modules(zip IMPORTED_TARGET libzip) + pkg_check_modules(GLU IMPORTED_TARGET glu) + pkg_check_modules(freetype2 IMPORTED_TARGET freetype2) - string(APPEND CMAKE_C_FLAGS "-g -O2 -mcpu=750 -meabi -mhard-float -Wall -mogc -DGEKKO") - set(CMAKE_FIND_ROOT_PATH "${DEVKITPRO}" "${DEVKITPPC}") - 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_SKIP_RPATH TRUE) - set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) - set(CMAKE_INSTALL_RPATH "") - - set(PORTLIBS_PATH "${DEVKITPRO}/portlibs") - - if(DUSK_TARGET_SYSTEM STREQUAL "gamecube") - set(_PORTLIBS_FLAVOR "gamecube") - set(_LIBOGC_LIBDIR "${DEVKITPRO}/libogc/lib/cube") - target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PRIVATE HW_DOL GAMECUBE) - set(_MACHDEP_OPTS -mogc) - else() - set(_PORTLIBS_FLAVOR "wii") - set(_LIBOGC_LIBDIR "${DEVKITPRO}/libogc/lib/wii") - target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PRIVATE HW_RVL WII) - set(_MACHDEP_OPTS -mrvll) - endif() - target_compile_options(${DUSK_LIBRARY_TARGET_NAME} PRIVATE ${_MACHDEP_OPTS} -DGEKKO -DDOLPHIN -Wall -O2 -DSDL_MAIN_HANDLED -meabi -mhard-float -g -mcpu=750) - target_link_options(${DUSK_LIBRARY_TARGET_NAME} PRIVATE ${_MACHDEP_OPTS} -DGEKKO -DDOLPHIN -Wall -O2 -DSDL_MAIN_HANDLED -meabi -mhard-float -g -mcpu=750) - - execute_process( - COMMAND /opt/devkitpro/portlibs/${_PORTLIBS_FLAVOR}/bin/powerpc-eabi-pkg-config --libs sdl2 SDL2_ttf SDL2_gfx SDL2_mixer SDL2_image - OUTPUT_VARIABLE PKG_CONFIG_LIBS - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - # message(FATAL_ERROR "DISABLED FOR NOW ${PKG_CONFIG_LIBS}") - target_compile_options(${DUSK_LIBRARY_TARGET_NAME} PUBLIC ${PKG_CONFIG_LIBS}) - target_link_options(${DUSK_LIBRARY_TARGET_NAME} PUBLIC ${PKG_CONFIG_LIBS}) - - target_include_directories(${DUSK_LIBRARY_TARGET_NAME} PRIVATE - "${DEVKITPRO}/libogc/include" - "${PORTLIBS_PATH}/${_PORTLIBS_FLAVOR}/include" - "${PORTLIBS_PATH}/${_PORTLIBS_FLAVOR}/include/SDL2" - "${PORTLIBS_PATH}/ppc/include" + target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC + PkgConfig::SDL2 + PkgConfig::SDL2_ttf + PkgConfig::SDL2_image + PkgConfig::SDL2_mixer + PkgConfig::zip + PkgConfig::GLU + PkgConfig::freetype2 ) - target_link_directories(${DUSK_LIBRARY_TARGET_NAME} PRIVATE - "${_LIBOGC_LIBDIR}" - "${PORTLIBS_PATH}/${_PORTLIBS_FLAVOR}/lib" - "${PORTLIBS_PATH}/ppc/lib" + target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC + DOLPHIN ) - set(Lua_FOUND TRUE) - set(libzip_FOUND TRUE) - # Custom flags for cglm - # set(CGLM_SHARED OFF CACHE BOOL "Build cglm shared" FORCE) - # set(CGLM_STATIC ON CACHE BOOL "Build cglm static" FORCE) - # find_package(cglm REQUIRED) + set(CGLM_SHARED OFF CACHE BOOL "Build cglm shared" FORCE) + set(CGLM_STATIC ON CACHE BOOL "Build cglm static" FORCE) + find_package(cglm REQUIRED) # Compile lua - # include(FetchContent) - # FetchContent_Declare( - # liblua - # URL https://www.lua.org/ftp/lua-5.5.0.tar.gz - # ) - # FetchContent_MakeAvailable(liblua) - # set(LUA_SRC_DIR "${liblua_SOURCE_DIR}/src") - # set(LUA_C_FILES - # lapi.c lauxlib.c lbaselib.c lcode.c lcorolib.c lctype.c ldblib.c ldebug.c - # ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c - # loadlib.c lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c - # lstrlib.c ltable.c ltablib.c ltm.c lundump.c lutf8lib.c lvm.c lzio.c - # ) - # list(TRANSFORM LUA_C_FILES PREPEND "${LUA_SRC_DIR}/") - # add_library(liblua STATIC ${LUA_C_FILES}) - # target_include_directories(liblua PUBLIC "${LUA_SRC_DIR}") - # target_compile_definitions(liblua PRIVATE LUA_USE_C89) - # add_library(lua::lua ALIAS liblua) + include(FetchContent) + FetchContent_Declare( + liblua + URL https://www.lua.org/ftp/lua-5.5.0.tar.gz + ) + FetchContent_MakeAvailable(liblua) + set(LUA_SRC_DIR "${liblua_SOURCE_DIR}/src") + set(LUA_C_FILES + lapi.c lauxlib.c lbaselib.c lcode.c lcorolib.c lctype.c ldblib.c ldebug.c + ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c + loadlib.c lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c + lstrlib.c ltable.c ltablib.c ltm.c lundump.c lutf8lib.c lvm.c lzio.c + ) + list(TRANSFORM LUA_C_FILES PREPEND "${LUA_SRC_DIR}/") + add_library(liblua STATIC ${LUA_C_FILES}) + target_include_directories(liblua PUBLIC "${LUA_SRC_DIR}") + target_compile_definitions(liblua PRIVATE LUA_USE_C89) + add_library(lua::lua ALIAS liblua) + set(Lua_FOUND TRUE CACHE BOOL "Lua found" FORCE) - target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC - # cglm - # liblua + target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE + cglm + liblua - # zip - # bz2 - # z - - SDL2_ttf - m - harfbuzz - - SDL2_gfx - - SDL2_mixer - m stdc++ - ogg - vorbisidec - modplug - mpg123 - opusfile - opus - FLAC - - SDL2_image - SDL2main - SDL2 - pthread - - aesnd - opengx - fat ogc - png16 - z - jpeg - freetype + m ) endif() @@ -247,7 +184,7 @@ endif() set(ENABLE_TESTS OFF CACHE BOOL "Enable tests" FORCE) # Add code -add_subdirectory(src2) +add_subdirectory(${DUSK_SOURCES_DIR}) # Handle tests if(ENABLE_TESTS) diff --git a/opengl.pc.in b/opengl.pc.in new file mode 100644 index 0000000..4692a04 --- /dev/null +++ b/opengl.pc.in @@ -0,0 +1,10 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: OpenGL +Description: OpenGL (without GLX) library and headers. +Version: @PROJECT_VERSION@ +Libs.private: -lstdc++ -logc -lm +Libs: -L${libdir} -lopengx +Cflags: -I${includedir} \ No newline at end of file diff --git a/src/display/displaydefs.h b/src/display/displaydefs.h index 71d4f2e..5090210 100644 --- a/src/display/displaydefs.h +++ b/src/display/displaydefs.h @@ -8,11 +8,21 @@ #pragma once #if DISPLAY_SDL2 - #include + #if DOLPHIN + #include "dusk.h" + #include + #include + #include + + #define GL_COLOR_INDEX8_EXT GX_RGBA8 - #define GL_GLEXT_PROTOTYPES - #include - #include + #else + #include + + #define GL_GLEXT_PROTOTYPES + #include + #include + #endif #ifndef DISPLAY_SIZE_DYNAMIC #define DISPLAY_SIZE_DYNAMIC 1 diff --git a/src/display/framebuffer.c b/src/display/framebuffer.c index 7b7e340..54a57c0 100644 --- a/src/display/framebuffer.c +++ b/src/display/framebuffer.c @@ -102,12 +102,16 @@ void frameBufferBind(const framebuffer_t *framebuffer) { if(framebuffer == &FRAMEBUFFER_BACKBUFFER) { #if PSP + #elif DOLPHIN + #else glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); #endif } else { #if PSP assertUnreachable("Framebuffers not supported on PSP"); + #elif DOLPHIN + assertUnreachable("Framebuffers not supported on DOLPHIN"); #else glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer->id); #endif @@ -140,7 +144,11 @@ void frameBufferClear(uint8_t flags, color_t color) { glFlags |= GL_DEPTH_BUFFER_BIT; } - glClear(glFlags); + #if DOLPHIN + assertUnreachable("Framebuffers not supported on DOLPHIN"); + #else + glClear(glFlags); + #endif #endif } diff --git a/src/display/texture.c b/src/display/texture.c index 63f24d7..6449303 100644 --- a/src/display/texture.c +++ b/src/display/texture.c @@ -77,6 +77,8 @@ void textureInit( #if PSP havePalTex = true; + #elif DOLPHIN + havePalTex = false; #else GLint mask = 0; glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); @@ -125,10 +127,14 @@ void textureInit( GL_UNSIGNED_BYTE, (void*)data.palette.data ); - glColorTableEXT( - GL_TEXTURE_2D, GL_RGBA, pal->colorCount, GL_RGBA, - GL_UNSIGNED_BYTE, (const void*)pal->colors - ); + #if DOLPHIN + assertUnreachable("Paletted textures not supported on DOLPHIN"); + #else + glColorTableEXT( + GL_TEXTURE_2D, GL_RGBA, pal->colorCount, GL_RGBA, + GL_UNSIGNED_BYTE, (const void*)pal->colors + ); + #endif } break; diff --git a/src/dusk.h b/src/dusk.h index ea3b4df..ecf804a 100644 --- a/src/dusk.h +++ b/src/dusk.h @@ -31,7 +31,6 @@ #if DOLPHIN #include - #include #endif typedef bool bool_t; diff --git a/src2/CMakeLists.txt b/src2/CMakeLists.txt index e4c1d4f..6bb5452 100644 --- a/src2/CMakeLists.txt +++ b/src2/CMakeLists.txt @@ -16,9 +16,9 @@ target_include_directories(${DUSK_LIBRARY_TARGET_NAME} # Main Binary Source target_sources(${DUSK_BINARY_TARGET_NAME} PRIVATE - main.cpp - sdl_starter.cpp - sdl_assets_loader.cpp + main.c + sdl_starter.c + sdl_assets_loader.c ) # Defs diff --git a/src2/main.cpp b/src2/main.c similarity index 98% rename from src2/main.cpp rename to src2/main.c index 1917184..894229e 100644 --- a/src2/main.cpp +++ b/src2/main.c @@ -2,8 +2,8 @@ #include "sdl_starter.h" #include "sdl_assets_loader.h" -SDL_Window *window = nullptr; -SDL_Renderer *renderer = nullptr; +SDL_Window *window = NULL; +SDL_Renderer *renderer = NULL; const int PLAYER_SPEED = 600; diff --git a/src2/null.c b/src2/null.c new file mode 100644 index 0000000..a7d5fbe --- /dev/null +++ b/src2/null.c @@ -0,0 +1,10 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +void dusk_null_method(void) { + return; +} \ No newline at end of file diff --git a/src2/sdl_assets_loader.cpp b/src2/sdl_assets_loader.c similarity index 72% rename from src2/sdl_assets_loader.cpp rename to src2/sdl_assets_loader.c index 935d5a1..7abc5de 100644 --- a/src2/sdl_assets_loader.cpp +++ b/src2/sdl_assets_loader.c @@ -6,7 +6,7 @@ Sprite loadSprite(SDL_Renderer *renderer, const char *filePath, int positionX, i SDL_Texture *texture = IMG_LoadTexture(renderer, filePath); - if (texture != nullptr) + if (texture != NULL) { SDL_QueryTexture(texture, NULL, NULL, &textureBounds.w, &textureBounds.h); } @@ -16,12 +16,13 @@ Sprite loadSprite(SDL_Renderer *renderer, const char *filePath, int positionX, i return sprite; } + Mix_Chunk *loadSound(const char *filePath) { - Mix_Chunk *sound = nullptr; + Mix_Chunk *sound = NULL; sound = Mix_LoadWAV(filePath); - if (sound == nullptr) + if (sound == NULL) { printf("Failed to load scratch sound effect! SDL_mixer Error: %s\n", Mix_GetError()); } @@ -29,12 +30,13 @@ Mix_Chunk *loadSound(const char *filePath) return sound; } + Mix_Music *loadMusic(const char *filePath) { - Mix_Music *music = nullptr; + Mix_Music *music = NULL; music = Mix_LoadMUS(filePath); - if (music == nullptr) + if (music == NULL) { printf("Failed to load music! SDL_mixer Error: %s\n", Mix_GetError()); } @@ -42,26 +44,27 @@ Mix_Music *loadMusic(const char *filePath) return music; } -void updateTextureText(SDL_Texture *&texture, const char *text, TTF_Font *&fontSquare, SDL_Renderer *renderer) + +void updateTextureText(SDL_Texture **texture, const char *text, TTF_Font **fontSquare, SDL_Renderer *renderer) { SDL_Color fontColor = {255, 255, 255}; - if (fontSquare == nullptr) + if (*fontSquare == NULL) { printf("TTF_OpenFont fontSquare: %s\n", TTF_GetError()); } - SDL_Surface *surface = TTF_RenderUTF8_Blended(fontSquare, text, fontColor); - if (surface == nullptr) + SDL_Surface *surface = TTF_RenderUTF8_Blended(*fontSquare, text, fontColor); + if (surface == NULL) { printf("TTF_OpenFont: %s\n", TTF_GetError()); SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Unable to create text surface! SDL Error: %s\n", SDL_GetError()); exit(3); } - SDL_DestroyTexture(texture); - texture = SDL_CreateTextureFromSurface(renderer, surface); - if (texture == nullptr) + SDL_DestroyTexture(*texture); + *texture = SDL_CreateTextureFromSurface(renderer, surface); + if (*texture == NULL) { printf("TTF_OpenFont: %s\n", TTF_GetError()); SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Unable to create texture from surface! SDL Error: %s\n", SDL_GetError()); diff --git a/src2/sdl_assets_loader.h b/src2/sdl_assets_loader.h index 4750d32..7bdbeea 100644 --- a/src2/sdl_assets_loader.h +++ b/src2/sdl_assets_loader.h @@ -4,7 +4,6 @@ #include #include #include -#include typedef struct { @@ -18,4 +17,4 @@ Mix_Chunk *loadSound(const char *filePath); Mix_Music *loadMusic(const char *filePath); -void updateTextureText(SDL_Texture *&texture, const char *text, TTF_Font *&fontSquare, SDL_Renderer *renderer); \ No newline at end of file +void updateTextureText(SDL_Texture **texture, const char *text, TTF_Font **fontSquare, SDL_Renderer *renderer); \ No newline at end of file diff --git a/src2/sdl_starter.cpp b/src2/sdl_starter.c similarity index 66% rename from src2/sdl_starter.cpp rename to src2/sdl_starter.c index 11857d6..78c7c14 100644 --- a/src2/sdl_starter.cpp +++ b/src2/sdl_starter.c @@ -1,44 +1,51 @@ + #include "sdl_starter.h" #include #include #include -#include +#include int startSDL(SDL_Window *window, SDL_Renderer *renderer) { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) { - std::cout << "SDL crashed. Error: " << SDL_GetError(); + printf("SDL crashed. Error: %s\n", SDL_GetError()); return 1; } - if (window == nullptr) + + if (window == NULL) { - std::cerr << "Failed to create window: " << SDL_GetError() << std::endl; + fprintf(stderr, "Failed to create window: %s\n", SDL_GetError()); SDL_Quit(); return 1; } - if (renderer == nullptr) + + if (renderer == NULL) { - std::cerr << "Failed to create renderer: " << SDL_GetError() << std::endl; + fprintf(stderr, "Failed to create renderer: %s\n", SDL_GetError()); SDL_DestroyWindow(window); SDL_Quit(); return 1; } + if (!IMG_Init(IMG_INIT_PNG)) { - std::cout << "SDL_image crashed. Error: " << SDL_GetError(); + printf("SDL_image crashed. Error: %s\n", SDL_GetError()); return 1; } + if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); return 1; } + if (TTF_Init() == -1) { return 1; diff --git a/src2/sdl_starter.h b/src2/sdl_starter.h index 9604e3f..ff3a63b 100644 --- a/src2/sdl_starter.h +++ b/src2/sdl_starter.h @@ -1,8 +1,15 @@ -#pragma once +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once #include -const int SCREEN_WIDTH = 640; -const int SCREEN_HEIGHT = 480; +#define SCREEN_WIDTH 640 +#define SCREEN_HEIGHT 480 int startSDL(SDL_Window *window, SDL_Renderer *renderer);