| Chromatic Admiration | |
| |
| Effects | Part | Effect name | Parameters | Notes |
| Plasma | Color mode: ECM Area: 40x25 chars | Different implementations of it: plain, radial, center-driven. |
| Texture-mapped Tunnel | Frame rate: 2.3 Color mode: ECM Area: 40x25 chars | Basically an evolution of Plasma into a Tunnel effect. |
| Metaballs | Frame rate: 1.4 Color mode: ECM Area: 40x25 chars | |
| |
| Description | chromatic admiration
a 4K intro for the Plus/4
by resource + logicoma
credits:
edhellon - code h0ffman - music and "stream" music player oswald - additional code poison - script, colors, dirart ferris - packer (custom build of admiral p4kbar) teo - DJ Khaled
thanks:
hermit - custom tedzakker build, lots of tips on reducing music size blueberry - sizecoding tips blala - moral support tobylobster - fast sqrt https://github.com/TobyLobster/sqrt_test/blob/main/sqrt/sqrt1.a cordic authors - atan2 algo https://www.eit.lth.se/fileadmin/eit/courses/eitf35/2017/CORDIC_For_Dummies.pdf
musical size coding notes - h0ffman
Hey reader, another release, another readme :) anyways, I thought I might add some notes on what happened with the music in this release. As with my last play with the Plus/4 I was using TEDzakker again. When working on phosphorizer I had to hand optimise the music data to save some bytes. Time was a bit more "compressed" then so I didn't get a chance to tool anything up to make things easier. This time however the music was finished literally weeks before the party. Tune in place, did a quick size check and found we were over the size limit without a finished intro.
1. Consume, optimize and re-organise
This first step was to just make life easier. Hand optimising sucks balls and I didn't want to waste time with it. I built a little C# console app which took the emulator snapshot and pulled all the pattern and sequence data out. Once in the classes it's easy to identify what isn't used and with a little more work I was able to organise all the patterns in sequential order. This had a fairly good gain, but not enough.
2. Half the size of the patterns
Hermit noticed most of the patterns in the tune had spaces between the notes. I tend to write this way so I have space for rolls etc. He suggested we change the tempo and remove the gaps. A quick change to the tool meant I could remove the spaces automatically, with a few hand adjustments. The result was the exported player and song data reduced quite a bit in size but the resulting packed file got larger than it was before, so wasn't completely helpful.
Hermit also suggested we switch off the NOP's pattern data packing function. This did manage to save quite a few bytes but I thought there must be more savings to be had.
3. Stream the data instead
Having worked with Cinter, Blueberrys Amiga 4k Synth, the thing I noticed was how the pattern data was huge. It takes up a lot of RAM because it's essentially just a data stream but it compresses really well. I wondered if we could do something like that here so as a test I did an export of the tune without any pattern data added byte streams with it just to get a feel for the size difference. A basic test with Shrinkler showed more than 128 bytes saved so seemed to be a winner. However it would mean the replay code would need to be modified. Song data in this state looked like it would take around 8kb RAM which Edhellon though should fit just fine with the intro.
4. Replay hacking
The replay code for TEDzakker is pretty complicated with a ton of switching statements to enable or disable features. First step here was to just get it working with the original song data as is. Instrument data was hacked out of the export into an includable source file in a repeatable way along with the original song data. I then added the byte streams and set about modifying the replayer to read those instead. This got working surprisingly quickly and brought us under 4kb. With everything in place and working, I carried on checking through the code, removing anything we didn't need like the code for the pattern order, byte init's which were no longer needed. This put us in a position where I could edit the tune and hit a button on the tool to generate all the new data format should we need to edit anything. Happy days!
And there we have it. My first play with 6510 ASM and a fun little experiment in leaning into compression algos.
Big thanks to Hermit for the help, advice and pointers on the replayer. It would have been so much harder without your help.
Also shouts to Edhellon who helped me with the 6510 stuff and chatting code shit late at night. This was super fun to work on mate.
Anyways, see you in the next release!
- h0ffman
general coding notes - edhellon
Hey all, I hope you like our 4K. This is actually my first 4K on Plus/4 somewhat weirdly. The idea to do something like this came I think sometime in late 2020 after we did "warpless", I thought it would be great to do this in 4K but also include other classic stuff (plasma, radialplasma, tunnel, etc) in this nice "halftone dithered" ECM mode. Told Oswald who agreed so we loosely planned for Revision 2021. Of course in typical Resource fashion we didn't even start (hence we did our Pico 8 demo "modern minimalism" as a plan B to have something for Revision). After I saw "phosphorizer" I realised we must do it on Plus/4 for the colors and of course with h0ffman doing the music - his approach to TED sounds is so fresh!
Teo (the DJ Khaled of the demoscene) put me in contact with h0ffman and we had some initial discussions and then of course nothing happened for months.
I really started around mid-february (the initial git commit was on 2022.02.20 - nice date!) when I started to panic about not making it. The first effect was of course the blob reused from "warpless" but that version needs a 32k distance texture which obviously isn't optimal for a 4K, although with nothing else in there it actually compresses down to about 3.5K. :-)
So the first thing to do was to precalc that at startup, I implemented that surprisingly quickly after realising it only needs squaring, a square root function and a division table of about 130 bytes. Then came the plasma which is a classic and after that all the other radial effects. For those we also needed an atan2() function, at first I was thinking about trying to reuse trigonometry stuff from the KERNAL but gave up on that and Oswald pointed me to (and later implemented) the CORDIC algorithm linked above.
All was well but despite h0ffman's heroic efforts regarding the music and player we were still well over the size limit. I spent the last weeks basically trying to get it down to size. I had _a lot_ of dead ends with packed code being larger after "size optimising". Eventually had to leave out some stuff like a dithered charset for the "glitch" but didn't want to sacrifice any of the effects (and luckily didn't have to in the end, although even a day before Revision started it looked like one of the effects needs to go).
Regarding packers, h0ffman had the idea to use Ferris's packer (admiral p4kbar). To be honest I was initially sceptic about this especially when the intro was half finished and around 2K in size exomizer seemed to be winning because it has a lot smaller depacker. Once we got to the 3K mark p4kbar started winning and in the end it won by a very comfortable 163 bytes. Ferris helped getting it to work (it's not exactly a turnkey solution as is) and in the last minute even did a custom p4kbar build for me with a slightly different model more fitting to the binary blob I sent him - this actually gained us 3 bytes!
I also had very nice discussions with Blueberry at GERP two weeks ago about size coding. The moral of the story there is basically: macro the shit out of everything so that all your loops etc. are packer friendly, and optimise for packed size not unpacked size. For an old(skool) coder like me this is a very different mental model than what I was used to. State of the art packers are as close to black magic as one gets with a deterministic algorithm: for example changing one zeropage address from $03 to $E8 can change the compressed size by 2-3 bytes with no actual code changes involved... so in the last days I spent a lot of time changing one bit here and there and rerunning p4kbar and seeing I only made the packed size larger.
Oswald had the idea of involving Poison for the scripting and colors on Monday and Poison luckily agreed to help us (as always) and IMHO he did a superb job (as always) - the intro would not look nearly as good as it does without him!
I did some last minute rewrite of the script "engine" in the last days (I rewrote it twice actually) partially because Poison run into its original limits _very quickly_ and partially to save some bytes. The halftone charset is also stored in a rather weird way to have a more "packer friendly" layout in memory (Oswald's idea) which gained us about 15 bytes I think.
Despite starting a bit later than I would have liked to and being last minute with a lot of things, we had a slightly over size (4104 bytes or so) and very badly scripted (by yours truly) but otherwise feature complete version two days before the party (this must be a first in the history of Resource). Nevertheless, in true demoscene tradition a lot of tweaks to bring the size under 4K and improvements to the scripting etc. were done in the last minute. H0ffman actually made the music about 10 seconds shorter one day before the party (which gained us 4 bytes!) and Poison needed to adjust the script accordingly (Which also gained us a few bytes).
Big thanks to all who helped in making this, h0ffman for the insanely great tune, Ferris for helping with admiral p4kbar and being so patient with me and my stupid questions, Hermit for helping out with TEDzakker custom builds and a lot of tips on reducing the music size, and of course Poison for really bringing the intro alive!
See you soon!
- edhellon
final words
Please also find the TEDzakker workfile for the demo tune in this archive. We hope this will help people do more TEDzakker tunes for Plus/4 demos in the future!
Resource and Logicomacorp signing off. |
| |
Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon |