HİKAYE
Neden yaptım?
I wanted to see how far an ESP32 could go without relying on external graphics hardware or a traditional operating system.
MÜHENDİSLİK ZORLUKLARI
En büyük engeller.
Shared SPI Bus
Managing concurrent access from both cores to a single SPI bus without causing deadlocks or display corruption.
Triple Buffer Synchronization
Implementing a tear-free render pipeline using mutexes and semaphores across two different CPU cores.
Memory Optimization
Fitting 15 games and a custom GUI into limited SRAM, utilizing PSRAM effectively without taking a performance hit.
Raycasting at 60 FPS
Writing a custom fixed-point math 3D engine that can render textured walls fast enough for a smooth experience.
ÇİFT ÇEKİRDEK MİMARİSİ
Core 0 hesaplar. Core 1 çizer.
Hiçbiri birbirini bekletmez.
Tüm yük iki çekirdeğe dengeli şekilde paylaştırıldı. Oyunun zorlu matematiğini ve fiziklerini arka planda Core 0 hesaplarken, Core 1 sadece ekrana kusursuz ve akıcı görüntüler çizmeye odaklanır.
CORE 0 — HESAPLAMA
TaskEnginepriority 2
↳ raycasting · fizik · AI~30KB stack
TaskRadarpriority 1
↳ OLED çizimi, düşük öncelik
CORE 1 — RENDER
TaskDisplaypriority 3
↳ pushImage · HUD delta-drawtek başına
↳ triple buffer swap, mutex korumalı
doom.ino — triple buffer swap
// fb_render: TaskEngine'in yazdığı buffer
// fb_display: TaskDisplay'in okuduğu buffer
// fb_ready: el değiştirmeye hazır olan buffer
if (xSemaphoreTake(fb_swap_mutex, pdMS_TO_TICKS(2)) == pdTRUE) {
fb_ready = fb_render;
fb_render = /* üçüncü boş buffer'ı seç */;
xSemaphoreGive(fb_swap_mutex);
}
main.ino — RTOS scheduler
// Core 0: Game logic & physics
xTaskCreatePinnedToCore(
TaskEngine, "Engine", 30000, NULL, 2, &TaskEngineHandle, 0
);
// Core 1: Dedicated hardware rendering
xTaskCreatePinnedToCore(
TaskDisplay, "Render", 10000, NULL, 3, &TaskDisplayHandle, 1
);
İŞLETİM SİSTEMİ
E-OS Launcher.
Tüm oyunlara ev sahipliği yapan akıcı, dönen (carousel) ana menü arayüzü.
[ pause ]
Donanımsal Duraklatma
Hangi oyunda olursan ol, joystick butonuna basınca ilgili RTOS task'ı anında askıya alınır.
[ ota ]
OTA Bootloader
SD karttan binary okuyup flash'a yazar. RTC magic value ile reboot sonrası oyun seçimi hatırlanır.
[ ui ]
Double-Buffered Menü
Dönen carousel menü, ekran yırtılması olmadan akar — telefon hissiyatına yakın geçişler.
[ sound ]
Donanımsal Ses Kontrolü
Settings menüsü üzerinden sistem genelindeki sesi kapatın, kısın (LOW) veya tam seste oynayın (HIGH).
[ fps ]
Canlı FPS Göstergesi
Geliştiriciler için tüm oyunların köşesinde gerçek zamanlı kare hızını (FPS) anlık olarak görebilme imkanı.
[ cpu ]
Asenkron Çift Çekirdek
Core 0 sadece arka plan görevlerini ve oyun mantığını işlerken, Core 1 tamamen grafik çizimine (render) adanmıştır.
YOL HARİTASI
Sırada ne var.
v1.0 — tamam
15 oyunluk kütüphane — Mode 7, Wire-Frame 3D, Galactic Strike ve Platformer çekirdek oyunlara katıldı; ardından Tetris, Dungeon ve Tower Defense eklendi. Ortak hardware_config.h ile pin tanımları tekilleştirildi.
v2.0 — planlanan
LiPo batarya entegrasyonu — korumalı TP4056 şarj devresi, voltaj bölücü ile yazılımsal pil yüzdesi takibi.
v2.1 — planlanan
I²S ses çıkışı — MAX98357A amplifikatör ile buzzer'ın yerini gerçek PCM ses alacak.
v3.0 — fikir aşamasında
ESP-NOW multiplayer — ESP32-S3'ün dahili radyosu üzerinden iki cihaz arası düşük gecikmeli bağlantı.
DERLEME
Arduino IDE veya PlatformIO.
Gerekli kütüphaneler ve pin ayarları aşağıda — tüm detaylar repo içinde.
// Gerekli kütüphaneler
TFT_eSPI // Ekran sürücüsü — User_Setup.h ile yapılandırılır
U8g2lib // OLED sürücüsü (HW I2C modunda)
Preferences // NVS — skor / ayar kalıcılığı
// Tüm oyunlar ortak pin dosyasını include eder
#include "../hardware_config.h"