rubyboy 1.0.0 → 1.1.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 +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
|