| |
knue
Registered: Dec 2012 Posts: 37 |
Layouting tiles for AGSP game
Hi all,
I'm currently trying to write an AGSP-based game engine. The thing that really inspired me on this is Mythos:
Mythos - Battle for Aivanor
Now for the question, I managed to implement the AGSP stuff, fighting the interrupts and everything but what really puzzles me: How the heck do you layout the tiles and manage the redraws???
Like Mythos, I'd like to use 3x2 sized tiles. Let's assume we always scroll 2 pixels at a time. This means you must copy 25% of the next screen in advance for one frame (double the amount if you scroll diagonally). But due to the AGSP there is also this wrap around of the buffers going and everything. How to do that without going insane is a complete mystery to me. |
|
... 11 posts hidden. Click here to view all posts.... |
| |
knue
Registered: Dec 2012 Posts: 37 |
Quote: You don't need a routine per two pixels; just do one for each row or column of chars. It's allowed to take three or four frames to execute if it's running in mainline instead of on interrupt.
(Or, start it at the end of your VBL interrupt, but CLI before entering the loop. Just make sure you don't trigger a second blit while you already have one in flight).
I don't really get this. Let's say I'm only scrolling left/right. Now the player moves to the right two pixels. So I'm starting the mainline scroll-left routine. But now the players moves back again. What should I do now? I somehow have to notify mainline that it should abort and start the scroll-right routine. I could do the copy for scroll-left from left to right and the copy for the scroll-right from right to left and pray for the best. Is this what you mean? |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
You've got a few options there.
You could indeed abort if the player changes direction, or alternately decouple the scroll position from the player position a little, and don't change scroll direction until you've finished the most recent blit.
It doesn't even have to be blitter dependent - for example if you implement a push scroll where the player can roam anywhere in the middle third of the screen before it starts scrolling, there will be a period of {screenwidth/3}/{player speed} when the screen is stationary. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: Conceptually, you "just" maintain a pointer to the the top left corner of the viewport, adding one whenever you scroll a character to the right, forty for down, -1 and -40 for up and left. Keep only the low ten bits, and the wrapping takes care of itself.
You can find addresses within screen ram or colour ram by adding that value to your screen ram or colour ram base address, and the address in bitmap by first multiplying by eight.
update column 39 when you're moving right, column -1 when you're moving left, etc.
As for scheduling, when I implemented this for Hysteron Proteron I had the interrupts maintain the screen position, and the mainline code perform the blitting in response to requests from the interrupt code. RMW instructions signalled from mainline back to interrupt so I didn't have to take care to avoid being interrupted between reading and updating a flag.
wow cj, this is so simple and brilliant at the same time. |
| |
knue
Registered: Dec 2012 Posts: 37 |
Quote: You've got a few options there.
You could indeed abort if the player changes direction, or alternately decouple the scroll position from the player position a little, and don't change scroll direction until you've finished the most recent blit.
It doesn't even have to be blitter dependent - for example if you implement a push scroll where the player can roam anywhere in the middle third of the screen before it starts scrolling, there will be a period of {screenwidth/3}/{player speed} when the screen is stationary.
Looking at Mythos, the player is stuck in the middle of the screen. This is potentially sth I really like. There are way to many games where the screen starts scrolling when the player is in the last third or so and you have hardly time to react to the new stuff that is coming at you. In that regard the best scrolling I've seen so far is in Sam's Journey. There the screen actually overruns you such that you have plenty of space to see what is in front of you. Really cool. Would be interested how exactly this works. |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
Don't know of what you're planning to have in the upper/Lower border part of screen, but assuming we're talking PAL-system here and the rasterlines in the border area are free (=no sprites to be shown, no other timing tricks for $3fff gfx etc.), you should have 312-200=112 Rasterlines in the upper/lower-border-area alone. This gives 112*63=7056 Cycles.
Now when copying a row, you'd need to do this for 40*10 bytes. Using speedcode (LDA/STA) this means we need 8 Cycles per byte, thus 400*8 = 3200 Cycles (<7056 Cycles -> can be done in one frame!)
Depending on all the other stuff you must calculate to keep your game engine going and depending on how fast you actually want to scroll, I'd go for a speedcode generator that does its job during the non-wrap-around frames and call the speed-code for copying when the wrap-around is due.
It might also help to start with an x-offset of 4 (setting $D016 accordingly) if the overall scrollingspeed allows for it, for example if you manage to do the speed-code calculation within say three frames and the scroll-speed is 1pixel/frame, the offset ensures that you have enough time no matter in which direction the player decides to go. Ofcourse the speedcode generator must take the direction into consideration. If the player decides to change direction before a wrap-around, you'll have enough time to do the calculation for the other direction.
Just some basic ideas that I would try out for agsp'ing.
Cheers-CF
[edit] x-offset is valid if you do left/right scrolling; y-offset is what is needed for up/down-scrolling in which case a row has to be copied upon wrap-around. But I guess you spotted this already, after all it's just a rough concept. |
| |
cadaver
Registered: Feb 2002 Posts: 1160 |
Quote: Looking at Mythos, the player is stuck in the middle of the screen. This is potentially sth I really like. There are way to many games where the screen starts scrolling when the player is in the last third or so and you have hardly time to react to the new stuff that is coming at you. In that regard the best scrolling I've seen so far is in Sam's Journey. There the screen actually overruns you such that you have plenty of space to see what is in front of you. Really cool. Would be interested how exactly this works.
In SJ, moving horizontally shifts the camera "origin" position to the opposite side, so that you will see more. If you run fast, the shift happens faster until it reaches the maximum. Turning centers the camera again. Vertically it seems to be just keeping the player in the center, but the scrolling is fairly slow, so that a jump does not catch up with you at first. |
| |
cadaver
Registered: Feb 2002 Posts: 1160 |
Btw. before going crazy with speedcode, I recommend checking out how traditional AGSP games like Fred's Back and Maximum Overdrive do the bitmap update. They're actually shockingly inefficient.
Mythos at least unrolls blitting a char onto the bitmap, in the manner of:
lda charrow1,x
sta (bitmap),y
iny
lda charrow2,x
sta (bitmap),y
iny
...
Where X is the char number to blit, and the destination is just a ZP pointer + Y.
Of course you can always go and optimize later, according to how much CPU you need for other things, but don't think you need to immediately break out the big guns just to get a basic scroller running. |
| |
knue
Registered: Dec 2012 Posts: 37 |
Thanks for all the valuable input.
On another note: Are there any pixel editors out there to at least create the tile set? Preferably something that runs on Linux. Or are you guys just using sth like Gimp + some homebrewn scripts to convert it to your desired output format? On another note, I thought about double-buffering the screen ram and swapping them each frame. This is a pretty cheap effect for mixing colors %01 and %10. But this requirement makes it even more difficult to find an appropriate editor.
EDIT: I've just used a little bit of python magic to create a nice palette and tweaked gimp a little bit. So far, it works quite nicely :) |
| |
Golara Account closed
Registered: Jan 2018 Posts: 212 |
Quote: Thanks for all the valuable input.
On another note: Are there any pixel editors out there to at least create the tile set? Preferably something that runs on Linux. Or are you guys just using sth like Gimp + some homebrewn scripts to convert it to your desired output format? On another note, I thought about double-buffering the screen ram and swapping them each frame. This is a pretty cheap effect for mixing colors %01 and %10. But this requirement makes it even more difficult to find an appropriate editor.
EDIT: I've just used a little bit of python magic to create a nice palette and tweaked gimp a little bit. So far, it works quite nicely :)
interlaced game ? lol i'm not sure i'd like to look at that flickering while playing.
As for pixeling, there's lots of programs for drawing c64 graphics, for example charpad, but you can also draw it in whatever graphics program you want and then convert it, it's pretty easy. You can load bmp/png images directly in KickAssembler and convert it to charset/bitmap data there. It has functions like getMulticolorByte which takes a x,y coordinate and automatically makes a byte out of 8 pixels at this position inside the image. |
| |
Hein
Registered: Apr 2004 Posts: 954 |
For bitmap tiles: GFX-Editor V1.4 |
Previous - 1 | 2 | 3 - Next |