Starting to add a GUI to the SDL port

This commit is contained in:
Lior Halphon 2017-10-04 12:43:31 +03:00
parent c1f27d7b27
commit 9cc8b3320a
8 changed files with 1218 additions and 137 deletions

View File

@ -88,7 +88,7 @@ endif
cocoa: $(BIN)/SameBoy.app
quicklook: $(BIN)/SameBoy.qlgenerator
sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/drop.bmp
sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp
bootroms: $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/dmg_boot.bin
tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin
all: cocoa sdl tester
@ -267,7 +267,7 @@ $(BIN)/SDL/LICENSE: LICENSE
$(BIN)/SDL/registers.sym: Misc/registers.sym
cp -f $^ $@
$(BIN)/SDL/drop.bmp: SDL/drop.bmp
$(BIN)/SDL/background.bmp: SDL/background.bmp
cp -f $^ $@
# Boot ROMs

BIN
SDL/background.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

956
SDL/font.c Normal file
View File

@ -0,0 +1,956 @@
#include "font.h"
#define _ 0
#define X 1
uint8_t font[] = {
/* */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* ! */
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* " */
X, X, _, X, X, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* # */
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
X, X, X, X, X, _ ,
_, X, _, X, _, _ ,
X, X, X, X, X, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
_, _, _, _, _, _ ,
/* $ */
_, _, X, _, _, _ ,
_, X, X, X, _, _ ,
X, _, X, _, X, _ ,
_, X, X, _, _, _ ,
_, _, X, X, _, _ ,
X, _, X, _, X, _ ,
_, X, X, X, _, _ ,
_, _, X, _, _, _ ,
/* % */
_, _, _, _, _, _ ,
X, X, _, _, _, X ,
X, X, _, _, X, _ ,
_, _, _, X, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, X, X ,
X, _, _, _, X, X ,
_, _, _, _, _, _ ,
/* & */
_, X, X, _, _, _ ,
X, _, _, X, _, _ ,
X, _, _, X, _, _ ,
_, X, X, _, X, _ ,
X, _, _, X, _, _ ,
X, _, _, X, _, _ ,
_, X, X, _, X, _ ,
_, _, _, _, _, _ ,
/* ' */
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* ( */
_, _, _, X, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, X, _, _ ,
/* ) */
_, X, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, _, _ ,
/* * */
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
X, _, X, _, X, _ ,
_, X, X, X, _, _ ,
X, _, X, _, X, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* + */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
X, X, X, X, X, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* , */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, _, _ ,
/* - */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* . */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* / */
_, _, _, _, X, _ ,
_, _, _, _, X, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
/* 0 */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* 1 */
_, _, X, _, _, _ ,
X, X, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* 2 */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
_, _, _, _, X, _ ,
_, _, X, X, _, _ ,
_, X, _, _, _, _ ,
X, _, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* 3 */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
_, _, _, _, X, _ ,
_, _, X, X, _, _ ,
_, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* 4 */
_, _, _, X, _, _ ,
_, _, X, X, _, _ ,
_, X, _, X, _, _ ,
X, _, _, X, _, _ ,
X, X, X, X, X, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, _, _, _ ,
/* 5 */
X, X, X, X, X, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, X, X, X, _, _ ,
_, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* 6 */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, _, _ ,
X, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* 7 */
X, X, X, X, X, _ ,
_, _, _, _, X, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* 8 */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* 9 */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, X, _ ,
_, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* : */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* ; */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, _, _ ,
/* < */
_, _, _, _, _, _ ,
_, _, _, _, X, _ ,
_, _, X, X, _, _ ,
X, X, _, _, _, _ ,
X, X, _, _, _, _ ,
_, _, X, X, _, _ ,
_, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* = */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* > */
_, _, _, _, _, _ ,
X, _, _, _, _, _ ,
_, X, X, _, _, _ ,
_, _, _, X, X, _ ,
_, _, _, X, X, _ ,
_, X, X, _, _, _ ,
X, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* ? */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
_, _, _, _, X, _ ,
_, _, X, X, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* @ */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, X, X, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
X, _, _, X, X, _ ,
X, _, _, _, _, _ ,
_, X, X, X, X, _ ,
/* A */
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* B */
X, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* C */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* D */
X, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* E */
X, X, X, X, X, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, X, X, X, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* F */
X, X, X, X, X, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, X, X, X, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* G */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, _, _ ,
X, _, X, X, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* H */
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, X, X, X, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* I */
X, X, X, X, X, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* J */
_, _, X, X, X, _ ,
_, _, _, _, X, _ ,
_, _, _, _, X, _ ,
_, _, _, _, X, _ ,
_, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* K */
X, _, _, _, X, _ ,
X, _, _, X, _, _ ,
X, _, X, _, _, _ ,
X, X, _, _, _, _ ,
X, _, X, _, _, _ ,
X, _, _, X, _, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* L */
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* M */
X, _, _, _, X, _ ,
X, X, _, X, X, _ ,
X, X, _, X, X, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* N */
X, _, _, _, X, _ ,
X, X, _, _, X, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
X, _, _, X, X, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* O */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* P */
X, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, X, X, X, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* Q */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, X, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, X, X ,
/* R */
X, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, X, X, X, _, _ ,
X, _, X, _, _, _ ,
X, _, _, X, _, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* S */
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, _, _ ,
_, X, X, X, _, _ ,
_, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* T */
X, X, X, X, X, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* U */
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* V */
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* W */
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
X, X, _, X, X, _ ,
X, X, _, X, X, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* X */
X, _, _, _, X, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
_, _, X, _, _, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* Y */
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, _, X, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* Z */
X, X, X, X, X, _ ,
_, _, _, _, X, _ ,
_, _, _, X, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, _, _ ,
X, _, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* [ */
_, X, X, X, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, X, X, _, _ ,
/* \ */
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, _, X, _ ,
_, _, _, _, X, _ ,
/* ] */
_, X, X, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, X, X, X, _, _ ,
/* ^ */
_, _, X, _, _, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* _ */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, X, X, X, X, X ,
/* ` */
_, X, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, X, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
/* a */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, X, X, _, _, _ ,
_, _, _, X, _, _ ,
_, X, X, X, _, _ ,
X, _, _, X, _, _ ,
_, X, X, _, X, _ ,
_, _, _, _, _, _ ,
/* b */
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, X, X, _, _ ,
X, X, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* c */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, _, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* d */
_, _, _, _, X, _ ,
_, _, _, _, X, _ ,
_, X, X, X, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* e */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, X, X, X, X, _ ,
X, _, _, _, _, _ ,
_, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* f */
_, _, X, X, _, _ ,
_, X, _, _, _, _ ,
X, X, X, X, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, _, _, _, _, _ ,
/* g */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, X, X, X, X, _ ,
X, _, _, X, _, _ ,
_, X, X, _, _, _ ,
_, _, _, X, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
/* h */
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, X, X, _, _ ,
X, X, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* i */
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
X, X, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* j */
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
X, X, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
X, X, _, _, _, _ ,
/* k */
X, _, _, _, _, _ ,
X, _, _, _, _, _ ,
X, _, _, _, X, _ ,
X, _, X, X, _, _ ,
X, X, _, _, _, _ ,
X, _, X, X, _, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* l */
X, X, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, X, X, _ ,
_, _, _, _, _, _ ,
/* m */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, X, X, X, _, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
_, _, _, _, _, _ ,
/* n */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, _, X, X, _, _ ,
X, X, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* o */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* p */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, X, X, X, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, X, _, _, X, _ ,
X, _, X, X, _, _ ,
X, _, _, _, _, _ ,
/* q */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, X, X, X, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, X, X, _ ,
_, X, X, _, X, _ ,
_, _, _, _, X, _ ,
/* r */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, X, _, X, _, _ ,
_, X, X, _, X, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, _, _, _, _, _ ,
/* s */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, X, X, X, X, _ ,
X, _, _, _, _, _ ,
_, X, X, X, _, _ ,
_, _, _, _, X, _ ,
X, X, X, X, _, _ ,
_, _, _, _, _, _ ,
/* t */
_, _, _, _, _, _ ,
_, X, _, _, _, _ ,
X, X, X, X, X, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, _, X, X, X, _ ,
_, _, _, _, _, _ ,
/* u */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, X, X, _ ,
_, X, X, _, X, _ ,
_, _, _, _, _, _ ,
/* v */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
_, _, X, _, _, _ ,
_, _, _, _, _, _ ,
/* w */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, _, _, _, X, _ ,
X, _, X, _, X, _ ,
X, _, X, _, X, _ ,
_, X, _, X, _, _ ,
_, X, _, X, _, _ ,
_, _, _, _, _, _ ,
/* x */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, _, _, _, X, _ ,
_, X, _, X, _, _ ,
_, _, X, _, _, _ ,
_, X, _, X, _, _ ,
X, _, _, _, X, _ ,
_, _, _, _, _, _ ,
/* y */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, _, _, _, X, _ ,
X, _, _, _, X, _ ,
X, _, _, X, X, _ ,
_, X, X, _, X, _ ,
_, _, _, _, X, _ ,
_, X, X, X, _, _ ,
/* z */
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, X, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, _, _ ,
X, X, X, X, X, _ ,
_, _, _, _, _, _ ,
/* { */
_, _, X, X, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, X, _, _, _, _ ,
_, X, _, _, _, _ ,
_, _, X, X, _, _ ,
/* | */
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
/* } */
_, X, X, _, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, _, X, _, _, _ ,
_, _, X, _, _, _ ,
_, _, _, X, _, _ ,
_, _, _, X, _, _ ,
_, X, X, _, _, _ ,
/* ~ */
_, _, _, _, _, X ,
_, _, _, _, _, _ ,
_, _, X, _, _, X ,
_, X, _, X, _, X ,
_, X, _, _, X, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
_, _, _, _, _, _ ,
};

9
SDL/font.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef font_h
#define font_h
#include <stdint.h>
extern uint8_t font[];
#define GLYPH_HEIGHT 8
#define GLYPH_WIDTH 6
#endif /* font_h */

213
SDL/gui.c Normal file
View File

@ -0,0 +1,213 @@
#include <SDL2/SDL.h>
#include <stdbool.h>
#include "utils.h"
#include "gui.h"
#include "font.h"
static const SDL_Color gui_palette[4] = {{8, 24, 16,}, {57, 97, 57,}, {132, 165, 99}, {198, 222, 140}};
static uint32_t gui_palette_native[4];
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *texture = NULL;
SDL_PixelFormat *pixel_format = NULL;
enum scaling_mode scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR;
#ifdef __APPLE__
#define MODIFIER_NAME "Cmd"
#else
#define MODIFIER_NAME "Ctrl"
#endif
static const char help[] =
"Drop a GB or GBC ROM file to play.\n"
"\n"
"Controls:\n"
" D-Pad: Arrow Keys\n"
" A: X\n"
" B: Z\n"
" Start: Enter\n"
" Select: Backspace\n"
"\n"
"Keyboard Shortcuts: \n"
" Restart: " MODIFIER_NAME "+R\n"
" Pause: " MODIFIER_NAME "+P\n"
" Turbo: Space\n"
#ifdef __APPLE__
" Mute/Unmute: " MODIFIER_NAME "+Shift+M\n"
#else
" Mute/Unmute: " MODIFIER_NAME "+M\n"
#endif
" Save state: " MODIFIER_NAME "+Number (0-9)\n"
" Load state: " MODIFIER_NAME "+Shift+Number (0-9)\n"
" Cycle between DMG/CGB emulation: " MODIFIER_NAME "+T\n"
" Cycle scaling modes: Tab"
;
void cycle_scaling(void)
{
scaling_mode++;
scaling_mode %= GB_SDL_SCALING_MAX;
update_viewport();
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
void update_viewport(void)
{
int win_width, win_height;
SDL_GetWindowSize(window, &win_width, &win_height);
double x_factor = win_width / 160.0;
double y_factor = win_height / 144.0;
if (scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) {
x_factor = (int)(x_factor);
y_factor = (int)(y_factor);
}
if (scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) {
if (x_factor > y_factor) {
x_factor = y_factor;
}
else {
y_factor = x_factor;
}
}
unsigned new_width = x_factor * 160;
unsigned new_height = y_factor * 144;
SDL_Rect rect = (SDL_Rect){(win_width - new_width) / 2, (win_height - new_height) /2,
new_width, new_height};
SDL_RenderSetViewport(renderer, &rect);
}
void show_help(void)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Help", help, window);
}
/* Does NOT check for bounds! */
static void draw_char(uint32_t *buffer, unsigned char ch, uint32_t color)
{
if (ch < ' ' || ch > '~') {
ch = '?';
}
uint8_t *data = &font[(ch - ' ') * GLYPH_WIDTH * GLYPH_HEIGHT];
for (unsigned y = GLYPH_HEIGHT; y--;) {
for (unsigned x = GLYPH_WIDTH; x--;) {
if (*(data++)) {
(*buffer) = color;
}
buffer++;
}
buffer += 160 - GLYPH_WIDTH;
}
}
/* Does NOT check for bounds! */
static void draw_bordered_char(uint32_t *buffer, unsigned char ch, uint32_t color, uint32_t border)
{
draw_char(buffer - 1, ch, border);
draw_char(buffer + 1, ch, border);
draw_char(buffer - 160, ch, border);
draw_char(buffer + 160, ch, border);
draw_char(buffer, ch, color);
}
static void draw_text(uint32_t *buffer, unsigned x, unsigned y, const char *string, uint32_t color, uint32_t border)
{
unsigned orig_x = x;
while (*string) {
if (*string == '\n') {
x = orig_x;
y += GLYPH_HEIGHT + 4;
string++;
continue;
}
if (x == 0 || x > 160 - GLYPH_WIDTH - 1 || y == 0 || y > 144 - GLYPH_HEIGHT - 1) {
break;
}
draw_bordered_char(&buffer[x + 160 * y], *string, color, border);
x += GLYPH_WIDTH;
string++;
}
}
static void draw_text_centered(uint32_t *buffer, unsigned y, const char *string, uint32_t color, uint32_t border)
{
draw_text(buffer, 160 / 2 - (unsigned) strlen(string) * GLYPH_WIDTH / 2, y, string, color, border);
}
extern void set_filename(const char *new_filename, bool new_should_free);
void run_gui(void)
{
/* Draw the "Drop file" screen */
static SDL_Surface *converted_background = NULL;
if (!converted_background) {
SDL_Surface *background = SDL_LoadBMP(executable_relative_path("background.bmp"));
SDL_SetPaletteColors(background->format->palette, gui_palette, 0, 4);
converted_background = SDL_ConvertSurface(background, pixel_format, 0);
SDL_LockSurface(converted_background);
SDL_FreeSurface(background);
for (unsigned i = 4; i--; ) {
gui_palette_native[i] = SDL_MapRGB(pixel_format, gui_palette[i].r, gui_palette[i].g, gui_palette[i].b);
}
}
uint32_t pixels[160 * 144];
memcpy(pixels, converted_background->pixels, sizeof(pixels));
draw_text_centered(pixels, 116, "Drop a GB or GBC", gui_palette_native[3], gui_palette_native[0]);
draw_text_centered(pixels, 128, "file to play", gui_palette_native[3], gui_palette_native[0]);
SDL_UpdateTexture(texture, NULL, pixels, 160 * sizeof (uint32_t));
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Event event;
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_QUIT: {
exit(0);
}
case SDL_WINDOWEVENT: {
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
update_viewport();
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
break;
}
case SDL_DROPFILE: {
set_filename(event.drop.file, true);
return;
}
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_TAB) {
cycle_scaling();
}
#ifndef __APPLE__
else if (event.key.keysym.sym == SDLK_F1) {
show_help();
}
#else
else if (event.key.keysym.sym == SDLK_QUESTION || (event.key.keysym.sym && (event.key.keysym.mod & KMOD_SHIFT))) {
show_help();
}
#endif
break;
}
}
}

25
SDL/gui.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef gui_h
#define gui_h
#include <SDL2/SDL.h>
extern SDL_Window *window;
extern SDL_Renderer *renderer;
extern SDL_Texture *texture;
extern SDL_PixelFormat *pixel_format;
enum scaling_mode {
GB_SDL_SCALING_ENTIRE_WINDOW,
GB_SDL_SCALING_KEEP_RATIO,
GB_SDL_SCALING_INTEGER_FACTOR,
GB_SDL_SCALING_MAX,
};
extern enum scaling_mode scaling_mode;
void update_viewport(void);
void cycle_scaling(void);
void show_help(void);
void run_gui(void);
#endif

View File

@ -2,8 +2,8 @@
#include <signal.h>
#include <SDL2/SDL.h>
#include "gb.h"
#include "utils.h"
#include "gui.h"
#ifndef _WIN32
#define AUDIO_FREQUENCY 96000
@ -12,37 +12,6 @@
#define AUDIO_FREQUENCY 44100
#endif
#ifdef __APPLE__
#define MODIFIER_NAME "Cmd"
#else
#define MODIFIER_NAME "Ctrl"
#endif
static const char help[] =
"Drop a GB or GBC ROM file to play.\n"
"\n"
"Controls:\n"
" D-Pad: Arrow Keys\n"
" A: X\n"
" B: Z\n"
" Start: Enter\n"
" Select: Backspace\n"
"\n"
"Keyboard Shortcuts: \n"
" Restart: " MODIFIER_NAME "+R\n"
" Pause: " MODIFIER_NAME "+P\n"
" Turbo: Space\n"
#ifdef __APPLE__
" Mute/Unmute: " MODIFIER_NAME "+Shift+M\n"
#else
" Mute/Unmute: " MODIFIER_NAME "+M\n"
#endif
" Save state: " MODIFIER_NAME "+Number (0-9)\n"
" Load state: " MODIFIER_NAME "+Shift+Number (0-9)\n"
" Cycle between DMG/CGB emulation: " MODIFIER_NAME "+T\n"
" Cycle scaling modes: Tab"
;
GB_gameboy_t gb;
static bool dmg = false;
static bool paused = false;
@ -52,10 +21,15 @@ static char *filename = NULL;
static bool should_free_filename = false;
static char *battery_save_path_ptr;
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static SDL_Texture *texture = NULL;
static SDL_PixelFormat *pixel_format = NULL;
void set_filename(const char *new_filename, bool new_should_free)
{
if (filename && should_free_filename) {
free(filename);
}
filename = (char *) new_filename;
should_free_filename = new_should_free;
}
static SDL_AudioSpec want_aspec, have_aspec;
static char *captured_log = NULL;
@ -106,53 +80,8 @@ static enum {
GB_SDL_TOGGLE_MODEL_COMMAND,
} pending_command;
static enum {
GB_SDL_SCALING_ENTIRE_WINDOW,
GB_SDL_SCALING_KEEP_RATIO,
GB_SDL_SCALING_INTEGER_FACTOR,
GB_SDL_SCALING_MAX,
} scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR;
static unsigned command_parameter;
static void update_viewport(void)
{
int win_width, win_height;
SDL_GetWindowSize(window, &win_width, &win_height);
double x_factor = win_width / 160.0;
double y_factor = win_height / 144.0;
if (scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) {
x_factor = (int)(x_factor);
y_factor = (int)(y_factor);
}
if (scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) {
if (x_factor > y_factor) {
x_factor = y_factor;
}
else {
y_factor = x_factor;
}
}
unsigned new_width = x_factor * 160;
unsigned new_height = y_factor * 144;
SDL_Rect rect = (SDL_Rect){(win_width - new_width) / 2, (win_height - new_height) /2,
new_width, new_height};
SDL_RenderSetViewport(renderer, &rect);
}
static void cycle_scaling(void)
{
scaling_mode++;
scaling_mode %= GB_SDL_SCALING_MAX;
update_viewport();
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
static void handle_events(GB_gameboy_t *gb)
{
#ifdef __APPLE__
@ -169,11 +98,7 @@ static void handle_events(GB_gameboy_t *gb)
exit(0);
case SDL_DROPFILE: {
if (should_free_filename) {
SDL_free(filename);
}
filename = event.drop.file;
should_free_filename = true;
set_filename(filename, true);
pending_command = GB_SDL_NEW_FILE_COMMAND;
break;
}
@ -236,7 +161,7 @@ static void handle_events(GB_gameboy_t *gb)
break;
}
case SDLK_QUESTION:
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Help", help, window);
show_help();
#endif
default:
@ -495,55 +420,8 @@ usage:
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
if (filename == NULL) {
/* Draw the "Drop file" screen */
SDL_Surface *drop_backround = SDL_LoadBMP(executable_relative_path("drop.bmp"));
SDL_Surface *drop_converted = SDL_ConvertSurface(drop_backround, pixel_format, 0);
SDL_LockSurface(drop_converted);
SDL_UpdateTexture(texture, NULL, drop_converted->pixels, drop_converted->pitch);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_FreeSurface(drop_converted);
SDL_FreeSurface(drop_backround);
SDL_Event event;
while (SDL_WaitEvent(&event))
{
switch (event.type) {
case SDL_QUIT: {
exit(0);
}
case SDL_WINDOWEVENT: {
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
update_viewport();
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
break;
}
case SDL_DROPFILE: {
filename = event.drop.file;
should_free_filename = true;
goto start;
}
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_TAB) {
cycle_scaling();
}
#ifndef __APPLE__
else if (event.key.keysym.sym == SDLK_F1) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Help", help, window);
}
#else
else if (event.key.keysym.sym == SDLK_QUESTION || (event.key.keysym.sym && (event.key.keysym.mod & KMOD_SHIFT))) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Help", help, window);
}
#endif
break;
}
}
run_gui();
}
start:
run(); // Never returns
return 0;
}