mvbg

VM_REPLACE_TILE

VM_REPLACE_TILE is a GBVM instruction used to replace a contiguous block of background tile definitions in VRAM with new tile data from a specified tileset.

Purpose: This instruction allows for dynamic and efficient updates to the graphical data of background tiles. Unlike VM_REPLACE_TILE_XY which changes a tile at a specific map coordinate, VM_REPLACE_TILE modifies the definition of the tiles themselves in VRAM. Any part of the background map that uses these modified tile IDs will then display the new graphics. This is essential for:

When VM_REPLACE_TILE is called, it copies LEN number of tiles from the source TILEDATA (starting at START_IDX) into VRAM, beginning at TARGET_TILE_IDX. Any background map that references these TARGET_TILE_IDX values will automatically update on screen.

Syntax:

VM_REPLACE_TILE TARGET_TILE_IDX, TILEDATA_BANK, TILEDATA, START_IDX, LEN

Usage Example: Animating a Water Tile

Imagine you have a water tile (e.g., tile ID 10) that you want to animate to show a gentle ripple effect. You have a small sequence of water animation frames (e.g., 3 frames) stored in a separate tileset.

; In your game loop or a dedicated animation script:

; Define the VRAM tile ID for the water animation (e.g., where the base water tile is)
WATER_TILE_VRAM_ID:
  .R_INT8 10 ; Example: VRAM tile ID 10 is our base water tile

; Define the animation frames for water (these would be in your assets)
TILESET_WATER_ANIM_BANK:
  .R_INT8 BANK(TILESET_WATER_ANIM)
TILESET_WATER_ANIM:
  ; Frame 0 of water animation
  .BYTE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  ; Frame 1 of water animation
  .BYTE 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
  ; Frame 2 of water animation
  .BYTE 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02

; Variable to track current animation frame
VAR_WATER_ANIM_FRAME:
  .R_INT8 0 ; Start at frame 0

; Variable for animation speed/timer
VAR_ANIM_TIMER:
  .R_INT8 0

ANIMATE_WATER_LOOP:
  ; Increment animation timer
  VM_RPN
    .R_REF_MEM .R_INT8, VAR_ANIM_TIMER
    .R_INT8 1
    .R_OPERATOR +
    .R_INT8
  VM_STOP
  VM_SET_INT8 VAR_ANIM_TIMER, 0

  ; Check if it's time to advance frame (e.g., every 15 frames)
  VM_IF_CONST .LT, VAR_ANIM_TIMER, 15, END_ANIM_UPDATE, 0

  ; Reset timer
  VM_SET_CONST VAR_ANIM_TIMER, 0

  ; Advance animation frame
  VM_RPN
    .R_REF_MEM .R_INT8, VAR_WATER_ANIM_FRAME
    .R_INT8 1
    .R_OPERATOR +
    .R_INT8
  VM_STOP
  VM_SET_INT8 VAR_WATER_ANIM_FRAME, 0

  ; Loop animation frames (0, 1, 2, then back to 0)
  VM_IF_CONST .EQ, VAR_WATER_ANIM_FRAME, 3, RESET_WATER_FRAME, 0
  VM_JUMP CONTINUE_WATER_ANIM

RESET_WATER_FRAME:
  VM_SET_CONST VAR_WATER_ANIM_FRAME, 0

CONTINUE_WATER_ANIM:
  ; Replace the VRAM tile at WATER_TILE_VRAM_ID with the current animation frame
  VM_REPLACE_TILE WATER_TILE_VRAM_ID, TILESET_WATER_ANIM_BANK, TILESET_WATER_ANIM, VAR_WATER_ANIM_FRAME, 1
  ; TARGET_TILE_IDX: WATER_TILE_VRAM_ID (e.g., 10)
  ; TILEDATA_BANK: TILESET_WATER_ANIM_BANK
  ; TILEDATA: TILESET_WATER_ANIM
  ; START_IDX: VAR_WATER_ANIM_FRAME (0, 1, or 2)
  ; LEN: 1 (replacing one tile at a time)

END_ANIM_UPDATE:
  VM_IDLE 1 ; Yield control for one frame
  VM_JUMP ANIMATE_WATER_LOOP

In this example, VM_REPLACE_TILE is used within a loop to continuously update the VRAM definition of WATER_TILE_VRAM_ID with different frames from TILESET_WATER_ANIM. This creates a smooth, looping animation for all water tiles on the background map that use WATER_TILE_VRAM_ID. The VAR_ANIM_TIMER controls the speed of the animation.

Analogy to other programming languages/game engines: This is analogous to dynamically updating a texture atlas or sprite sheet in graphics memory, or changing the definition of a tile in a tilemap system at runtime:

It provides a powerful way to create dynamic and animated backgrounds by directly manipulating the underlying tile graphics in VRAM.