Jump to content
IGNORED

Tile scrolling


Recommended Posts

I don't really understand how games work on the a8 with long sidescrollable levels..

I have tiles which are 2x2 mode E characters big. One full screen is 20x12 tiles big.
I have leveldata, which is 500(horizontal tiles)x 12 (vertical tiles).

If I put the whole level in ram, it will cost 500*12 = 6000 tiles *4 (each tile consist of 4 mode e characters)= 24000 bytes.

resevering 24000 bytes and hscroll threw it would do it- but is a lot, is there a trick like the NES does this? There the new tiles will be placed where you don't see them yet, and the viewport scrolls from the right in vram to the left, like this GIF attchad in this post...
NTS_scrolling_seam.gif.f9493c4fbfa06c31191d2f95bb53e6e2.gif
Are there techniques like that that can work on the a8? - or, what is a common used technique to do large sidescrolling?

Thanks ?

 

Link to comment
Share on other sites

Most games I have had a look at have a width of around 8 screens.

 

They also use 4x4 tiles. 2x2 is going to use 4x the memory of a 2x2 system.

 

So I expect most games would use (in tiles) 6 high x 10 width per screen x 8 = 480 bytes.

 

With that, you can afford to make the number of screens width higher. Add some compression in and you may get a lot of levels in.

Edited by snicklin
  • Like 1
Link to comment
Share on other sites

Thanks for all the replies ? 

Something is still not clear to me... (it's also a more global quiestion, but what if want to do more like the bitmap tile bitmapgraphics) I read a lot about the double screen buffer, like the nes example in my 1st post, it is also done on the Amiga. The viewport moves to the most right of the double screenbuffer and then gets back to the left (as in the NES gif above) - but how does it go back the left of the screen buffer?

I know I could say something like: If rightmost of screenbuffer go to leftmost. But how goes the viewport from right seamless to the left?


 

Although it doesn't look Atari related anymore (bitmap graphics and tiles etc)- I'm working on a VBXE sidescroller thing (and I know how to make a scroller with colums you don't see at the right/left of the viewport) - but I don't understande the Nes/Amiga etc double buffer thing with the viewport wrapping around... ?

Link to comment
Share on other sites

The NES is aided by the h/w in that the column wrap remains on the same row and hence you can keep scrolling right easily into the newly added column.

 

On the A8 this doesn't happen as the row data is contiguous. So to get around that you use a double width line as follows.

 

In a normal width screen you'd use 40 bytes but with scrolling enabled this becomes 48. Double this is 96, or in hex, a nice $60.

So the screen's display list is built up of LMS lines for each row, so row 0 would be $x000, row 1 would be $x060, row 2 would be $x0C0, row 3 would be $x120 etc.

 

Assuming our 'cell' is an 8x8 pixel or 2x1 char arrangement, we draw the tiles as pairs to 0,1 & 2,3 & 4,5 etc

So as we fine scroll, we can use 8 positions to traverse a cell. Then we hard-scroll by bumping the low-byte offset of the LMS by 2 and reset the fine scroll.

All good so far. So in order to scroll into new data we have to write the column of byte-pairs for tile in at the incoming right-side offset.

 

So the 'trick' is simply to also write the incoming data at the 'gone-out' position too. So lets recap what is seen.

 

At a scroll offset of zero (pixels) we see the chars from the charmap 0-39.

At a scroll offset of one (pixel) we see the 3 rightmost pixels from the char at offset 0, chars 1-39 and the leftmost pixels from the char at offset 40

At a scroll offset of two we see the 2 rightmost pixels from the char at offset 0, chars 1-39 and the 2 leftmost pixels from the char at offset 40

At a scroll offset of three we see the rightmost pixels from the char at offset 0, chars 1-39 and the 3 leftmost pixels from the char at offset 40

At a scroll offset of four we see the chars from the charmap 1-40

At a scroll offset of five we see the 3 rightmost pixels from the char at offset 1, chars 2-40 and the leftmost pixels from the char at offset 41

At a scroll offset of six we see the 2 rightmost pixels from the char at offset 1, chars 2-40 and the 2 leftmost pixels from the char at offset 41

At a scroll offset of seven we see the rightmost pixels from the char at offset 1, chars 2-40 and the 3 leftmost pixels from the char at offset 41

 

The next scroll requires a hardscroll and setting the fine scroll back to zero. and so we draw our incoming characters at offsets 42&43. So then:

 

At a scroll offset of zero (pixels) we see the chars from the charmap 2-41.

At a scroll offset of one (pixel) we see the 3 rightmost pixels from the char at offset 2, chars 3-41 and the leftmost pixels from the char at offset 42

At a scroll offset of two we see the 2 rightmost pixels from the char at offset 2, chars 3-41 and the 2 leftmost pixels from the char at offset 42

...

At a scroll offset of six we see the 2 rightmost pixels from the char at offset 3, chars 4-42 and the 2 leftmost pixels from the char at offset 43

At a scroll offset of seven we see the rightmost pixels from the char at offset 3, chars 4-42 and the 3 leftmost pixels from the char at offset 43

 

And then another hard scroll. This can continue until the LMS offset is 42 at which point the next hard-scroll would take us to the visible range of 42-81.

But if, at the same time as writing the incoming characters, we also write them to the exited offset, e.g. the first at 42&43 would also go to 0&1.

This way, when the LMS offset gets to 42 then everything to the left of the visible area is a copy of the visible area.

So all that is needed is to set the LMS offset back to 0 and the incoming offset to 42.

 

 

Edited by Wrathchild
existed -> exited in the last paragraph
  • Like 8
Link to comment
Share on other sites

1 hour ago, Wrathchild said:

And then another hard scroll. This can continue until the LMS offset is 42 at which point the next hard-scroll would take us to the visible range of 42-81.

But if, at the same time as writing the incoming characters, we also write them to the existed offset, e.g. the first at 42&43 would also go to 0&1.

This way, when the LMS offset gets to 42 then everything to the left of the visible area is a copy of the visible area.

So all that is needed is to set the LMS offset back to 0 and the incoming offset to 42.

 

 

Wow, it took me some time to understand the last sentence, but now I see how it works......This is a fantastic explanation- Thanks a lot for your extensive explanation!!! ? ?

Link to comment
Share on other sites

one note...maybe obvious, maybe not... but in case of side scroller, your data has to be stored in columns (not rows) so you can then decompress them (column by column) on-the-fly as the player progresses through level.

 

  • Like 2
Link to comment
Share on other sites

1 hour ago, matosimi said:

data has to be

I think 'is better stored' comes across better.

No harm in having a non-compressed tile map reflecting the level, memory permitting, e.g. with a cart.

The difference here is the 'step' to get to the next cell is one rather than the row's full length.

Another thing is that the tilemap 'cell' value may itself also be a lookup/expanded into a number of characters, e.g. 2x1 in the example above but could be 4x2 for a 16x16 pixel tile.

Same applies in a raster graphic mode where you output the tile image data across multiple lines.

  • Like 2
Link to comment
Share on other sites

Not reading through all this, the closest type of "tile scrolling" is to use the character set pointer and to rotate the character sets with an offset (4 at least for one byte), to have a scrolling effect. 

Using horizontal HW scrolling is wasting too much CPU cycles anyways.

 

  • Like 1
  • Confused 1
Link to comment
Share on other sites

Some time ago I did Hscroll for A7800 using Ring Buffer and Turrican 2 level from Charpad Pro.

Map is 2400 chars long and 20 chars high (unpacked data is 48KB for this level). But converted to 4x4 tiles is only 3KB.

 

Turrican online emulator A7800

https://raz0red.github.io/js7800/?cart=https://atariage.com/forums/applications/core/interface/file/attachment.php?id=899031

 

code examples

https://codebase64.org/doku.php?id=base:extract_row_from_tile_based_map

http://www.atari.org.pl/forum/viewtopic.php?pid=199838#p199838

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...
On 4/12/2022 at 12:13 PM, Wrathchild said:

So the 'trick' is simply to also write the incoming data at the 'gone-out' position too. So lets recap what is seen.

 

At a scroll offset of zero (pixels) we see the chars from the charmap 0-39.

At a scroll offset of one (pixel) we see the 3 rightmost pixels from the char at offset 0, chars 1-39 and the leftmost pixels from the char at offset 40

At a scroll offset of two we see the 2 rightmost pixels from the char at offset 0, chars 1-39 and the 2 leftmost pixels from the char at offset 40

At a scroll offset of three we see the rightmost pixels from the char at offset 0, chars 1-39 and the 3 leftmost pixels from the char at offset 40

At a scroll offset of four we see the chars from the charmap 1-40

At a scroll offset of five we see the 3 rightmost pixels from the char at offset 1, chars 2-40 and the leftmost pixels from the char at offset 41

At a scroll offset of six we see the 2 rightmost pixels from the char at offset 1, chars 2-40 and the 2 leftmost pixels from the char at offset 41

At a scroll offset of seven we see the rightmost pixels from the char at offset 1, chars 2-40 and the 3 leftmost pixels from the char at offset 41

 

I thought i'd get it, well, if I'm scrolling to the right I get it ? (increasing the LMS). But what if we are at a lms of 30 (or even some frames further), and I want to scroll to the left- how could I do this? Sorry, I'm just a hobby programmer ?


 

Link to comment
Share on other sites

15 minutes ago, Thelen said:

I thought i'd get it, well, if I'm scrolling to the right I get it ? (increasing the LMS). But what if we are at a lms of 30 (or even some frames further), and I want to scroll to the left- how could I do this? Sorry, I'm just a hobby programmer ?


 

Just decrease the LMS pointer?

Link to comment
Share on other sites

59 minutes ago, emkay said:

Just decrease the LMS pointer?

 


Yes, that will work, until the lms=0 - then there's no copy of the screen to jump back at 42-81 - or I'm Thinking wrong?

Edited by Thelen
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...