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.
@@ -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