Jump to content

Metasprite and Bank Swapping Bugs


Dullahan Software

283 views

Veil engine animating race car metasprites.

Fixed 2 bugs in the veil engine today. Neither were apparent til I tried to use the veil engine on a project other than Janus. The first bug was in the metasprite module's initialization subroutine and it manifested by crashing the game when no metasprites were in a scene. Here is a snippet containing the issue:

INVALID_METASPRITE_CHR_BANK = 255

.export __metasprites_init
.proc __metasprites_init
  lda #0
  sta updown_flag
  sta oam_spr_ptr

  lda #INVALID_METASPRITE_CHR_BNK
  sta __metasprites_chr_banks
  sta __metasprites_chr_banks + 1
  sta __metasprites_chr_banks + 2
  sta __metasprites_chr_banks + 3

  tay

  loop:
  sta current_animation_his, y

The issue above is that the loop towards the bottom of the code snippet expected the Y register to be 0 not 255. So moving the clearing of the updown_flag variable right before the TAY resolved this issue:

lda #0
sta updown_flag
sta oam_spr_ptr
tay

loop:
sta current_animation_his, y

The second bug showed up after I integrated some car assets for a racing game. Once I had added the sprites and animations I decided to see how they looked rendered in an emulator with my current OAM cycling algorithm. Having so many metasprites on the screen at once reliably triggered this bug after 20 seconds or so causing the game to crash and generate a core dump. The dump flagged the crash as an invalid veil lang code which is the veil engines scripting language. Here is a video of the OAM cycling in action:

The origin of this bug was me forgetting to restore the necessary PRG banks after the NMI completed. The sound driver which is updated at the end of the NMI needs to be bank-swapped in as well as whatever song and SFX are currently playing. So if the NMI interrupted game logic after that logic had already banked in what it needed, then we ran into problems. Reliably the NMI was interrupting while the game was interpreting scripts. Music data was loaded in where the game scripts should have been and the scripting engine therefore was trying to execute music data rather than a valid script and therefore the crash and core dump with the invalid veil lang code.

The fix was to create 2 variables to hold shadow bank values. Then set these shadow values whenever we banked so the music driver could restore banks in the NMI. Like this:
 

.proc __snd_update
  ; TODO: depending on track will be different
  lda #4
  sta registers::VRC6_8K_PRG_R0

  lda #1
  sta registers::VRC6_16K_PRG_R0

  soundengine_update

  ; fall thru
  ;jmp clean_up
.endproc

.proc clean_up
  ; restore banks
  lda registers::shadow_prg_16k
  sta registers::VRC6_16K_PRG_R0

  lda registers::shadow_prg_8k
  sta registers::VRC6_8K_PRG_R0

  rts
.endproc

Next, entry I will likely be back working on the static HUD for vertical scenes.

-c

0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...