rubyboy 0.3.0 → 0.4.0
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/rubyboy/bus.rb +4 -5
- data/lib/rubyboy/cpu.rb +2 -2
- data/lib/rubyboy/joypad.rb +41 -0
- data/lib/rubyboy/lcd.rb +0 -20
- data/lib/rubyboy/ppu.rb +4 -1
- data/lib/rubyboy/version.rb +1 -1
- data/lib/rubyboy.rb +35 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a90f9cbc5a0ac4a9f9b971f0c4454421dc83ae9686222c275679f173e7503232
|
4
|
+
data.tar.gz: 52833516da6531982602c373acb11a74d292db6221b8ad34d4420a94be7fe017
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef45830027a11b9827e8660bef2fbb45a5a0fc867486aef58ece8a930acae959eb66ac5709d425e8562d1a546608cbb4cce040efc9e17940b627dfc9095c4a7b
|
7
|
+
data.tar.gz: d8564cc7f5c66dbce015fead7ff770527736943e9c1de3858ed813c1cc012c1e9c5b9248010d16ee39a5fa668e720eb9cda93443b2097260b3b24688b9acdd42
|
data/CHANGELOG.md
CHANGED
data/lib/rubyboy/bus.rb
CHANGED
@@ -8,11 +8,12 @@ module Rubyboy
|
|
8
8
|
class Bus
|
9
9
|
attr_accessor :ppu, :rom, :interrupt
|
10
10
|
|
11
|
-
def initialize(ppu, rom, timer, interrupt)
|
11
|
+
def initialize(ppu, rom, timer, interrupt, joypad)
|
12
12
|
@ppu = ppu
|
13
13
|
@rom = rom
|
14
14
|
@ram = Ram.new
|
15
15
|
@mbc = Cartridge::Factory.create(rom, @ram)
|
16
|
+
@joypad = joypad
|
16
17
|
|
17
18
|
@interrupt = interrupt
|
18
19
|
@timer = timer
|
@@ -42,8 +43,7 @@ module Rubyboy
|
|
42
43
|
# unused
|
43
44
|
0xff
|
44
45
|
when 0xff00
|
45
|
-
|
46
|
-
@tmp[addr] ||= 0
|
46
|
+
@joypad.read_byte(addr)
|
47
47
|
when 0xff01..0xff02
|
48
48
|
# serial
|
49
49
|
@tmp[addr] ||= 0
|
@@ -102,8 +102,7 @@ module Rubyboy
|
|
102
102
|
when 0xfea0..0xfeff
|
103
103
|
# unused
|
104
104
|
when 0xff00
|
105
|
-
|
106
|
-
@tmp[addr] = value
|
105
|
+
@joypad.write_byte(addr, value)
|
107
106
|
when 0xff01..0xff02
|
108
107
|
# serial
|
109
108
|
@tmp[addr] = value
|
data/lib/rubyboy/cpu.rb
CHANGED
@@ -85,12 +85,12 @@ module Rubyboy
|
|
85
85
|
|
86
86
|
@bus.interrupt.if &= (~(1 << i)) & 0xff
|
87
87
|
@ime = false
|
88
|
-
@bus.write_word(@sp - 2, @pc)
|
89
88
|
@sp -= 2
|
89
|
+
@bus.write_word(@sp, @pc)
|
90
90
|
@pc = pcs[i]
|
91
|
-
opcode = read_byte(@pc)
|
92
91
|
break
|
93
92
|
end
|
93
|
+
return 20
|
94
94
|
end
|
95
95
|
|
96
96
|
if @ime_delay
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubyboy
|
4
|
+
class Joypad
|
5
|
+
def initialize(interupt)
|
6
|
+
@mode = 0xcf
|
7
|
+
@action = 0xff
|
8
|
+
@direction = 0xff
|
9
|
+
@interupt = interupt
|
10
|
+
end
|
11
|
+
|
12
|
+
def read_byte(addr)
|
13
|
+
raise "not implemented: write_byte #{addr}" unless addr == 0xff00
|
14
|
+
|
15
|
+
res = @mode | 0xcf
|
16
|
+
res &= @direction if @mode[4].zero?
|
17
|
+
res &= @action if @mode[5].zero?
|
18
|
+
|
19
|
+
res
|
20
|
+
end
|
21
|
+
|
22
|
+
def write_byte(addr, value)
|
23
|
+
raise "not implemented: write_byte #{addr}" unless addr == 0xff00
|
24
|
+
|
25
|
+
@mode = value & 0x30
|
26
|
+
@mode |= 0xc0
|
27
|
+
end
|
28
|
+
|
29
|
+
def direction_button(button)
|
30
|
+
@direction = button | 0xf0
|
31
|
+
|
32
|
+
@interupt.request(0b0001_0000) if button < 0b1111
|
33
|
+
end
|
34
|
+
|
35
|
+
def action_button(button)
|
36
|
+
@action = button | 0xf0
|
37
|
+
|
38
|
+
@interupt.request(0b0001_0000) if button < 0b1111
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/rubyboy/lcd.rb
CHANGED
@@ -11,7 +11,6 @@ module Rubyboy
|
|
11
11
|
SCALE = 4
|
12
12
|
|
13
13
|
def initialize
|
14
|
-
load_raylib
|
15
14
|
InitWindow(WIDTH * SCALE, HEIGHT * SCALE, 'RUBY BOY')
|
16
15
|
image = GenImageColor(WIDTH, HEIGHT, BLACK)
|
17
16
|
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8
|
@@ -34,24 +33,5 @@ module Rubyboy
|
|
34
33
|
def close_window
|
35
34
|
CloseWindow()
|
36
35
|
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def load_raylib
|
41
|
-
shared_lib_path = "#{Gem::Specification.find_by_name('raylib-bindings').full_gem_path}/lib/"
|
42
|
-
case RUBY_PLATFORM
|
43
|
-
when /mswin|msys|mingw/ # Windows
|
44
|
-
Raylib.load_lib("#{shared_lib_path}libraylib.dll")
|
45
|
-
when /darwin/ # macOS
|
46
|
-
Raylib.load_lib("#{shared_lib_path}libraylib.dylib")
|
47
|
-
when /linux/ # Ubuntu Linux (x86_64 or aarch64)
|
48
|
-
arch = RUBY_PLATFORM.split('-')[0]
|
49
|
-
Raylib.load_lib(shared_lib_path + "libraylib.#{arch}.so")
|
50
|
-
else
|
51
|
-
raise "Unknown system: #{RUBY_PLATFORM}"
|
52
|
-
end
|
53
|
-
|
54
|
-
SetTraceLogLevel(LOG_ERROR)
|
55
|
-
end
|
56
36
|
end
|
57
37
|
end
|
data/lib/rubyboy/ppu.rb
CHANGED
@@ -38,6 +38,7 @@ module Rubyboy
|
|
38
38
|
@cycles = 0
|
39
39
|
@interrupt = interrupt
|
40
40
|
@buffer = Array.new(144 * 160, 0x00)
|
41
|
+
@bg_pixels = Array.new(LCD_WIDTH, 0x00)
|
41
42
|
end
|
42
43
|
|
43
44
|
def read_byte(addr)
|
@@ -169,6 +170,7 @@ module Rubyboy
|
|
169
170
|
tile_index = get_tile_index(@lcdc[3], x, y)
|
170
171
|
pixel = get_pixel(tile_index, x, y)
|
171
172
|
@buffer[@ly * LCD_WIDTH + i] = get_color(@bgp, pixel)
|
173
|
+
@bg_pixels[i] = pixel
|
172
174
|
end
|
173
175
|
end
|
174
176
|
|
@@ -185,6 +187,7 @@ module Rubyboy
|
|
185
187
|
tile_index = get_tile_index(@lcdc[6], x, y)
|
186
188
|
pixel = get_pixel(tile_index, x, y)
|
187
189
|
@buffer[@ly * LCD_WIDTH + i] = get_color(@bgp, pixel)
|
190
|
+
@bg_pixels[i] = pixel
|
188
191
|
end
|
189
192
|
@wly += 1 if rendered
|
190
193
|
end
|
@@ -223,7 +226,7 @@ module Rubyboy
|
|
223
226
|
i = (sprite[:x] + x) % 256
|
224
227
|
|
225
228
|
next if pixel.zero? || i >= LCD_WIDTH
|
226
|
-
next if sprite[:flags][7] == 1 && @
|
229
|
+
next if sprite[:flags][7] == 1 && @bg_pixels[i] != 0
|
227
230
|
|
228
231
|
@buffer[@ly * LCD_WIDTH + i] = get_color(pallet, pixel)
|
229
232
|
end
|
data/lib/rubyboy/version.rb
CHANGED
data/lib/rubyboy.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'raylib'
|
3
4
|
require 'benchmark'
|
4
5
|
require_relative 'rubyboy/version'
|
5
6
|
require_relative 'rubyboy/bus'
|
@@ -8,21 +9,27 @@ require_relative 'rubyboy/ppu'
|
|
8
9
|
require_relative 'rubyboy/rom'
|
9
10
|
require_relative 'rubyboy/timer'
|
10
11
|
require_relative 'rubyboy/lcd'
|
12
|
+
require_relative 'rubyboy/joypad'
|
11
13
|
|
12
14
|
module Rubyboy
|
13
15
|
class Console
|
16
|
+
include Raylib
|
17
|
+
|
14
18
|
def initialize(rom_data)
|
19
|
+
load_raylib
|
15
20
|
rom = Rom.new(rom_data)
|
16
21
|
interrupt = Interrupt.new
|
17
22
|
@ppu = Ppu.new(interrupt)
|
18
23
|
@timer = Timer.new(interrupt)
|
19
|
-
@
|
24
|
+
@joypad = Joypad.new(interrupt)
|
25
|
+
@bus = Bus.new(@ppu, rom, @timer, interrupt, @joypad)
|
20
26
|
@cpu = Cpu.new(@bus)
|
21
27
|
@lcd = Lcd.new
|
22
28
|
end
|
23
29
|
|
24
30
|
def start
|
25
31
|
until @lcd.window_should_close?
|
32
|
+
key_input_check
|
26
33
|
cycles = @cpu.exec
|
27
34
|
@timer.step(cycles)
|
28
35
|
draw if @ppu.step(cycles)
|
@@ -33,6 +40,8 @@ module Rubyboy
|
|
33
40
|
raise e
|
34
41
|
end
|
35
42
|
|
43
|
+
private
|
44
|
+
|
36
45
|
def draw
|
37
46
|
pixel_data = buffer_to_pixel_data(@ppu.buffer)
|
38
47
|
@lcd.draw(pixel_data)
|
@@ -43,8 +52,32 @@ module Rubyboy
|
|
43
52
|
[row, row, row]
|
44
53
|
end.flatten.pack('C*')
|
45
54
|
end
|
55
|
+
|
56
|
+
def key_input_check
|
57
|
+
direction = (IsKeyUp(KEY_D) && 1 || 0) | ((IsKeyUp(KEY_A) && 1 || 0) << 1) | ((IsKeyUp(KEY_W) && 1 || 0) << 2) | ((IsKeyUp(KEY_S) && 1 || 0) << 3)
|
58
|
+
action = (IsKeyUp(KEY_K) && 1 || 0) | ((IsKeyUp(KEY_J) && 1 || 0) << 1) | ((IsKeyUp(KEY_U) && 1 || 0) << 2) | ((IsKeyUp(KEY_I) && 1 || 0) << 3)
|
59
|
+
@joypad.direction_button(direction)
|
60
|
+
@joypad.action_button(action)
|
61
|
+
end
|
62
|
+
|
63
|
+
def load_raylib
|
64
|
+
shared_lib_path = "#{Gem::Specification.find_by_name('raylib-bindings').full_gem_path}/lib/"
|
65
|
+
case RUBY_PLATFORM
|
66
|
+
when /mswin|msys|mingw/ # Windows
|
67
|
+
Raylib.load_lib("#{shared_lib_path}libraylib.dll")
|
68
|
+
when /darwin/ # macOS
|
69
|
+
Raylib.load_lib("#{shared_lib_path}libraylib.dylib")
|
70
|
+
when /linux/ # Ubuntu Linux (x86_64 or aarch64)
|
71
|
+
arch = RUBY_PLATFORM.split('-')[0]
|
72
|
+
Raylib.load_lib(shared_lib_path + "libraylib.#{arch}.so")
|
73
|
+
else
|
74
|
+
raise "Unknown system: #{RUBY_PLATFORM}"
|
75
|
+
end
|
76
|
+
|
77
|
+
SetTraceLogLevel(LOG_ERROR)
|
78
|
+
end
|
46
79
|
end
|
47
80
|
end
|
48
81
|
|
49
|
-
rom_data = File.open(File.expand_path('roms/
|
82
|
+
rom_data = File.open(File.expand_path('roms/bgbtest.gb', __dir__), 'r') { _1.read.bytes }
|
50
83
|
Rubyboy::Console.new(rom_data).start
|
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: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sacckey
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: raylib-bindings
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- lib/rubyboy/cartridge/nombc.rb
|
65
65
|
- lib/rubyboy/cpu.rb
|
66
66
|
- lib/rubyboy/interrupt.rb
|
67
|
+
- lib/rubyboy/joypad.rb
|
67
68
|
- lib/rubyboy/lcd.rb
|
68
69
|
- lib/rubyboy/ppu.rb
|
69
70
|
- lib/rubyboy/ram.rb
|