| |
Oswald
Registered: Apr 2002 Posts: 5094 |
AGSP - how to use sprite pointers for both sprites and char gfx
just wondering, would it be possible to change screen after sprite pointers have been loaded and before badline operation ? that would solve the problem of visible sprite pointers :)
badline + 8 sprites that is. there is maybe 1-2 free cycle with RMW but where in the line? cant find vic article with google.
or maybe one could write a multiplexer which only allows 7 sprites where critical. |
|
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: just wondering, would it be possible to change screen after sprite pointers have been loaded and before badline operation ? that would solve the problem of visible sprite pointers :)
badline + 8 sprites that is. there is maybe 1-2 free cycle with RMW but where in the line? cant find vic article with google.
or maybe one could write a multiplexer which only allows 7 sprites where critical.
Maybe. You have definitely some time between SPR0-3 fetches and before the bad line to change screen. But then you must switch it back immediately after the bad line otherwise the next line of the sprites will be wrong. So if it's possible at all it would be some inc $d018/dec $d018 and then maybe only some of the middle sprites. From the top of my head so read this with causion. :P |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
I'd been thinking about this problem some months ago for my own agsp routine. IIRC you need at least 5 cycles: last write from a preceeding ST(A/X/Y) $D018 (or RMW) and 4 for the second ST(X/Y/A) $D018.
The first write must happen before bad line *but* after sprite fetch, the second write must happen after badline *but* before next sprite fetch. You definitely lose at least 2 sprites and you have to cope with messy timings if you have - which is normally the case - a dynamic number of sprites in those lines.
IMHO Character & (partial) sprite redefinition is probably the way to go (even though it's clearly heavier). |
| |
HCL
Registered: Feb 2003 Posts: 728 |
It is not possible, i have tried (in another context but..). If you flip d018/dd00 just before the badline, and switch it back at once you loose some 3-4 chars on either side of the screen. Perhaps if you don't need the whole screen width, then you could live with that..
On non-badlines it is possible though. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
hcl, what if we loose 1 sprite ? that gives back that 3-4 chars on the sides. |
| |
HCL
Registered: Feb 2003 Posts: 728 |
Sounds likely.. :). i guess you just have to try it out in your context and requirements.. |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Would be a cool trick. Graphics Over Sprite Pointers - GOSP. |
| |
Burglar
Registered: Dec 2004 Posts: 1101 |
oswald, google is not your friend, csdb is ;)
VIC Article [english] |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
@HCL
Sorry for bothering you but I think I didn't quite get it.
If I make room (clearly losing 2 sprites) for one STA $d018 before bl and one, say, STX $d018 after it (possibly starting before bl but having its write-cycle after it), how should I get 3-4 garbage characters on either side? Does VIC update char bank some cycles after changing $d018? |
| |
HCL
Registered: Feb 2003 Posts: 728 |
Hmm, on a second thought, i didn't answer your question.. it was the answer to some other question perhaps :P.
So what you want to do is first some AGSP or whatever you call it..well, then you find out where the badline is that will display the sprite pointers as colors, Wait until all sprite pointers have been read, change $d018 just before the badline is triggered, and if possible change $d018 back before sprite pointers are read again. Ok, now even i am with out :).
Not sure if the first part is possible even, but i'm sure that doing both d018-stores are not possible as i think i recall there is only one cycle left when you have both badline and 8 sprites. If reducing number of sprites, maybe..
So.. the answer became sort of the same :P. The issue with loosing some 3-4 chars on the screen was related to something else i made, though similar problem.. It's so cool your heads would probably explode if i told you, but at the same time it didn't work with less than loosing 3-4 chars on either side of the screen :(. |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: Hmm, on a second thought, i didn't answer your question.. it was the answer to some other question perhaps :P.
So what you want to do is first some AGSP or whatever you call it..well, then you find out where the badline is that will display the sprite pointers as colors, Wait until all sprite pointers have been read, change $d018 just before the badline is triggered, and if possible change $d018 back before sprite pointers are read again. Ok, now even i am with out :).
Not sure if the first part is possible even, but i'm sure that doing both d018-stores are not possible as i think i recall there is only one cycle left when you have both badline and 8 sprites. If reducing number of sprites, maybe..
So.. the answer became sort of the same :P. The issue with loosing some 3-4 chars on the screen was related to something else i made, though similar problem.. It's so cool your heads would probably explode if i told you, but at the same time it didn't work with less than loosing 3-4 chars on either side of the screen :(.
Spoke to my bro and according to him Exilon/HZ did some research with this for a game and came to the conclusion that 6 sprites are possible. Trust the old lords! |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
6 is pretty reasonable. it must be rare that in a typical platformer more than 6 will gang up on THAT specific line.
and when it happens, live with it, do the flicker :) the solution is much better give n take ratio than others. you can have more than 8 pixel / frame scrolling and still a LOT of cpu free for doing a tight multiplexer, many char sprites and what not, while having almost a fullscreen window. |
| |
doynax Account closed
Registered: Oct 2004 Posts: 212 |
Is the cost of just brute-force copying really all that high?
You could perform all sorts of raster tricks to speed this up or limit copying but eating away two sprites will be a significant limitation when it comes to level design, and complicating your display with this scheme is going to get in the way when you want to combine it with other special-case raster effects.
Just keep a cache of 8-16 fixed sprites/characters and only copy in new graphics on-demand when something changes. Replace the sprites lazily in the spare raster time even, with the old pattern kept until the new one is ready. That's what I do for copying/flipping my main character and you'll be hard-pressed to spot the difference. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
16 sprite with templates makes 32 sprites, thats 32 chars you also have to copy gfx in and keep track of that aswell. I'd rather go for only 6 sprites in some cases, and have all the cpu time no platformer ever had.
Tho I have to admit I've no experience on cpu demands of 2d scrolling games. maybe loosing time to sprite and char copying is not that crucial. |
| |
doynax Account closed
Registered: Oct 2004 Posts: 212 |
Quoting Oswald16 sprite with templates makes 32 sprites, thats 32 chars you also have to copy gfx in and keep track of that aswell. Templates? At minimum you need nine sprites/chars to do lazy updates cleanly. One for each hardware sprite plus the buffer for off-screen rendering.
Of course you may want a couple more to expand the cache and be able to reuse previously copied sprites more often but 32 seems rather excessive. Admittedly you're not getting around copying the character data when a sprite pattern or channel changes though.
The point is that animations are short, slow, and highly repetitive, so you can get away with doing very little actual work on average.
Quote:I'd rather go for only 6 sprites in some cases, and have all the cpu time no platformer ever had. Aside from Mayhem in Monsterland? ;)
Quote:Tho I have to admit I've no experience on cpu demands of 2d scrolling games. maybe loosing time to sprite and char copying is not that crucial. It depends. In my experience the real cycle eater, aside from traditional scrolling, is attempting general logic. That is modelling every actors as a generic physics object traversing the world, a flexible animation system linking together multi-sprite objects, etc.
Beyond that the problem is spreading the pain evenly. You're going to have a fair bit of trouble with certain frames being loaded down while the workload on others is relatively light, so anything work unit which can easy be spread over multiple frames or performed ahead of time during spare cycles is a big plus (the sprite cache above, scrolling, background loading, pre-rendered music and so forth.) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
with 32 I was thinking that each sprite needs a copy buffer - obviously not :)
mayhem had to copy d800 after scrolling 40 chars, thats quite a bottleneck, tho I dont see it doing anything that it really needed that VSP code. It could have been done with a couple of half unrolled screen&color copy code. there's not even more than 8 sprites on screen at once I think - and that tells a lot - having a rasterline where the sprite limit is 6 is certainly not a bad compromise.
btw not even 16 bit games kept track of actors offscreen (except some limits) for the usual platformer, thats an overkill imho. usually you just run through the world, you dont need them to have their on lives in it, you kill them or leave them behind and thats it.
anyway I really wish some time I will have the time and motivation and dive into the subject, generic ingame sprite multiplexing is a very cool problem to tackle, also having a player interacting with the level and other sprites, and bullets. hopefully one day I'll get my hands dirty with this... :) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
@Doynax+oswald: I know I'm being lame and stupid now, but how does that solve the problem of visible sprite pointers in the GFX while AGSPing? |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:generic ingame sprite multiplexing is a very cool problem to tackle, also having a player interacting with the level and other sprites, and bullets.
multiplexing is not hard - collisions are what gives you grey hair =P |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: @Doynax+oswald: I know I'm being lame and stupid now, but how does that solve the problem of visible sprite pointers in the GFX while AGSPing?
you keep the sprite pointers constant, and change the sprite data instead, also redefine the constant chargfx as needed. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: Quote:generic ingame sprite multiplexing is a very cool problem to tackle, also having a player interacting with the level and other sprites, and bullets.
multiplexing is not hard - collisions are what gives you grey hair =P
which kind ? player - level, sprite-sprite, sprite char bullet? |
| |
doynax Account closed
Registered: Oct 2004 Posts: 212 |
Quoting Oswaldmayhem had to copy d800 after scrolling 40 chars, thats quite a bottleneck, tho I dont see it doing anything that it really needed that VSP code. It could have been done with a couple of half unrolled screen&color copy code. Huh.. I always assumed they did something more clever.
I've given AGSP a bit of thought myself but never managed to work out how to spread out the video matrix and color scrolling work very far.
I did have some success generating a 8x16 char-mode, allow for colour double buffering and halving the amount of data to copy.
Quoting Oswaldthere's not even more than 8 sprites on screen at once I think - and that tells a lot - having a rasterline where the sprite limit is 6 is certainly not a bad compromise. Yeah, you're probably right. Mayhem is very pretty but looking beyond that there isn't much tech behind it aside from the VSP.
Quoting Oswaldbtw not even 16 bit games kept track of actors offscreen (except some limits) for the usual platformer, thats an overkill imho. usually you just run through the world, you dont need them to have their on lives in it, you kill them or leave them behind and thats it. I was thinking more along the lines of maintaining "full" physics states for every actor on screen.
You can pretty easily special-case something like an enemy patrolling between two points on a piece of land with simple, fixed, animation in a minimal amount of cycles. Things get rather more expensive when you decide to allow the player to shoot them off of a cliff.
Quoting Oswaldwhich kind ? player - level, sprite-sprite, sprite char bullet? Simply detecting basic bounding-box collisions between sprites is fairly easy. You've already got the sprites sorted for the multiplexer so parallel traverse the array looking possible collisions.
For bonus points read out the hardware collision register after each multiplexer IRQ and use that to filter candidates, if you're not doing overlays that is.
Reacting to the collisions in a clean way is a bit trickier but hardly insurmountable.
I've found background collision detection/handling rather more involved.
Quoting Oswaldyou keep the sprite pointers constant, and change the sprite data instead, also redefine the constant chargfx as needed. What Oswald said. To be more specific you reserve a couple of overlapping chars/sprites and use those as the visible pointers by copying in the appropriate graphics as-needed.
Hence the need for efficient caching. Obviously this only works in (non-ECM) char mode. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:which kind ? player - level, sprite-sprite, sprite char bullet?
i found player-background the most annoying. eg walking on ground that isnt flat. and managing edges properly so you either dont get stuck, cant walk into the background, and dont hoover in the air. YUCK. special cases galore :( |
| |
doynax Account closed
Registered: Oct 2004 Posts: 212 |
Quoting Groepazi found player-background the most annoying. eg walking on ground that isnt flat. and managing edges properly so you either dont get stuck, cant walk into the background, and dont hoover in the air. YUCK. special cases galore Amen :(
You start out thinking you'll just implement a simple, generic, scheme. A height-map for every character type indicating where the ground lies.
But gradually you get bogged down in details of handling objects with width and height, diagonal tile transitions, fast movement, animation glitches, and so on.
Feel free to share any tips on doing this cleanly and/or efficiently, I could certainly use them.
One cute, albeit rather limiting, trick if you've got a separate collision attribute map is to manually extrude the edges ahead of time and pretend that the player is a point-size object. |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: Quoting Groepazi found player-background the most annoying. eg walking on ground that isnt flat. and managing edges properly so you either dont get stuck, cant walk into the background, and dont hoover in the air. YUCK. special cases galore Amen :(
You start out thinking you'll just implement a simple, generic, scheme. A height-map for every character type indicating where the ground lies.
But gradually you get bogged down in details of handling objects with width and height, diagonal tile transitions, fast movement, animation glitches, and so on.
Feel free to share any tips on doing this cleanly and/or efficiently, I could certainly use them.
One cute, albeit rather limiting, trick if you've got a separate collision attribute map is to manually extrude the edges ahead of time and pretend that the player is a point-size object.
Brr yeah, classic problem. Extruding the edge is what we did in Pinball Dreams! Anyway, I can only recommend implementing the algo in a simulator in a higher level language that works flawlessly, then port to asm. It requires a great deal of fiddeling. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
one particular annoying thing to get working right was having platforms on which you can jump by standing under them and jumping up through the gfx. this creates some great deal of interesting problems, considering the player can move horizontally at the same time, or hits an enemy on the platform (which throws him down or something like that). very easy to miss something there and then you can suddenly walk through gfx or get stuck or warped up a dozen pixels (because you hacked another problem away like that...)
i think we solved a bunch of things by fixing the leveldesign around the engines shortcomings there ..... =) |
| |
Danzig
Registered: Jun 2002 Posts: 440 |
Quoting groepazi think we solved a bunch of things by fixing the leveldesign around the engines shortcomings there ..... =)
Cheater! =) |
| |
Stone
Registered: Oct 2006 Posts: 172 |
I don't think that's cheating at all. You can spend your entire life thinking up and fixing pathological cases. It's time consuming enough already to write an engine for the c64... |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:Cheater! =)
hehe. i think if you take a closer look at a couple of games... you will find out that all of them do it in one way or another =D |