128 Sprites in C Demo

Show us your work, thrill and amaze us :)

Moderator: Programming Moderators

Alcoholics Anonymous
Posts: 495
Joined: Mon May 29, 2017 7:00 pm

128 Sprites in C Demo

Post by Alcoholics Anonymous » Wed May 16, 2018 2:25 pm

Source code:
https://github.com/z88dk/z88dk/tree/mas ... ixed-sw-hw

Direct link to sna:
https://github.com/z88dk/z88dk/raw/mast ... w/main.sna

Direct link to sna for cspect (hardware version should work with zesarux):
https://github.com/z88dk/z88dk/raw/mast ... cspect.sna

Note: The hardware version does not run properly under cspect currently but I expect it works properly under zesarux. Under zesarux I see garbage in layer 2 but I think that's because I am running an older version of the emulator before layer 2 could be moved. The issue for cspect is that it's using the wrong palette entry for bright magenta ($E3) when it should be $E7 (and actually the program should really be setting its palette instead of depending on the default for real programs as opposed to demos). This way bright magenta is not treated as transparent by the hardware which initializes the global transparent colour to $E3. There is also another potential discrepancy with the emulators where the global transparent colour is compared to the 8-bit colour coming out of the sprite palette instead of the final 9-bit colour for determining sprite transparency. This is currently listed as a hardware bug. This isn't really tested in this demo because, although it changes the global transparent colour to $E7 and the sprite transparent colour to $E7 in the hw sprite definition, it does not change the 8-bit sprite palette so the final 8-bit colour for transparent generated by the sprite unit is $E7 and the default 9-bit colour for that entry will be $E7*2 too.

It's not a pretty demo because I am pretty crap at graphics. The main thing I wanted to look at is the use of software sprites on the ula screen mixed with layer 2 graphics. If the ula is drawn on top of layer 2 and the software sprites are ink only, they can be mixed into layer 2 without colour clash. Since the software sprites do not contribute to the 12 per scan line limit on the hardware sprites, I though they could be used for things like bullets. There are a lot of indy games about that are showing that a proper mixture of spectrum-clash character and layer 2 freedom can be done well so that's a longer term goal to look at.

The software sprite engine being used is called sp1 and is built into z88dk. The intention is to port this to the timex hi-colour mode, the timex hi-res mode and something similar for layer 2 but for the moment it is only written for the standard spectrum display. Some of the key features of this engine is that it is free-running (you do not have to sync with the raster and flicker can never occur) and it has a differential update algorithm (it divides the screen into character squares and only redraws characters that are modified between updates). The former feature makes it very easy to use and the latter means it's especially interesting for a layer 2 port.

The engine has been used to make around 50 games on the spectrum, however this is largely unknown because it's rarely advertised as being used in games except for "churerra" which is a game scripting framework that uses an older version of the library.

A series of articles on how to use sp1 is being written now by another user learning sp1:
https://github.com/z88dk/z88dk/blob/mas ... edGuide.md

==============

When the program starts you'll just see a scrolling layer 2 background.

Create at least 30 software sprites by pressing "S" repeatedly. You'll need that many to make it slow enough to comfortably look at. The max number of software sprites is capped at 64. You can reduce the number of sprites with "s".

The software sprites are made ink-only and mix well with the underlying layer 2. You can turn on maximum colour clash by pressing "c". What this does is add a paper colour to the sprites. This can be undone by pressing "c" again.

Hardware sprites can be created by pressing "H". You can reduce the number by pressing "h". Up to 64 can be created but as the zx next has a 12 per scanline limit, you may see portions of hardware sprites disappear from view when more than 12 are on the same scan line.

Splats can be added with "Z" and removed with "z". Splats are just a hashed area added to the ula screen. The sp1 engine can be told not to draw into specific character squares and that's what happens with these splats. The character squares they are drawn to are removed from the engine so that the software sprites appear to move behind them. Go ahead and add about 10 of them.

You can pause sprite movement by holding down a key. If you hold down ENTER you can see how the software sprites move behind the splats. Layer 2 continues to scroll because this is done in the interrupt routine.

The program starts with the hw sprite layer on top of the ula screen. You can switch that order with the "p" key. If you hold down "p" the hw sprites will instantly move underneath the sw sprites and the splats. Keep pressing "p" to toggle.


================

The source code is at the link above:
https://github.com/z88dk/z88dk/tree/mas ... ixed-sw-hw

There's no api yet for hw sprites or layer 2 so the hardware is being programmed directly.

im2 mode is set up a little bit differently than is normally seen with z88dk programs. It's being set up with minimum overhead. The file "interrupt.asm" is directly creating a 257-byte vector table and jump to isr in memory. The sna generator will pick up these fragments and insert them in the right place in the output sna. The file also initializes im2 mode by inserting code into section "code_crt_init" - note there is no ret!. This code will run just before main is called. main.c enables interrupts after things are initialized.

The interrupt routine is written in C and is found in main.c. An IM2_ISR_8080 wrapper is used to ensure registers are saved and the exit is "ei; reti". The 8080 part indicates only the main set of registers is saved plus ix when zsdcc is used as compiler. Drop the 8080 part to get a wrapper that saves all registers.
Last edited by Alcoholics Anonymous on Fri May 18, 2018 2:49 pm, edited 3 times in total.

JoeZX
Posts: 574
Joined: Mon May 29, 2017 9:11 pm
Location: Slovakia

Re: 128 Sprites in C Demo

Post by JoeZX » Thu May 17, 2018 7:57 am


User avatar
chernandezba
Posts: 228
Joined: Mon May 29, 2017 8:14 pm

Re: 128 Sprites in C Demo

Post by chernandezba » Thu May 17, 2018 9:09 pm

Tested in ZEsarUX and works perfect!! :)
----

ZEsarUX
ZX Second-Emulator And Released for UniX
https://github.com/chernandezba/zesarux

Alcoholics Anonymous
Posts: 495
Joined: Mon May 29, 2017 7:00 pm

Re: 128 Sprites in C Demo

Post by Alcoholics Anonymous » Fri May 18, 2018 2:48 pm

Thanks JoeZX! There was an issue with running on real hardware that I've corrected and made a note of above. Chernandezba you may want to check against zesarux again. It's almost working on my zesarux install but I expect the problem I'm seeing (garbage in layer 2) is because my install is older than current. I'll have to update :)

User avatar
chernandezba
Posts: 228
Joined: Mon May 29, 2017 8:14 pm

Re: 128 Sprites in C Demo

Post by chernandezba » Tue May 22, 2018 1:50 pm

Well now I don't see the scrolling background. Just a pink solid colour. The rest of the demo works as expected
----

ZEsarUX
ZX Second-Emulator And Released for UniX
https://github.com/chernandezba/zesarux

Alcoholics Anonymous
Posts: 495
Joined: Mon May 29, 2017 7:00 pm

Re: 128 Sprites in C Demo

Post by Alcoholics Anonymous » Tue May 22, 2018 10:51 pm

chernandezba wrote:
Tue May 22, 2018 1:50 pm
Well now I don't see the scrolling background. Just a pink solid colour. The rest of the demo works as expected
The only change is changing the global transparent colour (nextreg 20) to 0xe7. This matches bright magenta as entered into the palette by NextOS and the current firmware. The older version was using the default transparent colour of 0xe3 which does not match bright magenta anymore and therefore on the real hardware you saw a magenta background. So it looks like zesarux has the wrong palette value for bright magenta (0xe3 instead of 0xe7) or nextreg 20 is not working.

I'm also accommodating a known bug in the sprite hardware where the global transparent colour is compared against the 8-bit colour generated out of the sprite palette to determine transparency. Ie the comparison is *not* made against the final 9-bit colour of the sprite pixel. I changed former $E3 bytes in the sprite definition to $E7. You should not see magenta in the sprites themselves, although you can't see that now with a magenta background in place. Maybe this won't show up as an emulation difference though as the 9-bit sprite palette may be initialized to contain the same colours ie 0xe7 maps to 0xe7*2 (I'm not sure about this).

User avatar
chernandezba
Posts: 228
Joined: Mon May 29, 2017 8:14 pm

Re: 128 Sprites in C Demo

Post by chernandezba » Wed May 23, 2018 7:12 am

ZEsarUX handles the transparent colour to the colour set to register 20, just like the documentation said, and comparing to the MSB of the final colour (discard bit 0 and shift right), just like this:

if (final_rgb9_colour>>1) == next_register [20] -> it's transparent colour

Also, the documentation says that this register 20 is initialized to E3, not E7, and so I'm having this E3 default value on ZEsarUX. If someone has changed it, I will wait until they change the specs and make it official. I'm not doing changes until they are final/stable

You should initialize register 20 to E7, or whatever value you want, so all versions of the firmware/emulator will work with your demo ;)

Cheers
----

ZEsarUX
ZX Second-Emulator And Released for UniX
https://github.com/chernandezba/zesarux

User avatar
chernandezba
Posts: 228
Joined: Mon May 29, 2017 8:14 pm

Re: 128 Sprites in C Demo

Post by chernandezba » Wed May 23, 2018 7:32 am

Update: I see you are changing register 20 to E7. But, you are setting Spectrum ULA background to paper 3+bright, so the default ULA1 rgb9 colour for index 139 (128+3+bright*8) is 1C7H (and 1C7H >>1 = E3H). So, if the Next team has not changed the default colur for index 139 (should be 1CEH or 1CFH to match your colour), you should change it by yourself.
----

ZEsarUX
ZX Second-Emulator And Released for UniX
https://github.com/chernandezba/zesarux

User avatar
chernandezba
Posts: 228
Joined: Mon May 29, 2017 8:14 pm

Re: 128 Sprites in C Demo

Post by chernandezba » Wed May 23, 2018 7:42 am

Update 2: You can have it working on ZEsarUX by changing colour 139, with ZRCP, like this:

command> tbblue-set-palette ula first 139 1CEH

You need to compile the last ZEsarUX sources because that ZRCP command was using only 8-bit values

;)
----

ZEsarUX
ZX Second-Emulator And Released for UniX
https://github.com/chernandezba/zesarux

Alcoholics Anonymous
Posts: 495
Joined: Mon May 29, 2017 7:00 pm

Re: 128 Sprites in C Demo

Post by Alcoholics Anonymous » Wed May 23, 2018 10:38 pm

chernandezba wrote:
Wed May 23, 2018 7:12 am
Also, the documentation says that this register 20 is initialized to E3, not E7, and so I'm having this E3 default value on ZEsarUX. If someone has changed it, I will wait until they change the specs and make it official. I'm not doing changes until they are final/stable
It has been changed to E7.

The current firmware is doing this when the machine initially powers up:

Code: Select all

	//initial colours
	for (c = 0; c<16;c++)
	{
		REG_VAL = 0b00000000;
		REG_VAL = 0b00000010;
		REG_VAL = 0b10100000;
		REG_VAL = 0b10100010;
		REG_VAL = 0b00010100;
		REG_VAL = 0b00010110;
		REG_VAL = 0b10110100;
		REG_VAL = 0b10110110;
				 
		REG_VAL = 0b00000000;
		REG_VAL = 0b00000011;
		REG_VAL = 0b11100000;
		REG_VAL = 0b11100111;    // <--- E7 bright magenta
		REG_VAL = 0b00011100;
		REG_VAL = 0b00011111;
		REG_VAL = 0b11111100;
		REG_VAL = 0b11111111;
	}
What the firmware does doesn't matter with NextOS because NextOS is also initializing the palette and uses E7. Garry provided me with the colours that NextOS is currently initializing the palette with:

https://github.com/z88dk/z88dk/blob/mas ... lor.m4#L24

However I think there is no actual problem with zesarux. I think you just have old firmware or an old NextOS installed in your mmc file (or if you don't have NextOS in the mmc file, it will be the old firmware) :) zesarux is different because it actually emulates the machine from power up this palette initialization will be taken care of automatically and is not baked into the emulator.

The firmware code that initializes the palette is in "tbblue_loader.rom" in zesarux which I think you have an old version of. The last version that victor compiled can be found here: https://drive.google.com/file/d/1u9cgf- ... sp=sharing I'm trying to build my own versions of these things but there are issues with the fat driver currently. I bet if you copy this file into zesarux as "tbblue_loader.rom", the whole thing works :) (NextOS will override the firmware though so if you are running that, it could be an old version of NextOS sets it back to E3).

Post Reply