97 lines
4.0 KiB
Markdown
97 lines
4.0 KiB
Markdown
# GameBoy Emulator (Tactility Prototype, No Audio)
|
||
|
||
DMG Game Boy emulator for Tactility side-loaded apps, using **Peanut-GB** (MIT) as CPU/LCD core.
|
||
|
||
## Status
|
||
|
||
- Prototype v0.1.0-dev – compiling draft focused on architecture, not yet production-hardened.
|
||
- **No audio** (ENABLE_SOUND 0). Audio path stubbed for future MiniGB APU or i2s-driven implementation.
|
||
- Supports MBC1/MBC2/MBC3/MBC5 via Peanut-GB.
|
||
- ROM loader from SD card.
|
||
- Save RAM persistence via `.sav` file next to ROM.
|
||
- LVGL framebuffer: native 160x144 RGB565, integer-scaled if display large enough, centered on black background.
|
||
- Input: on-screen D-pad + A/B + Start/Select + hardware keyboard arrows + LVGL key events (z= A, x= B).
|
||
- Timer-driven at ~16ms (~60Hz) calling `gb_run_frame()`.
|
||
|
||
## ROM Location
|
||
|
||
- Scanned directory: `/sdcard/roms/gb/` for `*.gb`, `*.gbc`, `*.bin` (up to 64 entries).
|
||
- Default quick-load: `/sdcard/roms/gb/default.gb` – if present on app show, autoloads and jumps directly to emulation.
|
||
- Place your legally dumped ROMs there; no ROMs are bundled.
|
||
|
||
## Save RAM Path Design (stubbed + implemented minimal)
|
||
|
||
- Save file = ROM path with extension replaced by `.sav` (e.g. `/sdcard/roms/gb/tetris.gb` -> `/sdcard/roms/gb/tetris.sav`).
|
||
- Loaded on ROM load, saved on:
|
||
- switching back to menu
|
||
- app hide
|
||
- error recovery path
|
||
- Size queried via `gb_get_save_size_s()` / `gb_get_save_size()`.
|
||
- Future improvement: also mirror to app user-data dir (`tt_app_get_user_data_child_path`) if SD is read-only.
|
||
|
||
## Memory Considerations (ESP32-S3 / PSRAM)
|
||
|
||
- Large buffers allocated via `heap_caps_malloc(..., MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT)` with fallback to internal.
|
||
- ROM buffer: up to 2MB (MBC5 max-ish) – PSRAM preferred.
|
||
- Cart RAM: variable, often 8KB-32KB, PSRAM.
|
||
- Framebuffer: 160*144*2 = 46,080 bytes (~45KB) native RGB565. PSRAM preferred. No double buffering needed (line callback writes directly).
|
||
- No huge heap allocations.
|
||
- Emulator context `struct gb_s` is static inside AppCtx (~few KB).
|
||
|
||
## Controls / Input Mapping
|
||
|
||
| GB | On-screen | Keyboard | Remarks |
|
||
|----|-----------|----------|---------|
|
||
| D-pad | 4 arrow buttons | LV_KEY_ arrows | press/release tracked |
|
||
| A | A button (right cluster) | z | |
|
||
| B | B button (right cluster) | x | |
|
||
| Start | Sta | Enter / Space | |
|
||
| Select | Sel | Esc / Backspace | |
|
||
| Touch | Quadrants not yet separated – buttons cover |
|
||
|
||
Future: touch quadrants mapping via `pointToQuadrant` like GameKitInput.
|
||
|
||
## LCD Rendering
|
||
|
||
- Peanut-GB calls `lcd_draw_line(gb, pixels[160], line)` per scanline.
|
||
- `pixels` low 2 bits = shade 0-3.
|
||
- Mapped to olive/gray palette RGB565 (editable).
|
||
- Canvas buffer is the framebuffer itself.
|
||
- Scale: if display resolution >= 320x432 => 2x, >=480x576 => 3x via LVGL transform scale (keeps native buffer).
|
||
|
||
## No-Audio Limitation
|
||
|
||
- `ENABLE_SOUND 0` – audio callbacks not compiled.
|
||
- To add audio:
|
||
1. Vendor MiniGB APU (`minigb_apu`) or similar.
|
||
2. Implement `audio_read` / `audio_write` forwarding to APU.
|
||
3. Define ENABLE_SOUND 1, include APU, create audio task similar to BookPlayer (i2s_controller).
|
||
4. Feed APU samples in timer / separate task.
|
||
|
||
## Build
|
||
|
||
Same as other Tactility apps:
|
||
|
||
```
|
||
. $IDF_PATH/export.sh
|
||
export TACTILITY_SDK_PATH=...
|
||
python3 tactility.py Apps/GameBoy build esp32s3 --local-sdk
|
||
```
|
||
|
||
## Licensing
|
||
|
||
- App code: GPLv3 (same as Tactility Apps).
|
||
- Peanut-GB vendored lib: MIT (Copyright (c) 2018-2023 Mahyar Koshkouei). License preserved in `Libraries/PeanutGB/peanut_gb.h`.
|
||
|
||
## Next Steps
|
||
|
||
- [ ] Improve input: add touch quadrant → D-pad, repeat timers for held buttons.
|
||
- [ ] Add pause/resume UI, FPS display.
|
||
- [ ] Add palette selector (auto_assign_palette logic from peanut_sdl).
|
||
- [ ] Add file picker dialog (`tt_app_selectiondialog_start`) improvement + recursive folder browsing.
|
||
- [ ] Audio: vendoring `minigb_apu` and creating I2S task.
|
||
- [ ] Save state beyond cart RAM (full emu snapshot).
|
||
- [ ] RTC persistence for MBC3 RTC games.
|
||
- [ ] Error dialog via `tt_app_alertdialog_start`.
|
||
- [ ] Validate with Cppcheck / clang-format and ESP-IDF build.
|