rubyboy 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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].zero?
17
- res &= @action if @mode[5].zero?
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]].zero?
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]].zero?
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(@lcdc[LCDC[:bg_tile_map_area]], x, y)
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]].zero? || @lcdc[LCDC[:window_enable]].zero? || @ly < @wy
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(@lcdc[LCDC[:window_tile_map_area]], x, y)
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]].zero?
225
+ return if @lcdc[LCDC[:sprite_enable]] == 0
222
226
 
223
- sprite_height = @lcdc[LCDC[:sprite_size]].zero? ? 8 : 16
227
+ sprite_height = @lcdc[LCDC[:sprite_size]] == 0 ? 8 : 16
224
228
  sprites = []
225
229
  cnt = 0
226
- @oam.each_slice(4).each do |sprite_attr|
227
- sprite = {
228
- y: (sprite_attr[0] - 16) % 256,
229
- x: (sprite_attr[1] - 8) % 256,
230
- tile_index: sprite_attr[2],
231
- flags: sprite_attr[3]
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]].zero? ? @obp0 : @obp1
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.zero? || i >= LCD_WIDTH
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(tile_map_area, x, y)
268
- tile_map_addr = tile_map_area.zero? ? 0x1800 : 0x1c00
269
- tile_map_index = (y / 8) * 32 + (x / 8)
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, x, y)
275
- @vram[tile_index * 16 + (y % 8) * 2][7 - (x % 8)] + (@vram[tile_index * 16 + (y % 8) * 2 + 1][7 - (x % 8)] << 1)
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
@@ -19,7 +19,7 @@ module Rubyboy
19
19
  @div += after_cycles / 256 - before_cycles / 256
20
20
  @div &= 0xffff
21
21
 
22
- return if @tac[2].zero?
22
+ return if @tac[2] == 0
23
23
 
24
24
  divider = case @tac & 0b11
25
25
  when 0b00 then 1024
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubyboy
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
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.0.0
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-03 00:00:00.000000000 Z
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.4.10
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