Class: Amaterasu::GameBoy::Ppu::Modes::OamScan
- Inherits:
-
Object
- Object
- Amaterasu::GameBoy::Ppu::Modes::OamScan
- Defined in:
- lib/amaterasu/game_boy/ppu/modes/oam_scan.rb,
sig/akane/game_boy/ppu/modes/oam_scan.rbs
Overview
Defines the behavior of the PPU during OAM Scan mode.
Constant Summary collapse
- SCAN_DURATION_IN_DOTS =
Each Sprite takes 2 dots to scan.
80
Instance Attribute Summary collapse
-
#name ⇒ String
readonly
Returns the value of attribute name.
-
#number ⇒ Integer
readonly
Returns the value of attribute number.
Instance Method Summary collapse
-
#initialize(ppu) ⇒ OamScan
constructor
A new instance of OamScan.
-
#inspect ⇒ String
Custom inspect to prevent circular dependencies.
-
#sort_sprites_by_x_positions ⇒ void
TODO: benchmark the performance of both.
- #sprite_within_current_scanline? ⇒ Boolean
-
#tick ⇒ void
This method is called by the PPU each T-cycle for all visible scanlines (0 - 143) and when dots are between 0 and 79.
-
#to_s ⇒ String
Custom to_s method to use in the Ppu#log_state method.
- #window_triggered? ⇒ Boolean
Constructor Details
#initialize(ppu) ⇒ OamScan
Returns a new instance of OamScan.
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 15 def initialize(ppu) @ppu = ppu @name = 'OAM SCAN' @number = 2 @sprite_count = 0 @sprite_index = 0 @current_sprite = nil end |
Instance Attribute Details
#name ⇒ String (readonly)
Returns the value of attribute name.
12 13 14 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 12 def name @name end |
#number ⇒ Integer (readonly)
Returns the value of attribute number.
12 13 14 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 12 def number @number end |
Instance Method Details
#inspect ⇒ String
Custom inspect to prevent circular dependencies.
53 54 55 56 57 58 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 53 def inspect '#<Amaterasu::GameBoy::Ppu::Modes::OamScan ' \ "@name='#{@name}' " \ "@number=#{@number} " \ "@sprite_buffer=#{@sprite_buffer}" end |
#sort_sprites_by_x_positions ⇒ void
This method returns an undefined value.
TODO: benchmark the performance of both
85 86 87 88 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 85 def sort_sprites_by_x_positions @ppu.sprite_buffer.sort_by!(&:x) # @ppu.sprite_buffer.sort! { |a, b| a.x <=> b.x } end |
#sprite_within_current_scanline? ⇒ Boolean
77 78 79 80 81 82 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 77 def sprite_within_current_scanline? sprite_height = @ppu.registers.lcdc.obj_size_8x16? ? 16 : 8 @ppu.registers.ly >= @current_sprite.y_screen_pos && @ppu.registers.ly < @current_sprite.y_screen_pos + sprite_height end |
#tick ⇒ void
This method returns an undefined value.
This method is called by the PPU each T-cycle for all visible scanlines (0 - 143) and when dots are between 0 and 79.
Takes exactly 2 dots to fetch a sprite so every even dot (0, 2, 4, ..., 78) is a NO-OP.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 32 def tick if @ppu.dots.odd? @current_sprite = @ppu.fetch_sprite_at(@sprite_index) #=> 0 - 39 @sprite_index += 1 if sprite_within_current_scanline? && @sprite_count < Ppu::MAX_SPRITES_PER_SCANLINE @ppu.sprite_buffer << @current_sprite @sprite_count += 1 end end return unless @ppu.dots == SCAN_DURATION_IN_DOTS sort_sprites_by_x_positions unless @ppu.sprite_buffer.empty? @sprite_count = 0 @sprite_index = 0 @ppu.wy_eq_ly = true if window_triggered? @ppu.set_mode(:rendering) end |
#to_s ⇒ String
Custom to_s method to use in the Ppu#log_state method.
61 62 63 64 65 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 61 def to_s "#{@name} (##{@number}) | " \ "SCANNED: Sprite ##{format('%02d', @sprite_index)} | " \ "BUFFER: #{@ppu.sprite_buffer} (#{@ppu.sprite_buffer.size})" end |
#window_triggered? ⇒ Boolean
69 70 71 72 73 74 75 |
# File 'lib/amaterasu/game_boy/ppu/modes/oam_scan.rb', line 69 def window_triggered? return false unless @ppu.registers.lcdc.window_enabled? return false unless @ppu.registers.ly == @ppu.registers.wy return false if @ppu.wy_eq_ly true end |