Class: Amaterasu::GameBoy::Vram::TileMap

Inherits:
Object
  • Object
show all
Defined in:
lib/amaterasu/game_boy/vram/tile_map.rb

Overview

Models the Tile Map that live in VRAM.

  • Each Tile Map is a 32 x 32 grid of Tile indices.

  • Each Tile index is exactly 1 byte.

  • So each Tile Map has exactly 32 * 32 * 1 = 1024 bytes (1 KiB).

Grid representation in 2 dimensions, each (X, Y) pair -> 1 byte:

          X = 0       X = 1      X = 2          X = 31

Y = 0     (0, 0)     (1, 0)     (2, 0)    ...  (31, 0)   <- Row 0

Y = 1     (0, 1)     (1, 1)     (2, 1)    ...  (31, 1)   <- Row 1

Y = 2     (0, 2)     (1, 2)     (2, 2)    ...  (31, 2)   <- Row 2

 ...       ...         ...        ...            ...         ...

Y = 31    (0, 31)    (1, 31)    (2, 31)   ...  (31, 31)  <- Row 31

             ↑         ↑        ↑              ↑

          Column 0   Column 1   Column 2  ...  Column 31

Constant Summary collapse

GRID_WIDTH =

Total number of columns in the grid.

32
GRID_HEIGHT =

Total number of rows in the grid.

32
BIT_MASK_WRAP_VALUE =

Mask to keep values between 0 and 31.

0x1F

Instance Method Summary collapse

Constructor Details

#initialize(vram_data:, base_offset:) ⇒ TileMap

Returns a new instance of TileMap.

Parameters:

  • vram_data (Array)

    Reference to the original VRAM data.

  • base_offset (Integer)

    Tile map start address within the VRAM data.



42
43
44
45
# File 'lib/amaterasu/game_boy/vram/tile_map.rb', line 42

def initialize(vram_data:, base_offset:)
  @vram_data   = vram_data
  @base_offset = base_offset
end

Instance Method Details

#tile_index_at(tile_x:, tile_y:) ⇒ Integer

Fetches a Tile index from the Tile Map at a given (X, Y) position.

Before looking up in which column or row the Tile index is, we need to wrap the values around 32 (0x1F).

Since the Memory is a flat array (single dimension) we need to offset the given Y value by the Grid WIDTH to “jump over” the rows in between and reach the correct row.

Parameters:

  • tile_x (Integer)

    Which column in the grid.

  • tile_y (Integer)

    Which row in the grid.

Returns:

  • (Integer)

    1 byte representing the Tile index at the given (X, Y).



59
60
61
62
63
64
65
66
67
# File 'lib/amaterasu/game_boy/vram/tile_map.rb', line 59

def tile_index_at(tile_x:, tile_y:)
  grid_row    = tile_y & BIT_MASK_WRAP_VALUE
  grid_column = tile_x & BIT_MASK_WRAP_VALUE

  tile_index_row    = grid_row * GRID_WIDTH
  tile_index_column = grid_column

  @vram_data[@base_offset + tile_index_row + tile_index_column]
end