rubyboy 1.1.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +15 -0
- data/README.md +5 -1
- data/exe/rubyboy +2 -1
- data/lib/rubyboy/apu.rb +118 -0
- data/lib/rubyboy/apu_channels/channel1.rb +154 -0
- data/lib/rubyboy/apu_channels/channel2.rb +116 -0
- data/lib/rubyboy/apu_channels/channel3.rb +117 -0
- data/lib/rubyboy/apu_channels/channel4.rb +148 -0
- data/lib/rubyboy/audio.rb +33 -0
- data/lib/rubyboy/bus.rb +65 -121
- data/lib/rubyboy/cartridge/factory.rb +1 -1
- data/lib/rubyboy/cartridge/mbc1.rb +52 -38
- data/lib/rubyboy/cpu.rb +701 -677
- data/lib/rubyboy/lcd.rb +30 -19
- data/lib/rubyboy/ppu.rb +16 -4
- data/lib/rubyboy/raylib/audio.rb +32 -0
- data/lib/rubyboy/raylib/lcd.rb +40 -0
- data/lib/rubyboy/raylib/raylib_loader.rb +36 -0
- data/lib/rubyboy/registers.rb +67 -61
- data/lib/rubyboy/sdl.rb +71 -0
- data/lib/rubyboy/version.rb +1 -1
- data/lib/rubyboy.rb +23 -41
- data/resource/logo/logo.png +0 -0
- data/resource/logo/logo.svg +1 -0
- metadata +23 -16
- data/lib/rubyboy/operand/direct16.rb +0 -13
- data/lib/rubyboy/operand/direct8.rb +0 -13
- data/lib/rubyboy/operand/hl_dec.rb +0 -11
- data/lib/rubyboy/operand/hl_inc.rb +0 -11
- data/lib/rubyboy/operand/immediate16.rb +0 -13
- data/lib/rubyboy/operand/immediate8.rb +0 -13
- data/lib/rubyboy/operand/indirect.rb +0 -13
- data/lib/rubyboy/operand/register16.rb +0 -13
- data/lib/rubyboy/operand/register8.rb +0 -13
- data/lib/rubyboy/operand.rb +0 -12
- data/lib/rubyboy/register.rb +0 -24
data/lib/rubyboy/lcd.rb
CHANGED
@@ -1,37 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rubyboy/sdl'
|
4
4
|
|
5
5
|
module Rubyboy
|
6
6
|
class Lcd
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
HEIGHT = 144
|
11
|
-
SCALE = 4
|
7
|
+
SCREEN_WIDTH = 160
|
8
|
+
SCREEN_HEIGHT = 144
|
9
|
+
SCALE = 3
|
12
10
|
|
13
11
|
def initialize
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@
|
18
|
-
end
|
12
|
+
raise SDL.GetError() if SDL.InitSubSystem(SDL::INIT_VIDEO) != 0
|
13
|
+
|
14
|
+
@buffer = FFI::MemoryPointer.new(:uint8, SCREEN_WIDTH * SCREEN_HEIGHT * 3)
|
15
|
+
@window = SDL.CreateWindow('RUBY BOY', 0, 0, SCREEN_WIDTH * SCALE, SCREEN_HEIGHT * SCALE, SDL::SDL_WINDOW_RESIZABLE)
|
19
16
|
|
20
|
-
|
21
|
-
UpdateTexture(@texture, pixel_data)
|
17
|
+
raise SDL.GetError() if @window.null?
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
@renderer = SDL.CreateRenderer(@window, -1, 0)
|
20
|
+
SDL.SetHint('SDL_HINT_RENDER_SCALE_QUALITY', '2')
|
21
|
+
SDL.RenderSetLogicalSize(@renderer, SCREEN_WIDTH * SCALE, SCREEN_HEIGHT * SCALE)
|
22
|
+
@texture = SDL.CreateTexture(@renderer, SDL::PIXELFORMAT_RGB24, 1, SCREEN_WIDTH, SCREEN_HEIGHT)
|
23
|
+
@event = FFI::MemoryPointer.new(:pointer)
|
24
|
+
end
|
25
|
+
|
26
|
+
def draw(framebuffer)
|
27
|
+
@buffer.write_array_of_uint8(framebuffer)
|
28
|
+
SDL.UpdateTexture(@texture, nil, @buffer, SCREEN_WIDTH * 3)
|
29
|
+
SDL.RenderClear(@renderer)
|
30
|
+
SDL.RenderCopy(@renderer, @texture, nil, nil)
|
31
|
+
SDL.RenderPresent(@renderer)
|
27
32
|
end
|
28
33
|
|
29
34
|
def window_should_close?
|
30
|
-
|
35
|
+
while SDL.PollEvent(@event) != 0
|
36
|
+
event_type = @event.read_int
|
37
|
+
return true if event_type == SDL::QUIT
|
38
|
+
end
|
39
|
+
|
40
|
+
false
|
31
41
|
end
|
32
42
|
|
33
43
|
def close_window
|
34
|
-
|
44
|
+
SDL.DestroyWindow(@window)
|
45
|
+
SDL.Quit
|
35
46
|
end
|
36
47
|
end
|
37
48
|
end
|
data/lib/rubyboy/ppu.rb
CHANGED
@@ -64,7 +64,7 @@ module Rubyboy
|
|
64
64
|
@wly = 0x00
|
65
65
|
@cycles = 0
|
66
66
|
@interrupt = interrupt
|
67
|
-
@buffer = Array.new(144 * 160, 0x00)
|
67
|
+
@buffer = Array.new(144 * 160 * 3, 0x00)
|
68
68
|
@bg_pixels = Array.new(LCD_WIDTH, 0x00)
|
69
69
|
end
|
70
70
|
|
@@ -196,7 +196,11 @@ module Rubyboy
|
|
196
196
|
x = (i + @scx) % 256
|
197
197
|
tile_index = get_tile_index(tile_map_addr + (x / 8))
|
198
198
|
pixel = get_pixel(tile_index << 4, 7 - (x % 8), (y % 8) * 2)
|
199
|
-
|
199
|
+
color = get_color(@bgp, pixel)
|
200
|
+
base = @ly * LCD_WIDTH * 3 + i * 3
|
201
|
+
@buffer[base] = color
|
202
|
+
@buffer[base + 1] = color
|
203
|
+
@buffer[base + 2] = color
|
200
204
|
@bg_pixels[i] = pixel
|
201
205
|
end
|
202
206
|
end
|
@@ -215,7 +219,11 @@ module Rubyboy
|
|
215
219
|
x = i - (@wx - 7)
|
216
220
|
tile_index = get_tile_index(tile_map_addr + (x / 8))
|
217
221
|
pixel = get_pixel(tile_index << 4, 7 - (x % 8), (y % 8) * 2)
|
218
|
-
|
222
|
+
color = get_color(@bgp, pixel)
|
223
|
+
base = @ly * LCD_WIDTH * 3 + i * 3
|
224
|
+
@buffer[base] = color
|
225
|
+
@buffer[base + 1] = color
|
226
|
+
@buffer[base + 2] = color
|
219
227
|
@bg_pixels[i] = pixel
|
220
228
|
end
|
221
229
|
@wly += 1 if rendered
|
@@ -258,7 +266,11 @@ module Rubyboy
|
|
258
266
|
next if pixel == 0 || i >= LCD_WIDTH
|
259
267
|
next if flags[SPRITE_FLAGS[:priority]] == 1 && @bg_pixels[i] != 0
|
260
268
|
|
261
|
-
|
269
|
+
color = get_color(pallet, pixel)
|
270
|
+
base = @ly * LCD_WIDTH * 3 + i * 3
|
271
|
+
@buffer[base] = color
|
272
|
+
@buffer[base + 1] = color
|
273
|
+
@buffer[base + 2] = color
|
262
274
|
end
|
263
275
|
end
|
264
276
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'raylib'
|
4
|
+
|
5
|
+
module Rubyboy
|
6
|
+
module Raylib
|
7
|
+
class Audio
|
8
|
+
include Raylib
|
9
|
+
|
10
|
+
MAX_SAMPLES = 512
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
InitAudioDevice()
|
14
|
+
SetAudioStreamBufferSizeDefault(MAX_SAMPLES * 2)
|
15
|
+
@stream = LoadAudioStream(48000, 32, 2)
|
16
|
+
PlayAudioStream(@stream)
|
17
|
+
end
|
18
|
+
|
19
|
+
def play(samples)
|
20
|
+
samples_pointer = FFI::MemoryPointer.new(:float, samples.size)
|
21
|
+
samples_pointer.put_array_of_float(0, samples)
|
22
|
+
|
23
|
+
UpdateAudioStream(@stream, samples_pointer, samples.size)
|
24
|
+
end
|
25
|
+
|
26
|
+
def close
|
27
|
+
UnloadAudioStream(@stream)
|
28
|
+
CloseAudioDevice()
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'raylib'
|
4
|
+
|
5
|
+
module Rubyboy
|
6
|
+
module Raylib
|
7
|
+
class Lcd
|
8
|
+
include Raylib
|
9
|
+
|
10
|
+
WIDTH = 160
|
11
|
+
HEIGHT = 144
|
12
|
+
SCALE = 4
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
InitWindow(WIDTH * SCALE, HEIGHT * SCALE, 'RUBY BOY')
|
16
|
+
image = GenImageColor(WIDTH, HEIGHT, BLACK)
|
17
|
+
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8
|
18
|
+
@texture = LoadTextureFromImage(image)
|
19
|
+
@vector = Vector2.create(0, 0)
|
20
|
+
end
|
21
|
+
|
22
|
+
def draw(pixel_data)
|
23
|
+
UpdateTexture(@texture, pixel_data.pack('C*'))
|
24
|
+
|
25
|
+
BeginDrawing()
|
26
|
+
ClearBackground(BLACK)
|
27
|
+
DrawTextureEx(@texture, @vector, 0.0, SCALE, WHITE)
|
28
|
+
EndDrawing()
|
29
|
+
end
|
30
|
+
|
31
|
+
def window_should_close?
|
32
|
+
WindowShouldClose()
|
33
|
+
end
|
34
|
+
|
35
|
+
def close_window
|
36
|
+
CloseWindow()
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'raylib'
|
4
|
+
|
5
|
+
module Rubyboy
|
6
|
+
module Raylib
|
7
|
+
class RaylibLoader
|
8
|
+
include Raylib
|
9
|
+
|
10
|
+
def load_raylib
|
11
|
+
shared_lib_path = "#{Gem::Specification.find_by_name('raylib-bindings').full_gem_path}/lib/"
|
12
|
+
case RUBY_PLATFORM
|
13
|
+
when /mswin|msys|mingw/ # Windows
|
14
|
+
Raylib.load_lib("#{shared_lib_path}libraylib.dll")
|
15
|
+
when /darwin/ # macOS
|
16
|
+
arch = RUBY_PLATFORM.split('-')[0]
|
17
|
+
Raylib.load_lib(shared_lib_path + "libraylib.#{arch}.dylib")
|
18
|
+
when /linux/ # Ubuntu Linux (x86_64 or aarch64)
|
19
|
+
arch = RUBY_PLATFORM.split('-')[0]
|
20
|
+
Raylib.load_lib(shared_lib_path + "libraylib.#{arch}.so")
|
21
|
+
else
|
22
|
+
raise "Unknown system: #{RUBY_PLATFORM}"
|
23
|
+
end
|
24
|
+
|
25
|
+
SetTraceLogLevel(LOG_ERROR)
|
26
|
+
end
|
27
|
+
|
28
|
+
def key_input_check
|
29
|
+
direction = (IsKeyUp(KEY_D) && 1 || 0) | ((IsKeyUp(KEY_A) && 1 || 0) << 1) | ((IsKeyUp(KEY_W) && 1 || 0) << 2) | ((IsKeyUp(KEY_S) && 1 || 0) << 3)
|
30
|
+
action = (IsKeyUp(KEY_K) && 1 || 0) | ((IsKeyUp(KEY_J) && 1 || 0) << 1) | ((IsKeyUp(KEY_U) && 1 || 0) << 2) | ((IsKeyUp(KEY_I) && 1 || 0) << 3)
|
31
|
+
@joypad.direction_button(direction)
|
32
|
+
@joypad.action_button(action)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/rubyboy/registers.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Rubyboy
|
4
4
|
class Registers
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :a, :b, :c, :d, :e, :h, :l, :f
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
@a = 0x01
|
@@ -15,66 +15,72 @@ module Rubyboy
|
|
15
15
|
@f = 0xb0
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
def
|
77
|
-
|
18
|
+
def a=(value)
|
19
|
+
@a = value & 0xff
|
20
|
+
end
|
21
|
+
|
22
|
+
def b=(value)
|
23
|
+
@b = value & 0xff
|
24
|
+
end
|
25
|
+
|
26
|
+
def c=(value)
|
27
|
+
@c = value & 0xff
|
28
|
+
end
|
29
|
+
|
30
|
+
def d=(value)
|
31
|
+
@d = value & 0xff
|
32
|
+
end
|
33
|
+
|
34
|
+
def e=(value)
|
35
|
+
@e = value & 0xff
|
36
|
+
end
|
37
|
+
|
38
|
+
def h=(value)
|
39
|
+
@h = value & 0xff
|
40
|
+
end
|
41
|
+
|
42
|
+
def l=(value)
|
43
|
+
@l = value & 0xff
|
44
|
+
end
|
45
|
+
|
46
|
+
def f=(value)
|
47
|
+
@f = value & 0xf0
|
48
|
+
end
|
49
|
+
|
50
|
+
def af
|
51
|
+
(@a << 8) | @f
|
52
|
+
end
|
53
|
+
|
54
|
+
def bc
|
55
|
+
(@b << 8) | @c
|
56
|
+
end
|
57
|
+
|
58
|
+
def de
|
59
|
+
(@d << 8) | @e
|
60
|
+
end
|
61
|
+
|
62
|
+
def hl
|
63
|
+
(@h << 8) | @l
|
64
|
+
end
|
65
|
+
|
66
|
+
def af=(value)
|
67
|
+
@a = (value >> 8) & 0xff
|
68
|
+
@f = value & 0xf0
|
69
|
+
end
|
70
|
+
|
71
|
+
def bc=(value)
|
72
|
+
@b = (value >> 8) & 0xff
|
73
|
+
@c = value & 0xff
|
74
|
+
end
|
75
|
+
|
76
|
+
def de=(value)
|
77
|
+
@d = (value >> 8) & 0xff
|
78
|
+
@e = value & 0xff
|
79
|
+
end
|
80
|
+
|
81
|
+
def hl=(value)
|
82
|
+
@h = (value >> 8) & 0xff
|
83
|
+
@l = value & 0xff
|
78
84
|
end
|
79
85
|
end
|
80
86
|
end
|
data/lib/rubyboy/sdl.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
module Rubyboy
|
6
|
+
module SDL
|
7
|
+
extend FFI::Library
|
8
|
+
ffi_lib 'SDL2'
|
9
|
+
|
10
|
+
INIT_TIMER = 0x01
|
11
|
+
INIT_AUDIO = 0x10
|
12
|
+
INIT_VIDEO = 0x20
|
13
|
+
INIT_KEYBOARD = 0x200
|
14
|
+
WINDOW_RESIZABLE = 0x20
|
15
|
+
PIXELFORMAT_RGB24 = 386930691
|
16
|
+
SDL_WINDOW_RESIZABLE = 0x20
|
17
|
+
QUIT = 0x100
|
18
|
+
|
19
|
+
SDL_SCANCODE_W = 26
|
20
|
+
SDL_SCANCODE_A = 4
|
21
|
+
SDL_SCANCODE_S = 22
|
22
|
+
SDL_SCANCODE_D = 7
|
23
|
+
SDL_SCANCODE_J = 13
|
24
|
+
SDL_SCANCODE_K = 14
|
25
|
+
SDL_SCANCODE_U = 24
|
26
|
+
SDL_SCANCODE_I = 12
|
27
|
+
|
28
|
+
attach_function :Init, 'SDL_Init', [:uint32], :int
|
29
|
+
attach_function :InitSubSystem, 'SDL_InitSubSystem', [:uint32], :int
|
30
|
+
attach_function :CreateWindow, 'SDL_CreateWindow', %i[string int int int int uint32], :pointer
|
31
|
+
attach_function :DestroyWindow, 'SDL_DestroyWindow', [:pointer], :void
|
32
|
+
attach_function :CreateRenderer, 'SDL_CreateRenderer', %i[pointer int uint32], :pointer
|
33
|
+
attach_function :CreateTexture, 'SDL_CreateTexture', %i[pointer uint32 int int int], :pointer
|
34
|
+
attach_function :UpdateTexture, 'SDL_UpdateTexture', %i[pointer pointer pointer int], :int
|
35
|
+
attach_function :LockTexture, 'SDL_LockTexture', %i[pointer pointer pointer int], :int
|
36
|
+
attach_function :UnlockTexture, 'SDL_UnlockTexture', [:pointer], :void
|
37
|
+
attach_function :RenderClear, 'SDL_RenderClear', [:pointer], :int
|
38
|
+
attach_function :RenderCopy, 'SDL_RenderCopy', %i[pointer pointer pointer pointer], :int
|
39
|
+
attach_function :RenderPresent, 'SDL_RenderPresent', [:pointer], :int
|
40
|
+
attach_function :PumpEvents, 'SDL_PumpEvents', [], :void
|
41
|
+
attach_function :GetKeyboardState, 'SDL_GetKeyboardState', [:pointer], :pointer
|
42
|
+
attach_function :SetHint, 'SDL_SetHint', %i[string string], :int
|
43
|
+
attach_function :RenderSetLogicalSize, 'SDL_RenderSetLogicalSize', %i[pointer int int], :int
|
44
|
+
attach_function :SetWindowTitle, 'SDL_SetWindowTitle', %i[pointer string], :void
|
45
|
+
attach_function :RaiseWindow, 'SDL_RaiseWindow', [:pointer], :void
|
46
|
+
attach_function :GetError, 'SDL_GetError', [], :string
|
47
|
+
attach_function :SetRenderDrawColor, 'SDL_SetRenderDrawColor', %i[pointer uint8 uint8 uint8 uint8], :int
|
48
|
+
attach_function :PollEvent, 'SDL_PollEvent', [:pointer], :int
|
49
|
+
attach_function :Quit, 'SDL_Quit', [], :void
|
50
|
+
|
51
|
+
AUDIO_F32SYS = 0x8120
|
52
|
+
attach_function :OpenAudioDevice, 'SDL_OpenAudioDevice', %i[string int pointer pointer int], :uint32
|
53
|
+
attach_function :PauseAudioDevice, 'SDL_PauseAudioDevice', %i[uint32 int], :void
|
54
|
+
attach_function :GetQueuedAudioSize, 'SDL_GetQueuedAudioSize', [:uint32], :uint32
|
55
|
+
attach_function :QueueAudio, 'SDL_QueueAudio', %i[uint32 pointer uint32], :int
|
56
|
+
|
57
|
+
class AudioSpec < FFI::Struct
|
58
|
+
layout(
|
59
|
+
:freq, :int,
|
60
|
+
:format, :ushort,
|
61
|
+
:channels, :uchar,
|
62
|
+
:silence, :uchar,
|
63
|
+
:samples, :ushort,
|
64
|
+
:padding, :ushort,
|
65
|
+
:size, :uint,
|
66
|
+
:callback, :pointer,
|
67
|
+
:userdata, :pointer
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/rubyboy/version.rb
CHANGED
data/lib/rubyboy.rb
CHANGED
@@ -1,40 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rubyboy/sdl'
|
4
|
+
require_relative 'rubyboy/apu'
|
4
5
|
require_relative 'rubyboy/bus'
|
5
6
|
require_relative 'rubyboy/cpu'
|
6
7
|
require_relative 'rubyboy/ppu'
|
7
8
|
require_relative 'rubyboy/rom'
|
9
|
+
require_relative 'rubyboy/ram'
|
8
10
|
require_relative 'rubyboy/timer'
|
9
11
|
require_relative 'rubyboy/lcd'
|
10
12
|
require_relative 'rubyboy/joypad'
|
11
13
|
require_relative 'rubyboy/interrupt'
|
14
|
+
require_relative 'rubyboy/cartridge/factory'
|
12
15
|
|
13
16
|
module Rubyboy
|
14
17
|
class Console
|
15
|
-
include Raylib
|
16
|
-
|
17
18
|
def initialize(rom_path)
|
18
|
-
load_raylib
|
19
19
|
rom_data = File.open(rom_path, 'r') { _1.read.bytes }
|
20
20
|
rom = Rom.new(rom_data)
|
21
|
+
ram = Ram.new
|
22
|
+
mbc = Cartridge::Factory.create(rom, ram)
|
21
23
|
interrupt = Interrupt.new
|
22
24
|
@ppu = Ppu.new(interrupt)
|
23
25
|
@timer = Timer.new(interrupt)
|
24
26
|
@joypad = Joypad.new(interrupt)
|
25
|
-
@
|
27
|
+
@apu = Apu.new
|
28
|
+
@bus = Bus.new(@ppu, rom, ram, mbc, @timer, interrupt, @joypad, @apu)
|
26
29
|
@cpu = Cpu.new(@bus, interrupt)
|
27
30
|
@lcd = Lcd.new
|
28
31
|
end
|
29
32
|
|
30
33
|
def start
|
31
|
-
|
34
|
+
SDL.InitSubSystem(SDL::INIT_KEYBOARD)
|
35
|
+
loop do
|
32
36
|
cycles = @cpu.exec
|
33
37
|
@timer.step(cycles)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
+
@apu.step(cycles)
|
39
|
+
next unless @ppu.step(cycles)
|
40
|
+
|
41
|
+
@lcd.draw(@ppu.buffer)
|
42
|
+
key_input_check
|
43
|
+
break if @lcd.window_should_close?
|
38
44
|
end
|
39
45
|
@lcd.close_window
|
40
46
|
rescue StandardError => e
|
@@ -59,39 +65,15 @@ module Rubyboy
|
|
59
65
|
|
60
66
|
private
|
61
67
|
|
62
|
-
def draw
|
63
|
-
pixel_data = buffer_to_pixel_data(@ppu.buffer)
|
64
|
-
@lcd.draw(pixel_data)
|
65
|
-
end
|
66
|
-
|
67
|
-
def buffer_to_pixel_data(buffer)
|
68
|
-
buffer.map do |row|
|
69
|
-
[row, row, row]
|
70
|
-
end.flatten.pack('C*')
|
71
|
-
end
|
72
|
-
|
73
68
|
def key_input_check
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
@joypad.action_button(action)
|
78
|
-
end
|
79
|
-
|
80
|
-
def load_raylib
|
81
|
-
shared_lib_path = "#{Gem::Specification.find_by_name('raylib-bindings').full_gem_path}/lib/"
|
82
|
-
case RUBY_PLATFORM
|
83
|
-
when /mswin|msys|mingw/ # Windows
|
84
|
-
Raylib.load_lib("#{shared_lib_path}libraylib.dll")
|
85
|
-
when /darwin/ # macOS
|
86
|
-
Raylib.load_lib("#{shared_lib_path}libraylib.dylib")
|
87
|
-
when /linux/ # Ubuntu Linux (x86_64 or aarch64)
|
88
|
-
arch = RUBY_PLATFORM.split('-')[0]
|
89
|
-
Raylib.load_lib(shared_lib_path + "libraylib.#{arch}.so")
|
90
|
-
else
|
91
|
-
raise "Unknown system: #{RUBY_PLATFORM}"
|
92
|
-
end
|
69
|
+
SDL.PumpEvents
|
70
|
+
keyboard = SDL.GetKeyboardState(nil)
|
71
|
+
keyboard_state = keyboard.read_array_of_uint8(229)
|
93
72
|
|
94
|
-
|
73
|
+
direction = (keyboard_state[SDL::SDL_SCANCODE_D]) | (keyboard_state[SDL::SDL_SCANCODE_A] << 1) | (keyboard_state[SDL::SDL_SCANCODE_W] << 2) | (keyboard_state[SDL::SDL_SCANCODE_S] << 3)
|
74
|
+
action = (keyboard_state[SDL::SDL_SCANCODE_K]) | (keyboard_state[SDL::SDL_SCANCODE_J] << 1) | (keyboard_state[SDL::SDL_SCANCODE_U] << 2) | (keyboard_state[SDL::SDL_SCANCODE_I] << 3)
|
75
|
+
@joypad.direction_button(15 - direction)
|
76
|
+
@joypad.action_button(15 - action)
|
95
77
|
end
|
96
78
|
end
|
97
79
|
end
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="467" height="75" viewBox="0 0 467 75"><path fill="#cc342d" d="M25.40 46.45L21.75 46.45L18.40 73.65L2.20 73.65L11.10 0.80L33.20 0.80Q39.90 0.80 44.63 2.23Q49.35 3.65 52.35 6.15Q55.35 8.65 56.73 12.08Q58.10 15.50 58.10 19.50L58.10 19.50Q58.10 23.55 57.03 27.15Q55.95 30.75 53.90 33.78Q51.85 36.80 48.88 39.13Q45.90 41.45 42.10 42.95L42.10 42.95Q43.60 43.80 44.93 45Q46.25 46.20 47 48L47 48L57.60 73.65L42.90 73.65Q40.85 73.65 39.45 72.85Q38.05 72.05 37.50 70.55L37.50 70.55L29.60 49Q29.05 47.60 28.13 47.03Q27.20 46.45 25.40 46.45L25.40 46.45ZM31.70 12.95L25.90 12.95L23.15 35.20L29.10 35.20Q32.60 35.20 35.05 34.13Q37.50 33.05 39.03 31.25Q40.55 29.45 41.23 27.05Q41.90 24.65 41.90 22L41.90 22Q41.90 19.95 41.30 18.28Q40.70 16.60 39.43 15.43Q38.15 14.25 36.23 13.60Q34.30 12.95 31.70 12.95L31.70 12.95ZM90.40 60.85L90.40 60.85Q93.45 60.85 95.95 59.68Q98.45 58.50 100.35 56.33Q102.25 54.15 103.50 51.05Q104.75 47.95 105.20 44.10L105.20 44.10L110.50 0.80L126.80 0.80L121.50 44.10Q120.65 50.75 117.98 56.33Q115.30 61.90 111.03 65.93Q106.75 69.95 101.10 72.20Q95.45 74.45 88.70 74.45L88.70 74.45Q82.60 74.45 77.83 72.60Q73.05 70.75 69.78 67.38Q66.50 64 64.80 59.30Q63.10 54.60 63.10 48.95L63.10 48.95Q63.10 46.60 63.40 44.10L63.40 44.10L68.60 0.80L84.90 0.80L79.60 44.10Q79.50 45 79.45 45.88Q79.40 46.75 79.40 47.60L79.40 47.60Q79.40 53.80 82.23 57.33Q85.05 60.85 90.40 60.85ZM154.50 73.65L127.30 73.65L136.30 0.80L161.30 0.80Q167.65 0.80 172.18 2Q176.70 3.20 179.58 5.42Q182.45 7.65 183.78 10.78Q185.10 13.90 185.10 17.70L185.10 17.70Q185.10 20.70 184.33 23.48Q183.55 26.25 181.88 28.60Q180.20 30.95 177.55 32.88Q174.90 34.80 171.15 36.10L171.15 36.10Q177.05 37.70 179.88 41.08Q182.70 44.45 182.70 49.60L182.70 49.60Q182.70 54.65 180.78 59.03Q178.85 63.40 175.20 66.65Q171.55 69.90 166.33 71.78Q161.10 73.65 154.50 73.65L154.50 73.65ZM157.90 42.55L147.40 42.55L145.10 61.40L155.80 61.40Q158.80 61.40 160.85 60.53Q162.90 59.65 164.18 58.08Q165.45 56.50 166.03 54.40Q166.60 52.30 166.60 49.80L166.60 49.80Q166.60 48.15 166.18 46.80Q165.75 45.45 164.73 44.53Q163.70 43.60 162.03 43.08Q160.35 42.55 157.90 42.55L157.90 42.55ZM151 12.95L148.70 31.75L156.50 31.75Q159.25 31.75 161.45 31.20Q163.65 30.65 165.23 29.33Q166.80 28 167.65 25.80Q168.50 23.60 168.50 20.35L168.50 20.35Q168.50 16.30 166.38 14.63Q164.25 12.95 159.80 12.95L159.80 12.95L151 12.95ZM255.30 0.80L225.45 45.75L222 73.65L205.70 73.65L209.15 45.90L190.40 0.80L204.90 0.80Q207 0.80 208.18 1.78Q209.35 2.75 209.90 4.35L209.90 4.35L216.90 26.40Q217.60 28.60 218.18 30.65Q218.75 32.70 219.15 34.60L219.15 34.60Q220.10 32.70 221.25 30.68Q222.40 28.65 223.70 26.40L223.70 26.40L236.10 4.35Q236.85 3 238.30 1.90Q239.75 0.80 241.80 0.80L241.80 0.80L255.30 0.80ZM297 73.65L269.80 73.65L278.80 0.80L303.80 0.80Q310.15 0.80 314.68 2Q319.20 3.20 322.08 5.42Q324.95 7.65 326.28 10.78Q327.60 13.90 327.60 17.70L327.60 17.70Q327.60 20.70 326.83 23.48Q326.05 26.25 324.38 28.60Q322.70 30.95 320.05 32.88Q317.40 34.80 313.65 36.10L313.65 36.10Q319.55 37.70 322.38 41.08Q325.20 44.45 325.20 49.60L325.20 49.60Q325.20 54.65 323.28 59.03Q321.35 63.40 317.70 66.65Q314.05 69.90 308.83 71.78Q303.60 73.65 297 73.65L297 73.65ZM300.40 42.55L289.90 42.55L287.60 61.40L298.30 61.40Q301.30 61.40 303.35 60.53Q305.40 59.65 306.68 58.08Q307.95 56.50 308.53 54.40Q309.10 52.30 309.10 49.80L309.10 49.80Q309.10 48.15 308.68 46.80Q308.25 45.45 307.23 44.53Q306.20 43.60 304.53 43.08Q302.85 42.55 300.40 42.55L300.40 42.55ZM293.50 12.95L291.20 31.75L299 31.75Q301.75 31.75 303.95 31.20Q306.15 30.65 307.73 29.33Q309.30 28 310.15 25.80Q311 23.60 311 20.35L311 20.35Q311 16.30 308.88 14.63Q306.75 12.95 302.30 12.95L302.30 12.95L293.50 12.95ZM401.40 32.55L401.40 32.55Q401.40 38.45 400.02 43.85Q398.65 49.25 396.13 53.90Q393.60 58.55 390.02 62.35Q386.45 66.15 382 68.83Q377.55 71.50 372.35 72.98Q367.15 74.45 361.40 74.45L361.40 74.45Q354.20 74.45 348.48 71.93Q342.75 69.40 338.75 65.03Q334.75 60.65 332.63 54.73Q330.50 48.80 330.50 41.95L330.50 41.95Q330.50 36.05 331.88 30.63Q333.25 25.20 335.77 20.55Q338.30 15.90 341.90 12.10Q345.50 8.30 349.95 5.63Q354.40 2.95 359.60 1.48Q364.80 0 370.60 0L370.60 0Q377.75 0 383.48 2.53Q389.20 5.05 393.18 9.45Q397.15 13.85 399.27 19.80Q401.40 25.75 401.40 32.55ZM384.70 32.95L384.70 32.95Q384.70 28.45 383.63 24.78Q382.55 21.10 380.48 18.48Q378.40 15.85 375.40 14.43Q372.40 13 368.60 13L368.60 13Q363.60 13 359.65 15.08Q355.70 17.15 352.93 20.90Q350.15 24.65 348.68 29.93Q347.20 35.20 347.20 41.60L347.20 41.60Q347.20 46.10 348.25 49.75Q349.30 53.40 351.32 56Q353.35 58.60 356.35 60.03Q359.35 61.45 363.20 61.45L363.20 61.45Q368.20 61.45 372.18 59.40Q376.15 57.35 378.93 53.60Q381.70 49.85 383.20 44.60Q384.70 39.35 384.70 32.95ZM467 0.80L437.15 45.75L433.70 73.65L417.40 73.65L420.85 45.90L402.10 0.80L416.60 0.80Q418.70 0.80 419.88 1.78Q421.05 2.75 421.60 4.35L421.60 4.35L428.60 26.40Q429.30 28.60 429.88 30.65Q430.45 32.70 430.85 34.60L430.85 34.60Q431.80 32.70 432.95 30.68Q434.10 28.65 435.40 26.40L435.40 26.40L447.80 4.35Q448.55 3 450 1.90Q451.45 0.80 453.50 0.80L453.50 0.80L467 0.80Z"></path></svg>
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubyboy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sacckey
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: ffi
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1.16'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.16.3
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - "~>"
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
29
|
+
version: '1.16'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.16.3
|
27
33
|
description:
|
28
34
|
email:
|
29
35
|
executables:
|
@@ -61,6 +67,12 @@ files:
|
|
61
67
|
- lib/roms/instr_timing/readme.txt
|
62
68
|
- lib/roms/tobu.gb
|
63
69
|
- lib/rubyboy.rb
|
70
|
+
- lib/rubyboy/apu.rb
|
71
|
+
- lib/rubyboy/apu_channels/channel1.rb
|
72
|
+
- lib/rubyboy/apu_channels/channel2.rb
|
73
|
+
- lib/rubyboy/apu_channels/channel3.rb
|
74
|
+
- lib/rubyboy/apu_channels/channel4.rb
|
75
|
+
- lib/rubyboy/audio.rb
|
64
76
|
- lib/rubyboy/bus.rb
|
65
77
|
- lib/rubyboy/cartridge/factory.rb
|
66
78
|
- lib/rubyboy/cartridge/mbc1.rb
|
@@ -69,23 +81,18 @@ files:
|
|
69
81
|
- lib/rubyboy/interrupt.rb
|
70
82
|
- lib/rubyboy/joypad.rb
|
71
83
|
- lib/rubyboy/lcd.rb
|
72
|
-
- lib/rubyboy/operand.rb
|
73
|
-
- lib/rubyboy/operand/direct16.rb
|
74
|
-
- lib/rubyboy/operand/direct8.rb
|
75
|
-
- lib/rubyboy/operand/hl_dec.rb
|
76
|
-
- lib/rubyboy/operand/hl_inc.rb
|
77
|
-
- lib/rubyboy/operand/immediate16.rb
|
78
|
-
- lib/rubyboy/operand/immediate8.rb
|
79
|
-
- lib/rubyboy/operand/indirect.rb
|
80
|
-
- lib/rubyboy/operand/register16.rb
|
81
|
-
- lib/rubyboy/operand/register8.rb
|
82
84
|
- lib/rubyboy/ppu.rb
|
83
85
|
- lib/rubyboy/ram.rb
|
84
|
-
- lib/rubyboy/
|
86
|
+
- lib/rubyboy/raylib/audio.rb
|
87
|
+
- lib/rubyboy/raylib/lcd.rb
|
88
|
+
- lib/rubyboy/raylib/raylib_loader.rb
|
85
89
|
- lib/rubyboy/registers.rb
|
86
90
|
- lib/rubyboy/rom.rb
|
91
|
+
- lib/rubyboy/sdl.rb
|
87
92
|
- lib/rubyboy/timer.rb
|
88
93
|
- lib/rubyboy/version.rb
|
94
|
+
- resource/logo/logo.png
|
95
|
+
- resource/logo/logo.svg
|
89
96
|
- sig/rubyboy.rbs
|
90
97
|
homepage: https://github.com/sacckey/rubyboy
|
91
98
|
licenses:
|