diff --git a/Firmware/components/sdk-esp/CMakeLists.txt b/Firmware/components/sdk-esp/CMakeLists.txt index b8343a2..583ee97 100644 --- a/Firmware/components/sdk-esp/CMakeLists.txt +++ b/Firmware/components/sdk-esp/CMakeLists.txt @@ -1,21 +1,31 @@ -idf_component_register() +idf_component_register( + PRIV_REQUIRES driver esp_timer esp_driver_spi +) add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../sdk" cb-sdk-build) -target_link_libraries(${COMPONENT_LIB} - INTERFACE - cardboy_sdk - cardboy_apps -) - -target_compile_definitions(${COMPONENT_LIB} - INTERFACE - CARDBOY_SDK_BACKEND_HEADER=\"cardboy/backend/esp_backend.hpp\" - CARDBOY_SDK_ACTIVE_BACKEND_TYPE=cardboy::backend::EspBackend -) - -target_include_directories(${COMPONENT_LIB} +target_include_directories(cardboy_backend INTERFACE ${CMAKE_CURRENT_LIST_DIR}/../../main/include ) -target_compile_options(${COMPONENT_LIB} INTERFACE -fjump-tables -ftree-switch-conversion) + +target_compile_options(cardboy_backend + INTERFACE + -fjump-tables + -ftree-switch-conversion +) + +target_link_libraries(cardboy_backend + INTERFACE + idf::driver + idf::esp_timer + idf::esp_driver_spi + idf::freertos +) + +target_link_libraries(${COMPONENT_LIB} + INTERFACE + cardboy_backend + cardboy_sdk + cardboy_apps +) diff --git a/Firmware/main/CMakeLists.txt b/Firmware/main/CMakeLists.txt index f9b0008..aa60050 100644 --- a/Firmware/main/CMakeLists.txt +++ b/Firmware/main/CMakeLists.txt @@ -10,7 +10,7 @@ idf_component_register(SRCS src/buzzer.cpp src/fs_helper.cpp PRIV_REQUIRES spi_flash esp_driver_i2c driver sdk-esp esp_timer nvs_flash littlefs - INCLUDE_DIRS "include" "../sdk/include" - EMBED_FILES "roms/builtin_demo1.gb" "roms/builtin_demo2.gb") + EMBED_FILES "roms/builtin_demo1.gb" "roms/builtin_demo2.gb" + INCLUDE_DIRS "include" "../sdk/include") littlefs_create_partition_image(littlefs ../flash_data FLASH_IN_PROJECT) diff --git a/Firmware/main/include/cardboy/backend/backend_impl.hpp b/Firmware/main/include/cardboy/backend/backend_impl.hpp new file mode 100644 index 0000000..9fcdde8 --- /dev/null +++ b/Firmware/main/include/cardboy/backend/backend_impl.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "cardboy/backend/esp_backend.hpp" + +namespace cardboy::backend { +using ActiveBackend = EspBackend; +} + diff --git a/Firmware/main/src/app_main.cpp b/Firmware/main/src/app_main.cpp index 1b615d6..5d1bd62 100644 --- a/Firmware/main/src/app_main.cpp +++ b/Firmware/main/src/app_main.cpp @@ -42,10 +42,33 @@ #include #include #include +#include #include namespace { +extern "C" { +extern const uint8_t _binary_builtin_demo1_gb_start[]; +extern const uint8_t _binary_builtin_demo1_gb_end[]; +extern const uint8_t _binary_builtin_demo2_gb_start[]; +extern const uint8_t _binary_builtin_demo2_gb_end[]; +} + +constexpr apps::EmbeddedRomDescriptor kEmbeddedRoms[] = { + { + .name = "Builtin Demo 1", + .saveSlug = "builtin_demo1", + .start = _binary_builtin_demo1_gb_start, + .end = _binary_builtin_demo1_gb_end, + }, + { + .name = "Builtin Demo 2", + .saveSlug = "builtin_demo2", + .start = _binary_builtin_demo2_gb_start, + .end = _binary_builtin_demo2_gb_end, + }, +}; + class EspBuzzer final : public cardboy::sdk::IBuzzer { public: void tone(std::uint32_t freq, std::uint32_t duration_ms, std::uint32_t gap_ms = 0) override { @@ -302,6 +325,8 @@ extern "C" void app_main() { FsHelper::get().mount(); + apps::setGameboyEmbeddedRoms(std::span(kEmbeddedRoms)); + static PlatformFramebuffer framebuffer; static PlatformInput input; static PlatformClock clock; diff --git a/Firmware/sdk/CMakeLists.txt b/Firmware/sdk/CMakeLists.txt index d55955e..2d91769 100644 --- a/Firmware/sdk/CMakeLists.txt +++ b/Firmware/sdk/CMakeLists.txt @@ -5,39 +5,39 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_EXTENSIONS NO) -add_library(cardboy_sdk INTERFACE) +add_library(cardboy_backend INTERFACE) + +add_library(cardboy_sdk STATIC + src/app_system.cpp +) target_include_directories(cardboy_sdk - INTERFACE + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ) -target_compile_features(cardboy_sdk INTERFACE cxx_std_20) +target_compile_features(cardboy_sdk PUBLIC cxx_std_20) +target_link_libraries(cardboy_sdk PUBLIC cardboy_backend) -target_sources(cardboy_sdk - INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR}/src/app_system.cpp +add_library(cardboy_apps STATIC + apps/menu_app.cpp + apps/clock_app.cpp + apps/tetris_app.cpp + apps/gameboy_app.cpp ) -add_library(cardboy_apps INTERFACE) - target_include_directories(cardboy_apps - INTERFACE + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries(cardboy_apps - INTERFACE + PUBLIC cardboy_sdk + cardboy_backend ) -target_sources(cardboy_apps - INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR}/apps/menu_app.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/apps/clock_app.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/apps/tetris_app.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/apps/gameboy_app.cpp -) +target_compile_features(cardboy_apps PUBLIC cxx_std_20) option(CARDBOY_BUILD_SFML "Build SFML harness" OFF) @@ -58,6 +58,17 @@ if (CARDBOY_BUILD_SFML) ) FetchContent_MakeAvailable(SFML) + target_include_directories(cardboy_backend + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/hosts/include + ) + + target_link_libraries(cardboy_backend + INTERFACE + SFML::Window + SFML::Graphics + SFML::System + ) add_executable(cardboy_desktop hosts/sfml_main.cpp ) @@ -65,20 +76,7 @@ if (CARDBOY_BUILD_SFML) target_link_libraries(cardboy_desktop PRIVATE cardboy_apps - SFML::Graphics - SFML::Window - SFML::System - ) - - target_include_directories(cardboy_desktop - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/hosts/include - ) - - target_compile_definitions(cardboy_desktop - PRIVATE - CARDBOY_SDK_BACKEND_HEADER=\"cardboy/backend/desktop_backend.hpp\" - CARDBOY_SDK_ACTIVE_BACKEND_TYPE=cardboy::backend::DesktopBackend + cardboy_sdk ) target_compile_features(cardboy_desktop PRIVATE cxx_std_20) diff --git a/Firmware/sdk/apps/gameboy_app.cpp b/Firmware/sdk/apps/gameboy_app.cpp index e9adfb0..d2188b0 100644 --- a/Firmware/sdk/apps/gameboy_app.cpp +++ b/Firmware/sdk/apps/gameboy_app.cpp @@ -1,4 +1,3 @@ -#pragma GCC optimize("Ofast") #include "cardboy/apps/gameboy_app.hpp" #include "cardboy/apps/peanut_gb.h" @@ -22,7 +21,7 @@ #include #include #include -#define ESP_PLATFORM 1 + #define GAMEBOY_PERF_METRICS 0 #ifndef GAMEBOY_PERF_METRICS @@ -52,36 +51,7 @@ using Framebuffer = typename AppContext::Framebuffer; constexpr std::array kRomExtensions = {".gb", ".gbc"}; -struct EmbeddedRomDescriptor { - std::string_view name; - std::string_view saveSlug; - const uint8_t* start; - const uint8_t* end; -}; - -#ifdef ESP_PLATFORM -extern "C" { -extern const uint8_t _binary_builtin_demo1_gb_start[]; -extern const uint8_t _binary_builtin_demo1_gb_end[]; -extern const uint8_t _binary_builtin_demo2_gb_start[]; -extern const uint8_t _binary_builtin_demo2_gb_end[]; -} - -static const std::array kEmbeddedRomDescriptors = {{{ - "Builtin Demo 1", - "builtin_demo1", - _binary_builtin_demo1_gb_start, - _binary_builtin_demo1_gb_end, - }, - { - "Builtin Demo 2", - "builtin_demo2", - _binary_builtin_demo2_gb_start, - _binary_builtin_demo2_gb_end, - }}}; -#else -static const std::array kEmbeddedRomDescriptors{}; -#endif +static std::span gEmbeddedRomDescriptors{}; struct RomEntry { std::string name; // short display name @@ -114,7 +84,7 @@ struct RomEntry { } void appendEmbeddedRoms(std::vector& out) { - for (const auto& desc: kEmbeddedRomDescriptors) { + for (const auto& desc: gEmbeddedRomDescriptors) { if (!desc.start || !desc.end || desc.end <= desc.start) continue; const std::size_t size = static_cast(desc.end - desc.start); @@ -1397,6 +1367,10 @@ public: } // namespace +void setGameboyEmbeddedRoms(std::span descriptors) { + gEmbeddedRomDescriptors = descriptors; +} + std::unique_ptr createGameboyAppFactory() { return std::make_unique(); } } // namespace apps diff --git a/Firmware/sdk/hosts/include/cardboy/backend/backend_impl.hpp b/Firmware/sdk/hosts/include/cardboy/backend/backend_impl.hpp new file mode 100644 index 0000000..fdd4ca8 --- /dev/null +++ b/Firmware/sdk/hosts/include/cardboy/backend/backend_impl.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "cardboy/backend/desktop_backend.hpp" + +namespace cardboy::backend { +using ActiveBackend = DesktopBackend; +} + diff --git a/Firmware/sdk/include/cardboy/apps/gameboy_app.hpp b/Firmware/sdk/include/cardboy/apps/gameboy_app.hpp index 7f0897e..be098b6 100644 --- a/Firmware/sdk/include/cardboy/apps/gameboy_app.hpp +++ b/Firmware/sdk/include/cardboy/apps/gameboy_app.hpp @@ -4,13 +4,23 @@ #include #include +#include +#include namespace apps { inline constexpr char kGameboyAppName[] = "Game Boy"; inline constexpr std::string_view kGameboyAppNameView = kGameboyAppName; +struct EmbeddedRomDescriptor { + std::string_view name; + std::string_view saveSlug; + const std::uint8_t* start = nullptr; + const std::uint8_t* end = nullptr; +}; + +void setGameboyEmbeddedRoms(std::span descriptors); + std::unique_ptr createGameboyAppFactory(); } // namespace apps - diff --git a/Firmware/sdk/include/cardboy/sdk/app_framework.hpp b/Firmware/sdk/include/cardboy/sdk/app_framework.hpp index 17107ac..60c6628 100644 --- a/Firmware/sdk/include/cardboy/sdk/app_framework.hpp +++ b/Firmware/sdk/include/cardboy/sdk/app_framework.hpp @@ -38,11 +38,7 @@ struct AppEvent { AppTimerEvent timer{}; }; -#ifdef CARDBOY_SDK_ACTIVE_BACKEND_TYPE -using ActiveBackend = CARDBOY_SDK_ACTIVE_BACKEND_TYPE; -#else -#error "CARDBOY_SDK_ACTIVE_BACKEND_TYPE must name the active backend type" -#endif +using ActiveBackend = cardboy::backend::ActiveBackend; struct AppContext { using Framebuffer = typename ActiveBackend::Framebuffer; diff --git a/Firmware/sdk/include/cardboy/sdk/backend.hpp b/Firmware/sdk/include/cardboy/sdk/backend.hpp index f6ce78a..d0b61c9 100644 --- a/Firmware/sdk/include/cardboy/sdk/backend.hpp +++ b/Firmware/sdk/include/cardboy/sdk/backend.hpp @@ -2,9 +2,4 @@ #include "platform.hpp" -#ifndef CARDBOY_SDK_BACKEND_HEADER -#error "CARDBOY_SDK_BACKEND_HEADER must expand to the active backend header path" -#endif - -#include CARDBOY_SDK_BACKEND_HEADER - +#include "cardboy/backend/backend_impl.hpp" diff --git a/Firmware/sdk/include/cardboy/sdk/platform.hpp b/Firmware/sdk/include/cardboy/sdk/platform.hpp index dcd2fa7..56b5e5a 100644 --- a/Firmware/sdk/include/cardboy/sdk/platform.hpp +++ b/Firmware/sdk/include/cardboy/sdk/platform.hpp @@ -60,7 +60,7 @@ public: impl().sendFrame_impl(clearDrawBuffer); } - __attribute__((always_inline)) [[nodiscard]] bool isFrameInFlight() const { + [[nodiscard]] __attribute__((always_inline)) bool isFrameInFlight() const { if constexpr (detail::HasFrameInFlightImpl) return impl().frameInFlight_impl(); return false; @@ -71,8 +71,8 @@ protected: ~FramebufferFacade() = default; private: - __attribute__((always_inline)) [[nodiscard]] Impl& impl() { return static_cast(*this); } - __attribute__((always_inline)) [[nodiscard]] const Impl& impl() const { return static_cast(*this); } + [[nodiscard]] __attribute__((always_inline)) Impl& impl() { return static_cast(*this); } + [[nodiscard]] __attribute__((always_inline)) const Impl& impl() const { return static_cast(*this); } void defaultClear(bool on) { for (int y = 0; y < height(); ++y)