Jump to content

Bankswitching backgrounds & drawwait


Recommended Posts

So just thinking out loud... I was  banging my head on the keyboard for a couple days on this bug, so even though I got it working (see below) I don't really understand why. When I moved my tilesets and room setup code into different banks for different levels I saw a bug where the top 12 pixels were cutoff:


when I moved the hero sprite around, even more pixels in the top rows of tiles were cutoff



bank1 - no gfx, just common setup & control code, MovePlayer, the main loop, etc

bank2 - tileset and sprites for a forest level

bank3 - tileset and sprites for a castle level


bank16 - the hero sprite, common background routines (poking chars into currentmapdata buffer), "default" tileset (in theory unused), fonts, etc


Then I realized maybe it's drawing those rows from bank 1, and sure enough I put a default tileset & fonts at the start of bank 1 (where the tilesets are inc'd for banks 2 & 3) and then I saw those bank1 tiles being drawn for the rows in question:




I supposed it makes sense that while you're moving the player around more code is being executed, so more rows from bank 1 are being drawn. I'm not sure why that is. I don't restore screen until after MovePlayer is complete, and the restore/draw calls are all (now) from within whatever bank is being used.


Seemed like I need some kind of wait before it actually draws the screen.


Here is the main loop, which is in bank 1.

    rem ** control and input
    gosub Bank1_MovePlayer


    rem ** draw level-specific sprites
    if cur_level=2 then gosub Bank2_DrawScreen bank2
    if cur_level=3 then gosub Bank3_DrawScreen bank3

    rem ** if we've moved to a new level, set that up and restart
    if goto_level <> cur_level then goto Bank1_InitNewLevel

    goto Bank1_MainLoop

And the screen drawing bank2 (bank3 has an equivalent):

    rem ** restore background first
    rem ** draw bank-specific sprites
    gosub Bank2_DrawEnemies bank2

    rem ** draw general graphics (Bank16)
    gosub Bank16_DrawHero
    gosub Bank16_DrawStatus



Sticking a drawwait after drawscreen fixed the bug, but not if I move the restorescreen & drawscreen back into the main loop where I originally had it. It only worked if I called restorescreen / drawscreen from bank 2 or 3.  I suppose it makes sense, is that expected?  Since I use plot* commands to draw sprites at the end of the frame, it seemed like that would be unnecessary. I don't really understand what it's doing. Happy the bug is fixed, but I don't like not really knowing why.  I think the real issue is that I don't quite understand what's being executed across the frame, and what overlaps with the actual drawing. It didn't matter in a 48k game...


Sorry for the rambling, I actually fixed (or worked around) the bug as I was iterating on this post.  It's helpful to try to explain it.


  • Like 2
Link to comment
Share on other sites

The drawscreen command finishes at near the top of the visible screen rather than the bottom meaning with the code you posted it would jump into bank 2, wait for the end of the visible display to run restorescreen, run your drawing subroutines, then wait until the start of the visible screen, at which point it then returns back to bank 1 before going through the motions and going back to bank 2 and waiting for restorescreen.


Essentially with that setup the more logic you have in bank 1 the longer it takes to get back to bank 2 where your graphics are.

Of course having a drawscreen command in bank 2 to wait around while the screen draws is one way to solve the problem as you found, but it also means wasting a lot of CPU time. Hopping back and forth between banks actually requires a small bit of setup that can easily add up as well so this looks like the kind of situation where you would be best off duplicating your code into each of your banks to do as much as you can without leaving the bank your graphics are in.

  • Like 3
Link to comment
Share on other sites

I'm curious how the drawscreen/drawwait tempo with the CPU changes (or doesn't) when one decides to use the double buffer.  My current multibank setup logic is something like this:


Bank 1 - Game Logic, no drawing but a lot of setting x and y of "sprites" to be drawn, goto Bank 2 at the end of calculations

Bank 2 - Actually Plot sprites/maps/etc. doublebuffer flip, goto Bank 1 after flipping (Bank2 also has 2 graphics blocks)



Bank 8 -(i.e. Shared Bank) with 1 graphic block


This setup gives me 3 full graphics blocks when I do want to draw something while having a lot of space for other code on a separate bank.  Performance seems ok (for now) and mentally it feels coherent, but if there's an order of operations that would make more sense in terms when the screen is drawn vs. when the CPU is active I would be keen to know :) 

Link to comment
Share on other sites

When using double-buffering, you don't technically use drawscreen, you use "doublebuffer flip". That said...


If you're using double-buffering, if you jump to another bank that doesn't contain graphics needed for the currently displayed screen, you'll still get a glitch. So if you're trying something like that, you'll either need to drawwait first before jumping away, or you'll need to duplicate all of the graphics needed in the various banks you'll be visiting.


  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...