Browse Source

Add overlay & font support

v2
Nathaniel Walizer 8 months ago
parent
commit
3b53923af9
5 changed files with 491 additions and 3 deletions
  1. +1
    -0
      Makefile
  2. +147
    -0
      src/charbits.h
  3. +16
    -3
      src/linux/port.c
  4. +280
    -0
      src/overlay.c
  5. +47
    -0
      src/overlay.h

+ 1
- 0
Makefile View File

@@ -31,6 +31,7 @@ NESE_SRC_SRCS = f6502.c f6502_opcodes.c
NESE_SRC_SRCS += nese.c nes.c cart.c mapper.c
NESE_SRC_SRCS += ppu.c apu.c
NESE_SRC_SRCS += memory.c serdes.c save.c rle.c
NESE_SRC_SRCS += overlay.c
NESE_SRC_SRCS += $(OS)/port.c
NESE_MAP_SRCS = $(notdir $(wildcard $(MAPDIR)/*.c))



+ 147
- 0
src/charbits.h View File

@@ -0,0 +1,147 @@
static const char chars[] = "\x7f!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~";

static const int char_w = 10U;
static const int char_h = 10U;
static const int charbit_size = (1U + ((char_w * char_h * 2) + 7) / 8);
static const int char_count = (sizeof(chars) - 1);

static const uint8_t charbits[1794] = {
0x09, 0x55, 0x55, 0x90, 0xaa, 0x16, 0x59, 0x69, 0x91, 0xa5, 0x16, 0x99, 0x66,
0x91, 0x5a, 0x16, 0x69, 0x65, 0x91, 0xaa, 0x16, 0x55, 0x55, 0x41, 0x55, 0x15,
0x07, 0x50, 0x05, 0x00, 0x69, 0x01, 0x94, 0x16, 0x40, 0x6a, 0x01, 0xa4, 0x15,
0x40, 0x5a, 0x01, 0x55, 0x05, 0x90, 0x56, 0x00, 0x55, 0x01, 0x40, 0x15, 0x00,
0x08, 0x55, 0x15, 0x90, 0xa6, 0x05, 0x69, 0x5a, 0x90, 0xa6, 0x05, 0x55, 0x55,
0x40, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0a, 0x54, 0x55, 0x40, 0x9a, 0x16, 0xa5, 0x69, 0x91, 0xaa, 0x5a, 0xa5, 0x69,
0x95, 0xaa, 0x5a, 0xa5, 0x69, 0x45, 0x9a, 0x56, 0x54, 0x55, 0x01, 0x55, 0x15,
0x09, 0x50, 0x05, 0x40, 0x69, 0x05, 0xa5, 0x6a, 0x91, 0x56, 0x15, 0xa5, 0x5a,
0x51, 0x95, 0x16, 0xa9, 0x5a, 0x51, 0x69, 0x15, 0x54, 0x55, 0x00, 0x55, 0x01,
0x0a, 0x00, 0x00, 0x50, 0x45, 0x15, 0x69, 0xa5, 0x95, 0x96, 0x56, 0x55, 0x5a,
0x45, 0x69, 0x15, 0xa5, 0xa5, 0x95, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x0a, 0x50, 0x15, 0x40, 0xa9, 0x05, 0xa4, 0x69, 0x41, 0x9a, 0x16, 0xa5, 0x5a,
0x91, 0x96, 0x5a, 0x69, 0x6a, 0x55, 0x6a, 0x5a, 0x54, 0x55, 0x05, 0x55, 0x55,
0x05, 0x55, 0x00, 0x90, 0x16, 0x00, 0x69, 0x01, 0x90, 0x16, 0x00, 0x55, 0x01,
0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x54, 0x01, 0x50, 0x5a, 0x00, 0x69, 0x05, 0x90, 0x56, 0x00, 0x69, 0x01,
0x90, 0x16, 0x00, 0x69, 0x01, 0x50, 0x5a, 0x00, 0x54, 0x05, 0x00, 0x55, 0x00,
0x06, 0x55, 0x00, 0x90, 0x16, 0x00, 0xa5, 0x05, 0x40, 0x5a, 0x00, 0xa4, 0x05,
0x40, 0x5a, 0x00, 0xa5, 0x05, 0x90, 0x56, 0x00, 0x55, 0x01, 0x40, 0x05, 0x00,
0x0a, 0x00, 0x00, 0x40, 0x55, 0x05, 0xa4, 0x69, 0x51, 0xa9, 0x15, 0xa9, 0xaa,
0x55, 0xa9, 0x55, 0xa4, 0x69, 0x45, 0x55, 0x15, 0x50, 0x55, 0x01, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x50, 0x16, 0x00, 0xa9, 0x05,
0x50, 0x56, 0x00, 0x54, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01,
0x40, 0x5a, 0x00, 0xa5, 0x05, 0x90, 0x56, 0x00, 0x55, 0x05, 0x40, 0x15, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x15, 0x00, 0xa9, 0x05,
0x50, 0x55, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x15, 0x00, 0xa4, 0x05, 0x40, 0x5a, 0x00, 0x54, 0x05, 0x00, 0x55, 0x00,
0x07, 0x50, 0x05, 0x00, 0x69, 0x01, 0x94, 0x16, 0x40, 0x5a, 0x01, 0xa4, 0x05,
0x50, 0x5a, 0x00, 0x69, 0x05, 0x90, 0x16, 0x00, 0x55, 0x01, 0x40, 0x15, 0x00,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x96, 0x5a, 0x69, 0xa6,
0x95, 0x5a, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x09, 0x50, 0x05, 0x40, 0x69, 0x01, 0xa4, 0x16, 0x40, 0x69, 0x01, 0x90, 0x16,
0x00, 0x69, 0x01, 0x95, 0x56, 0x90, 0xaa, 0x16, 0x55, 0x55, 0x41, 0x55, 0x15,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x96, 0x5a, 0x55, 0x6a,
0x45, 0xa9, 0x55, 0xa5, 0x56, 0x91, 0xaa, 0x5a, 0x55, 0x55, 0x45, 0x55, 0x55,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x55, 0x55, 0x5a, 0x54, 0x6a,
0x55, 0x55, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x0a, 0x00, 0x55, 0x00, 0x94, 0x16, 0x50, 0x6a, 0x41, 0xa9, 0x16, 0xa5, 0x69,
0x91, 0x96, 0x16, 0xa9, 0xaa, 0x55, 0x95, 0x56, 0x54, 0x55, 0x05, 0x40, 0x15,
0x0a, 0x55, 0x55, 0x95, 0xaa, 0x5a, 0x69, 0x55, 0x95, 0xaa, 0x56, 0x55, 0xa5,
0x55, 0x55, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x0a, 0x50, 0x15, 0x40, 0xa9, 0x05, 0xa5, 0x55, 0x90, 0x56, 0x05, 0xa9, 0x6a,
0x91, 0x56, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x0a, 0x55, 0x55, 0x91, 0xaa, 0x5a, 0x55, 0x69, 0x45, 0x95, 0x56, 0x40, 0x5a,
0x01, 0xa5, 0x15, 0x90, 0x56, 0x00, 0x69, 0x05, 0x50, 0x15, 0x00, 0x54, 0x01,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x5a, 0x5a, 0xa5, 0x6a,
0x95, 0x96, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0xa5, 0xaa,
0x45, 0x55, 0x5a, 0x50, 0x69, 0x05, 0xa9, 0x55, 0x50, 0x55, 0x01, 0x54, 0x05,
0x05, 0x00, 0x00, 0x50, 0x05, 0x00, 0x69, 0x01, 0x90, 0x16, 0x00, 0x55, 0x01,
0x90, 0x16, 0x00, 0x69, 0x01, 0x50, 0x15, 0x00, 0x54, 0x01, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x40, 0x15, 0x00, 0xa4, 0x05, 0x40, 0x5a, 0x00, 0x54, 0x05,
0x40, 0x5a, 0x00, 0xa5, 0x05, 0x90, 0x56, 0x00, 0x55, 0x05, 0x40, 0x15, 0x00,
0x08, 0x40, 0x15, 0x00, 0xa5, 0x05, 0x94, 0x56, 0x50, 0x5a, 0x05, 0x69, 0x15,
0x50, 0x5a, 0x00, 0x94, 0x16, 0x00, 0xa5, 0x05, 0x40, 0x55, 0x00, 0x50, 0x05,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x90, 0x5a, 0x00, 0x55, 0x05,
0x90, 0x5a, 0x00, 0x55, 0x05, 0x40, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x55, 0x00, 0x90, 0x16, 0x00, 0xa5, 0x05, 0x40, 0x69, 0x01, 0x50, 0x5a,
0x40, 0x69, 0x05, 0xa5, 0x55, 0x90, 0x56, 0x01, 0x55, 0x05, 0x40, 0x15, 0x00,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x55, 0x55, 0x5a, 0x54, 0x6a,
0x05, 0x69, 0x55, 0x50, 0x55, 0x01, 0x69, 0x01, 0x50, 0x15, 0x00, 0x54, 0x01,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0xa9, 0x59, 0x99, 0x99,
0x95, 0xa9, 0x5a, 0x69, 0x55, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x01, 0x55, 0x15,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x69, 0xa5,
0x95, 0xaa, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x0a, 0x55, 0x55, 0x90, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0xa9, 0x6a,
0x95, 0x56, 0x5a, 0x69, 0xa5, 0x95, 0xaa, 0x56, 0x55, 0x55, 0x45, 0x55, 0x15,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x55, 0x69, 0x55,
0x95, 0x56, 0x15, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x0a, 0x55, 0x15, 0x90, 0xaa, 0x05, 0x69, 0x69, 0x91, 0x56, 0x5a, 0x69, 0xa5,
0x95, 0x56, 0x5a, 0x69, 0x69, 0x95, 0xaa, 0x55, 0x55, 0x55, 0x41, 0x55, 0x05,
0x0a, 0x55, 0x55, 0x91, 0xaa, 0x5a, 0x69, 0x55, 0x95, 0x56, 0x55, 0xa9, 0x6a,
0x91, 0x56, 0x15, 0x69, 0x55, 0x91, 0xaa, 0x5a, 0x55, 0x55, 0x45, 0x55, 0x55,
0x0a, 0x55, 0x55, 0x91, 0xaa, 0x5a, 0x69, 0x55, 0x95, 0x56, 0x55, 0xa9, 0x6a,
0x91, 0x56, 0x15, 0x69, 0x55, 0x91, 0x16, 0x00, 0x55, 0x01, 0x40, 0x15, 0x00,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x55, 0x69, 0xa9,
0x95, 0x56, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x59, 0x54, 0x55, 0x05, 0x55, 0x55,
0x0a, 0x55, 0x54, 0x91, 0x56, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0xa9, 0xaa,
0x95, 0x56, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x05, 0x55, 0x00, 0x90, 0x16, 0x00, 0x69, 0x01, 0x90, 0x16, 0x00, 0x69, 0x01,
0x90, 0x16, 0x00, 0x69, 0x01, 0x90, 0x16, 0x00, 0x55, 0x01, 0x40, 0x15, 0x00,
0x0a, 0x00, 0x54, 0x01, 0x40, 0x5a, 0x00, 0xa4, 0x05, 0x40, 0x5a, 0x55, 0xa5,
0x95, 0x56, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x0a, 0x55, 0x54, 0x91, 0x56, 0x5a, 0x69, 0x69, 0x95, 0xa6, 0x55, 0xa9, 0x56,
0x91, 0xa6, 0x05, 0x69, 0x69, 0x91, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x09, 0x55, 0x00, 0x90, 0x16, 0x00, 0x69, 0x01, 0x90, 0x16, 0x00, 0x69, 0x01,
0x90, 0x16, 0x00, 0x69, 0x55, 0x90, 0xaa, 0x16, 0x55, 0x55, 0x41, 0x55, 0x15,
0x0a, 0x55, 0x54, 0x91, 0x56, 0x5a, 0xa9, 0xa9, 0x95, 0xaa, 0x5a, 0x69, 0xa6,
0x95, 0x56, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x0a, 0x55, 0x54, 0x91, 0x56, 0x5a, 0xa9, 0xa5, 0x95, 0x6a, 0x5a, 0x69, 0xaa,
0x95, 0x96, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x69, 0xa5,
0x95, 0x56, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x0a, 0x55, 0x55, 0x90, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x69, 0xa5,
0x95, 0xaa, 0x56, 0x69, 0x55, 0x95, 0x56, 0x15, 0x55, 0x01, 0x40, 0x15, 0x00,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x69, 0xa5,
0x95, 0x56, 0x5a, 0x69, 0x69, 0x55, 0xaa, 0x5a, 0x54, 0x55, 0x05, 0x55, 0x55,
0x0a, 0x55, 0x55, 0x90, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0xa9, 0x6a,
0x95, 0x56, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x0a, 0x54, 0x55, 0x50, 0xaa, 0x16, 0x69, 0xa5, 0x95, 0x56, 0x55, 0xa5, 0x6a,
0x55, 0x55, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x09, 0x55, 0x55, 0x90, 0xaa, 0x16, 0x95, 0x56, 0x01, 0x69, 0x15, 0x90, 0x16,
0x00, 0x69, 0x01, 0x90, 0x16, 0x00, 0x69, 0x01, 0x50, 0x15, 0x00, 0x54, 0x01,
0x0a, 0x55, 0x54, 0x91, 0x56, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x69, 0xa5,
0x95, 0x56, 0x5a, 0x69, 0xa5, 0x55, 0xaa, 0x56, 0x54, 0x55, 0x05, 0x55, 0x15,
0x0a, 0x55, 0x54, 0x91, 0x56, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x69, 0xa5,
0x55, 0x9a, 0x56, 0x94, 0x5a, 0x05, 0x65, 0x15, 0x40, 0x55, 0x00, 0x50, 0x01,
0x0a, 0x55, 0x54, 0x91, 0x56, 0x5a, 0x69, 0xa5, 0x95, 0x56, 0x5a, 0x69, 0xa6,
0x95, 0xaa, 0x5a, 0xa9, 0xa9, 0x95, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x0a, 0x55, 0x54, 0x91, 0x56, 0x5a, 0xa9, 0xa9, 0x55, 0xaa, 0x56, 0x94, 0x5a,
0x55, 0xaa, 0x16, 0xa9, 0xa9, 0x95, 0x56, 0x5a, 0x55, 0x55, 0x45, 0x15, 0x55,
0x09, 0x55, 0x55, 0x90, 0x96, 0x16, 0x69, 0x69, 0x91, 0x96, 0x16, 0xa5, 0x5a,
0x41, 0x69, 0x15, 0x90, 0x56, 0x00, 0x69, 0x01, 0x50, 0x15, 0x00, 0x54, 0x01,
0x0a, 0x55, 0x55, 0x91, 0xaa, 0x5a, 0x55, 0xa9, 0x05, 0xa5, 0x56, 0x94, 0x5a,
0x55, 0x6a, 0x15, 0xa9, 0x55, 0x91, 0xaa, 0x5a, 0x55, 0x55, 0x45, 0x55, 0x55,
0x06, 0x55, 0x01, 0x90, 0x5a, 0x00, 0x69, 0x05, 0x90, 0x56, 0x00, 0x69, 0x01,
0x90, 0x16, 0x00, 0x69, 0x01, 0x90, 0x5a, 0x00, 0x55, 0x05, 0x40, 0x55, 0x00,
0x07, 0x55, 0x00, 0x90, 0x16, 0x00, 0x69, 0x01, 0x50, 0x5a, 0x00, 0xa4, 0x05,
0x40, 0x5a, 0x00, 0x94, 0x16, 0x00, 0x69, 0x01, 0x50, 0x15, 0x00, 0x54, 0x01,
0x06, 0x55, 0x01, 0x90, 0x5a, 0x00, 0xa5, 0x05, 0x40, 0x5a, 0x00, 0xa4, 0x05,
0x40, 0x5a, 0x00, 0xa5, 0x05, 0x90, 0x5a, 0x00, 0x55, 0x05, 0x40, 0x55, 0x00,
0x08, 0x50, 0x01, 0x40, 0x59, 0x00, 0xa5, 0x16, 0x90, 0xa6, 0x05, 0x59, 0x59,
0x50, 0x55, 0x05, 0x54, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x55, 0x55, 0x91, 0xaa, 0x5a, 0x55, 0x55, 0x45, 0x55, 0x55,
0x07, 0x55, 0x00, 0x90, 0x16, 0x00, 0xa5, 0x05, 0x40, 0x69, 0x01, 0x50, 0x15,
0x00, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x50, 0x05, 0x40, 0x69, 0x01, 0xa4, 0x15, 0x50, 0x5a, 0x01, 0x69, 0x05,
0x50, 0x5a, 0x00, 0xa4, 0x05, 0x40, 0x69, 0x01, 0x50, 0x15, 0x00, 0x54, 0x01,
0x04, 0x15, 0x00, 0x90, 0x05, 0x00, 0x59, 0x00, 0x90, 0x05, 0x00, 0x59, 0x00,
0x90, 0x05, 0x00, 0x59, 0x00, 0x90, 0x05, 0x00, 0x55, 0x00, 0x40, 0x05, 0x00,
0x07, 0x55, 0x00, 0x90, 0x16, 0x00, 0xa5, 0x05, 0x40, 0x5a, 0x00, 0x94, 0x16,
0x40, 0x5a, 0x01, 0xa5, 0x15, 0x90, 0x56, 0x00, 0x55, 0x05, 0x40, 0x15, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x51, 0x6a, 0x5a, 0x69, 0x6a,
0x55, 0x55, 0x55, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

+ 16
- 3
src/linux/port.c View File

@@ -12,6 +12,7 @@

#include "cart.h"
#include "nese.h"
#include "overlay.h"
#include "port.h"
#include "save.h"

@@ -98,6 +99,8 @@ typedef struct {
SDL_Texture* texture;
SDL_Surface* target;
SDL_Surface* screen;
SDL_Rect view;
Overlay overlay;
} platform_data;


@@ -309,7 +312,9 @@ int nese_frame_ready(void* plat_data) {
SDL_LockTextureToSurface(plat->texture, NULL,
&plat->target);

// TODO: Overlay
overlay_render(&plat->overlay,
nes_ppu_render_w, nes_ppu_render_h,
&plat->view, plat->renderer);

SDL_RenderPresent(plat->renderer);

@@ -357,12 +362,15 @@ static int plat_init(platform_data* plat) {
);

if (0 == status) {
plat->view = (SDL_Rect){
.w = nes_ppu_render_w * 8,
.h = nes_ppu_render_h * 7,
};
plat->window = SDL_CreateWindow(
"NESe",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
nes_ppu_render_w * 8,
nes_ppu_render_h * 7,
plat->view.w, plat->view.h,
0
);
if (NULL == plat->window) {
@@ -418,6 +426,10 @@ static int plat_init(platform_data* plat) {
}
}

if (0 == status) {
status = overlay_init(&plat->overlay, plat->renderer);
}

if (0 == status) {
plat->t_target = time_now();
}
@@ -429,6 +441,7 @@ static void plat_done(platform_data* plat) {
if (NULL != plat->texture) SDL_DestroyTexture(plat->texture);
if (NULL != plat->renderer) SDL_DestroyRenderer(plat->renderer);
if (NULL != plat->window) SDL_DestroyWindow(plat->window);
overlay_done(&plat->overlay);
SDL_Quit();
}



+ 280
- 0
src/overlay.c View File

@@ -0,0 +1,280 @@
#include <stdint.h>

#include "charbits.h"
#include "overlay.h"


/* Font */

typedef struct {
const uint8_t* bits;
uint8_t shift;
} bit_buffer;

static void make_bit_buffer(bit_buffer* buf,
const uint8_t* bits) {
buf->bits = bits;
buf->shift = 0;
}

static uint8_t get_bits(bit_buffer* buf) {
uint8_t val = ((buf->bits[0] >> buf->shift) & 3);
if (buf->shift == 6) {
buf->shift = 0;
buf->bits++;
} else {
buf->shift += 2;
}
return val;
}

static const SDL_Color pal[2] = {
{0, 0, 0, 255}, {255, 255, 255, 255}
};

static SDL_Surface* create_char_surface(const uint8_t* bits) {
int w = *bits++;
bit_buffer buf = {0};
make_bit_buffer(&buf, bits);

SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(
0, w, char_h, 8, SDL_PIXELFORMAT_INDEX8
);
SDL_SetPaletteColors(surface->format->palette, pal, 1U, 2U);
SDL_SetColorKey(surface, SDL_TRUE, 0);

uint8_t* line = surface->pixels;
for (int y = char_h; y > 0; --y) {
uint8_t* dst = line;
for (int x = w; x > 0; --x) {
*dst++ = get_bits(&buf);
}
for (int x = (char_w - w); x > 0; --x) get_bits(&buf);
line += surface->pitch;
}

return surface;
}

static SDL_Texture* create_char_texture(SDL_Renderer* rend,
const uint8_t* bits) {
SDL_Surface* surface = create_char_surface(bits);
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
SDL_Texture* texture = SDL_CreateTextureFromSurface(
rend, surface
);
SDL_FreeSurface(surface);
return texture;
}

int overlay_font_init(Overlay_font* font, SDL_Renderer* rend) {
font->chars = chars;
font->charbits = charbits;
font->char_count = char_count;
font->textures = calloc(char_count, sizeof(SDL_Texture*));
if (NULL != font->textures) {
for (int i = 0; i < font->char_count; ++i) {
font->textures[i] = create_char_texture(
rend, &font->charbits[i * charbit_size]
);
}
}
return (NULL != font->textures) ? 0 : -1;
}

void overlay_font_done(Overlay_font* font) {
for (int i = 0; i < font->char_count; ++i) {
SDL_DestroyTexture(font->textures[i]);
}
free(font->textures);
font->textures = NULL;
}


#define overlay_start_x (char_w / 2)
#define overlay_start_y (char_h / 2)

#define space_width ((char_w / 2) - 1)

static inline int char_index(char c) {
if (c >= 'a' && c <= 'z') c += ('A' - 'a');
if (c > ' ' && c < 'a') return (c - ' ');
if (c >= '{' && c <= '~') return (65 + c - '{');
return 0;
}

void overlay_font_measure(const Overlay_font* font,
const char* string,
int* w, int* h) {
*h = char_h;
int max_w = 1;
int cur_w = 1;
for (const char* c = string; *c; ++c) {
if (*c == '\n') {
if (cur_w > max_w) max_w = cur_w;
cur_w = 1;
*h += char_h;
} else if (*c == ' ') {
cur_w += space_width;
} else {
int index = char_index(*c);
int cw = font->charbits[index * charbit_size];
cur_w += (cw - 1);
}
}
if (cur_w > max_w) max_w = cur_w;
*w = max_w;
}

void overlay_font_render(Overlay_font* font, const char* string,
const SDL_Rect* target,
const SDL_Rect* view,
uint32_t color, SDL_Renderer *rend) {
int x = target->x;
int y = target->y;
for (const char* c = string; *c; ++c) {
if (*c == '\n') {
x = target->x;
y += (char_h + 1);
} else if (*c == ' ') {
x += space_width;
} else {
int index = char_index(*c);
int cw = font->charbits[index * charbit_size];
SDL_Texture* texture = font->textures[index];

SDL_Rect rect = {
.x = ((x * view->w) / target->w) + view->x,
.y = ((y * view->h) / target->h) + view->y,
.w = (cw * view->w) / target->w,
.h = (char_h * view->h) / target->h,
};

SDL_SetTextureColorMod(
texture,
((color >> 16) & 0xFFU),
((color >> 8) & 0xFFU),
((color >> 0) & 0xFFU)
);
SDL_SetTextureAlphaMod(texture,
((color >> 24) & 0xFFU));
SDL_RenderCopy(rend, texture, NULL, &rect);

x += (cw - 1);
}
}
}


/* Overlay */

typedef struct Overlay_message_t {
char* string;
int id;
int expiry;
struct Overlay_message_t* next;
} Overlay_message;


int overlay_init(Overlay* overlay, SDL_Renderer* rend) {
overlay->messages = NULL;
overlay->next_id = 0;
overlay_font_init(&overlay->font, rend);
return 0;
}

int overlay_clear(Overlay* overlay) {
int n_cleared = 0;
Overlay_message* next = NULL;
for ( Overlay_message* message = overlay->messages;
NULL != message;
message = next) {
next = message->next;
free(message->string);
free(message);
++n_cleared;
}
overlay->messages = NULL;
return n_cleared;
}

void overlay_done(Overlay* overlay) {
overlay_clear(overlay);
overlay_font_done(&overlay->font);
}

int overlay_clear_message(Overlay* overlay, int id) {
int result = -1;
Overlay_message* last = NULL;
Overlay_message* message = overlay->messages;
for ( ;
NULL != message && message->id != id;
last = message, message = message->next
);
if (NULL != message) {
result = 0;
if (NULL == last) {
overlay->messages = message->next;
} else {
last->next = message->next;
}
free(message->string);
free(message);
}
return result;
}

int overlay_add_message(Overlay* overlay,
const char* string, int expiry) {
Overlay_message* message = calloc(1, sizeof(*message));
message->string = strdup(string);
message->id = ++(overlay->next_id);
message->expiry = expiry;
message->next = NULL;
if (NULL == overlay->messages) {
overlay->messages = message;
} else {
Overlay_message* last = overlay->messages;
for ( ; NULL != last->next; last = last->next);
last->next = message;
}
return message->id;
}

void overlay_render(Overlay* overlay, int w, int h,
const SDL_Rect* view, SDL_Renderer* rend) {
SDL_Rect target = {
.x = overlay_start_x,
.y = overlay_start_y,
.w = w,
.h = h,
};
for ( Overlay_message* message = overlay->messages;
NULL != message;
message = message->next) {
overlay_font_render(&overlay->font, message->string,
&target, view,
0xFFFFFFFFU, rend);
target.y += (char_h + 1);
}
}

void overlay_step(Overlay* overlay) {
Overlay_message* last = NULL, *next = NULL;
for ( Overlay_message* message = overlay->messages;
NULL != message;
message = next) {
next = message->next;
if (message->expiry > 0 && --(message->expiry) == 0) {
if (NULL == last) {
overlay->messages = message->next;
} else {
last->next = message->next;
}
free(message->string);
free(message);
} else {
last = message;
}
}
}

+ 47
- 0
src/overlay.h View File

@@ -0,0 +1,47 @@
#ifndef NESE_OVERLAY_H_
#define NESE_OVERLAY_H_

#include <SDL.h>


typedef struct {
const char* chars;
const uint8_t* charbits;
int char_count;
SDL_Texture** textures;
} Overlay_font;

int overlay_font_init(Overlay_font*, SDL_Renderer*);
void overlay_font_done(Overlay_font*);

void overlay_font_measure(const Overlay_font*,
const char* string,
int* w, int* h);
void overlay_font_render(Overlay_font*, const char* string,
const SDL_Rect* target,
const SDL_Rect* view,
uint32_t color, SDL_Renderer*);


struct Overlay_message_t;

typedef struct {
struct Overlay_message_t* messages;
int next_id;
Overlay_font font;
} Overlay;

int overlay_init(Overlay*, SDL_Renderer*);
void overlay_done(Overlay*);

int overlay_add_message(Overlay*, const char*, int expiry);
int overlay_clear_message(Overlay*, int id);
int overlay_clear(Overlay*);

void overlay_step(Overlay*);

void overlay_render(Overlay*, int w, int h,
const SDL_Rect* view, SDL_Renderer*);


#endif // NESE_OVERLAY_H_

Loading…
Cancel
Save