mirror of
https://github.com/usatiuk/cardboy.git
synced 2025-10-28 23:27:49 +01:00
checkpoint
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
8
Firmware/main/include/cardboy/backend/backend_impl.hpp
Normal file
8
Firmware/main/include/cardboy/backend/backend_impl.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "cardboy/backend/esp_backend.hpp"
|
||||
|
||||
namespace cardboy::backend {
|
||||
using ActiveBackend = EspBackend;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "cardboy/backend/desktop_backend.hpp"
|
||||
|
||||
namespace cardboy::backend {
|
||||
using ActiveBackend = DesktopBackend;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user