Start work on WASM frontend
This commit is contained in:
parent
e268efefef
commit
0692347002
10
Makefile
10
Makefile
@ -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)
|
||||||
@ -347,8 +347,12 @@ $(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.rle
|
|||||||
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
124
wasm/Makefile
Normal 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
97
wasm/main.c
Normal 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
15
wasm/web/index.html
Normal 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>
|
Loading…
Reference in New Issue
Block a user