Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added webassembly support as an option to make a standalone HTML file #238

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*.smdh
*.bnr
*.cia

*.html
*.nacp
*.nro
*.nso
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ clean-miyoomini:
clean-windows:
@$(MAKE) -C platform/windows clean

clean-wasm:
@$(MAKE) -C platform/Webassembly clean

3ds:
@$(MAKE) -C platform/3ds

Expand All @@ -75,6 +78,9 @@ vita:
sdl2:
@$(MAKE) -C platform/SDL2Desktop

wasm:
@$(MAKE) -C platform/Webassembly

sdl:
@$(MAKE) -C platform/SDL1_2

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Installation will vary by console and executable type. If it is a console with a

Pico 8 cart files go in the `p8carts/` directory of your memory card (SD card on 3DS, Switch, and Wii U, memory card at `ux0:/` on Vita). `.p8` text file carts and `.p8.png` image file carts are supported.

The Standalone webpage is different. You use the '/' key to upload, the '.' key to save everything, and the '`' key to reset the filesystem (don't worry, it will ask you if you're sure you want to reset everything.)

Launch FAKE-08 either via the homebrew menu or normal system UI (depending on how you installed). Use left and right to cycle through carts on the SD card. Choose a cart using the `A` (Nintendo consoles) or `X`(Vita) button. To exit the currently running cart, press `Start` or `+` to open the pause menu and select `Exit to Menu`. Press `R` to cycle between rendering sizes. Press `L` and `R` simultaneously to exit the appication. You can also close it via your console's operating system controls (home button etc).

For bittboy and similar consoles, back up `emus/pico8/pico8.elf` and replace it with the one from the release. Place your cart files in `roms/pico-8/` and use the front end of choice to launch games. Press the menu button to return to the menu (though you can also press start and exit to the FAKE-08 bios menu if you would like).
Expand Down Expand Up @@ -42,6 +44,8 @@ Building for bittboy requires builing your own toolchain first (and will probabl

Building for Miyoo mini uses shauninman's Union Miyoo Mini toolchain: https://github.com/shauninman/union-miyoomini-toolchain

Building the standalone webpage requires emsdk: The installation instructions are available at https://emscripten.org/docs/getting_started/downloads.html
When emsdk is installed (and sourced), use `emmake make wasm` to build.
## Acknowledgements
* Zep/Lexaloffle software for making pico 8. Buy a copy if you can. You won't regret it. https://www.lexaloffle.com/pico-8.php
* Nintendo Homebrew Community
Expand Down
3 changes: 2 additions & 1 deletion platform/SDL2Common/source/sdl2basehost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ void Host::setPlatformParams(


void Host::oneTimeSetup(Audio* audio){
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
//Haptic support is not being used and many devices are not compiled with haptic support
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER|SDL_INIT_JOYSTICK) != 0)
{
fprintf(stderr, "SDL could not initialize\n");
return;
Expand Down
119 changes: 119 additions & 0 deletions platform/Webassembly/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@

#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing header files
#
#---------------------------------------------------------------------------------
TARGET := FAKE08.html
BUILD := build
SOURCES := ${SOURCES} source
INCLUDES := ${INCLUDES}

#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CC = $(CXX)

CFLAGS := -g -Wall -Wno-deprecated -ffunction-sections -std=c++17 -sUSE_SDL=2 \
$(DEFINES)

CFLAGS += $(INCLUDE) -DVER_STR=\"$(APP_VERSION)\"

CXXFLAGS := $(CFLAGS) -fno-rtti
#-std=gnu++11 was used before... not sure of difference

LIBS := -lSDL2

LDFLAGS := $(LIBS) -sSINGLE_FILE -sUSE_SDL=2 -sASYNCIFY -sINITIAL_MEMORY=100mb -sALLOW_MEMORY_GROWTH -lidbfs.js --pre-js $(CURDIR)/../pre.js -s EXPORTED_RUNTIME_METHODS=callMain -fsanitize=address --shell-file $(CURDIR)/../shell.htm -sNO_DISABLE_EXCEPTION_CATCHING -O3


#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------

export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)

export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))

export DEPSDIR := $(CURDIR)/$(BUILD)

CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))

#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))

export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)

export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)


.PHONY: $(BUILD) clean all

#---------------------------------------------------------------------------------
all: $(BUILD)

$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile

#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET) $(OUTPUT)


#---------------------------------------------------------------------------------
else
.PHONY: all

DEPENDS := $(OFILES:.o=.d)

#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all : $(OUTPUT)

$(OUTPUT) : $(OFILES)
$(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)

$(OFILES_SRC) : $(HFILES_BIN)

#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)

-include $(DEPENDS)

#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
39 changes: 39 additions & 0 deletions platform/Webassembly/pre.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//current command in ascii decimal
let currentcmd = [0,0,0]
let currentfile = "";
const sleep = ms => new Promise(r => setTimeout(r,ms));
Module['print'] = function(text){console.log(text);}
Module['preRun'] = function()
{

function stdin(){return 10};
var stdout = null;
var stderr = null;
FS.init(stdin,stdout,stderr);
FS.mount(IDBFS,{},"/home/web_user/");
FS.chdir("/home/web_user");

}
Module['noInitialRun'] = true
document.addEventListener('click', (ev) => {
console.log("event is captured only once.");
args = []
document.getElementById("instructions").remove();
FS.syncfs(true,function(){
try {
FS.mkdir("/home/web_user/p8carts")
} catch (error) {

}
try {
FS.mkdir("/home/web_user/fake08")
} catch (error) {

}

Module.callMain(args);
});

}, { once: true });


65 changes: 65 additions & 0 deletions platform/Webassembly/shell.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<!-- Thank You Stack Overflow! -->
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8, width=device-width, initial-scale=1">
<title>Fake-08</title>
</head>

<body style="margin:0;padding:0">

<!-- Create the canvas that the C++ code will draw into -->
<canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<p id="instructions"> Once the page fully loads, click on the page to start! </p>
<!-- Allow the C++ to access the canvas element -->
<script type='text/javascript'>
var Module = {
canvas: (function() { return document.getElementById('canvas'); })()
};
Module['preRun'] = []
</script>
<script type='text/javascript'>

const file_reader = new FileReader();
file_reader.addEventListener("load", readf);
function readf(event){
currentname = "p8carts/"
//also heavily derivative of Riot's code on Stack Overflow cause I sure as hell don't udnerstand it.
const uint8Arr = new Uint8Array(file_reader.result);
console.log(currentname+fname);
try {
stream = FS.open(currentname+fname,'w');
} catch (error) {
alert(error.toString() + "... Was that not a directory?");
return;
}

FS.write(stream, uint8Arr, 0, uint8Arr.length, 0);
FS.close(stream);
alert("File Uploaded");
}

var currentname = "";
var fname = ""

function save_files(){
fname = this.files[0].name;
file_reader.readAsArrayBuffer(this.files[0]);
};


var file_selector = document.createElement('input');
file_selector.setAttribute('type', 'file');
file_selector.addEventListener("change", save_files, false);



</script>

<!-- Where the script shall be -->
{{{ SCRIPT }}}

</body>

</html>
Loading