Enterprise Forever

:UK => Programming => Topic started by: ssr86 on 2015.November.19. 18:59:14

Title: Pixel modes screen scroling
Post by: ssr86 on 2015.November.19. 18:59:14
I have never done in-game scrolling and so I have some questions for those who have some experience with it.

There's no screen memory wrap like on the cpc so I guess you can't use the "adaptive tile refresh" technique and can't use other techniques from the cpc?...
What's the minimal back-buffer for horizontal scrolling if I don't want to do software scrolling with a tile-based screen? I think that I would need nearly 2 screens width for the video buffer...And that's rather unfortunate... How should I go about doing it?

The question is somewhat related to the "tripbuffer techdemo" (https://enterpriseforever.com/programming/video-config-that-allows-to-draw-sprites-vertically/) where I wanted to have 3 video buffers - two screen for double buffer and an additional clean buffer for erasing... However it seems that if I want to do scrolling I would need to drop the third buffer then I would have a 128-bytes wide lines.. and that's still 32 bytes less than 2 screens... No good (if I want to follow the vertical-stripes based drawing for optimization...)
Title: Re: Pixel modes screen scroling
Post by: geco on 2015.November.20. 09:25:21
I have never done it either, but during converting programs I saw some solutions, and ex Star Sabre drew only the last column (2 pixel) , and increased video address by 1, in this case 2 video page was enough for scrolling (1 active memory, 2nd is shadow, and it was flip-flopped) , every frame used 1 additional byte
Title: Re: Pixel modes screen scroling
Post by: ssr86 on 2015.November.20. 10:29:40
I have never done it either, but during converting programs I saw some solutions, and ex Star Sabre drew only the last column (2 pixel) , and increased video address by 1, in this case 2 video page was enough for scrolling (1 active memory, 2nd is shadow, and it was flip-flopped) , every frame used 1 additional byte
I can't understand how 1 byte is enough...
I mean...
before scroll:
ABCDEFGH:I
after scroll
A:BCDEFGHI
next I want
CDEFGHIJ:K
but for that I would need to redraw the entire screen...
There's something I'm doing wrong there...
Could you maybe elaborate?
The second screen is just so that the scroll will be in one-mode0-pixel steps instead of in one-byte steps, right?
Title: Re: Pixel modes screen scroling
Post by: ssr86 on 2015.November.20. 10:43:34
On the site below there are some scroll examples (by Arnoldemu) for the cpc...
http://www.cpctech.org.uk/source.html
here for a tilemap: http://www.cpctech.org.uk/source/scrltile.asm

I'll try to read them again and maybe I'll get to understand some more... Although the cpc has memory wrap which I guess helps somewhat...
Title: Re: Pixel modes screen scroling
Post by: geco on 2015.November.20. 11:37:25
The second screen is just so that the scroll will be in one-mode0-pixel steps instead of in one-byte steps, right?
It can be used to one pixel step movement, and if I remember well it is used in Star Sabre for it, I mentioned the 2nd screen just for shadow screen (avoid flashing)

1st row ex
0000-003f
and the full screen 0000-2fff

1st frame
after moving right (the program fills every 40h th byte so the old 0000+x*40h bytes will be overwritten, 0000h will not be touched, and 3000h will get value)
0001-0040 1st row
and the full screen 0001-3000

2nd frame
0002-0041 1st row
and the full screen 0002-3001

Sorry I think this method was mentioned and used by IstvánV.
Title: Re: Pixel modes screen scroling
Post by: ssr86 on 2015.November.20. 11:48:03
But the problem for me is what to do when my "scroll backbuffer" (say I have only 4 columns worth of space - display width is $50 bytes but buffer width of lines id $55 - so only 5 bytes of backbuffer for scrolling) runs out and I need to wrap...
I know that while I use the backbuffer it's enough to update the screen offsets in the lpt, but what to do when I need to wrap and I wan't to avoid redrawing od the screen as much as possible...
The examples don't mention that too I think (or maybe it's because the auto-wrap)

Because what you're writing covers only these steps:
before scroll:
ABCDEFGH:IJKLMNO....
after scroll
A:BCDEFGHI:JKLMNO...
after scroll
AB:CDEFGHIJ:KLMNO...
after scroll
ABC:DEFGHIJK:LMNO...
and so on...

Having a long backbuffer, I could do:
Code: [Select]
ABCDEFGHij------
aBCDEFGHIj------
jbCDEFGHIJk-----
jkcDEFGHIJKl----
jkldEFGHIJKLm---
jklmeFGHIJKLMn--
jklmnfGHIJKLMNo-
jklmnogHIJKLMNOp
jklmnophIJKLMNOP

.. and then I need to reset the scroll offset and get:

JKLMNOPQrjklmnop
jKLMNOPQRsklmnop
jkLMNOPQRStlmnop
and so on...
Title: Re: Pixel modes screen scroling
Post by: ergoGnomik on 2015.November.20. 12:19:02
ABCD____
eBCDE___
efCDEF__
efgDEFG_
efghEFGH
iFGHIfgh
ijGHIJgh
ijkHIJKh
ijklIJKL
mJKLMjkl
mnKLMNkl
mnoLMNOl
mnopMNOP
Title: Re: Pixel modes screen scroling
Post by: ssr86 on 2015.November.20. 12:34:06
ABCD____
eBCDE___
efCDEF__
efgDEFG_
efghEFGH
iFGHIfgh
ijGHIJgh
ijkHIJKh
ijklIJKL
mJKLMjkl
mnKLMNkl
mnoLMNOl
mnopMNOP

But isn't this the case when your "scroll backbuffer" has the width of the display buffer?
Is this the minimal backbuffer size to avoid redrawing the entire screen or is there a trick to avoid this? (or am I missing something and don't understand what all of you are trying to say)
Title: Re: Pixel modes screen scroling
Post by: ergoGnomik on 2015.November.20. 12:41:23
But isn't this the case when your "scroll backbuffer" has the width of the display buffer?
Is this the minimal backbuffer size to avoid redrawing the entire screen or is there a trick to avoid this? (or am I missing something and don't understand what all of you are trying to say)
Either this or you soft-scroll. I don't know any other way. VRAM is always linear and LPT cannot be interfered with.
Title: Re: Pixel modes screen scroling
Post by: ssr86 on 2015.November.20. 12:43:27
Either this or you soft-scroll. I don't know any other way. VRAM is always linear and LPT cannot be interfered with.
Ok, that's a definite answer I wanted to get.
Title: Re: Pixel modes screen scroling
Post by: geco on 2015.November.20. 13:27:55
If you use a whole 16KB for displaying screen, and another 16KB for scrolling, you can scroll 327 seconds without redrawing with 50 FPS
Title: Re: Pixel modes screen scroling
Post by: ssr86 on 2015.November.20. 14:39:33
I have never done it either, but during converting programs I saw some solutions, and ex Star Sabre drew only the last column (2 pixel) , and increased video address by 1, in this case 2 video page was enough for scrolling (1 active memory, 2nd is shadow, and it was flip-flopped) , every frame used 1 additional byte
Do you remember how many bytes "wide" was a single screen buffer in Star Sabre?
Title: Re: Pixel modes screen scroling
Post by: ergoGnomik on 2015.November.20. 16:10:26
On the other hand, you may use a mixed soft/hard-scroll mode. In this case you have to build the screen which is offset to the displayed picture with your scroll length in a back buffer during the frames you do the hard-scrolling, then flip the buffers and start again.

E.g. you have an 80 bytes wide screen with a four bytes wide scroll length, and you're scrolling towards the  left. During the time you scroll through the four bytes part, you build a new screen that has a starting offset four compared to the displayed 84 bytes wide buffer. So, if absolute scroll position of the displayed buffer is 0, then draw your next screen from absolute position 4.

But this is good only if you have a set direction of scrolling.

Anyone with a better idea?
Title: Re: Pixel modes screen scroling
Post by: geco on 2015.November.20. 20:55:54
Do you remember how many bytes "wide" was a single screen buffer in Star Sabre?
I did not remember but now I checked.
A scroll phase starts at 01f8h and ends at 03b0h the end address of the screen  moving from 3e39h to 3ff1h, the address is increased by 2 at every 2nd frame.
With this solution 1 restart is needed during one level, but it is solved simply in Star Sabre, at restart phase the map is empty, and after restart the map elements start appearing.
The buffer size 01b8h the game speed is 25 fps if I calculated well 17,6 s is the scrolling time.
Title: Re: Pixel modes screen scroling
Post by: ssr86 on 2015.November.21. 14:03:58
Sorry to all... I thought that I need a backbuffer for every line on the ep... But geco's post made me rethink... So I've tried it and got the scroll to work... Sorry :oops:

So here's an example of horizontal scrolling.
The scroll_offset can get values between 0 and 256-display_line_width_in_bytes.
I update the scroll offset, draw the new column and update the lpt... So it's more like

AAAA
AAAA
AAAABBBB

where A is the screen data and B stands for the backbuffer...
And after scroll it becomes:

BAAAA
 AAAA
 AAAABBB

I feel stupid...:oops:

There remains the problem that when I scroll the first and last column don't show what they should but I think that that is because I use a single buffer and the the screen refresh. When using double buffering this problem should disappear, I think (or hope)...
Title: Re: Pixel modes screen scroling
Post by: geco on 2015.November.21. 14:22:59
There's no screen memory wrap like on the cpc so I guess you can't use the "adaptive tile refresh" technique and can't use other techniques from the cpc?...
You can use any technique from CPC, if you use the vertical scrolling of CPC there is one disadvantage on EP, sometimes 1 char row or part of it will be corrupted, but I think it can be avoided to decrease the screen size by 1 char row.
Title: Re: Pixel modes screen scroling
Post by: geco on 2015.November.21. 14:44:47
Sorry to all... I thought that I need a backbuffer for every line on the ep... But geco's post made me rethink... So I've tried it and got the scroll to work... Sorry :oops:
No problem :)
This way is the most space efficient scrolling I think, if your scroll moves right 1 byte at 25 fps, and you use a SPECCY size screen (3000h) then you can make a 163 sec scroll in a 16KB page.
Other thing if you need to use bigger screen ex CPC default size (320x200 3e80h) and an alternate screen to avoid flashing then with 3 video segment the scrolling can take 670 sec without redraw of the screen.

screen1 on FC, starts at 0000h
screen2 on FD, starts at 0000h (address on the page)
and FE is used later for scrolling
the scroll can move 0000-0180h FE segment is not needed
when start pos of screen reached 0181h FE segment is involved and screen2 starts on FD segment but ends on FE, screen1 starts on FC and ends on FD.