mirror of
https://github.com/usatiuk/cardboy.git
synced 2025-10-28 23:27:49 +01:00
faster
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "app_platform.hpp"
|
||||||
|
#include "input_state.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -8,46 +11,18 @@
|
|||||||
|
|
||||||
class AppSystem;
|
class AppSystem;
|
||||||
|
|
||||||
struct InputState {
|
template<typename FramebufferT, typename InputT, typename ClockT>
|
||||||
bool up = false;
|
struct BasicAppContext {
|
||||||
bool left = false;
|
using Framebuffer = FramebufferT;
|
||||||
bool right = false;
|
using Input = InputT;
|
||||||
bool down = false;
|
using Clock = ClockT;
|
||||||
bool a = false;
|
|
||||||
bool b = false;
|
|
||||||
bool select = false;
|
|
||||||
bool start = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IFramebuffer {
|
BasicAppContext() = delete;
|
||||||
public:
|
BasicAppContext(FramebufferT& fb, InputT& in, ClockT& clk) : framebuffer(fb), input(in), clock(clk) {}
|
||||||
virtual ~IFramebuffer() = default;
|
|
||||||
virtual void drawPixel(int x, int y, bool on) = 0; // on=true => black
|
|
||||||
virtual void clear(bool on) = 0; // fill full screen to on/off
|
|
||||||
virtual int width() const = 0;
|
|
||||||
virtual int height() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IInput {
|
FramebufferT& framebuffer;
|
||||||
public:
|
InputT& input;
|
||||||
virtual ~IInput() = default;
|
ClockT& clock;
|
||||||
virtual InputState readState() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IClock {
|
|
||||||
public:
|
|
||||||
virtual ~IClock() = default;
|
|
||||||
virtual uint32_t millis() = 0;
|
|
||||||
virtual void sleep_ms(uint32_t ms) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AppContext {
|
|
||||||
AppContext() = delete;
|
|
||||||
AppContext(IFramebuffer& fb, IInput& in, IClock& clk) : framebuffer(fb), input(in), clock(clk) {}
|
|
||||||
|
|
||||||
IFramebuffer& framebuffer;
|
|
||||||
IInput& input;
|
|
||||||
IClock& clock;
|
|
||||||
AppSystem* system = nullptr;
|
AppSystem* system = nullptr;
|
||||||
|
|
||||||
void requestAppSwitchByIndex(std::size_t index) {
|
void requestAppSwitchByIndex(std::size_t index) {
|
||||||
@@ -73,6 +48,8 @@ private:
|
|||||||
std::string pendingAppName;
|
std::string pendingAppName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using AppContext = BasicAppContext<PlatformFramebuffer, PlatformInput, PlatformClock>;
|
||||||
|
|
||||||
struct AppSleepPlan {
|
struct AppSleepPlan {
|
||||||
uint32_t slow_ms = 0; // long sleep allowing battery/UI periodic refresh
|
uint32_t slow_ms = 0; // long sleep allowing battery/UI periodic refresh
|
||||||
uint32_t normal_ms = 0; // short sleep for responsiveness on input wake
|
uint32_t normal_ms = 0; // short sleep for responsiveness on input wake
|
||||||
|
|||||||
64
Firmware/main/include/app_platform.hpp
Normal file
64
Firmware/main/include/app_platform.hpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "config.hpp"
|
||||||
|
#include "input_state.hpp"
|
||||||
|
|
||||||
|
#include <buttons.hpp>
|
||||||
|
#include <disp_tools.hpp>
|
||||||
|
#include <power_helper.hpp>
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
class PlatformFramebuffer {
|
||||||
|
public:
|
||||||
|
int width() const { return DISP_WIDTH; }
|
||||||
|
int height() const { return DISP_HEIGHT; }
|
||||||
|
|
||||||
|
void drawPixel(int x, int y, bool on) {
|
||||||
|
if (x < 0 || y < 0 || x >= width() || y >= height())
|
||||||
|
return;
|
||||||
|
DispTools::set_pixel(x, y, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(bool on) {
|
||||||
|
for (int y = 0; y < height(); ++y)
|
||||||
|
for (int x = 0; x < width(); ++x)
|
||||||
|
DispTools::set_pixel(x, y, on);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlatformInput {
|
||||||
|
public:
|
||||||
|
InputState readState() {
|
||||||
|
InputState state{};
|
||||||
|
const uint8_t pressed = Buttons::get().get_pressed();
|
||||||
|
if (pressed & BTN_UP)
|
||||||
|
state.up = true;
|
||||||
|
if (pressed & BTN_LEFT)
|
||||||
|
state.left = true;
|
||||||
|
if (pressed & BTN_RIGHT)
|
||||||
|
state.right = true;
|
||||||
|
if (pressed & BTN_DOWN)
|
||||||
|
state.down = true;
|
||||||
|
if (pressed & BTN_A)
|
||||||
|
state.a = true;
|
||||||
|
if (pressed & BTN_B)
|
||||||
|
state.b = true;
|
||||||
|
if (pressed & BTN_SELECT)
|
||||||
|
state.select = true;
|
||||||
|
if (pressed & BTN_START)
|
||||||
|
state.start = true;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlatformClock {
|
||||||
|
public:
|
||||||
|
uint32_t millis() {
|
||||||
|
TickType_t ticks = xTaskGetTickCount();
|
||||||
|
return static_cast<uint32_t>((static_cast<uint64_t>(ticks) * 1000ULL) / configTICK_RATE_HZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sleep_ms(uint32_t ms) { PowerHelper::get().delay(static_cast<int>(ms), static_cast<int>(ms)); }
|
||||||
|
};
|
||||||
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
namespace font16x8 {
|
namespace font16x8 {
|
||||||
|
|
||||||
constexpr int kGlyphWidth = 8;
|
constexpr int kGlyphWidth = 8;
|
||||||
constexpr int kGlyphHeight = 16;
|
constexpr int kGlyphHeight = 16;
|
||||||
constexpr unsigned char kFallbackChar = '?';
|
constexpr unsigned char kFallbackChar = '?';
|
||||||
|
|
||||||
inline unsigned char normalizeChar(char ch) {
|
inline unsigned char normalizeChar(char ch) {
|
||||||
@@ -27,7 +27,8 @@ inline const std::array<uint8_t, kGlyphHeight>& glyphBitmap(char ch) {
|
|||||||
return fonts_Terminess_Powerline[uc];
|
return fonts_Terminess_Powerline[uc];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void drawGlyph(IFramebuffer& fb, int x, int y, char ch, int scale = 1, bool on = true) {
|
template<typename Framebuffer>
|
||||||
|
inline void drawGlyph(Framebuffer& fb, int x, int y, char ch, int scale = 1, bool on = true) {
|
||||||
const auto& rows = glyphBitmap(ch);
|
const auto& rows = glyphBitmap(ch);
|
||||||
for (int row = 0; row < kGlyphHeight; ++row) {
|
for (int row = 0; row < kGlyphHeight; ++row) {
|
||||||
const uint8_t rowBits = rows[row];
|
const uint8_t rowBits = rows[row];
|
||||||
@@ -49,7 +50,8 @@ inline int measureText(std::string_view text, int scale = 1, int letterSpacing =
|
|||||||
return static_cast<int>(text.size()) * advance - letterSpacing * scale;
|
return static_cast<int>(text.size()) * advance - letterSpacing * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void drawText(IFramebuffer& fb, int x, int y, std::string_view text, int scale = 1, bool on = true,
|
template<typename Framebuffer>
|
||||||
|
inline void drawText(Framebuffer& fb, int x, int y, std::string_view text, int scale = 1, bool on = true,
|
||||||
int letterSpacing = 1) {
|
int letterSpacing = 1) {
|
||||||
int cursor = x;
|
int cursor = x;
|
||||||
for (char ch: text) {
|
for (char ch: text) {
|
||||||
|
|||||||
12
Firmware/main/include/input_state.hpp
Normal file
12
Firmware/main/include/input_state.hpp
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct InputState {
|
||||||
|
bool up = false;
|
||||||
|
bool left = false;
|
||||||
|
bool right = false;
|
||||||
|
bool down = false;
|
||||||
|
bool a = false;
|
||||||
|
bool b = false;
|
||||||
|
bool select = false;
|
||||||
|
bool start = false;
|
||||||
|
};
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
#include <buzzer.hpp>
|
#include <buzzer.hpp>
|
||||||
#include <disp_tools.hpp>
|
#include <disp_tools.hpp>
|
||||||
#include <display.hpp>
|
#include <display.hpp>
|
||||||
#include <i2c_global.hpp>
|
|
||||||
#include <fs_helper.hpp>
|
#include <fs_helper.hpp>
|
||||||
|
#include <i2c_global.hpp>
|
||||||
#include <power_helper.hpp>
|
#include <power_helper.hpp>
|
||||||
#include <shutdowner.hpp>
|
#include <shutdowner.hpp>
|
||||||
#include <spi_global.hpp>
|
#include <spi_global.hpp>
|
||||||
@@ -29,63 +29,6 @@
|
|||||||
#include "esp_sleep.h"
|
#include "esp_sleep.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class PlatformFramebuffer final : public IFramebuffer {
|
|
||||||
public:
|
|
||||||
int width() const override { return DISP_WIDTH; }
|
|
||||||
int height() const override { return DISP_HEIGHT; }
|
|
||||||
|
|
||||||
void drawPixel(int x, int y, bool on) override {
|
|
||||||
if (x < 0 || y < 0 || x >= width() || y >= height())
|
|
||||||
return;
|
|
||||||
DispTools::set_pixel(x, y, on);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear(bool on) override {
|
|
||||||
for (int y = 0; y < height(); ++y)
|
|
||||||
for (int x = 0; x < width(); ++x)
|
|
||||||
DispTools::set_pixel(x, y, on);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlatformInput final : public IInput {
|
|
||||||
public:
|
|
||||||
InputState readState() override {
|
|
||||||
InputState state{};
|
|
||||||
const uint8_t pressed = Buttons::get().get_pressed();
|
|
||||||
if (pressed & BTN_UP)
|
|
||||||
state.up = true;
|
|
||||||
if (pressed & BTN_LEFT)
|
|
||||||
state.left = true;
|
|
||||||
if (pressed & BTN_RIGHT)
|
|
||||||
state.right = true;
|
|
||||||
if (pressed & BTN_DOWN)
|
|
||||||
state.down = true;
|
|
||||||
if (pressed & BTN_A)
|
|
||||||
state.a = true;
|
|
||||||
if (pressed & BTN_B)
|
|
||||||
state.b = true;
|
|
||||||
if (pressed & BTN_SELECT)
|
|
||||||
state.select = true;
|
|
||||||
if (pressed & BTN_START)
|
|
||||||
state.start = true;
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlatformClock final : public IClock {
|
|
||||||
public:
|
|
||||||
uint32_t millis() override {
|
|
||||||
TickType_t ticks = xTaskGetTickCount();
|
|
||||||
return static_cast<uint32_t>((static_cast<uint64_t>(ticks) * 1000ULL) / configTICK_RATE_HZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sleep_ms(uint32_t ms) override { PowerHelper::get().delay(static_cast<int>(ms), static_cast<int>(ms)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
extern "C" void app_main() {
|
extern "C" void app_main() {
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
// const esp_pm_config_t pm_config = {
|
// const esp_pm_config_t pm_config = {
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ namespace {
|
|||||||
|
|
||||||
constexpr const char* kClockAppName = "Clock";
|
constexpr const char* kClockAppName = "Clock";
|
||||||
|
|
||||||
|
using Framebuffer = typename AppContext::Framebuffer;
|
||||||
|
using Clock = typename AppContext::Clock;
|
||||||
|
|
||||||
struct TimeSnapshot {
|
struct TimeSnapshot {
|
||||||
bool hasWallTime = false;
|
bool hasWallTime = false;
|
||||||
int hour24 = 0;
|
int hour24 = 0;
|
||||||
@@ -76,9 +79,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppContext& context;
|
AppContext& context;
|
||||||
IFramebuffer& framebuffer;
|
Framebuffer& framebuffer;
|
||||||
IClock& clock;
|
Clock& clock;
|
||||||
|
|
||||||
bool use24Hour = true;
|
bool use24Hour = true;
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
@@ -119,7 +122,7 @@ private:
|
|||||||
return snap;
|
return snap;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawCenteredText(IFramebuffer& fb, int y, std::string_view text, int scale, int letterSpacing = 0) {
|
static void drawCenteredText(Framebuffer& fb, int y, std::string_view text, int scale, int letterSpacing = 0) {
|
||||||
const int width = font16x8::measureText(text, scale, letterSpacing);
|
const int width = font16x8::measureText(text, scale, letterSpacing);
|
||||||
const int x = (fb.width() - width) / 2;
|
const int x = (fb.width() - width) / 2;
|
||||||
font16x8::drawText(fb, x, y, text, scale, true, letterSpacing);
|
font16x8::drawText(fb, x, y, text, scale, true, letterSpacing);
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ namespace {
|
|||||||
constexpr int kMenuStartY = 48;
|
constexpr int kMenuStartY = 48;
|
||||||
constexpr int kMenuSpacing = font16x8::kGlyphHeight + 6;
|
constexpr int kMenuSpacing = font16x8::kGlyphHeight + 6;
|
||||||
|
|
||||||
|
using Framebuffer = typename AppContext::Framebuffer;
|
||||||
|
|
||||||
constexpr std::array<std::string_view, 2> kRomExtensions = {".gb", ".gbc"};
|
constexpr std::array<std::string_view, 2> kRomExtensions = {".gb", ".gbc"};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -116,7 +118,7 @@ int measureVerticalText(std::string_view text, int scale = 1, int letterSpacing
|
|||||||
return static_cast<int>(text.size()) * advance - letterSpacing * scale;
|
return static_cast<int>(text.size()) * advance - letterSpacing * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawGlyphRotated(IFramebuffer& fb, int x, int y, char ch, bool clockwise, int scale = 1, bool on = true) {
|
void drawGlyphRotated(Framebuffer& fb, int x, int y, char ch, bool clockwise, int scale = 1, bool on = true) {
|
||||||
const auto& rows = font16x8::glyphBitmap(ch);
|
const auto& rows = font16x8::glyphBitmap(ch);
|
||||||
for (int row = 0; row < font16x8::kGlyphHeight; ++row) {
|
for (int row = 0; row < font16x8::kGlyphHeight; ++row) {
|
||||||
const uint8_t rowBits = rows[row];
|
const uint8_t rowBits = rows[row];
|
||||||
@@ -142,7 +144,7 @@ void drawGlyphRotated(IFramebuffer& fb, int x, int y, char ch, bool clockwise, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawTextRotated(IFramebuffer& fb, int x, int y, std::string_view text, bool clockwise, int scale = 1,
|
void drawTextRotated(Framebuffer& fb, int x, int y, std::string_view text, bool clockwise, int scale = 1,
|
||||||
bool on = true, int letterSpacing = 1) {
|
bool on = true, int letterSpacing = 1) {
|
||||||
int cursor = y;
|
int cursor = y;
|
||||||
const int advance = (font16x8::kGlyphWidth + letterSpacing) * scale;
|
const int advance = (font16x8::kGlyphWidth + letterSpacing) * scale;
|
||||||
@@ -482,9 +484,9 @@ private:
|
|||||||
std::array<int, LCD_WIDTH> colXEnd{};
|
std::array<int, LCD_WIDTH> colXEnd{};
|
||||||
};
|
};
|
||||||
|
|
||||||
AppContext& context;
|
AppContext& context;
|
||||||
IFramebuffer& framebuffer;
|
Framebuffer& framebuffer;
|
||||||
PerfTracker perf{};
|
PerfTracker perf{};
|
||||||
|
|
||||||
Mode mode = Mode::Browse;
|
Mode mode = Mode::Browse;
|
||||||
ScaleMode scaleMode = ScaleMode::Original;
|
ScaleMode scaleMode = ScaleMode::Original;
|
||||||
@@ -1129,7 +1131,7 @@ private:
|
|||||||
auto* self = fromGb(gb);
|
auto* self = fromGb(gb);
|
||||||
if (!self)
|
if (!self)
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
ScopedCallbackTimer timer(self, PerfTracker::CallbackKind::RomRead);
|
// ScopedCallbackTimer timer(self, PerfTracker::CallbackKind::RomRead);
|
||||||
if (!self->romDataView || addr >= self->romDataViewSize)
|
if (!self->romDataView || addr >= self->romDataViewSize)
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
return self->romDataView[static_cast<std::size_t>(addr)];
|
return self->romDataView[static_cast<std::size_t>(addr)];
|
||||||
@@ -1186,7 +1188,7 @@ private:
|
|||||||
|
|
||||||
self->frameDirty = true;
|
self->frameDirty = true;
|
||||||
|
|
||||||
IFramebuffer& fb = self->framebuffer;
|
Framebuffer& fb = self->framebuffer;
|
||||||
|
|
||||||
if (geom.scaledWidth == LCD_WIDTH && geom.scaledHeight == LCD_HEIGHT) {
|
if (geom.scaledWidth == LCD_WIDTH && geom.scaledHeight == LCD_HEIGHT) {
|
||||||
const int dstY = yStart;
|
const int dstY = yStart;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ namespace apps {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using Framebuffer = typename AppContext::Framebuffer;
|
||||||
|
|
||||||
struct MenuEntry {
|
struct MenuEntry {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::size_t index = 0;
|
std::size_t index = 0;
|
||||||
@@ -60,7 +62,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
AppContext& context;
|
AppContext& context;
|
||||||
IFramebuffer& framebuffer;
|
Framebuffer& framebuffer;
|
||||||
std::vector<MenuEntry> entries;
|
std::vector<MenuEntry> entries;
|
||||||
std::size_t selected = 0;
|
std::size_t selected = 0;
|
||||||
|
|
||||||
@@ -110,7 +112,7 @@ private:
|
|||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawCenteredText(IFramebuffer& fb, int y, std::string_view text, int scale, int letterSpacing = 0) {
|
static void drawCenteredText(Framebuffer& fb, int y, std::string_view text, int scale, int letterSpacing = 0) {
|
||||||
const int width = font16x8::measureText(text, scale, letterSpacing);
|
const int width = font16x8::measureText(text, scale, letterSpacing);
|
||||||
const int x = (fb.width() - width) / 2;
|
const int x = (fb.width() - width) / 2;
|
||||||
font16x8::drawText(fb, x, y, text, scale, true, letterSpacing);
|
font16x8::drawText(fb, x, y, text, scale, true, letterSpacing);
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ using RotGrid = std::array<char, 16>;
|
|||||||
using PieceR = std::array<RotGrid, 4>;
|
using PieceR = std::array<RotGrid, 4>;
|
||||||
constexpr char _ = '.', X = '#';
|
constexpr char _ = '.', X = '#';
|
||||||
|
|
||||||
|
using Framebuffer = typename AppContext::Framebuffer;
|
||||||
|
using InputDevice = typename AppContext::Input;
|
||||||
|
using Clock = typename AppContext::Clock;
|
||||||
|
|
||||||
static const std::array<PieceR, 7> TET = {{
|
static const std::array<PieceR, 7> TET = {{
|
||||||
PieceR{{RotGrid{_, _, _, _, X, X, X, X, _, _, _, _, _, _, _, _},
|
PieceR{{RotGrid{_, _, _, _, X, X, X, X, _, _, _, _, _, _, _, _},
|
||||||
RotGrid{_, _, X, _, _, _, X, _, _, _, X, _, _, _, X, _},
|
RotGrid{_, _, X, _, _, _, X, _, _, _, X, _, _, _, X, _},
|
||||||
@@ -201,7 +205,7 @@ constexpr int kHudLabelGap = 2;
|
|||||||
constexpr int kHudBlockGap = 8;
|
constexpr int kHudBlockGap = 8;
|
||||||
constexpr int kHudLineGapBattery = 4;
|
constexpr int kHudLineGapBattery = 4;
|
||||||
|
|
||||||
inline void drawHudText(IFramebuffer& fb, int x, int y, std::string_view text) {
|
inline void drawHudText(Framebuffer& fb, int x, int y, std::string_view text) {
|
||||||
font16x8::drawText(fb, x, y, text, kHudFontScale, true, kHudLetterSpacing);
|
font16x8::drawText(fb, x, y, text, kHudFontScale, true, kHudLetterSpacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +215,7 @@ inline int hudFontHeight() { return font16x8::kGlyphHeight * kHudFontScale; }
|
|||||||
// Renderer (centered board + HUD)
|
// Renderer (centered board + HUD)
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
Renderer(IFramebuffer& fb) : fb(fb) {
|
Renderer(Framebuffer& fb) : fb(fb) {
|
||||||
bw = cfg::BoardW * cfg::CellPx; // 10 * 11 = 110
|
bw = cfg::BoardW * cfg::CellPx; // 10 * 11 = 110
|
||||||
bh = cfg::BoardH * cfg::CellPx; // 20 * 11 = 220 (leaves 10px margins vertically)
|
bh = cfg::BoardH * cfg::CellPx; // 20 * 11 = 220 (leaves 10px margins vertically)
|
||||||
ox = (fb.width() - bw) / 2; // centered horizontally
|
ox = (fb.width() - bw) / 2; // centered horizontally
|
||||||
@@ -375,8 +379,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IFramebuffer& fb;
|
Framebuffer& fb;
|
||||||
int ox = 0, oy = 0, bw = 0, bh = 0;
|
int ox = 0, oy = 0, bw = 0, bh = 0;
|
||||||
|
|
||||||
// Pattern helper: returns true if pixel (xx,yy) inside w x h interior should be filled for piece type
|
// Pattern helper: returns true if pixel (xx,yy) inside w x h interior should be filled for piece type
|
||||||
bool patternOn(int type, int w, int h, int xx, int yy) const {
|
bool patternOn(int type, int w, int h, int xx, int yy) const {
|
||||||
@@ -926,15 +930,15 @@ private:
|
|||||||
static constexpr uint32_t idleActivePollMs = 40; // normal_ms provided to PowerHelper for responsiveness
|
static constexpr uint32_t idleActivePollMs = 40; // normal_ms provided to PowerHelper for responsiveness
|
||||||
static constexpr uint32_t activeNormalCapMs = 40; // cap for normal_ms during active play
|
static constexpr uint32_t activeNormalCapMs = 40; // cap for normal_ms during active play
|
||||||
|
|
||||||
AppContext& appContext;
|
AppContext& appContext;
|
||||||
IFramebuffer& fb;
|
Framebuffer& fb;
|
||||||
IInput& input;
|
InputDevice& input;
|
||||||
IClock& clock;
|
Clock& clock;
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
Board board;
|
Board board;
|
||||||
Bag bag;
|
Bag bag;
|
||||||
ScoreState score;
|
ScoreState score;
|
||||||
bool running = true, paused = false, touchingGround = false;
|
bool running = true, paused = false, touchingGround = false;
|
||||||
bool rotPrev = false, lHeld = false, rHeld = false, backPrev = false, selectPrev = false, exitComboPrev = false;
|
bool rotPrev = false, lHeld = false, rHeld = false, backPrev = false, selectPrev = false, exitComboPrev = false;
|
||||||
uint32_t lHoldStart = 0, rHoldStart = 0, lLastRep = 0, rLastRep = 0, lastFall = 0, touchTime = 0;
|
uint32_t lHoldStart = 0, rHoldStart = 0, lLastRep = 0, rLastRep = 0, lastFall = 0, touchTime = 0;
|
||||||
int current = 0, nextPiece = 0, px = 3, py = -2, rot = 0;
|
int current = 0, nextPiece = 0, px = 3, py = -2, rot = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user