Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## [Unreleased]

## [1.4.2] - 2025-01-11

- Use DefaultRubyVM
- Bump ruby.wasm version to 2.7.0

## [1.4.1] - 2024-12-25

- PPU performance optimization through data caching and pixel format changes
Expand Down
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ group :development, :test do
end

group :wasm do
gem 'js', '2.6.2'
gem 'ruby_wasm', '2.6.2'
gem 'js', '2.7.0'
gem 'ruby_wasm', '2.7.0'
end
12 changes: 6 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
rubyboy (1.4.1)
rubyboy (1.4.2)
ffi (~> 1.16, >= 1.16.3)

GEM
Expand All @@ -12,7 +12,7 @@ GEM
diff-lcs (1.5.0)
ffi (1.16.3)
heap-profiler (0.7.0)
js (2.6.2)
js (2.7.0)
json (2.6.3)
language_server-protocol (3.17.0.3)
parallel (1.23.0)
Expand Down Expand Up @@ -52,8 +52,8 @@ GEM
rubocop-ast (1.29.0)
parser (>= 3.2.1.0)
ruby-progressbar (1.13.0)
ruby_wasm (2.6.2-x86_64-darwin)
ruby_wasm (2.6.2-x86_64-linux)
ruby_wasm (2.7.0-x86_64-darwin)
ruby_wasm (2.7.0-x86_64-linux)
stackprof (0.2.25)
unicode-display_width (2.5.0)

Expand All @@ -63,11 +63,11 @@ PLATFORMS

DEPENDENCIES
heap-profiler (~> 0.7.0)
js (= 2.6.2)
js (= 2.7.0)
rake (~> 13.0)
rspec (~> 3.12)
rubocop (~> 1.57)
ruby_wasm (= 2.6.2)
ruby_wasm (= 2.7.0)
rubyboy!
stackprof (~> 0.2.25)

Expand Down
41 changes: 7 additions & 34 deletions docs/worker.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RubyVM } from 'https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.6.2/+esm';
import { Directory, File, OpenDirectory, OpenFile, PreopenDirectory, WASI } from 'https://cdn.jsdelivr.net/npm/@bjorn3/browser_wasi_shim@0.3.0/+esm';
import { DefaultRubyVM } from 'https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.0/dist/browser/+esm';
import { File } from 'https://cdn.jsdelivr.net/npm/@bjorn3/browser_wasi_shim@0.3.0/+esm';

const DIRECTION_KEY_MASKS = {
'KeyD': 0b0001, // Right
Expand All @@ -19,20 +19,6 @@ class Rubyboy {
constructor() {
this.wasmUrl = 'https://proxy.sacckey.dev/rubyboy.wasm';

const rootContents = new Map();
rootContents.set('RUBYBOY_TMP', new Directory(new Map()));
this.rootFs = rootContents;

const args = ['ruby.wasm', '-e_=0'];
this.wasi = new WASI(args, [], [
new OpenFile(new File([])), // stdin
new OpenFile(new File([])), // stdout
new OpenFile(new File([])), // stderr
new PreopenDirectory('/', rootContents)
], {
debug: false
});

this.directionKey = 0b1111;
this.actionKey = 0b1111;
}
Expand All @@ -43,18 +29,8 @@ class Rubyboy {
response = await fetch(this.wasmUrl);
}

const buffer = await response.arrayBuffer();
const imports = {
wasi_snapshot_preview1: this.wasi.wasiImport,
};
const vm = new RubyVM();
vm.addToImports(imports);

const { instance } = await WebAssembly.instantiate(buffer, imports);
await vm.setInstance(instance);
this.wasi.initialize(instance);
vm.initialize();

const module = await WebAssembly.compileStreaming(response)
const { vm, wasi } = await DefaultRubyVM(module);
vm.eval(`
require 'js'
require_relative 'lib/executor'
Expand All @@ -63,15 +39,13 @@ class Rubyboy {
`);

this.vm = vm;
this.rootDir = wasi.fds[3].dir
}

sendPixelData() {
this.vm.eval(`$executor.exec(${this.directionKey}, ${this.actionKey})`);

const tmpDir = this.rootFs.get('RUBYBOY_TMP');
const op = new OpenDirectory(tmpDir);
const result = op.path_lookup('video.data', 0);
const file = result.inode_obj;
const file = this.rootDir.contents.get('video.data');
const bytes = file.data;

postMessage({ type: 'pixelData', data: bytes.buffer }, [bytes.buffer]);
Expand Down Expand Up @@ -127,8 +101,7 @@ self.addEventListener('message', async (event) => {

if (event.data.type === 'loadROM') {
const romFile = new File(new Uint8Array(event.data.data));
const tmpDir = rubyboy.rootFs.get('RUBYBOY_TMP');
tmpDir.contents.set('rom.data', romFile);
rubyboy.rootDir.contents.set('rom.data', romFile);
rubyboy.vm.eval(`
$executor.read_rom_from_virtual_fs
`);
Expand Down
4 changes: 2 additions & 2 deletions lib/executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ def initialize

def exec(direction_key = 0b1111, action_key = 0b1111)
bin = @emulator.step(direction_key, action_key).pack('V*')
File.binwrite(File.join('/RUBYBOY_TMP', 'video.data'), bin)
File.binwrite('/video.data', bin)
end

def read_rom_from_virtual_fs
rom_path = '/RUBYBOY_TMP/rom.data'
rom_path = '/rom.data'
raise "ROM file not found in virtual filesystem at #{rom_path}" unless File.exist?(rom_path)

rom_data = File.open(rom_path, 'rb') { |file| file.read.bytes }
Expand Down
2 changes: 1 addition & 1 deletion lib/rubyboy/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Rubyboy
VERSION = '1.4.1'
VERSION = '1.4.2'
end
Loading