checkpoint

This commit is contained in:
2025-10-11 12:54:46 +02:00
parent 535b0078e5
commit 899bfeef41
11 changed files with 120 additions and 96 deletions

View File

@@ -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
)

View File

@@ -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)

View File

@@ -0,0 +1,8 @@
#pragma once
#include "cardboy/backend/esp_backend.hpp"
namespace cardboy::backend {
using ActiveBackend = EspBackend;
}

View File

@@ -42,10 +42,33 @@
#include <cstring>
#include <string>
#include <string_view>
#include <span>
#include <vector>
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<const apps::EmbeddedRomDescriptor>(kEmbeddedRoms));
static PlatformFramebuffer framebuffer;
static PlatformInput input;
static PlatformClock clock;

View File

@@ -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)

View File

@@ -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 <string_view>
#include <sys/stat.h>
#include <vector>
#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<std::string_view, 2> 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<EmbeddedRomDescriptor, 2> 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<EmbeddedRomDescriptor, 0> kEmbeddedRomDescriptors{};
#endif
static std::span<const EmbeddedRomDescriptor> gEmbeddedRomDescriptors{};
struct RomEntry {
std::string name; // short display name
@@ -114,7 +84,7 @@ struct RomEntry {
}
void appendEmbeddedRoms(std::vector<RomEntry>& 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<std::size_t>(desc.end - desc.start);
@@ -1397,6 +1367,10 @@ public:
} // namespace
void setGameboyEmbeddedRoms(std::span<const EmbeddedRomDescriptor> descriptors) {
gEmbeddedRomDescriptors = descriptors;
}
std::unique_ptr<cardboy::sdk::IAppFactory> createGameboyAppFactory() { return std::make_unique<GameboyAppFactory>(); }
} // namespace apps

View File

@@ -0,0 +1,8 @@
#pragma once
#include "cardboy/backend/desktop_backend.hpp"
namespace cardboy::backend {
using ActiveBackend = DesktopBackend;
}

View File

@@ -4,13 +4,23 @@
#include <memory>
#include <string_view>
#include <span>
#include <cstdint>
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<const EmbeddedRomDescriptor> descriptors);
std::unique_ptr<cardboy::sdk::IAppFactory> createGameboyAppFactory();
} // namespace apps

View File

@@ -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;

View File

@@ -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"

View File

@@ -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<Impl>)
return impl().frameInFlight_impl();
return false;
@@ -71,8 +71,8 @@ protected:
~FramebufferFacade() = default;
private:
__attribute__((always_inline)) [[nodiscard]] Impl& impl() { return static_cast<Impl&>(*this); }
__attribute__((always_inline)) [[nodiscard]] const Impl& impl() const { return static_cast<const Impl&>(*this); }
[[nodiscard]] __attribute__((always_inline)) Impl& impl() { return static_cast<Impl&>(*this); }
[[nodiscard]] __attribute__((always_inline)) const Impl& impl() const { return static_cast<const Impl&>(*this); }
void defaultClear(bool on) {
for (int y = 0; y < height(); ++y)