Jump to content
  • 0
CursorKeys

Smooth Scrolling

Question

Posted (edited)

Hi guys,

 

I am working on a small problem: smooth scrolling.

Scrolling the vera layers is really smooth and easy (VERA_L0_VSCROLL_L), but you cannot scroll forever, since you will run out of vera memory at some point to display.

So I like to scroll 8 pixels, in text mode, and then scroll the whole text buffer up one char, and reset the VERA_L0_VSCROLL_L register, and fill the bottom screen text line with new data (using a pseudo random generator)


I have all of that working, and now it is up to optimizations to avoid screen flicker.
Flicker seemed to start somewhere to 1/5th of the bottom of the screen.
After optimizing, it's from 1/4th of the top of the screen. 
I start scrolling on vsync.   So I managed to improve speed about 120 scan lines or so.

But there is more to be done. The flicker is not gone, it just got reduced.

 

So the core issue is this.

The moving of the screen data around is relatively slow.  And I won't be able to do it in just a few scanlines, it needs at least a 100 scanlines or so, and those scanlines flicker, when I do it when the scanline is being drawn while I update .

Solutions I see:

1. Double buffering.  Done this before, Blitzbasic and so on, but feels somehow like cheating on a 6502 retro machine.

2. Split up the operations of moving data around. When the rasterline is in the top half of the screen, scroll the lower screen part, and visa versa.

3. Just scroll more pixels by hardware, so the moving of the data, happens less often, it flickers only now and then a little.
 

I was thinking, I am sure not the first to encounter the issue, what is your opinions on best solution?

Thanks
/CK

Edited by CursorKeys

Share this post


Link to post
Share on other sites

8 answers to this question

Recommended Posts

  • 0
Posted (edited)

Actually, you can scroll forever. So, you only need to fill in where you are scrolling to. It's like a circular buffer, and you just have a sliding window.

Edited by SlithyMatt
  • Like 2

Share this post


Link to post
Share on other sites
  • 0

Wow. I missed that.  Thanks for the tip, that super simplifies the whole thing!!

 

So if I scroll to the "end", it will start showing the beginning, like this (imagine a screen of 6x4 characters :)) ?

 

w w w w w w

----------------- <- scollpointer <- screen top

x x x x x x

y y y y y y

z z z z z z

a a a a a a  <------- after "zzzzzz" the screen starts showing "aaaaaa", since "aaaaaa" is at the beginning of vmem

----------------  <------ screen end


I see one problem though,
the whole of vmem would be dedicated to the scrolling area, what if you have two layers, sprites, and so on,
they also live in vmem, so they would be overwritten, if I use up all memory as a scroll buffer.

Or is that not so?

 

 

Share this post


Link to post
Share on other sites
  • 0
10 minutes ago, CursorKeys said:

Or is that not so?

It's not so. You specify the tile map dimensions in the layer config, so it will stay constrained to that area. So, if you have a 64x32 tile map, and only 40x30 are visible, then you have a 14-tile horizontal margin and a 2-tile vertical margin that you can modify while they are off screen.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
1 minute ago, SlithyMatt said:

It's not so. You specify the tile map dimensions in the layer config, so it will stay constrained to that area. So, if you have a 64x32 tile map, and only 40x30 are visible, then you have a 14-tile horizontal margin and a 2-tile vertical margin that you can modify while they are off screen.

Additionally, the HSCROLL and VSCROLL layer parameters will not change the VRAM address of the window, just the portion of the window that gets drawn. If the window would "run off the edge" of the tilemap, the VERA just loops back around.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

Here - run this BASIC program and you'll see it demonstrated quite clearly.

Quote

10 SL=$9F37 :SH=$9F38 : S=0
20 FOR S = 0 TO 4096
30 POKE SL,(S AND 255):POKE SH,INT(S/256)
40 NEXT S

Note that the default screen tilemap width is 128 tiles wide, 8px wide, which is 1024 scroll values to wrap once around. 4096 is the total number of possible scroll values. Thus the screen wraps 4 times during this program.

The garbage you see during the scroll is the portion of the tilemap which is off-screen by default, but still part of the tilemap. Essentially, that's how much off-screen (horizontal) real estate you have to work with in a scrolling engine.

Edited by ZeroByte
  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

And here's some BASIC that scrolls some text.

On line 800, I intentionally left the logic that chooses the first off-screen column as a math-y formula with a logical AND instead of just doing it with a loop of c=c+1:if c>128 then c=0, because in a game with scrolling, you're going to want to be able to address tiles by their screen position, and this program shows the logic of choosing column 80

Quote

5 PRINT "MAKING THE OFF-SCREEN AREA PRETTIER...." :GOSUB 2000
6 PRINT "\X93" : SCREEN 0 : REM SHIFT+HOME
10 SL=$9F37 : SH=$9F38 : NM=4 : M$=""
20 FOR S = 0 TO 4096
30 IF (S AND 7) = 0 THEN GOSUB 700
39 REM GOTO 60
40 POKE SL,(S AND 255):POKE SH,INT(S/256)
50 FOR I=1 TO 10 :NEXT I
60 NEXT S
690 POKE SL,0 :POKE SH,0
695 SCREEN 2
698 END
699 REM PRINT NEXT CHARACTER
700 IF LEN(M$) > 0 THEN 800
710 M=M+1 :IF M=NM THEN M=0:RESTORE
720 READ M$:M$=M$ +"        "
800 C=2*(127 AND (INT(S/8)+80)) +$C00
809 T$=MID$(M$,1,1)
810 CH=ASC(MID$(M$,1,1)) AND 63
820 M$=MID$(M$,2)
830 VPOKE 0,C,ASC(T$) AND 63
840 VPOKE 0,C+1,$61
850 RETURN
1000 DATA "HELLO WORLD"
1001 DATA "THIS IS A DEMONSTRATION OF SMOOTH SCROLLING USING BASIC"
1002 DATA "EACH MESSAGE CAN BE SCROLLED ACROSS THE SCREEN ONE AFTER THE NEXT"
1003 DATA "IN FACT, YOU CAN EASILY ADD AND REMOVE MORE MESSSAGES IF YOU WISH"
2000 REM CLEAR THE GARBAGE FROM THE RIGHT SIDE OF THE TILEMAP
2010 FOR R= $200 TO $1000 STEP $100
2020 FOR C=160 TO 255 STEP 2
2040 VPOKE 0,R+C,32 :VPOKE 0,R+C+1,$61
2050 NEXT C
2060 NEXT R
2070 RETURN

 

Edited by ZeroByte
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0

Hi guys, thanks for the input so far.

This is perfect, I am working on including it in my game now, (converted to c).

Thanks
CKs

Share this post


Link to post
Share on other sites
  • 0

Ok, so for those interested in my results, I made a little you tube video.  Yeah, I know, I talk slow and not very "smooth" (pun intended), but it's a little side adventure from me to make good videos.

https://youtu.be/Ln7pIIZKyvI

  • Like 1

Share this post


Link to post
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.

Guest
Answer this question...

×   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.


×
×
  • Create New...

Important Information

Please review our Terms of Use