I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by rothers »

So I'm trying a fast 8 way scrolling engine only using the attribute layer for the 48k. It scrolls at 4x left and right, an 8 vertical.

I'm going to have 2 maps, one for each 4bit shift attribute.

So all the ASM has to do is read the section of the map to the attribute screen and like magic it will 'scroll'.

It's been a long time since I wrote anything in ASM, and I want to modify this to deal with it as it'll be too slow in C:

org 0x5ccb ; start of code

LD A,1
LD B,8 ; Number of times to loop (8 bits)

scroll
ld de,0x4000 ; DE = screen
LD B,A
LOOP:
inc DE
DJNZ LOOP ; Decrease B, and loop A times
inc a

Start
ld hl,ImgData ; HL = image data
ld bc,0x1aff ; 6144 bytes bitmap, 768 bytes attributes ldir counts this down until 0
ldir ; Repeats LDI (LD (DE),(HL), then increments DE, HL, and decrements BC) until BC=0. Note that if BC=0 before this instruction is called, it will loop around until BC=0 again.
;Loop
jp scroll ; infinite loop

ImgData ; data file
incbin "themap.bin"
org 0xff57
defb 00h ; end of ROM

Is this a good starting point? Is the way I'm increasing DE wrong? I've done a little loop... I need to unnderstand how to put C variables in to ASM code really.

Here is a picture of the layout of the screen to get an idea what I'm doing, all the scrolling is done by manipulating the attribute later. The sprites are then drawn on top.

Image
AndyC
Dynamite Dan
Posts: 1409
Joined: Mon Nov 13, 2017 5:12 am

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by AndyC »

It's a bit hard to follow what you're actually trying to do.

I'd have expected:

LD HL, 8
ADD HL, DE
EX HL,DE

would be faster than looping 8 times incrementing DE.

BUT why is DE incrementing anyway? Surely as you scroll the attributes your source pointer would change (i.e. the value in HL) but the destination (the screen attributes) would remain constant?

Maybe I've just not had enough coffee yet....
berarma
Microbot
Posts: 106
Joined: Thu Mar 09, 2023 10:55 am

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by berarma »

I guess you're trying to implement vertical attribute scrolling but your code is pretty incomprehensible.

It's been also some time since I've written assembler routines for the Spectrum but this could be a starting point without any optimisations.

Code: Select all

; Scroll up
ld bc, 0x2e0 ; size of the attribute map minus one line
ld hl, 0x5820 ; start of second line of attribute map
ld de, 0x5800 ; start of the attribute map
ldir

Code: Select all

; Scroll down
ld bc, 0x2e0 ; size of the attribute line minus one line
ld hl, 0x5adf ; end of attribute map minus one line
ld de, 0x5aff ; end of attribute map
lddr
User avatar
Einar Saukas
Bugaboo
Posts: 3146
Joined: Wed Nov 15, 2017 2:48 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by Einar Saukas »

Unrolled loops is an easy way to improve performance. For instance, instead of this:

Code: Select all

; Scroll up
ld bc, 0x2e0 ; size of the attribute map minus one line
ld hl, 0x5820 ; start of second line of attribute map
ld de, 0x5800 ; start of the attribute map
ldir
you can use this:

Code: Select all

; Scroll up
    ld bc, 23*256+736 ; 23 rows + 736 LDIs
    ld hl, 0x5820 ; start of second line of attribute map
    ld de, 0x5800 ; start of the attribute map
loop:
REPT 32
    ldi
ENDR
    djnz loop
or if you want to skip a column on each side:

Code: Select all

; Scroll up
    ld bc, 23*256+736 ; 23 rows + 690 LDIs
    ld hl, 0x5820 ; start of second line of attribute map
    ld de, 0x5800 ; start of the attribute map
loop:
    inc l ; skip left side column
    inc e
REPT 30
    ldi
ENDR
    inc hl ; skip right side column
    inc de
    djnz loop
Last edited by Einar Saukas on Wed Jan 31, 2024 12:03 pm, edited 1 time in total.
User avatar
Einar Saukas
Bugaboo
Posts: 3146
Joined: Wed Nov 15, 2017 2:48 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by Einar Saukas »

rothers wrote: Wed Jan 31, 2024 7:15 am It scrolls at 4x left and right, an 8 vertical.

I'm going to have 2 maps, one for each 4bit shift attribute.

Image
Thus basically you fill the screen with CHR$ 133 (or CHR$ 138) and your scenery will be mostly scrolling attributes, correct?

However... whenever you move left or right, you need to copy all attributes from one of your alternate maps. So why do you need to scroll anything? Is it not enough to simply copy attributes from a different part of the map to the screen?
Last edited by Einar Saukas on Wed Jan 31, 2024 11:59 am, edited 1 time in total.
User avatar
Joefish
Rick Dangerous
Posts: 2059
Joined: Tue Nov 14, 2017 10:26 am

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by Joefish »

Sounds complicated - far easier just to have two buffers and swap between them, and scroll each one a byte at a time.

Now, if you really want to be clever, write the data to the two screens of a 128K Spectrum and time it such that it takes four scanlines to update each row, and then swap screens every half character row, thus doubling the vertical attribute resolution and letting you scroll by 4 pixels vertically. Simples! :lol:
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by rothers »

I've uploaded a demo of this working, it's absurdly fast and this is with a wait VBL.

https://toastyfox.com/zx/sonic.html

Will keep you updated thank you for all the ideas, I feel 'Super Sonic Bro' might be coming sooner than I thought :lol:
User avatar
ParadigmShifter
Manic Miner
Posts: 671
Joined: Sat Sep 09, 2023 4:55 am

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by ParadigmShifter »

TLL (or Cyclone, or both) had a good optimisation where it didn't redraw any character cells which are all 1 colour (by just setting ink and paper to same value), only drawing the diagonal bits of cliffs etc. which might be worth doing (although if it is fast enough already never mind).
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by rothers »

Stefan wrote: Wed Jan 31, 2024 7:28 pm Have you looked at Ringo? https://spectrumcomputing.co.uk/entry/3 ... trum/Ringo

Source code available on GitHub https://github.com/DenisGrachev/Ringo-8
Yes, I know about Ringo, but it does not work on the 48k which is my target. It's the computer I had, and I want to push it to its limits.

Anyhow, I now have sprites working. Using the attribute layer is damned fast, why on earth didn't more games do this back in the day...
highrise
Manic Miner
Posts: 305
Joined: Fri Mar 20, 2020 11:29 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by highrise »

True story - I'm quite friendly with Denis who wrote Ringo and before he coded it, I had a chat with him about a technique to use attributes to create a full colour low res effect. I completed a demo engine that ran on 48k. I think he must have been inspired since Ringo came out several months later, using his own methods for the 128k machine.

Anyway, long story short, I have some code which can maybe do what you want. It's timed for the 48k machine, and can read and draw attributes from a memory buffer to the screen fast enough to be synched to the beam. When it's full screen It doesn't leave a lot of time for game code, but it runs in a timed loop as the beam moves down so it can be any height. I've attached a sample picture.

Drop me a pm if you want to take a look,it would be interesting to dig it out of storage.
Image
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by rothers »

Hi,

Yes, if it can handle 50 fps or so. I've got sprites in my demo now, and you can run around the first level of Sonic, which I spent more time writing a converter for than writing the engine for this :lol:

The way I'm doing 4x8 means it takes hardly any CPU to update the screen, it's a decent trade-off but obviously Ringu on the 48k would be mind-blowing, beyond my abilities at the moment, I was told only the 128k could do it due to the ghost screen.

If you could open source your code, maybe I and everyone else could have a look at it be a real shame for something like that to be lost!
highrise
Manic Miner
Posts: 305
Joined: Fri Mar 20, 2020 11:29 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by highrise »

Well, I used to open source stuff, with the strict proviso that people didn't use it for commercial games without my permission. Unfortunately this got ignored one too many times so I don't really do that anymore. But I'm always open to collaborations with like-minded chaps.
highrise
Manic Miner
Posts: 305
Joined: Fri Mar 20, 2020 11:29 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by highrise »

p.s the screen does update at 50hz. It uses an attribute buffer of 1536 bytes, with each byte containing two 3-bit colour values. Whatever you write to that buffer will be displayed on screen. But given that anything you do would have to be in the border, it's quite limiting.
highrise
Manic Miner
Posts: 305
Joined: Fri Mar 20, 2020 11:29 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by highrise »

sorry, reading that back, I don't think I was especially clear - any game code would have to be done when the raster beam was in the border, thus making it quite limited - although you could potentially use the top two thirds for the game and have quite a few more cycles to play with.
User avatar
Lethargeek
Manic Miner
Posts: 744
Joined: Wed Dec 11, 2019 6:47 am

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by Lethargeek »

a bit faster method than unrolled ldis - for the each line, prepare a code like:

start: ld (hl),N: inc l: ld (hl),N ... ld (hl),N: inc l:jp start

somewhere in the middle there is a ret, you just need to shift it the each frame and replace one N value and the entry point on the stack table
for vertical scrolling you need to replace all N values for one line and correct the stack table in a similar way (with the calls to correct h in it as well)

(but it's only 14 cycles/byte vs ldi's 16 so maybe it's not worth the hassle)
User avatar
ParadigmShifter
Manic Miner
Posts: 671
Joined: Sat Sep 09, 2023 4:55 am

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by ParadigmShifter »

The stack is the fastest way to copy but you need to make sure no interrupts go off during the copy (so either put it inside a DI/EI section or do it straight after a HALT and make sure it does not take a whole frame to finish)

Code: Select all

	MACRO MEMCPY16 dest, src
	ld sp, src
	pop af
	pop bc
	pop de
	pop hl
	exx
	ex af, af`
	pop af
	pop bc
	pop de
	pop hl
	ld sp, dest+16
	push hl
	push de
	push bc
	push af
	exx
	ex   af, af`
	push hl
	push de
	push bc
	push af	
	ENDM
If you don't use a macro you can self modify the dest, src address before you execute it.

I also have versions which copy 14, 6 or 4 bytes for some reason. 4 byte version has HL and DE available for addresses. 6 byte version you can use HL and H'L' as src/dest address

Code: Select all

	MACRO MEMCPY14 dest, src
	ld sp, src
	pop af
	pop bc
	pop de
	pop hl
	exx
	pop bc
	pop de
	pop hl
	ld sp, dest+14
	push hl
	push de
	push bc
	exx
	push hl
	push de
	push bc
	push af	
	ENDM

	MACRO MEMCPY6 dest, src
	ld sp, src
	pop af
	pop bc
	pop de
	ld sp, dest+6
	push de
	push bc
	push af	
	ENDM

	MACRO MEMCPY4 dest, src
	ld sp, src
	pop af
	pop bc
	ld sp, dest+4
	push bc
	push af	
	ENDM
rothers
Drutt
Posts: 35
Joined: Sat Dec 30, 2023 2:50 pm

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by rothers »

Thanks guys, I'm just reading up on the best way to store level data in terms of reading/writing to it (why not write to it, we have RAM after all, this isn't a console 😅). I apologise if I end up asking some dumb questions, I was barely alive during the spectrum era, but I love how simple the machine is.

I'm looking at the master system sonic game as a kind of inspiration, I especially like the bonus levels on that game, they seem to be the most fun part.

I'm trying to use the quirks of this engine to the Spectrums advantage in doing something a console could not, so I'm thinking maybe highly destructible levels, smashing through walls, explosions etc. etc.
User avatar
ParadigmShifter
Manic Miner
Posts: 671
Joined: Sat Sep 09, 2023 4:55 am

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by ParadigmShifter »

Obviously for my fast memcpy routines you also need to save and restore SP before changing the stack pointer.

e.g. here's a fast CLS showing how to do that (also uses DI/EI)

Code: Select all

	; A -> attrib to set when clearing screen
	; at exit
	; HL = 0
	; B = 0
cls_fast:
	di                  ;disable interrupt
	ld (.stack+1), sp	;store current stack pointer
	ld sp, 16384 + 6144 + 768
	ld b, 128			; clear attribs in 128 * 3 pushes
	ld h, a
	ld l, a

.attribloop
	push hl
	push hl
	push hl
	djnz .attribloop

	ld hl, 0
.loop1
	push hl             
	push hl             
	push hl             
	push hl
	push hl             
	push hl             
	push hl             
	push hl
	push hl             
	push hl             
	push hl             
	push hl
	djnz .loop1			
.stack
	ld sp, 0            ;parameter will be overwritten
	ei
	ret
User avatar
+3code
Manic Miner
Posts: 434
Joined: Sat Mar 19, 2022 7:40 am

Re: I'm doing a sonic clone, best way to scroll the attributes layer 4 bits at a time?

Post by +3code »

I see the demo has been updated, now there is a sprite you can control with o-p-space. Nice thing.
Post Reply