Start work on WASM frontend

This commit is contained in:
Maximilian Mader 2019-06-05 02:26:31 +02:00
parent e268efefef
commit 0692347002
Signed by: Max
GPG Key ID: F71D56A3151C4FB3
4 changed files with 252 additions and 12 deletions

View File

@ -126,7 +126,7 @@ quicklook: $(BIN)/SameBoy.qlgenerator
sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders
bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin
tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin
all: cocoa sdl tester libretro all: cocoa sdl tester libretro wasm
# Get a list of our source files and their respective object file targets # Get a list of our source files and their respective object file targets
@ -151,7 +151,7 @@ TESTER_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(TESTER_SOURCES))
# Automatic dependency generation # Automatic dependency generation
ifneq ($(filter-out clean bootroms libretro %.bin, $(MAKECMDGOALS)),) ifneq ($(filter-out clean bootroms libretro wasm %.bin, $(MAKECMDGOALS)),)
-include $(CORE_OBJECTS:.o=.dep) -include $(CORE_OBJECTS:.o=.dep)
ifneq ($(filter $(MAKECMDGOALS),sdl),) ifneq ($(filter $(MAKECMDGOALS),sdl),)
-include $(SDL_OBJECTS:.o=.dep) -include $(SDL_OBJECTS:.o=.dep)
@ -177,12 +177,12 @@ $(OBJ)/Core/%.c.o: Core/%.c
$(OBJ)/%.c.o: %.c $(OBJ)/%.c.o: %.c
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
# HexFiend requires more flags # HexFiend requires more flags
$(OBJ)/HexFiend/%.m.o: HexFiend/%.m $(OBJ)/HexFiend/%.m.o: HexFiend/%.m
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
$(CC) $(CFLAGS) $(OCFLAGS) -c $< -o $@ -fno-objc-arc -include HexFiend/HexFiend_2_Framework_Prefix.pch $(CC) $(CFLAGS) $(OCFLAGS) -c $< -o $@ -fno-objc-arc -include HexFiend/HexFiend_2_Framework_Prefix.pch
$(OBJ)/%.m.o: %.m $(OBJ)/%.m.o: %.m
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
$(CC) $(CFLAGS) $(OCFLAGS) -c $< -o $@ $(CC) $(CFLAGS) $(OCFLAGS) -c $< -o $@
@ -220,7 +220,7 @@ endif
$(BIN)/SameBoy.app/Contents/Resources/Base.lproj/%.nib: Cocoa/%.xib $(BIN)/SameBoy.app/Contents/Resources/Base.lproj/%.nib: Cocoa/%.xib
ibtool --compile $@ $^ ibtool --compile $@ $^
# Quick Look generator # Quick Look generator
$(BIN)/SameBoy.qlgenerator: $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL \ $(BIN)/SameBoy.qlgenerator: $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL \
@ -245,7 +245,7 @@ endif
$(BIN)/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin: $(BIN)/BootROMs/cgb_boot_fast.bin $(BIN)/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin: $(BIN)/BootROMs/cgb_boot_fast.bin
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
cp -f $^ $@ cp -f $^ $@
# SDL Port # SDL Port
# Unix versions build only one binary # Unix versions build only one binary
@ -272,7 +272,7 @@ $(OBJ)/%.o: %.rc
else else
$(OBJ)/%.res: %.rc $(OBJ)/%.res: %.rc
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
rc /fo $@ /dVERSION=\"$(VERSION)\" $^ rc /fo $@ /dVERSION=\"$(VERSION)\" $^
%.o: %.res %.o: %.res
cvtres /OUT:"$@" $^ cvtres /OUT:"$@" $^
@ -299,11 +299,11 @@ $(BIN)/tester/sameboy_tester.exe: $(CORE_OBJECTS) $(SDL_OBJECTS)
$(BIN)/SDL/%.bin $(BIN)/tester/%.bin: $(BOOTROMS_DIR)/%.bin $(BIN)/SDL/%.bin $(BIN)/tester/%.bin: $(BOOTROMS_DIR)/%.bin
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
cp -f $^ $@ cp -f $^ $@
$(BIN)/SameBoy.app/Contents/Resources/%.bin: $(BOOTROMS_DIR)/%.bin $(BIN)/SameBoy.app/Contents/Resources/%.bin: $(BOOTROMS_DIR)/%.bin
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
cp -f $^ $@ cp -f $^ $@
$(BIN)/SDL/LICENSE: LICENSE $(BIN)/SDL/LICENSE: LICENSE
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
cp -f $^ $@ cp -f $^ $@
@ -311,7 +311,7 @@ $(BIN)/SDL/LICENSE: LICENSE
$(BIN)/SDL/registers.sym: Misc/registers.sym $(BIN)/SDL/registers.sym: Misc/registers.sym
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
cp -f $^ $@ cp -f $^ $@
$(BIN)/SDL/background.bmp: SDL/background.bmp $(BIN)/SDL/background.bmp: SDL/background.bmp
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $(dir $@)
cp -f $^ $@ cp -f $^ $@
@ -346,9 +346,13 @@ $(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.rle
# Libretro Core (uses its own build system) # Libretro Core (uses its own build system)
libretro: libretro:
$(MAKE) -C libretro $(MAKE) -C libretro
# WASM core (uses its own build system)
wasm:
$(MAKE) -C wasm
# Clean # Clean
clean: clean:
rm -rf build rm -rf build
.PHONY: libretro .PHONY: libretro wasm

124
wasm/Makefile Normal file
View File

@ -0,0 +1,124 @@
# Make hacks
.INTERMEDIATE:
# Set target, configuration, version and destination folders
PLATFORM := $(shell uname -s)
ifneq ($(findstring MINGW,$(PLATFORM)),)
PLATFORM := windows32
USE_WINDRES := true
endif
ifneq ($(findstring MSYS,$(PLATFORM)),)
PLATFORM := windows32
endif
ifeq ($(PLATFORM),windows32)
_ := $(shell chcp 65001)
endif
DEFAULT := wasm
default: $(DEFAULT)
ifeq ($(MAKECMDGOALS),)
MAKECMDGOALS := $(DEFAULT)
endif
CORE_DIR += ..
VERSION := 0.11.1
export VERSION
CONF ?= debug
BIN := $(CORE_DIR)/build/wasm_bin
OBJ := $(CORE_DIR)/build/wasm_obj
BOOTROMS_DIR ?= $(BIN)/BootROMs
ifdef DATA_DIR
CFLAGS += -DDATA_DIR="\"$(DATA_DIR)\""
endif
# Set tools
CC := emcc
ifeq ($(PLATFORM),windows32)
# To force use of the Unix version instead of the Windows version
MKDIR := $(shell which mkdir)
else
MKDIR := mkdir
endif
ifeq ($(CONF),native_release)
override CONF := release
LDFLAGS += -march=native -mtune=native
CFLAGS += -march=native -mtune=native
endif
# Set compilation and linkage flags based on target, platform and configuration
CFLAGS += -Werror -Wall -Wno-strict-aliasing -Wno-unknown-warning -Wno-unknown-warning-option -Wno-multichar -Wno-int-in-bool-context -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES
CFLAGS += -I$(CORE_DIR)
WASM_LDFLAGS := -lopenal
LDFLAGS += -lc -lm -ldl
CFLAGS += -Wno-deprecated-declarations
ifeq ($(CONF),debug)
CFLAGS += -g
else ifeq ($(CONF), release)
CFLAGS += -O3 -DNDEBUG
else
$(error Invalid value for CONF: $(CONF). Use "debug", "release" or "native_release")
endif
# Define our targets
wasm: $(BIN)/SameBoy.js
all: wasm
# Get a list of our source files and their respective object file targets
CORE_SOURCES_RAW := $(shell ls $(CORE_DIR)/Core/*.c)
CORE_SOURCES := $(shell realpath --relative-to=$(CORE_DIR) $(CORE_SOURCES_RAW))
CORE_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(CORE_SOURCES))
WASM_SOURCES := $(shell ls *.c)
WASM_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(WASM_SOURCES))
# Automatic dependency generation
ifneq ($(filter-out clean %.bin, $(MAKECMDGOALS)),)
-include $(CORE_OBJECTS:.o=.dep)
ifneq ($(filter $(MAKECMDGOALS),wasm),)
-include $(WASM_OBJECTS:.o=.dep)
endif
endif
$(OBJ)/%.dep: %
-@$(MKDIR) -p $(dir $@)
$(CC) $(CFLAGS) -MT $(OBJ)/$^.o -M $^ -c -o $@
$(CORE_DIR)/build/bin/BootROMs/%_boot.bin:
$(MAKE) -C $(CORE_DIR) $(patsubst $(CORE_DIR)/%,%,$@)
# Compilation rules
$(OBJ)/Core/%.c.o: $(CORE_DIR)/Core/%.c
-@$(MKDIR) -p $(dir $@)
$(CC) $(CFLAGS) -DGB_INTERNAL -c $< -o $@
$(OBJ)/%.c.o: %.c
-@$(MKDIR) -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@
$(BIN)/SameBoy.js: $(CORE_OBJECTS) $(WASM_OBJECTS)
-@$(MKDIR) -p $(dir $@)
cp -r web/* $(BIN)
$(CC) -s WASM=1 $^ -o $@ $(LDFLAGS) $(WASM_LDFLAGS)
ifeq ($(CONF), release)
strip $@
endif
clean:
rm -f $(WASM_OBJECTS) $(BIN)/SameBoy.js $(BIN)/SameBoy.wasm

97
wasm/main.c Normal file
View File

@ -0,0 +1,97 @@
#include <emscripten.h>
#include <stdbool.h>
#include <stdio.h>
#include <Core/gb.h>
unsigned audio_sample_rate = 0;
GB_gameboy_t gb;
#define VIDEO_WIDTH 160
#define VIDEO_HEIGHT 144
#define VIDEO_PIXELS (VIDEO_WIDTH * VIDEO_HEIGHT)
#define SGB_VIDEO_WIDTH 256
#define SGB_VIDEO_HEIGHT 224
#define SGB_VIDEO_PIXELS (SGB_VIDEO_WIDTH * SGB_VIDEO_HEIGHT)
#define FRAME_RATE 0 // let the browser schedule (usually 60 FPS), if absolutely needed define as (0x400000 / 70224.0)
static GB_model_t model;
// static GB_model_t auto_model = GB_MODEL_CGB_C;
static uint32_t pixel_buffer_1[256 * 224], pixel_buffer_2[256 * 224];
static uint32_t *active_pixel_buffer = pixel_buffer_1;
static uint32_t *previous_pixel_buffer = pixel_buffer_2;
signed short soundbuf[1024 * 2];
unsigned query_sample_rate_of_audiocontexts() {
return EM_ASM_INT({
var AudioContext = window.AudioContext || window.webkitAudioContext;
var ctx = new AudioContext();
var sr = ctx.sampleRate;
ctx.close();
return sr;
});
}
static void handle_events(GB_gameboy_t *gb) {
GB_set_key_state(gb, GB_KEY_START, true);
}
static void vblank(GB_gameboy_t *gb) {
if (1 == 1) {
// render_texture(active_pixel_buffer, previous_pixel_buffer);
uint32_t *temp = active_pixel_buffer;
active_pixel_buffer = previous_pixel_buffer;
previous_pixel_buffer = temp;
GB_set_pixels_output(gb, active_pixel_buffer);
}
else {
// render_texture(active_pixel_buffer, NULL);
}
handle_events(gb);
}
static uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b)
{
return (r << 16) | (g << 8) | b;
}
void run() {
if (GB_is_inited(&gb)) {
GB_switch_model_and_reset(&gb, model);
}
else {
GB_init(&gb, model);
GB_set_vblank_callback(&gb, (GB_vblank_callback_t) vblank);
GB_set_pixels_output(&gb, active_pixel_buffer);
GB_set_rgb_encode_callback(&gb, rgb_encode);
GB_set_sample_rate(&gb, audio_sample_rate);
GB_set_color_correction_mode(&gb, GB_COLOR_CORRECTION_DISABLED); // TODO
GB_set_highpass_filter_mode(&gb, GB_HIGHPASS_OFF); // TODO
GB_set_rewind_length(&gb, 0);
}
GB_debugger_execute_command(&gb, "registers");
}
int main(int argc, char **argv)
{
#define str(x) #x
#define xstr(x) str(x)
fprintf(stderr, "SameBoy v" xstr(VERSION) "\n");
audio_sample_rate = query_sample_rate_of_audiocontexts();
fprintf(stderr, "Sample rate: %u\n", audio_sample_rate);
emscripten_set_main_loop(
run, // our main loop
FRAME_RATE,
true // infinite loop
);
}

15
wasm/web/index.html Normal file
View File

@ -0,0 +1,15 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>SameBoy</title>
</head>
<body>
<script src="SameBoy.js"></script>
<script>
Module.onRuntimeInitialized = _ => {
console.log(Module)
};
</script>
</body>
</html>