| |
Taskmaster Account closed
Registered: May 2012 Posts: 12 |
Clearing bitmap screen quickly
I've begun tinkering with drawing software sprites to the bitmap screen and I'm already running into serious problem. Good ol' 64. Nice and challenging, just how I remember it.
At any rate, my thought was to take my PC mentality into the rendering here and clear the screen each frame and redraw all the graphics from scratch. This is proving a challenge because ... well, clearing the bitmap memory takes the entire screen refresh and THEN some. Makes for kind of a boring game.
Anyhoo, I tried several methods of loop unrolling and self modifying code but it's just too much. Always too slow.
So I started to think about maybe drawing back over the graphics I drew the last frame and turn those bits off before drawing the new frame. Essentially drawing the frame once so the player can see it, and then inverted to erase it when the time comes.
Is this the generally accepted method on the C=64? I'm running out of options here... |
|
| |
Codey
Registered: Oct 2005 Posts: 79 |
i would zero out any unique bytes that were previously written to only. this could possibly be pre-calculated if you know what you're plotting. keep everything unrolled of course. if u can't do it in a single frame, double buffering would work... |
| |
Angel of Death
Registered: Apr 2008 Posts: 211 |
Do you really need to redraw EVERY frame?
No idea what game you are making but 12 to 16 frames/second is generally accepted for a 'vector' game. Then double-buffering is the way to go. (even DOT.NET in Windows uses DB)
For redrawing parts of the screen or just updating seperate objects you could use a sort of partial clear. (with blocks of fixed size?)
If you want to scroll a hires screen then mostly a witches-brew of VSP and hardware-scroll is used, all or not combined with DB. (there should be some games on here showing an example) |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
You might want to check in the with Plus/4 coders at Plus/4 World since they have a lot of experience working with software sprites. And I assume you have a valid reason for not using char mode and a sprite multiplexer, which is how you typically move a lot of graphics around? If you share what you're trying to achieve it'd be easier to give good suggestions.
I've never implemented software sprites myself, but from what I've gleaned from others the two big cycle savers are keeping pre-rotated sprites in memory so you don't have to shift when blitting, and only erasing what you need to erase. |
| |
Skate
Registered: Jul 2003 Posts: 494 |
@Taskmaster: Yes, deleting only the drawn parts instead of the entire screen is a commonly used method on C64. But to achieve that, you have to slow down your drawing routine a little bit. So, if you draw only a few software sprites, you have a gain. But if you plan to draw a lot of them, covering a big part of the screen, a simple drawing routine with an unrolled clear screen code might be faster. So, the answer is "it depends".
If you believe cleaning the drawn parts would be faster, here is the fastest method i know.
clearScreen
sta $ffff
sta $ffff
sta $ffff
sta $ffff
sta $ffff
...
You need a lot of STAs prepared in your initialization routine. You set a pointer to clearScreen+1 address and when you set a byte on the bitmap screen, you write this byte's address as parameters of the STA opcode.
Next thing to do is to increase your pointer by 3. Something like;
lda #<clearScreen+1
sta pointerClearScreen ; a zeropage pointer
lda #>clearScreen+1
sta pointerClearScreen
...
...
ldy #$00
lda #<address
sta (pointerClearScreen),y
iny
lda #>address
sta (pointerClearScreen),y
lda pointerClearScreen
clc
adc #3
sta pointerClearScreen
bcc +
inc pointerClearScreen+1
+
you need to blend this code with your drawing routine and optimize as much as you can.
After you set the last drawing byte you need to put an RTS opcode using pointerClearScreen to the correct position. After that, to clear screen, all you need to do is;
jsr clearScreen
Notes:
1) After you call clearScreen routine, don't forget to replace the last RTS with STA again.
2) Required STAs for each frame would be different. Be sure to have enough STAs reserved for your drawing/cleaning routine. You may want to measure a maximum first and add a 10% to that for safety.
3) If you need double buffering (i think you would...), you will probably need 2x space for cleaning code since clear screen routine is created with the drawing routine. But you may find a way to use the same memory space somehow. It might be possible with a well designed frame switching system, i'm not really sure. |
| |
Wisdom
Registered: Dec 2001 Posts: 90 |
You might employ a "dirty rectangles" algorithm, with optionally taking delta of two consecutive frames to determine the final dirty area. Then you can generate an unrolled eraser routine with the addresses of the dirty area on the fly. Just the first thought that came to my mind.
|
| |
enthusi
Registered: May 2004 Posts: 677 |
It also often helps to just set the FG colors to BG of areas you want 'erased'.
Often when you plot new data into 8x8-blocks you set the bg-col new anyway. |
| |
Taskmaster Account closed
Registered: May 2012 Posts: 12 |
I'm playing around with a little space ship shooter game idea. Player controls a ship that fires at a screen full of randomly spawning enemies and there are some power ups and things they can collect along the way.
Nothing all that complicated but there is a lot of stuff moving around so I didn't want to mess with sprites for this.
At any rate, you guys are BEASTS. Thanks for the ideas! Some of these methods would never have occurred to me.
I'll give this stuff a shot and report back, thanks! |
| |
Skate
Registered: Jul 2003 Posts: 494 |
@Taskmaster: I've never coded a shoot'em up game before but afaik, fastest method is using hardware sprites for player & enemies (multiplexers & sorting algorithms are heavily involved) and software sprites for bullets and other small stuff. I know multiplexers are not really easy to handle and using multiplexers may affect your game design (not trying to have more than 8 sprites in a line etc.) but if you try to do everything using software sprites, you shouldn't expect a reasonable FPS i guess.
I remember Doynax was working on some shooter 4-5 years ago. I don't know the project's current status but he may share his experience if he sees this thread.
Edit: I just found this.
http://www.gtw64.co.uk/Pages/b/Review_Ballsofscrolling.php
It seems like Doynax' game is unfinished but it was in a good shape when he decided to abandon the project. He has released the source codes. It may help you to find a faster way for your project. |
| |
Taskmaster Account closed
Registered: May 2012 Posts: 12 |
OK, so this will be a silly question I'm sure but I can't make heads or tails out of the documentation on this.
I know that:
lda #$18
sta $d018
Sets my bitmap screen to be at $2000 ... how do I set it to be at $4000? This SHOULD be simple, and maybe it's just too early in the morning, but I'll be damned if I can figure it out. |
| |
Mixer
Registered: Apr 2008 Posts: 452 |
Learn about c-64 memory banks, and address $dd00
Check following for instance. http://unusedino.de/ec64/technical/project64/mapping_c64.html |
... 11 posts hidden. Click here to view all posts.... |
Previous - 1 | 2 | 3 - Next |