rubyboy 1.0.0 → 1.1.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/.rubocop.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/exe/rubyboy +12 -2
- data/lib/bench.rb +26 -0
- data/lib/rubyboy/cartridge/mbc1.rb +1 -1
- data/lib/rubyboy/cpu.rb +517 -517
- data/lib/rubyboy/joypad.rb +2 -2
- data/lib/rubyboy/ppu.rb +28 -29
- data/lib/rubyboy/timer.rb +1 -1
- data/lib/rubyboy/version.rb +1 -1
- data/lib/rubyboy.rb +15 -0
- metadata +4 -3
data/lib/rubyboy/joypad.rb
CHANGED
@@ -13,8 +13,8 @@ module Rubyboy
|
|
13
13
|
raise "not implemented: write_byte #{addr}" unless addr == 0xff00
|
14
14
|
|
15
15
|
res = @mode | 0xcf
|
16
|
-
res &= @direction if @mode[4]
|
17
|
-
res &= @action if @mode[5]
|
16
|
+
res &= @direction if @mode[4] == 0
|
17
|
+
res &= @action if @mode[5] == 0
|
18
18
|
|
19
19
|
res
|
20
20
|
end
|
data/lib/rubyboy/ppu.rb
CHANGED
@@ -131,7 +131,7 @@ module Rubyboy
|
|
131
131
|
end
|
132
132
|
|
133
133
|
def step(cycles)
|
134
|
-
return false if @lcdc[LCDC[:lcd_ppu_enable]]
|
134
|
+
return false if @lcdc[LCDC[:lcd_ppu_enable]] == 0
|
135
135
|
|
136
136
|
res = false
|
137
137
|
@cycles += cycles
|
@@ -187,30 +187,34 @@ module Rubyboy
|
|
187
187
|
end
|
188
188
|
|
189
189
|
def render_bg
|
190
|
-
return if @lcdc[LCDC[:bg_window_enable]]
|
190
|
+
return if @lcdc[LCDC[:bg_window_enable]] == 0
|
191
191
|
|
192
192
|
y = (@ly + @scy) % 256
|
193
|
+
tile_map_addr = @lcdc[LCDC[:bg_tile_map_area]] == 0 ? 0x1800 : 0x1c00
|
194
|
+
tile_map_addr += (y / 8) * 32
|
193
195
|
LCD_WIDTH.times do |i|
|
194
196
|
x = (i + @scx) % 256
|
195
|
-
tile_index = get_tile_index(
|
196
|
-
pixel = get_pixel(tile_index, x, y)
|
197
|
+
tile_index = get_tile_index(tile_map_addr + (x / 8))
|
198
|
+
pixel = get_pixel(tile_index << 4, 7 - (x % 8), (y % 8) * 2)
|
197
199
|
@buffer[@ly * LCD_WIDTH + i] = get_color(@bgp, pixel)
|
198
200
|
@bg_pixels[i] = pixel
|
199
201
|
end
|
200
202
|
end
|
201
203
|
|
202
204
|
def render_window
|
203
|
-
return if @lcdc[LCDC[:bg_window_enable]]
|
205
|
+
return if @lcdc[LCDC[:bg_window_enable]] == 0 || @lcdc[LCDC[:window_enable]] == 0 || @ly < @wy
|
204
206
|
|
205
207
|
rendered = false
|
206
208
|
y = @wly
|
209
|
+
tile_map_addr = @lcdc[LCDC[:window_tile_map_area]] == 0 ? 0x1800 : 0x1c00
|
210
|
+
tile_map_addr += (y / 8) * 32
|
207
211
|
LCD_WIDTH.times do |i|
|
208
212
|
next if i < @wx - 7
|
209
213
|
|
210
214
|
rendered = true
|
211
215
|
x = i - (@wx - 7)
|
212
|
-
tile_index = get_tile_index(
|
213
|
-
pixel = get_pixel(tile_index, x, y)
|
216
|
+
tile_index = get_tile_index(tile_map_addr + (x / 8))
|
217
|
+
pixel = get_pixel(tile_index << 4, 7 - (x % 8), (y % 8) * 2)
|
214
218
|
@buffer[@ly * LCD_WIDTH + i] = get_color(@bgp, pixel)
|
215
219
|
@bg_pixels[i] = pixel
|
216
220
|
end
|
@@ -218,21 +222,18 @@ module Rubyboy
|
|
218
222
|
end
|
219
223
|
|
220
224
|
def render_sprites
|
221
|
-
return if @lcdc[LCDC[:sprite_enable]]
|
225
|
+
return if @lcdc[LCDC[:sprite_enable]] == 0
|
222
226
|
|
223
|
-
sprite_height = @lcdc[LCDC[:sprite_size]]
|
227
|
+
sprite_height = @lcdc[LCDC[:sprite_size]] == 0 ? 8 : 16
|
224
228
|
sprites = []
|
225
229
|
cnt = 0
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
}
|
233
|
-
next if sprite[:y] > @ly || sprite[:y] + sprite_height <= @ly
|
234
|
-
|
235
|
-
sprites << sprite
|
230
|
+
|
231
|
+
@oam.each_slice(4) do |y, x, tile_index, flags|
|
232
|
+
y = (y - 16) % 256
|
233
|
+
x = (x - 8) % 256
|
234
|
+
next if y > @ly || y + sprite_height <= @ly
|
235
|
+
|
236
|
+
sprites << { y:, x:, tile_index:, flags: }
|
236
237
|
cnt += 1
|
237
238
|
break if cnt == 10
|
238
239
|
end
|
@@ -240,7 +241,7 @@ module Rubyboy
|
|
240
241
|
|
241
242
|
sprites.each do |sprite|
|
242
243
|
flags = sprite[:flags]
|
243
|
-
pallet = flags[SPRITE_FLAGS[:dmg_palette]]
|
244
|
+
pallet = flags[SPRITE_FLAGS[:dmg_palette]] == 0 ? @obp0 : @obp1
|
244
245
|
tile_index = sprite[:tile_index]
|
245
246
|
tile_index &= 0xfe if sprite_height == 16
|
246
247
|
y = (@ly - sprite[:y]) % 256
|
@@ -251,10 +252,10 @@ module Rubyboy
|
|
251
252
|
8.times do |x|
|
252
253
|
x_flipped = flags[SPRITE_FLAGS[:x_flip]] == 1 ? 7 - x : x
|
253
254
|
|
254
|
-
pixel = get_pixel(tile_index, x_flipped, y)
|
255
|
+
pixel = get_pixel(tile_index << 4, 7 - x_flipped, (y % 8) * 2)
|
255
256
|
i = (sprite[:x] + x) % 256
|
256
257
|
|
257
|
-
next if pixel
|
258
|
+
next if pixel == 0 || i >= LCD_WIDTH
|
258
259
|
next if flags[SPRITE_FLAGS[:priority]] == 1 && @bg_pixels[i] != 0
|
259
260
|
|
260
261
|
@buffer[@ly * LCD_WIDTH + i] = get_color(pallet, pixel)
|
@@ -264,15 +265,13 @@ module Rubyboy
|
|
264
265
|
|
265
266
|
private
|
266
267
|
|
267
|
-
def get_tile_index(
|
268
|
-
|
269
|
-
|
270
|
-
tile_index = @vram[tile_map_addr + tile_map_index]
|
271
|
-
@lcdc[LCDC[:bg_window_tile_data_area]].zero? ? to_signed_byte(tile_index) + 256 : tile_index
|
268
|
+
def get_tile_index(tile_map_addr)
|
269
|
+
tile_index = @vram[tile_map_addr]
|
270
|
+
@lcdc[LCDC[:bg_window_tile_data_area]] == 0 ? to_signed_byte(tile_index) + 256 : tile_index
|
272
271
|
end
|
273
272
|
|
274
|
-
def get_pixel(tile_index,
|
275
|
-
@vram[tile_index
|
273
|
+
def get_pixel(tile_index, c, r)
|
274
|
+
@vram[tile_index + r][c] + (@vram[tile_index + r + 1][c] << 1)
|
276
275
|
end
|
277
276
|
|
278
277
|
def get_color(pallet, pixel)
|
data/lib/rubyboy/timer.rb
CHANGED
data/lib/rubyboy/version.rb
CHANGED
data/lib/rubyboy.rb
CHANGED
@@ -42,6 +42,21 @@ module Rubyboy
|
|
42
42
|
raise e
|
43
43
|
end
|
44
44
|
|
45
|
+
def bench
|
46
|
+
cnt = 0
|
47
|
+
start_time = Time.now
|
48
|
+
while cnt < 1500
|
49
|
+
cycles = @cpu.exec
|
50
|
+
@timer.step(cycles)
|
51
|
+
if @ppu.step(cycles)
|
52
|
+
key_input_check
|
53
|
+
cnt += 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
Time.now - start_time
|
58
|
+
end
|
59
|
+
|
45
60
|
private
|
46
61
|
|
47
62
|
def draw
|
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.
|
4
|
+
version: 1.1.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-12-
|
11
|
+
date: 2023-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: raylib-bindings
|
@@ -39,6 +39,7 @@ files:
|
|
39
39
|
- README.md
|
40
40
|
- Rakefile
|
41
41
|
- exe/rubyboy
|
42
|
+
- lib/bench.rb
|
42
43
|
- lib/opcodes.json
|
43
44
|
- lib/roms/bgbtest.gb
|
44
45
|
- lib/roms/cpu_instrs/cpu_instrs.gb
|
@@ -110,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
111
|
- !ruby/object:Gem::Version
|
111
112
|
version: '0'
|
112
113
|
requirements: []
|
113
|
-
rubygems_version: 3.
|
114
|
+
rubygems_version: 3.5.3
|
114
115
|
signing_key:
|
115
116
|
specification_version: 4
|
116
117
|
summary: A Game Boy emulator written in Ruby
|