pouët.net

Eager (to live) by Life on Mars

Full title:     Eager (to live)
Label:          Life on Mars

Credits:        spke^lom (Design, Code)
                nq^skrju (Music)

                The "Hype Productions" intro was coded by trefi
                using graphics by diver^4d and music by nq^skrju

Party:          3BM OpenAir 2015
Compo:          ZX Spectrum Demo

Requirements:   ZX Spectrum 128K/+2ab/+3/Pentagon/ScorpionZS256+
                This demo absolutely requires 3.5MHz CPU.
                It may start without it, but you won't enjoy it
                nearly as much. AY/YM stereo mod is highly
                recommended (ABC or ACB are both supported).

Duration:       About 3 minutes of content; the demo is looped
Contacts:       zxintrospec@gmail.com

Notes:          <3 summer, 3BM and Hype.

                Special thank you to diver^4d for his massive
                help in re-designing the intro, few other cool
                suggestions and real ZX Pentevo testing/audio
                recording. We are also very grateful to riskej
                for his help with testing the demo on a real
                ZX Spectrum +3 (this is how we discovered that
                our original balance was not all that great) and
                also for his extensive knowledge of classics.

                "Eager" is a demo about sensation (in the Jungian
                sense of the word). It is very much a demo build
                around a sound design, and as such it is intended
                to reproduce a sensation of sound blowing at you
                through a set of substantial speakers. Hence
                this demo's obsession with tunnels and zoomers
                is an intentional part of the design; hence, the
                story this demo is trying to tell has no true
                ending. Put simply, this demo is about stuff
                flying in your face endlessly.

                I believe that "Eager" is the second ZX Spectrum
                demo to properly combine digi-drums with 50Hz
                newschool demoeffects in full screen (the first
                demo of this kind was "Scroller" by DeMarche
                (2010)). "Scroller" implemented digidrums using
                Covox; this demo does not require any extensions.
                Thanks to riskej and boleg, I know several other
                examples of demos that featured digi-drums tracks
                combined with non-static imagery ("Mind Gigademo"
                by Cross Road/Bad Boys Company (1994), "Zy-zy
                Megademo" by Megacode/KSA (1996) as well as
                "Andrenalize" by Global Corp (1998)). All of
                them ("Scroller" included) achieved this feat by
                careful interleaving of the sound loop with the
                effect codes. The complexity of such an
                arrangement is such that in every one of these
                demos, only one scene is coded with the digital
                drums and the effects are limited to various
                constant-time routines: i.e. combinations of
                multicolour, scrolling, unpacked animations etc.
                
                The strategy used in this demo is very different
                and is more reminiscent of the "interrupting
                drums" commonly used in beeper engines. The basic
                idea is that if digi-drum sounds are all
                relatively short (about 110,000 t-states in our
                case, i.e. about 31.4 ms), it is possible to use
                track with relatively slow speed and pre-generate
                in advance video frames to be shown as needed
                (even in the middle of drum playback). This
                dramatically reduces the (constant) time
                requirements for the effects and allows, in
                principle, to implement almost any type of an
                effect as long as its average and maximum running
                times are within the engine requirements. It also
                allowed me to use fairly high-quality samples, at
                31.25kHz. The engine can simultaneously playback
                two samples into two different channels, which
                helped to compensate for relatively low volume of
                digital sounds on AY/YM chip by doubling up the
                sound. It also allowed us to play some neat
                tricks with the stereo.

                In the case of this demo, the music speed is 5,
                i.e. in theory drum sounds may need to be
                produced once every 5 frames. In reality the
                average would be just over one drum kick per 10
                frames. One frame out of every five is occupued
                by copying of frames from buffer onto the screen.
                This leaves me, on average, with about 30-35K
                t-states per generated frame, i.e. I tend to
                generate about 4 new frames per every 5 frames
                with the drum sound. My frame buffer holds 8
                frames. The need to render effects into the
                buffer and then copy them onto the screen
                necessitates the use of attribute-only effects
                and gives me about 30000/768 ~ 40 t-states per
                byte to play with. I worked hard to make this
                limitation not overly blatant.

                Essentially, the demo is based upon three
                effects. First, I prepared two different
                versions of the tunnel. One type of the tunnel
                is a plasma-type LUT, which is very smooth
                (fixed-point arithmetics, essentially), but
                fairly slow, ~100 t-states per byte and not
                very convenient to use with textures. The key
                speed up is achieved by working with the 256
                bytes square chunk buffer and then very quickly
                copying/reflecting it onto the screen:
                ld a,(hl) : ld (nn),a : ld (mm),a
                ld (bc),a : ldi ; less than 15t per byte
                The second kind of the tunnel is a much faster
                direct LUT, which is great for working with
                textures, but not very flexible in terms of
                available dynamics.

                The second effect is the combination of
                striped animation technique that appeared in
                my previous demos with the palette cycling, to
                significantly increase the number of frames for
                motion of objects across the screen, all in
                50fps full screen. I am still very excited
                about this style of animation and will surely
                do more of it.

                The third effect is a true chaos zoomer, also
                in 50Hz. It turns out that the main trick to
                get this effect working translates well onto
                ZX Spectrum architecture; the resulting render
                is simply a sequence of pre-generated:
                ld hl,nn : ldi
                (the main magic is, of course, in the specially
                prepared table look-ups). I will definitely
                look into higher resolution implementation of
                chaos zoomer on ZX Spectrum some time soon.

                Overall, this demo took a lot more time than
                I expected due to my difficulties in coming
                up with the scheme for synchronizing
                asynchronyous frame generator with the
                display of frames synchronized to the soundtrack.
                The balance between digital/chip sound also
                proved tricky to get right. I definitely was not
                ready for the resulting complications; hence,
                the relatively raw state of the party version
                of the demo. Hopefully, this improved final
                version should resolve most of the issues
                with the party release.

Libraries:      The variation of PSG player used in this demo
                is the fastest player of compressed PSG music
                currently available on ZX Spectrum. It always
                uses less than 1K t-states (below 500 t-states
                per frame on average). The compressor is by
                psndcj^tbk, with some minor format
                modifications by yours truly.

                The demo kernel is my usual demo kernel with
                numerous hacks needed to accomodate the
                asynchronious playback of frames. I do not
                think I will use the kernel from this demo
                elsewhere, at least not without re-writing;
                I did not fully comprehend the consequences
                of asynchronicity when I was hacking together
                a custom kernel and the resulting kernel ended
                up being too capricious.

                Otherwise, the toolset I used to make "Eager"
                is very similar to what I did in my previous
                demos. The only big change was much more
                active use of Processing, where I created
                all of my effects before converting them to
                ZX Spectrum and generated over 100K of
                assembler source codes for some of the effects.