Compare commits

...

4 Commits

Author SHA1 Message Date
jasonhilder 747702d256 Updated gitignore to exclude build output. 2026-06-28 07:01:00 +02:00
jasonhilder 717ef479fa Added globals and refactor for wasm. 2026-06-28 06:59:46 +02:00
jasonhilder 5edae5d2d8 Web build script and updates to web source.
Added Karl Zylinski web build script.
Updated template for better width.
Removed resizing function.
2026-06-28 06:57:48 +02:00
jasonhilder d43ec53d8d Added build tag for non web only. 2026-06-28 06:55:13 +02:00
9 changed files with 83 additions and 43 deletions
+5
View File
@@ -2,5 +2,10 @@
*.bin *.bin
*.o *.o
# Artifact output directory
build/
# Project management # Project management
todo todo
Executable
+38
View File
@@ -0,0 +1,38 @@
#!/bin/bash -eu
# Point this to where you installed emscripten. Optional on systems that already
# have `emcc` in the path.
EMSCRIPTEN_SDK_DIR="$HOME/Probe/emsdk"
OUT_DIR="build/web"
mkdir -p $OUT_DIR
export EMSDK_QUIET=1
[[ -f "$EMSCRIPTEN_SDK_DIR/emsdk_env.sh" ]] && . "$EMSCRIPTEN_SDK_DIR/emsdk_env.sh"
# Note RAYLIB_WASM_LIB=env.o -- env.o is an internal WASM object file. You can
# see how RAYLIB_WASM_LIB is used inside <odin>/vendor/raylib/raylib.odin.
#
# The emcc call will be fed the actual raylib library file. That stuff will end
# up in env.o
#
# Note that there is a rayGUI equivalent: -define:RAYGUI_WASM_LIB=env.o
# odin build src/main_web -target:js_wasm32 -build-mode:obj -define:RAYLIB_WASM_LIB=env.o -define:RAYGUI_WASM_LIB=env.o -vet -strict-style -out:$OUT_DIR/game.wasm.o
odin build src/main_web -target:js_wasm32 -build-mode:obj -define:RAYLIB_WASM_LIB=env.o -define:RAYGUI_WASM_LIB=env.o -out:$OUT_DIR/game.wasm.o
ODIN_PATH=$(odin root)
cp $ODIN_PATH/core/sys/wasm/js/odin.js $OUT_DIR
files="$OUT_DIR/game.wasm.o ${ODIN_PATH}/vendor/raylib/wasm/libraylib.a ${ODIN_PATH}/vendor/raylib/wasm/libraygui.a"
# index_template.html contains the javascript code that calls the procedures in
# src/main_web/main_web.odin
flags="-sEXPORTED_RUNTIME_METHODS=['HEAPF32'] -sSTACK_SIZE=524288 -sUSE_GLFW=3 -sWASM_BIGINT -sWARN_ON_UNDEFINED_SYMBOLS=0 -sASSERTIONS --shell-file src/main_web/index_template.html --preload-file assets"
# For debugging: Add `-g` to `emcc` (gives better error callstack in chrome)
emcc -o $OUT_DIR/index.html $files $flags
rm $OUT_DIR/game.wasm.o
echo "Web build created in ${OUT_DIR}"
+1
View File
@@ -1,3 +1,4 @@
#+build !js
package tinyfiledialogs package tinyfiledialogs
import "base:builtin" import "base:builtin"
+1
View File
@@ -1,3 +1,4 @@
#+build !js
package machine package machine
import "core:log" import "core:log"
+1
View File
@@ -16,6 +16,7 @@
background-color: black; background-color: black;
} }
canvas.game_canvas { canvas.game_canvas {
max-width: 1550px;
border: 0px none; border: 0px none;
background-color: black; background-color: black;
padding-left: 0; padding-left: 0;
-2
View File
@@ -63,6 +63,4 @@ main_end :: proc "c" () {
@export @export
web_window_size_changed :: proc "c" (w: c.int, h: c.int) { web_window_size_changed :: proc "c" (w: c.int, h: c.int) {
context = web_context context = web_context
// TODO
game.parent_window_size_changed(int(w), int(h))
} }
+27 -19
View File
@@ -3,9 +3,6 @@ package simulator
import emu "../machine" import emu "../machine"
import rl "vendor:raylib" import rl "vendor:raylib"
// Globals
run: bool
// Window // Window
WINDOW_WIDTH :: 1920 WINDOW_WIDTH :: 1920
WINDOW_HEIGHT :: 1080 WINDOW_HEIGHT :: 1080
@@ -42,21 +39,30 @@ Layout :: struct {
} }
init :: proc(sim: ^Simulator) { init :: proc(sim: ^Simulator) {
run = true _sim = sim
// desktop
when ODIN_OS != .JS {
rl.SetConfigFlags({.WINDOW_RESIZABLE})
rl.SetTargetFPS(60)
}
// web
when ODIN_OS == .JS {
rl.SetConfigFlags({.VSYNC_HINT})
}
rl.SetConfigFlags({.WINDOW_RESIZABLE})
rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Octal Cookie - Chip 8 Simulator") rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Octal Cookie - Chip 8 Simulator")
rl.InitAudioDevice() rl.InitAudioDevice()
rl.SetTargetFPS(60)
// Load sound // Load sound
beep := rl.LoadSound("./assets/sounds/beep.wav") beep := rl.LoadSound("./assets/sounds/beep.wav")
sim.sound = beep _sim.sound = beep
// Load fonts // Load fonts
font := rl.LoadFontEx("./assets/fonts/Inter_18pt-Regular.ttf", 18, nil, 0) font := rl.LoadFontEx("./assets/fonts/Inter_18pt-Regular.ttf", 18, nil, 0)
rl.SetTextureFilter(font.texture, .BILINEAR) rl.SetTextureFilter(font.texture, .BILINEAR)
sim.font = font _sim.font = font
rl.GuiLoadStyleDefault() rl.GuiLoadStyleDefault()
rl.GuiLoadStyle("./assets/raygui_styles/genesis.rgs") rl.GuiLoadStyle("./assets/raygui_styles/genesis.rgs")
@@ -65,7 +71,9 @@ init :: proc(sim: ^Simulator) {
rl.GuiSetStyle(.DEFAULT, i32(rl.GuiDefaultProperty.TEXT_SIZE), 18) rl.GuiSetStyle(.DEFAULT, i32(rl.GuiDefaultProperty.TEXT_SIZE), 18)
} }
update :: proc(sim: ^Simulator) { update :: proc() {
sim := _sim
// Recalculate layout each frame based on current window size // Recalculate layout each frame based on current window size
// Pass these down to gui functions so they can setup their sizes? // Pass these down to gui functions so they can setup their sizes?
screen_width := f32(rl.GetScreenWidth()) screen_width := f32(rl.GetScreenWidth())
@@ -98,7 +106,7 @@ update :: proc(sim: ^Simulator) {
// Left // Left
// ------------------------------------------ // ------------------------------------------
gui_file_loader(layout.file_loader, sim) when ODIN_OS != .JS { gui_file_loader(layout.file_loader, sim)}
gui_key_pad(layout.keypad, sim.machine.keypad, sim.font) gui_key_pad(layout.keypad, sim.machine.keypad, sim.font)
// Center // Center
@@ -119,9 +127,11 @@ update :: proc(sim: ^Simulator) {
gui_info_box(layout.info_box, sim, screen_width, screen_height) gui_info_box(layout.info_box, sim, screen_width, screen_height)
rl.EndDrawing() rl.EndDrawing()
free_all(context.temp_allocator)
} }
shutdown :: proc(sim: ^Simulator) { shutdown :: proc() {
sim := _sim
rl.UnloadFont(sim.font) rl.UnloadFont(sim.font)
rl.UnloadSound(sim.sound) rl.UnloadSound(sim.sound)
rl.CloseAudioDevice() rl.CloseAudioDevice()
@@ -129,13 +139,10 @@ shutdown :: proc(sim: ^Simulator) {
} }
should_run :: proc() -> bool { should_run :: proc() -> bool {
when ODIN_OS != .JS { when ODIN_OS != .JS {
if rl.WindowShouldClose() { return !rl.WindowShouldClose()
run = false }
} return true // web loop is controlled by JS requestAnimationFrame
}
return run
} }
tick_timers :: proc(sim: ^Simulator) { tick_timers :: proc(sim: ^Simulator) {
@@ -146,7 +153,8 @@ tick_timers :: proc(sim: ^Simulator) {
sim.machine.sound_timer -= 1 sim.machine.sound_timer -= 1
if !rl.IsSoundPlaying(beep) do rl.PlaySound(beep) if !rl.IsSoundPlaying(beep) do rl.PlaySound(beep)
} else { } else {
rl.StopSound(beep) // only stop if actually playing
if rl.IsSoundPlaying(beep) do rl.StopSound(beep)
} }
} }
+1
View File
@@ -1,3 +1,4 @@
#+build !js
package simulator package simulator
import "core:strings" import "core:strings"
+3 -16
View File
@@ -3,6 +3,9 @@ package simulator
import emu "../machine" import emu "../machine"
import rl "vendor:raylib" import rl "vendor:raylib"
@(private="package")
_sim: ^Simulator
// Embed roms // Embed roms
roms := #load_directory("../roms") roms := #load_directory("../roms")
@@ -43,19 +46,3 @@ Simulator :: struct {
disasm_count: int, disasm_count: int,
disasm_scroll: rl.Vector2, disasm_scroll: rl.Vector2,
} }
// Requires an initilized emulatore System Struct
/*
run_simulator :: proc(s: ^emu.System) {
sim := Simulator {
machine = s,
rom_loaded = false,
paused = true,
step = false,
cpu_hz = 700,
disasm_follow = true,
}
run_gui(&sim)
}
*/