Class: Amaterasu::GameBoy::Ppu::Modes::Rendering

Inherits:
Object
  • Object
show all
Defined in:
lib/amaterasu/game_boy/ppu/modes/rendering.rb,
lib/amaterasu/game_boy/ppu/modes/rendering/pixel_fifo.rb,
lib/amaterasu/game_boy/ppu/modes/rendering/pixel_emitter.rb,
lib/amaterasu/game_boy/ppu/modes/rendering/bg_win_fetcher.rb,
lib/amaterasu/game_boy/ppu/modes/rendering/sprite_fetcher.rb

Overview

Defines the behavior of the PPU during Rendering mode.

The Rendering mode does not have a fixed duration, it can vary between 172 and 289 dots.

This mode can be considered completed when 160 pixels are outputted to the LCD. Normally, the PPU can output a pixel per dot, but this is not always the case, there are several scenarios in which “penalties” occur and this causes the mode to take longer.

Defined Under Namespace

Classes: BgWinFetcher, PixelEmitter, PixelFifo, SpriteFetcher

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ppu) ⇒ Rendering

Returns a new instance of Rendering.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/amaterasu/game_boy/ppu/modes/rendering.rb', line 20

def initialize(ppu)
  @ppu = ppu

  @name = 'RENDERING'
  @number = 3

  @bg_win_fifo    = PixelFifo.new
  @sprite_fifo    = PixelFifo.new
  @bg_win_fetcher = BgWinFetcher.new(ppu, @bg_win_fifo)
  @sprite_fetcher = SpriteFetcher.new(ppu, @sprite_fifo)
  @pixel_emitter  = PixelEmitter.new(ppu, @bg_win_fifo, @sprite_fifo)

  @sprite_found = nil
  @mode = :fetch_bg
  @lcd_x = 0
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



18
19
20
# File 'lib/amaterasu/game_boy/ppu/modes/rendering.rb', line 18

def name
  @name
end

#numberObject (readonly)

Returns the value of attribute number.



18
19
20
# File 'lib/amaterasu/game_boy/ppu/modes/rendering.rb', line 18

def number
  @number
end

Instance Method Details

#inspectObject



63
64
65
66
67
# File 'lib/amaterasu/game_boy/ppu/modes/rendering.rb', line 63

def inspect
  '#<Amaterasu::GameBoy::Ppu::Modes::Rendering ' \
    "@name='#{@name}' " \
    "@number=#{@number} "
end

#tickObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/amaterasu/game_boy/ppu/modes/rendering.rb', line 37

def tick
  if any_sprites? && @mode != :fetch_sprite
    @mode = :fetch_sprite
    @sprite_found = @ppu.sprite_buffer.shift
    @sprite_fetcher.start_for(@sprite_found) unless sprite_offscreen?(@sprite_found)
  elsif @mode == :fetch_sprite
    @sprite_fetcher.tick
    @mode = :fetch_bg if @sprite_fetcher.done?
  else
    @bg_win_fetcher.activate_window! if window_reached?

    @bg_win_fetcher.tick
    pixel_drawn = @pixel_emitter.tick?
  end

  @lcd_x += 1 if pixel_drawn
  return unless @lcd_x == PIXELS_PER_SCANLINE && @bg_win_fetcher.step == :sleep

  @bg_win_fetcher.reset_for_scanline
  @pixel_emitter.reset_for_scanline
  @lcd_x = 0
  @sprite_fifo.clear
  @bg_win_fifo.clear
  @ppu.set_mode(:h_blank)
end

#to_sObject



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/amaterasu/game_boy/ppu/modes/rendering.rb', line 69

def to_s
  if @mode == :fetch_bg
    "#{@name} (##{@number}) | " \
      "LCD X: #{@lcd_x} | " \
      "#{@bg_win_fetcher} | " \
      "#{@pixel_emitter}"
  else
    "#{@name} (##{@number}) | " \
      "LCD X: #{@lcd_x} | " \
      "Sprite: #{@sprite_fetcher}"
  end
end