diff options
| -rw-r--r-- | README.md | 72 | ||||
| -rw-r--r-- | src/render.c | 3 |
2 files changed, 75 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..2b19c65 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# gbc — a Game Boy Color emulator in C, rendered to the terminal + +A from-scratch Game Boy / Game Boy Color emulator written in plain C11. It +renders graphics directly to the terminal using 24-bit (truecolor) ANSI escape +codes and the Unicode upper-half-block trick (`▀`): each character cell packs +two vertical pixels (foreground = top pixel, background = bottom pixel), +giving a 160×144 GB screen in 160×72 terminal cells. + +## Build & run + +```sh +make +./build/gbc path/to/rom.gb # interactive +./build/gbc rom.gb --test 30 # headless: run 30s, log serial (test roms) +./build/gbc rom.gb --shot 60 out.ppm # run 60 frames, dump a PPM screenshot +``` + +Requires a truecolor-capable terminal (`COLORTERM=truecolor`) at least +160 columns wide. + +## Controls + +| Key | Button | +|----------------|---------| +| arrows / WASD | D-pad | +| `z` / `j` | A | +| `x` / `k` | B | +| enter | Start | +| space | Select | +| `q` / Ctrl-C | Quit | + +Since terminals don't report key-release, buttons are held for a few frames +after each keypress (relying on the terminal's key-repeat for sustained holds). + +## Architecture + +| File | Responsibility | +|-------------|-----------------------------------------------------------| +| `types.h` | fixed-width integer typedefs | +| `cart.c` | ROM loading, header parsing, MBC1/2/3/5, battery saves | +| `gb.c` | system bus / memory map, joypad, OAM-DMA, HDMA/GDMA, reset| +| `cpu.c` | Sharp SM83 core (full opcode set, cycle-accurate accesses)| +| `timer.c` | DIV/TIMA/TMA/TAC with falling-edge accuracy | +| `ppu.c` | LCD controller, scanline renderer (BG/window/sprites), CGB| +| `render.c` | terminal truecolor output + raw-mode keyboard input | +| `main.c` | argument parsing, frame loop, timing, screenshot/test modes| + +## Emulation status + +Passing: +- **blargg `cpu_instrs`** — all 11 sub-tests +- **blargg `instr_timing`** +- **blargg `mem_timing`** — all 3 +- **dmg-acid2** — PPU test renders correctly +- **cgb-acid2** — CGB PPU test renders correctly + +Implemented: +- Full SM83 CPU incl. HALT bug, EI delay, interrupt dispatch +- Accurate timer edge behavior +- PPU modes 0–3, STAT/LYC/VBlank interrupts, window line counter +- CGB: double VRAM banks, BG/OBJ color palettes, tile attributes, + master priority, WRAM banking, double-speed (KEY1), HDMA/GDMA +- MBC1/2/3/5 with RAM banking and battery `.sav` files + +Not yet implemented: +- APU (audio) — registers are stubbed +- MBC3 RTC advancement +- Sub-instruction PPU FIFO timing edge cases + +## License + +For educational use. Test ROMs are downloaded separately and not included. diff --git a/src/render.c b/src/render.c index 005fd71..72e5558 100644 --- a/src/render.c +++ b/src/render.c @@ -61,6 +61,9 @@ void render_frame(GB *gb) { } memcpy(o, "\x1b[0m\r\n", 6); o += 6; } + o += sprintf(o, "\x1b[0m\x1b[38;2;150;150;150m %.*s " + "[wasd/arrows] z:A x:B space:sel enter:start q:quit\x1b[0m\r\n", + 15, gb->cart.title); fwrite(outbuf, 1, o - outbuf, stdout); fflush(stdout); } |
