BydoEmpire Posted March 20, 2022 Share Posted March 20, 2022 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. Bank1_MainLoop_Control rem ** control and input gosub Bank1_MovePlayer Bank1_MainLoop_Draw 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): Bank2_DrawScreen rem ** restore background first restorescreen rem ** draw bank-specific sprites gosub Bank2_DrawEnemies bank2 rem ** draw general graphics (Bank16) gosub Bank16_DrawHero gosub Bank16_DrawStatus drawscreen return 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. 2 Quote Link to comment Share on other sites More sharing options...
+SmittyB Posted March 20, 2022 Share Posted March 20, 2022 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. 3 Quote Link to comment Share on other sites More sharing options...
Revontuli Posted March 21, 2022 Share Posted March 21, 2022 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 Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 21, 2022 Share Posted March 21, 2022 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. 1 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.