Page 2 of 2
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Fri Mar 22, 2024 12:00 pm
by Joefish
ketmar wrote: ↑Fri Mar 22, 2024 8:38 am
by the way, you cannot copy the whole screen in one frame, not even using stack tricks. there is simply not enough tstates. you may be able to
build it from several tiles, but copying fullscreen backbuffer and keeping 50 FPS is physically impossible.
This is true.
This is the first time I got it working (with parallax background too!), although 128K only. It does waste a bit of time as there's no need to redraw the attributes every frame in a pixel scroll. But then technically it could scroll at any speed, or jump to any place on the map instantly.
The matter is that there isn't enough time to both
read and
write a full screen of data in one frame. But by loading a minimal set of tile data into registers, you're cutting back enormously on the amount of data you have to
read, so that leaves you with enough time to
write an entire screen of data. And that doesn't take much longer than wiping the screen entirely, as you'd still have to write a lot of zeroes just to do that.
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Fri Mar 22, 2024 12:16 pm
by ketmar
by the way, it is possible to do this (copy the whole screen in one frame) on Pentagon. it has slightly more tstates per frame, and no wait states. but you have to load values directly into registers in blit routine, so drawing to such backbuffer is a PITA, and will kill the performance anyway. but you can do fullscreen vertical scroll with static image at 50 FPS (albeit the image should be monochrome, afair). not that it has any practical sense outside of demos, tho.
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Fri Mar 22, 2024 12:30 pm
by ParadigmShifter
This
https://github.com/Liniya/intenseoffici ... -test1.sna
was linked to in my WoS thread which looks like 50FPS and on the 48K but I didn't try and disassemble it.
I think it's way faster to redraw the whole screen than to attempt to rotate what is already on the screen anyway. (For horizontal scrolling anyway). If there's a large amount of blank space copying parts of the screen might start to win though.
In my columns game I am actually copying the screen contents when I move a column down 8 pixels (it only scrolls 8 pixels at a time) which I haven't timed much when it is very busy scrolling a lot of columns at once, it runs ok with no noticeable flicker though (and scrolling what is on screen means I don't have to check the collision map to work out what to draw where).
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Fri Mar 22, 2024 12:41 pm
by ParadigmShifter
So I assume the Hewson article was talking about scrolling in Uridium which sounds like it uses a back buffer. Screen area seems to be 16 rows x 28 or 30 columns (probably uses the full 32 columns for clipping purposes though). It also sounds like they are doing a ton of copying (keep the background layer in a separate buffer, copy it to the off screen buffer, then draw the sprites?) which sounds like a big waste of memory. Uridium is smooth though I did not attempt to guess the frame rate (I am guessing not 25fps though).
Joffa's stuff seems a lot more impressive than that. And GNG was good for what it was doing (the graphics were very limited in that they had to be 4 cells wide if they tiled though), and that was unrolled up the wazoo. My spectrum broke soon after so I didn't see if the GNG Guy (was Keith Burkhill I think) went on to improve his scrolling engine later on.
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Fri Mar 22, 2024 2:01 pm
by Ralf
If we talk about scrolling, then a good game to discuss is Stormlord:
https://spectrumcomputing.co.uk/entry/4 ... /Stormlord
It allows much more variety in background tiles than let's say Cobra. Cobra is actually very limited and allows background built only with a few tiles.
Here is my old post about Stormlord:
viewtopic.php?p=1937#p1937
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Fri Mar 22, 2024 2:10 pm
by Joefish
Uridium runs at 25fps, so there's no time for multiple screen copies. There are plenty of tricks it could be using, all of them very complicated. The dreadnought designs aren't exact copies of the C64 ones either, so it seems there are limitations to what it can render. And even at it's slowest it's a 2-pixel scroll, not 1.
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Fri Mar 22, 2024 2:51 pm
by ParadigmShifter
Anyway it is complicated to answer the OPs question
And you need to do a lot of quite complicated stuff to get it to run fast (use the stack to copy, preshift your graphics, lots of unrolling).
Joefish's 128K scroller linked to earlier has the source available and I would have a look at that (that was when I gave up on my own scroller since I saw Joefish had basically already done what I was trying to do anyway, and there was some gnarly bug trying to make my tiles 48x16 instead of 16x16 which I never got around to fixing). His code is better than mine
(although it was my first attempt at scrolling).
I also borrowed part of my line copy routine from another poster on WoS which uses each row of the preshifted graphics offset by 256 bytes for each row to avoid having to add anything to HL when moving down a row, you can just INC H instead, which was a good idea. I can't remember if Joefish did that in his code or not. That made it harder to debug though I seem to remember lol
You don't end up wasting space you can put other graphics offset by the width (so my first preshifted tile is at someaddress, next line down preshifted to someaddress+256, etc. and the next tile is at someaddress + 16, etc.)
Or you can use an offscreen buffer which is easy but I expect you won't be able to run faster than 16.7 fps then (which isn't that bad tbh, especially if it is your first attempt at a scroller).
EDIT: Ghosts N' Goblins does not preshift it just rotates the tiles by the scroll delta amount each frame IIRC. The tiles repeat every 4 cells though I think which is quite restricting (but you can draw them at any width on the screen via a load of unrolled code - one routine to draw 30 cell width repeated tile, another to draw 29 cell width, and so on.
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Fri Mar 22, 2024 11:50 pm
by Hedge1970
Thanks for all the great input, much of it does not make any sense at the moment but I will endeavour to learn more. What I take away is I will leave it as is for now but I must implement some code - and potentially optimise my code - to write to screen following the Rasta scan.
Re: Machine Code: Moving from Attribute scrolling to pixel scrolling
Posted: Sun Mar 24, 2024 11:33 pm
by C.Born
i have my own notations, hope it helps a little
the IM2 is not needed offcourse
Code: Select all
; http://www.worldofspectrum.net/faq/reference/128kreference.htm
; model -128k -timings in T-state
; T-state 228 per raster-scanline
; Scanline 311 per frame
; screen build in blocks with timing:
; hiddenlines 00000-03419t 000-014 15= 3420
; border-uppr 03420-14364t 015-063 48=10944
; screen 14365-58140t 064-255 192=43776
; border-under 58141-70907t 256-310 56=12768
; ---+----- ---+-----
; total 311=70908
; borderline = 38 * 228 = 8664
; borderline = 39 * 228 = 8892
; borderline = 40 * 228 = 9120
; borderline = 41 * 228 = 9348
; borderline = 42 * 228 = 9576
; borderline = 43 * 228 = 9804
; 1st screenline = 63 * 228 =14364
;first pix @16384 14364-1 t (zero-offset)
;A 128k-video screen line (228t) is timed as follows:
; 128 T ( 0-127) states of screen, (left to right ) CONtended
; 24 T (128-151) states of right border, (right to left !!!) UNcontended
; 48 T (152-199) states of horizontal retrace and UNcontended
; 28 T (200-227) states of left border. (4t extra on 224t ) UNcontended
; per scan line
; 0t 128t
; ----|+++ > +++|----151t
; /
; 199t - < - 152t
; /
; 200t 228t 356t
; ----|+++ > +++|----379t
; /
; 427t - < - 380t
; /
; 428t 456t
; ----|---->----|----
; screen time ( 0-127) = 128 tstate,
;right border time (128-151) = 24
; retracetime (152-199) = 48
; left border time (200-227) = 28 =128 24+48+28 = 228
; screen time (228-355) = 128
;right border time (356-379) = 24
; retrace time (380-427) = 48
; left border time (428-455) = 28 total 456 tstate
;https://www.worldofspectrum.net/faq/reference/z80reference.htm#Interrupts
;In IM 2, it takes 19 cycles to get to the interrupt routine:
; M1: 7 T states: acknowledge interrupt and decrement SP
; M2: 3 T states: write high byte and decrement SP
; M3: 3 T states: write low byte
; M4: 3 T states: read low byte from the interrupt vector
; M5: 3 T states: read high byte and jump to interrupt routine
; next t=+1 ULA interrupt does not wait for an instruction, so the instruction can be contended HALFWAY
; ut tstate average division
; ......
; 48k/128k+2 Cycle +2A/+3
; 6 14335 7 x/8=y.875 j.needle
;@16384 5 14336 6 x/8=y.00 64x224 null start !!
; 4 14337 5 x/8=y.125
; 3 14338 4 x/8=y.25
; *2 14339 3 x/8=y.375
; *1 14340 2 x/8=y.50
; *0 14341 1 x/8=y.625 <<<
; *0 14342 0 x/8=y.75 <<<
; 6 14343 7 x/8=y.875
; 5 14344 6 x/8=y.00
; 4 14345 5 x/8=y.125
; 3 14346 4 x/8=y.25
; 2 14347 3 x/8=y.375
; 1 14348 2 x/8=y.50
; 0 14349 1 x/8=y.625
; 0 14350 0 x/8=y.75
; 6 14351 7 x/8=y.875
; 5 14352 6 x/8=y.00
; 4 14353 5 x/8=y.125
; 3 14354 4 x/8=y.25
; 2 14355 3 x/8=y.375
; 1 14356 2 x/8=y.50
; 0 14357 1 x/8=y.625
; 0 14358 0 x/8=y.75
; 6 14359 7 x/8=y.875
; 5 14360 6 x/8=y.00
; 4 14361 5 x/8=y.125 j.needle
; 3 14362 4 x/8=y.25
; 2 14363 3 x/8=y.375
; 1@16384 14364 2 x/8=y.5 63×228 halve start !!
; 0 *14365 1 x/8=y.625
; 0 *14366 0_NO_delay x/8=y.75
; 6 *14367 7 x/8=y.875
;5<0+ 5 *14368 6 .0 >+6>6 <| check
;5<1+ 4 14369 5 .1 >+5>6 | apparent
;5<2+ 3 14370 4 .2 >+4>6 | number
;5<3+ 2 14371 3 .3 >+3>6 | cycle
;6<5+ 1 14372 2 .5 >+2>7 | in
;6<6+ 0 14373 1 .6 >+1>7 | Cycle
;6<7 0 14374 0_NOdelay .7 >+0>7 | +2A/+3
;14< 6 14375 7 .8 >+7>15 >>6 >| ONLY
; every (7th and) 8th cycle are 'UN'contended= NOT-delayed !!!!!!
; my own calc says:
; 19/8=2.375 8*0.375 x=3 > ut=+2
; 20/8=2.5 8*0.5 x=4 > ut=+1
; 21/8=2.625 8*0.625 x=5 > ut=+0
; 22/8=2.75 8*0.75 x=6 > ut=+0
; 19=10011 > 011 >> 100 = 4 -2= 2 ula
; 20=10100 > 100 >> 011 = 3 -2= 1 ula
; 21=10101 > 101 >> 010 = 2 -2= 0 ula
; 22=10110 > 110 >> 001 = 1 -2=-1 =0 ula
; sync idea IN a,(254)=11tstate and contended ?? 128k port 254 is UNcontended :)
; screentime bordertime
;@14364 14364+128=14492 +100 =14592 128-228
; +128=14720 +100 =14820 356-456 noncontention
hmm, does not look very readable anymore, the tabs seems a bit wrong now
i tryed a double-screen pixel rotate and the ATTR is difficult