rubyboy 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f641e78dedf235a5ac8bab34c18fbd624150e5e6c9df92a710d2bc458fab3d62
4
- data.tar.gz: 7ab941409fcbec7b0eff98241231e002c249f84be16a19c28216e33f91ac14d2
3
+ metadata.gz: d1065bd051087c47a5b6a73fdde2887b92a4eaceef15b73fb1ed0f0fc5d6ad2f
4
+ data.tar.gz: 0e3f57c3c7258170c58c7ce855fa51352c989e1b07fbe3755d1c1bdf6134715d
5
5
  SHA512:
6
- metadata.gz: f220a9aeff3fa642f334c0248c4f155cf648c53a4bb132801e86a8008039f50d3cb9d3519af07b47e44f5aa2032419ba370e8ddcbb41ffebcb7937e8ed397b92
7
- data.tar.gz: 63065e706e48de9fc26dcd9f7bb75332876374769db0914c54843c3f60aa1dd53a950fe0f33755539331e8f02b5b71cc0d4cf0bdca31421911d23911454a8108
6
+ metadata.gz: 64e5b3e5fa9a54dee5f153a264816e9e1d307d7c95b349d9d92e717cb4f6725307e0d992c3294e4c9c06bee9f22c5ca04cc3257e756e453df432e8b02f244655
7
+ data.tar.gz: 9b1ace44a5900036efabd776686cbf41bb68d8696176922fcbae445a0b2db84469f4383aae9299ddb3df12cbe70f89f703c6828c647a20b52628a0fdfd328a83
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.3.1] - 2024-03-17
4
+
5
+ - Enable YJIT when initialize
6
+ - Down volume
7
+ - Update README.md
8
+ - Clear queued audio if buffer is full
9
+ - Add CPU clock and cycle timing
10
+
3
11
  ## [1.3.0] - 2024-03-09
4
12
 
5
13
  - Add ffi to dependencies
data/README.md CHANGED
@@ -6,17 +6,23 @@
6
6
 
7
7
  A Game Boy emulator written in Ruby
8
8
 
9
+ ## Requirements
10
+ [SDL2](https://wiki.libsdl.org/SDL2/Installation)
11
+
9
12
  ## Installation
10
13
 
11
14
  This project requires Ruby 3.2.0 or higher.
12
15
 
16
+ > [!TIP]
17
+ > To enhance performance, it is highly recommended to use Ruby 3.3.x with YJIT.
18
+
13
19
  Install the gem and add to the application's Gemfile by executing:
14
20
 
15
21
  $ bundle add rubyboy
16
22
 
17
23
  If bundler is not being used to manage dependencies, install the gem by executing:
18
24
 
19
- $ gem install rubyboy
25
+ $ gem install ffi rubyboy
20
26
 
21
27
  ## Usage
22
28
 
data/exe/rubyboy CHANGED
@@ -6,9 +6,6 @@ require 'bench'
6
6
 
7
7
  arg = ARGV[0]
8
8
 
9
- puts "Ruby: #{RUBY_VERSION}"
10
- puts "YJIT: #{RubyVM::YJIT.enabled?}"
11
-
12
9
  if arg == 'bench'
13
10
  Rubyboy::Bench.new.bench
14
11
  elsif arg == 'stackprof'
data/lib/rubyboy/apu.rb CHANGED
@@ -32,8 +32,8 @@ module Rubyboy
32
32
  @channel3.step(cycles)
33
33
  @channel4.step(cycles)
34
34
 
35
- if @cycles >= 0x1fff
36
- @cycles -= 0x1fff
35
+ if @cycles >= 0x2000
36
+ @cycles -= 0x2000
37
37
 
38
38
  @channel1.step_fs(@fs)
39
39
  @channel2.step_fs(@fs)
@@ -62,8 +62,8 @@ module Rubyboy
62
62
 
63
63
  raise "#{@nr51} #{@channel4.dac_output}, #{@channel3.dac_output}, #{@channel2.dac_output},#{@channel1.dac_output}" if left_sample.abs > 1.0 || right_sample.abs > 1.0
64
64
 
65
- @samples[@sample_idx * 2] = (@nr50[4..6] / 7.0) * left_sample
66
- @samples[@sample_idx * 2 + 1] = (@nr50[0..2] / 7.0) * right_sample
65
+ @samples[@sample_idx * 2] = (@nr50[4..6] / 7.0) * left_sample / 8.0
66
+ @samples[@sample_idx * 2 + 1] = (@nr50[0..2] / 7.0) * right_sample / 8.0
67
67
  @sample_idx += 1
68
68
  end
69
69
 
data/lib/rubyboy/audio.rb CHANGED
@@ -22,7 +22,9 @@ module Rubyboy
22
22
  end
23
23
 
24
24
  def queue(buffer)
25
- sleep(0.001) while SDL.GetQueuedAudioSize(@device) > 8192
25
+ # sleep(0.001) while SDL.GetQueuedAudioSize(@device) > 8192
26
+
27
+ SDL.ClearQueuedAudio(@device) if SDL.GetQueuedAudioSize(@device) > 8192
26
28
 
27
29
  buf_ptr = FFI::MemoryPointer.new(:float, buffer.size)
28
30
  buf_ptr.put_array_of_float(0, buffer)
data/lib/rubyboy/sdl.rb CHANGED
@@ -53,6 +53,7 @@ module Rubyboy
53
53
  attach_function :PauseAudioDevice, 'SDL_PauseAudioDevice', %i[uint32 int], :void
54
54
  attach_function :GetQueuedAudioSize, 'SDL_GetQueuedAudioSize', [:uint32], :uint32
55
55
  attach_function :QueueAudio, 'SDL_QueueAudio', %i[uint32 pointer uint32], :int
56
+ attach_function :ClearQueuedAudio, 'SDL_ClearQueuedAudio', [:uint32], :void
56
57
 
57
58
  class AudioSpec < FFI::Struct
58
59
  layout(
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubyboy
4
- VERSION = '1.3.0'
4
+ VERSION = '1.3.1'
5
5
  end
data/lib/rubyboy.rb CHANGED
@@ -15,6 +15,9 @@ require_relative 'rubyboy/cartridge/factory'
15
15
 
16
16
  module Rubyboy
17
17
  class Console
18
+ CPU_CLOCK_HZ = 4_194_304
19
+ CYCLE_NANOSEC = 1_000_000_000 / CPU_CLOCK_HZ
20
+
18
21
  def initialize(rom_path)
19
22
  rom_data = File.open(rom_path, 'r') { _1.read.bytes }
20
23
  rom = Rom.new(rom_data)
@@ -28,23 +31,38 @@ module Rubyboy
28
31
  @bus = Bus.new(@ppu, rom, ram, mbc, @timer, interrupt, @joypad, @apu)
29
32
  @cpu = Cpu.new(@bus, interrupt)
30
33
  @lcd = Lcd.new
34
+
35
+ RubyVM::YJIT.enable
36
+
37
+ puts "Ruby: #{RUBY_VERSION}"
38
+ puts "YJIT: #{RubyVM::YJIT.enabled?}"
31
39
  end
32
40
 
33
41
  def start
34
42
  SDL.InitSubSystem(SDL::INIT_KEYBOARD)
35
- loop do
36
- cycles = @cpu.exec
37
- @timer.step(cycles)
38
- @apu.step(cycles)
39
- next unless @ppu.step(cycles)
40
43
 
41
- @lcd.draw(@ppu.buffer)
42
- key_input_check
43
- break if @lcd.window_should_close?
44
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
45
+ elapsed_machine_time = 0
46
+ catch(:exit_loop) do
47
+ loop do
48
+ elapsed_real_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond) - start_time
49
+ while elapsed_real_time > elapsed_machine_time
50
+ cycles = @cpu.exec
51
+ @timer.step(cycles)
52
+ @apu.step(cycles)
53
+ if @ppu.step(cycles)
54
+ @lcd.draw(@ppu.buffer)
55
+ key_input_check
56
+ throw :exit_loop if @lcd.window_should_close?
57
+ end
58
+
59
+ elapsed_machine_time += cycles * CYCLE_NANOSEC
60
+ end
61
+ end
44
62
  end
45
63
  @lcd.close_window
46
64
  rescue StandardError => e
47
- p e.to_s[0, 100]
65
+ puts e.to_s[0, 100]
48
66
  raise e
49
67
  end
50
68
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyboy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - sacckey
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-09 00:00:00.000000000 Z
11
+ date: 2024-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi