diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0455ed3e8..f7d893610 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y cmake libglfw3-dev libbz2-dev - name: Configure - run: cmake -B build -DWERROR=ON -DDESKTOP_BACKEND=glfw3 -DCMAKE_BUILD_TYPE=Release "-DBUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }}" "-DBUTTERSCOTCH_COMMIT_DATE=${{ steps.commit-info.outputs.date }}" + run: cmake -B build -DWERROR=ON -DBACKEND=glfw3 -DCMAKE_BUILD_TYPE=Release "-DBUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }}" "-DBUTTERSCOTCH_COMMIT_DATE=${{ steps.commit-info.outputs.date }}" - name: Build run: cmake --build build -j$(nproc) @@ -71,7 +71,7 @@ jobs: sudo cp /tmp/bzip2-1.0.8/bzlib.h /usr/x86_64-w64-mingw32/include/ - name: Configure - run: cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/mingw-w64.cmake -DWERROR=ON -DDESKTOP_BACKEND=glfw3 -DCMAKE_BUILD_TYPE=Release "-DBUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }}" "-DBUTTERSCOTCH_COMMIT_DATE=${{ steps.commit-info.outputs.date }}" + run: cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/mingw-w64.cmake -DWERROR=ON -DBACKEND=glfw3 -DCMAKE_BUILD_TYPE=Release "-DBUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }}" "-DBUTTERSCOTCH_COMMIT_DATE=${{ steps.commit-info.outputs.date }}" - name: Build run: cmake --build build -j$(nproc) @@ -114,7 +114,7 @@ jobs: - name: Configure run: | export PKG_CONFIG_PATH=/usr/local/glfw-x86/lib/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig - cmake -B build -DWERROR=ON -DDESKTOP_BACKEND=glfw3 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 "-DBUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }}" "-DBUTTERSCOTCH_COMMIT_DATE=${{ steps.commit-info.outputs.date }}" + cmake -B build -DWERROR=ON -DBACKEND=glfw3 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 "-DBUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }}" "-DBUTTERSCOTCH_COMMIT_DATE=${{ steps.commit-info.outputs.date }}" - name: Build run: cmake --build build -j$(nproc) @@ -166,7 +166,7 @@ jobs: NO_COLOR=1 \ VERBOSE=1 \ CC='ccache i486-w64-mingw32-gcc' \ - DESKTOP_BACKEND=glfw2 \ + BACKEND=glfw2 \ GLFW2_LIBS='-lglfw -lopengl32' \ EXTRALIBS='-latomic' \ BUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }} \ @@ -398,7 +398,7 @@ jobs: - name: Build run: | sudo mv butterscotch ~/woody - sudo chroot ~/woody /bin/sh --login -c 'make -C /butterscotch NO_COLOR=1 VERBOSE=1 CC="${{ matrix.compiler }} ${{ matrix.flags }}" DESKTOP_BACKEND=sdl1 AUDIO_BACKEND=none SDL1_LIBS='-lSDL' DISABLE_MMD=1' + sudo chroot ~/woody /bin/sh --login -c 'make -C /butterscotch NO_COLOR=1 VERBOSE=1 CC="${{ matrix.compiler }} ${{ matrix.flags }}" BACKEND=sdl1 AUDIO_BACKEND=none SDL1_LIBS='-lSDL' DISABLE_MMD=1' build-cxx: name: Build as C++ diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 017a7fbb8..6482df4d6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,7 +25,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y cmake libglfw3-dev libbz2-dev - name: Configure - run: cmake -B build -DDESKTOP_BACKEND=glfw3 -DCMAKE_BUILD_TYPE=Release "-DBUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }}" "-DBUTTERSCOTCH_COMMIT_DATE=${{ steps.commit-info.outputs.date }}" + run: cmake -B build -DBACKEND=glfw3 -DCMAKE_BUILD_TYPE=Release "-DBUTTERSCOTCH_COMMIT_HASH=${{ steps.commit-info.outputs.hash }}" "-DBUTTERSCOTCH_COMMIT_DATE=${{ steps.commit-info.outputs.date }}" - name: Build Butterscotch run: cmake --build build -j$(nproc) diff --git a/CMakeLists.txt b/CMakeLists.txt index e344daea5..529e01d17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,12 +39,12 @@ else() endif() endif() -set(PLATFORM "desktop" CACHE STRING "Platform backend") -set(DESKTOP_BACKEND "" CACHE STRING "Desktop platform backend") +set(PLATFORM "cli" CACHE STRING "Platform backend") +set(BACKEND "" CACHE STRING "Desktop platform backend") set(AUDIO_BACKEND "" CACHE STRING "Audio backend") -if(PLATFORM STREQUAL "desktop" AND DESKTOP_BACKEND STREQUAL "") - message(FATAL_ERROR "You need to set a DESKTOP_BACKEND!") +if(PLATFORM STREQUAL "cli" AND BACKEND STREQUAL "") + message(FATAL_ERROR "You need to set a BACKEND!") endif() # Build metadata @@ -203,7 +203,7 @@ if(ENABLE_VM_EXCEPTIONS_LOGS) add_compile_definitions(ENABLE_VM_EXCEPTIONS_LOGS) endif() -if(PLATFORM STREQUAL "desktop") +if(PLATFORM STREQUAL "cli") # Matches the GitHub Actions container flags (FORTIFY requires building with optimizations enabled!) target_compile_options(butterscotch PRIVATE "$<$:-U_FORTIFY_SOURCE;-D_FORTIFY_SOURCE=2>") @@ -269,7 +269,7 @@ if(PLATFORM STREQUAL "desktop") set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${CMAKE_DL_LIBS}) endif() - if(DESKTOP_BACKEND STREQUAL "glfw3") + if(BACKEND STREQUAL "glfw3") add_compile_definitions(USE_GLFW3) if(MINGW) @@ -291,7 +291,7 @@ if(PLATFORM STREQUAL "desktop") target_link_directories(butterscotch PRIVATE ${GLFW3_LIBRARY_DIRS}) set(BACKEND_LIBRARIES ${GLFW3_LIBRARIES}) endif() - elseif(DESKTOP_BACKEND STREQUAL "glfw2") + elseif(BACKEND STREQUAL "glfw2") add_compile_definitions(USE_GLFW2) find_package(PkgConfig REQUIRED) @@ -299,13 +299,13 @@ if(PLATFORM STREQUAL "desktop") target_include_directories(butterscotch PRIVATE ${GLFW2_INCLUDE_DIRS}) target_link_directories(butterscotch PRIVATE ${GLFW2_LIBRARY_DIRS}) set(BACKEND_LIBRARIES ${GLFW2_LIBRARIES}) - elseif(DESKTOP_BACKEND STREQUAL "sdl1") + elseif(BACKEND STREQUAL "sdl1") add_compile_definitions(USE_SDL1) find_package(SDL REQUIRED) target_include_directories(butterscotch PUBLIC ${SDL_INCLUDE_DIR}) set(BACKEND_LIBRARIES ${SDL_LIBRARY}) - elseif(DESKTOP_BACKEND STREQUAL "sdl2") + elseif(BACKEND STREQUAL "sdl2") add_compile_definitions(USE_SDL2) find_package(PkgConfig REQUIRED) @@ -313,7 +313,7 @@ if(PLATFORM STREQUAL "desktop") target_include_directories(butterscotch PRIVATE ${SDL2_INCLUDE_DIRS}) target_link_directories(butterscotch PRIVATE ${SDL2_LIBRARY_DIRS}) set(BACKEND_LIBRARIES ${SDL2_LIBRARIES}) - elseif(DESKTOP_BACKEND STREQUAL "sdl3") + elseif(BACKEND STREQUAL "sdl3") add_compile_definitions(USE_SDL3) find_package(PkgConfig REQUIRED) @@ -323,7 +323,7 @@ if(PLATFORM STREQUAL "desktop") set(BACKEND_LIBRARIES ${SDL3_LIBRARIES}) endif() target_link_libraries(butterscotch PRIVATE ${BACKEND_LIBRARIES} ${AUDIO_LIBRARIES} ${PLATFORM_LIBRARIES}) - target_sources(butterscotch PRIVATE src/desktop/backends/${DESKTOP_BACKEND}.c) + target_sources(butterscotch PRIVATE src/backends/${BACKEND}.c) # Enable AddressSanitizer by default in Debug builds if(CMAKE_BUILD_TYPE STREQUAL "Debug") diff --git a/CMakePresets.json b/CMakePresets.json index 782f022f6..a87d7d429 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -7,8 +7,8 @@ "generator": "Ninja", "binaryDir": "${sourceDir}/build", "cacheVariables": { - "PLATFORM": "desktop", - "DESKTOP_BACKEND": "glfw3", + "PLATFORM": "cli", + "BACKEND": "glfw3", "ENABLE_ASAN": false, "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" } diff --git a/Makefile b/Makefile index c270d0e51..9ed611c0b 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,8 @@ INCLUDES += $(INCLUDE). \ HEADERS += $(wildcard src/*.h) $(shell find vendor -name '*.h') SRCS += $(wildcard src/*.c) $(wildcard src/image/*.c) $(wildcard vendor/bzip2/*.c) vendor/md5/md5.c vendor/sha1/sha1.c vendor/base64/base64.c -DESKTOP_BACKEND := glfw3 +PLATFORM := cli +BACKEND := glfw3 AUDIO_BACKEND := miniaudio ifdef BUTTERSCOTCH_COMMIT_DATE @@ -69,35 +70,44 @@ ifndef DISABLE_WAD17 DEFINES += $(DEFINE)ENABLE_WAD17 endif -# TODO: add support for non-desktop backends -SRCS += $(wildcard src/desktop/*.c) src/desktop/backends/$(DESKTOP_BACKEND).c +ifeq ($(PLATFORM),cli) +SRCS += $(wildcard src/cli/*.c) +else +ifeq ($(PLATFORM),embedded) +SRCS += $(wildcard src/embedded/*.c) +else +$(error unknown platform) +endif +endif + +SRCS += src/backends/$(BACKEND).c ifeq ($(OS),Windows) PKG_CONFIG_FLAGS := --static endif -INCLUDES += $(INCLUDE)src/desktop -ifeq ($(DESKTOP_BACKEND),glfw3) +INCLUDES += $(INCLUDE)src/cli +ifeq ($(BACKEND),glfw3) GLFW3_LIBS += $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --libs glfw3) LIBS += $(GLFW3_LIBS) DEFINES += $(DEFINE)USE_GLFW3 ENABLE_GLAD := 1 endif -ifeq ($(DESKTOP_BACKEND),glfw2) +ifeq ($(BACKEND),glfw2) GLFW2_LIBS += $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --libs libglfw) LIBS += $(GLFW2_LIBS) DEFINES += $(DEFINE)USE_GLFW2 ENABLE_GLAD := 1 endif -ifeq ($(DESKTOP_BACKEND),sdl1) +ifeq ($(BACKEND),sdl1) SDL1_LIBS += $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --libs sdl) LIBS += $(SDL1_LIBS) DEFINES += $(DEFINE)USE_SDL1 endif -ifeq ($(DESKTOP_BACKEND),sdl2) +ifeq ($(BACKEND),sdl2) SDL2_LIBS += $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --libs sdl2) LIBS += $(SDL2_LIBS) DEFINES += $(DEFINE)USE_SDL2 endif -ifeq ($(DESKTOP_BACKEND),sdl3) +ifeq ($(BACKEND),sdl3) SDL3_LIBS += $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --libs sdl3) LIBS += $(SDL3_LIBS) DEFINES += $(DEFINE)USE_SDL3 diff --git a/README.md b/README.md index 421b3d5c9..d5a5f5eb2 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ The following compilers have been tested to successfully build butterscotch, old ```bash mkdir build && cd build -cmake -DPLATFORM=desktop -DDESKTOP_BACKEND=glfw3 -DCMAKE_BUILD_TYPE=Debug .. +cmake -DPLATFORM=desktop -DBACKEND=glfw3 -DCMAKE_BUILD_TYPE=Debug .. make ``` diff --git a/src/android/stb_impl.c b/src/android/stb_impl.c index c349348c7..873f3656b 100644 --- a/src/android/stb_impl.c +++ b/src/android/stb_impl.c @@ -4,6 +4,3 @@ #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" - -#define STB_DS_IMPLEMENTATION -#include "stb_ds.h" diff --git a/src/desktop/backends/glfw2.c b/src/backends/glfw2.c similarity index 99% rename from src/desktop/backends/glfw2.c rename to src/backends/glfw2.c index 0a3001089..3f07ef37e 100644 --- a/src/desktop/backends/glfw2.c +++ b/src/backends/glfw2.c @@ -12,7 +12,7 @@ #include "common.h" #include "input_recording.h" -#include "desktop/platformdefs.h" +#include "platformdefs.h" #include "gettime.h" #include "runner_mouse.h" diff --git a/src/desktop/backends/glfw3.c b/src/backends/glfw3.c similarity index 99% rename from src/desktop/backends/glfw3.c rename to src/backends/glfw3.c index 6abfccf1a..23af551ee 100644 --- a/src/desktop/backends/glfw3.c +++ b/src/backends/glfw3.c @@ -14,7 +14,7 @@ #include "common.h" #include "input_recording.h" -#include "desktop/platformdefs.h" +#include "platformdefs.h" #include "gettime.h" #include "runner_mouse.h" diff --git a/src/desktop/backends/sdl1.c b/src/backends/sdl1.c similarity index 99% rename from src/desktop/backends/sdl1.c rename to src/backends/sdl1.c index e1917d80c..cc65997c0 100644 --- a/src/desktop/backends/sdl1.c +++ b/src/backends/sdl1.c @@ -8,7 +8,7 @@ #include "common.h" #include "input_recording.h" -#include "desktop/platformdefs.h" +#include "platformdefs.h" #include "gettime.h" #ifndef SDL_BUTTON_WHEELUP diff --git a/src/desktop/backends/sdl2.c b/src/backends/sdl2.c similarity index 99% rename from src/desktop/backends/sdl2.c rename to src/backends/sdl2.c index 7b13a7294..da31683bb 100644 --- a/src/desktop/backends/sdl2.c +++ b/src/backends/sdl2.c @@ -5,7 +5,7 @@ #include "common.h" #include "input_recording.h" -#include "desktop/platformdefs.h" +#include "platformdefs.h" #include "gettime.h" #include "runner_mouse.h" diff --git a/src/desktop/backends/sdl3.c b/src/backends/sdl3.c similarity index 99% rename from src/desktop/backends/sdl3.c rename to src/backends/sdl3.c index 4c3c8c237..7c9f6bee2 100644 --- a/src/desktop/backends/sdl3.c +++ b/src/backends/sdl3.c @@ -5,7 +5,7 @@ #include "common.h" #include "input_recording.h" -#include "desktop/platformdefs.h" +#include "platformdefs.h" #include "gettime.h" #include #include "runner_mouse.h" diff --git a/src/cli/main.c b/src/cli/main.c new file mode 100644 index 000000000..5567634d4 --- /dev/null +++ b/src/cli/main.c @@ -0,0 +1,547 @@ +#include +#include +#ifdef _WIN32 +#include +#else +#include +#endif + +/* For SDL_main */ +#if defined(USE_SDL1) +#include +#elif defined(USE_SDL2) +#include +#elif defined(USE_SDL3) +#include +#endif + +static bool parseOsTypeArg(const char* s, YoYoOperatingSystem* out) { + forEach(const OsTypeNameEntry, entry, OS_TYPE_NAMES, OS_TYPE_NAMES_COUNT) { + if (strcmp(s, entry->name) == 0) { + *out = entry->value; + return true; + } + } + return false; +} + +static void printOsTypeNames(FILE* out) { + forEachIndexed(const OsTypeNameEntry, entry, i, OS_TYPE_NAMES, OS_TYPE_NAMES_COUNT) { + fprintf(out, "%s%s", i > 0 ? ", " : "", entry->name); + } +} + +static bool logColour; + +void platformLog(const logType type, const char *format, va_list va) { + FILE *out = stderr; + const char* colourPrefix = ANSI_COLOUR_CODE_RESET; + const char* textPrefix = ""; + switch (type) { + case LOG_TYPE_NORMAL: + out = stdout; + break; + case LOG_TYPE_WARNING: + colourPrefix = ANSI_COLOUR_CODE_BOLD_YELLOW; + textPrefix = "Warning: "; + break; + case LOG_TYPE_ERROR: + colourPrefix = ANSI_COLOUR_CODE_BOLD_RED; + textPrefix = "Error: "; + break; + case LOG_TYPE_DEBUG: + colourPrefix = ANSI_COLOUR_CODE_BOLD_PURPLE; + textPrefix = "Debug: "; + break; + } + + if (logColour) fputs(colourPrefix, out); + fputs(textPrefix, out); + if (logColour) fputs(ANSI_COLOUR_CODE_RESET, out); + vfprintf(out, format, va); +} + +static void printUsage(const char *argv0) { + logInfo( + "Usage: %s \n" + " --help - Show this message\n" + " --screenshot - Specify the filename for screenshots\n" + " --screenshot-at-frame - Take a screenshot at the specified frame\n" + " --screenshot-surfaces - Take a screenshot of all surfaces at the specified frame\n" + " --screenshot-surfaces-at-frame - Specify the filename for surface screenshots\n" +#ifndef USE_GLFW2 + " --headless - Launch without a window\n" +#endif + " --print-rooms - Print all rooms in the game and exit\n" + " --print-objects - Print all objects in the game and exit\n" + " --print-shaders - Print all shaders in the game and exit\n" + " --print-declared-functions - Print all declared functions in the game and exit\n" + " --print-unknown-functions - Print all unknown functions used by the game and exit\n" + " --trace-variable-reads - Trace variable reads\n" + " --trace-variable-writes - Trace variable writes\n" + " --trace-function-calls - Trace function calls\n" + " --trace-alarms - Trace alarms\n" + " --trace-instance-lifecycles - Trace instance creations and deletions\n" + " --trace-events - Trace events\n" + " --trace-collisions - Trace collisions between instances\n" + " --trace-event-inherited - Trace event inherited calls\n" + " --trace-tiles - Trace drawn tiles\n" + " --trace-opcodes - Trace opcodes\n" + " --trace-stack - Trace stack\n" + " --trace-frames - Log frametimes\n" + " --always-log-unknown-functions - Always log unknown function calls instead of once per script\n" + " --always-log-stubbed-functions - Always log stubbed function calls instead of once per script\n" + " --exit-at-frame - Exit at the specified frame\n" + " --trace-bytecode-after-frame - Delay stack and opcode tracing until the specified frame\n" + " --dump-frame - Dump the runner state at the specified frame\n" + " --dump-frame-json - Dump the runner state in json at the specified frame\n" + " --dump-frame-json-file - Specify an output file for runner state dumps\n" + " --speed - Set a normal speed multiplier\n" + " --fast-forward-speed - Set a fast-forward speed multiplier\n" + " --seed - Seed for the random number generator\n" + " --debug - Enable debug mode\n" + " --disassemble