mirror of
https://github.com/usatiuk/cardboy.git
synced 2025-10-28 15:17:48 +01:00
check macro
This commit is contained in:
@@ -21,6 +21,7 @@ idf_component_register(
|
||||
nvs_flash
|
||||
)
|
||||
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../sdk/utils" cardboy_utils_esp)
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../sdk/backend_interface" backend_interface_from_backend_esp)
|
||||
|
||||
add_library(cardboy_backend_esp INTERFACE)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define CB_DISPLAY_HPP
|
||||
|
||||
#include "cardboy/backend/esp/config.hpp"
|
||||
#include "cardboy/utils/utils.hpp"
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
// (Async memcpy removed for debugging simplification)
|
||||
@@ -34,7 +35,7 @@ void frame_ready();
|
||||
bool frame_transfer_in_flight(); // optional diagnostic: is a frame transfer still in flight?
|
||||
|
||||
__attribute__((always_inline)) static void set_pixel(int x, int y, bool value) {
|
||||
assert(x >= 0 && x < DISP_WIDTH && y >= 0 && y < DISP_HEIGHT);
|
||||
CARDBOY_CHECK(x >= 0 && x < DISP_WIDTH && y >= 0 && y < DISP_HEIGHT);
|
||||
|
||||
unsigned lineIdx = 2 + kLineMultiSingle * y + (x / 8);
|
||||
unsigned bitIdx = 1 << (7 - (x % 8)) % 8;
|
||||
@@ -47,8 +48,8 @@ __attribute__((always_inline)) static void set_pixel(int x, int y, bool value) {
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static void set_pixel_8(int x, int y, std::uint8_t value) {
|
||||
assert(x >= 0 && x < DISP_WIDTH && y >= 0 && y < DISP_HEIGHT);
|
||||
assert((x % 8) == 0);
|
||||
CARDBOY_CHECK(x >= 0 && x < DISP_WIDTH && y >= 0 && y < DISP_HEIGHT);
|
||||
CARDBOY_CHECK((x % 8) == 0);
|
||||
unsigned lineIdx = 2 + kLineMultiSingle * y + (x / 8);
|
||||
dma_buf[lineIdx] = ~value;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ public:
|
||||
|
||||
[[nodiscard]] int width_impl() const { return cardboy::sdk::kDisplayWidth; }
|
||||
[[nodiscard]] int height_impl() const { return cardboy::sdk::kDisplayHeight; }
|
||||
void drawPixel_impl(int x, int y, bool on) { SMD::set_pixel(x, y, on); }
|
||||
void drawBits8_impl(int x, int y, std::uint8_t bits) { SMD::set_pixel_8(x, y, bits); }
|
||||
void __attribute__((always_inline)) drawPixel_impl(int x, int y, bool on) { SMD::set_pixel(x, y, on); }
|
||||
void __attribute__((always_inline)) drawBits8_impl(int x, int y, std::uint8_t bits) {
|
||||
SMD::set_pixel_8(x, y, bits);
|
||||
}
|
||||
void clear_impl(bool on);
|
||||
void frameReady_impl();
|
||||
void sendFrame_impl(bool clearAfterSend);
|
||||
|
||||
@@ -5,6 +5,8 @@ set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||
set(CMAKE_CXX_EXTENSIONS NO)
|
||||
|
||||
add_subdirectory(utils)
|
||||
|
||||
add_subdirectory(backend_interface)
|
||||
|
||||
set(CARDBOY_SDK_BACKEND_LIBRARY "" CACHE STRING "Backend implementation library for Cardboy SDK")
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "cardboy/sdk/app_framework.hpp"
|
||||
#include "cardboy/sdk/app_system.hpp"
|
||||
#include "cardboy/sdk/services.hpp"
|
||||
#include "cardboy/utils/utils.hpp"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
@@ -1039,8 +1040,7 @@ private:
|
||||
if (!activeRomName.empty()) {
|
||||
const std::string rotatedRomName(activeRomName.rbegin(), activeRomName.rend());
|
||||
const auto textBounds =
|
||||
font16x8::measureTextBounds(rotatedRomName, textScale, 1,
|
||||
font16x8::Rotation::Clockwise90);
|
||||
font16x8::measureTextBounds(rotatedRomName, textScale, 1, font16x8::Rotation::Clockwise90);
|
||||
const int textHeight = textBounds.height;
|
||||
const int maxOrigin = std::max(0, screenHeight - textHeight);
|
||||
int leftX = 8;
|
||||
@@ -1049,8 +1049,7 @@ private:
|
||||
font16x8::Rotation::Clockwise90);
|
||||
if (!statusMessage.empty()) {
|
||||
const std::string rotatedStatusMessage(statusMessage.rbegin(), statusMessage.rend());
|
||||
const auto statusBounds =
|
||||
font16x8::measureTextBounds(rotatedStatusMessage, textScale, 1,
|
||||
const auto statusBounds = font16x8::measureTextBounds(rotatedStatusMessage, textScale, 1,
|
||||
font16x8::Rotation::Clockwise90);
|
||||
const int textHeight = statusBounds.height;
|
||||
const int maxOrigin = std::max(0, screenHeight - textHeight);
|
||||
@@ -1075,9 +1074,7 @@ private:
|
||||
std::string rotated(text.rbegin(), text.rend());
|
||||
if (totalRightHeight > 0)
|
||||
totalRightHeight += gap;
|
||||
const auto bounds =
|
||||
font16x8::measureTextBounds(rotated, textScale, 1,
|
||||
font16x8::Rotation::Clockwise90);
|
||||
const auto bounds = font16x8::measureTextBounds(rotated, textScale, 1, font16x8::Rotation::Clockwise90);
|
||||
totalRightHeight += bounds.height;
|
||||
}
|
||||
|
||||
@@ -1093,9 +1090,7 @@ private:
|
||||
if (text.empty())
|
||||
continue;
|
||||
std::string rotated(text.rbegin(), text.rend());
|
||||
const auto bounds =
|
||||
font16x8::measureTextBounds(rotated, textScale, 1,
|
||||
font16x8::Rotation::Clockwise90);
|
||||
const auto bounds = font16x8::measureTextBounds(rotated, textScale, 1, font16x8::Rotation::Clockwise90);
|
||||
rightY = screenHeight - bounds.height - 8;
|
||||
font16x8::drawText(framebuffer, rightX, rightY, rotated, textScale, true, 1,
|
||||
font16x8::Rotation::Clockwise90);
|
||||
@@ -1193,8 +1188,7 @@ private:
|
||||
}
|
||||
|
||||
static GameboyApp* fromGb(struct gb_s* gb) {
|
||||
if (!gb)
|
||||
return nullptr;
|
||||
CARDBOY_CHECK_CODE(if (!gb) return nullptr;);
|
||||
return static_cast<GameboyApp*>(gb->direct.priv);
|
||||
}
|
||||
|
||||
@@ -1210,11 +1204,10 @@ private:
|
||||
|
||||
static uint8_t romRead(struct gb_s* gb, const uint_fast32_t addr) {
|
||||
auto* self = fromGb(gb);
|
||||
if (!self)
|
||||
return 0xFF;
|
||||
// ScopedCallbackTimer timer(self, PerfTracker::CallbackKind::RomRead);
|
||||
if (!self->romDataView || addr >= self->romDataViewSize)
|
||||
return 0xFF;
|
||||
CARDBOY_CHECK_CODE(if (!self) return 0xFF;
|
||||
if (!self->romDataView || addr >= self->romDataViewSize) return 0xFF;);
|
||||
// ScopedCallbackTimer timer(self,
|
||||
// PerfTracker::CallbackKind::RomRead);
|
||||
return self->romDataView[static_cast<std::size_t>(addr)];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
add_library(cardboy_backend_interface INTERFACE)
|
||||
|
||||
target_link_libraries(cardboy_backend_interface INTERFACE cardboy_utils)
|
||||
|
||||
set_target_properties(cardboy_backend_interface PROPERTIES
|
||||
EXPORT_NAME backend_interface
|
||||
)
|
||||
|
||||
21
Firmware/sdk/utils/CMakeLists.txt
Normal file
21
Firmware/sdk/utils/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
add_library(cardboy_utils INTERFACE)
|
||||
|
||||
option(CARDBOY_MORE_CHECKS "More checks" OFF)
|
||||
|
||||
set_target_properties(cardboy_utils PROPERTIES
|
||||
EXPORT_NAME utils
|
||||
)
|
||||
|
||||
target_include_directories(cardboy_utils
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
if(CARDBOY_MORE_CHECKS)
|
||||
target_compile_definitions(cardboy_utils INTERFACE CARDBOY_MORE_CHECKS=1)
|
||||
endif()
|
||||
|
||||
target_sources(cardboy_utils
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/cardboy/utils/utils.hpp
|
||||
)
|
||||
59
Firmware/sdk/utils/include/cardboy/utils/utils.hpp
Normal file
59
Firmware/sdk/utils/include/cardboy/utils/utils.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 11.10.2025.
|
||||
//
|
||||
|
||||
#ifndef CARDBOY_SDK_UTILS_HPP
|
||||
#define CARDBOY_SDK_UTILS_HPP
|
||||
|
||||
#ifndef CARDBOY_MORE_CHECKS
|
||||
#define CARDBOY_MORE_CHECKS 0
|
||||
#endif
|
||||
|
||||
#if CARDBOY_MORE_CHECKS
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
// Fails the program with a message. Internal use.
|
||||
#define CARDBOY__CHECK_FAIL_IMPL(expr_str, file, line, func, msg_opt) \
|
||||
do { \
|
||||
std::fprintf(stderr, \
|
||||
"CARDBOY_CHECK failed: %s\n at %s:%d in %s%s%s\n", \
|
||||
(expr_str), (file), (line), (func), \
|
||||
((msg_opt) ? "\n message: " : ""), \
|
||||
((msg_opt) ? (msg_opt) : "")); \
|
||||
std::fflush(stderr); \
|
||||
std::abort(); \
|
||||
} while (0)
|
||||
|
||||
// Runtime check that is active only when CARDBOY_MORE_CHECKS != 0.
|
||||
// Evaluates the expression exactly once.
|
||||
#define CARDBOY_CHECK(expr) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
CARDBOY__CHECK_FAIL_IMPL(#expr, __FILE__, __LINE__, __func__, NULL); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Same as CARDBOY_CHECK but allows providing a custom C-string message.
|
||||
#define CARDBOY_CHECK_MSG(expr, msg) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
CARDBOY__CHECK_FAIL_IMPL(#expr, __FILE__, __LINE__, __func__, (msg));\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Execute arbitrary code only when checks are enabled.
|
||||
#define CARDBOY_CHECK_CODE(code) \
|
||||
do { \
|
||||
code; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
// Checks compiled out when CARDBOY_MORE_CHECKS == 0.
|
||||
#define CARDBOY_CHECK(expr) do { (void)sizeof(expr); } while (0)
|
||||
#define CARDBOY_CHECK_MSG(expr, _) do { (void)sizeof(expr); } while (0)
|
||||
#define CARDBOY_CHECK_CODE(code) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // CARDBOY_SDK_UTILS_HPP
|
||||
Reference in New Issue
Block a user