| |
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.... |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
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. |
| |
knue
Registered: Dec 2012 Posts: 37 |
Well this is more or less clear to me. What really bugs me is the following:
* there are 4 scrolling cases to consider (left, right, top, bottom)
* 3*2 cases for each tile position
* 4 cases for x-scroll (assuming scrolling 2 pixels at once)
* 4 cases for y-scroll
So that's in total 384 cases! Even if I manage to program all that cases with some macro magic to at least share some of the code, I'm afraid that in the end of the day I need to have all 384 code variants in memory, or am I missing something? |
| |
cadaver
Registered: Feb 2002 Posts: 1160 |
Shouldn't you only need "update horizontal span" and "update vertical span" routines, which redraw one char-column or one char-row worth of bitmap data at a time, and handle wrapping as they go?
If you check with e.g. ICU64 how Mythos updates the bitmap, it appears to be working like that.
You could compose your tiles from a virtual bitmap "charset" to save memory, instead of always storing unique data for each 3x2 tile. |
| |
knue
Registered: Dec 2012 Posts: 37 |
But updating a complete row is too much to handle in one frame, no? Updating a complete row needs 40*10 reads & writes. (8 for bitmap + 1 for screen ram + 1 for color ram).
I already thought about this virtual char set for compressing the tile data but then the number of cases even explode more. |
| |
cadaver
Registered: Feb 2002 Posts: 1160 |
It's still less than a char-mode standard hardscroll (1000 bytes for whole screen)
I'd recommend trying how your rastertime fares with that first, as it's simplest.
If your gamelogic can signal the IRQ with the sprite + scroll positions that should be shown on the next frame, while it already calculates ahead, it should be able to take the occasional heavier rastertime hit. |
| |
mad Account closed
Registered: Feb 2017 Posts: 6 |
Perhaps you can prebuild your charlines to append..
So that you only have (bitmapData*8,colorRam1*1,colorRam2*1)*40 into a buffer. Then when you really need to append the data you just do a simple copy loop whilst maintaining the wraparound.
The candidates for prebuilding depend on your (xyScrollPosition & 7)..
If x is bigger or equal 4 you can start prebuilding the buffer for the right. if x is below 4 you can start prebuilding the buffer for the left. The same for y.
On actual appending the prebuild buffers, you can handle the x+y appending cases.
it's just an idea perhaps it doesn't work. Most probably there are better solutions.
However I think it's easier to first inspect the rastertime needed like Cadaver suggested. You somehow have the whole (AGSP) frame to do the appending.. |
| |
mad Account closed
Registered: Feb 2017 Posts: 6 |
Actually that doesn't work! :) You would have to implement some delay on a direct direction switch.. |
| |
knue
Registered: Dec 2012 Posts: 37 |
Any suggestions how to layout the tiles in memory?
Let's say a tile looks like this:
ABC
DEF
The most obvious solution would be this:
A0...A7 B0...B7 C0...C7 D0...D7 E0...E7 F0...F7 Next tile here
But I think address computations can be quite expansive.
Next option:
Tile0_A0...A7 Tile1_A0...A7 ... Tile_7F_A0..A7
Tile0_B0...B7 Tile1_B0...B7 ... Tile_7F_B0..B7
...
Tile0_F0...F7 Tile1_F0...F7 ... Tile_7F_F0..F7
But maybe using a virtual char set isn't that bad after all.
Maybe sth like this:
Tile0_A Tile1_A ... Tile_7F_A
Tile0_B Tile1_B ... Tile_7F_B
...
Tile0_F Tile1_F ... Tile_7F_F
char_00_row0 ... char_00_row7
char_01_row0 ... char_01_row7
...
char_FF_row0 ... char_FF_row7
|
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
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). |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
As for memory layout, suspect I'd lean towards a table for A0, then a table for A1, etc - so you can just index each source table by tile ID.
If you've the ram for it, then that's 60 tables, so nearly 16k for 256 tile elements (less if you've fewer tiles).
Could always go for a hierarchy to save memory of course (tiles are made of virtual chars etc). |
Previous - 1 | 2 | 3 - Next |