Compressors Part 1: Delta Animation Compressor
There are many ways to compress screen contents; many of them are used by various compressors designed to reduce title screens from games to a tolerable size. Regular readers of SCENE+ already know one of these compressors: Screen Compressor+D, which was featured in an earlier issue. Its advantage was that it tried 4 different methods and then chose the most efficient one. The disadvantage was that it was relatively slow.
A compressor presented in YS, on the other hand, was capable of smoothly animating 1/3 of the screen, and was also used by me for the rotating SCENE+ logo. But how do you achieve smooth animation across the entire screen?
To my knowledge, no one besides me has ever implemented the Delta Compressor for the Spectrum, yet it is precisely the compressor that allows you to animate full screen contents smoothly, provided certain conditions are met.
The Delta Compressor—which I will simply call Delta from now on—was used in the late eighties to get what were then state-of-the-art computers, like the Amiga or Atari ST, to display smooth animations. One of the programs I have from that era was Videoscape 3D, the most user-unfriendly program ever! Its only plus point was that it used Delta to play back very long animations.
What's good for the Amiga should be good enough for the Spectrum, I thought to myself, and pondered how this routine could be ported to the Speccy. Well, I don't know 68000 assembler—I'm no masochist! So I gathered information from Happy Computer and other magazines about how this compressor works, and indeed, it was ingenious for its time, back when MPEG meant nothing to anyone.
Delta works very simply: only the changes compared to the previous frame are saved. This means that you neither need a flag byte that doesn't occur in the screen data, nor much processing time, because only the changed bytes are written to the screen. With small changes on the screen, you could achieve a frame rate of 50 FPS and a small animation file size. With larger changes, I ended up with a size of approx. 3–4 KB per frame and an unacceptable frame rate, but with minor changes everything ran very smoothly. With the total of 640 KB of my MB-02+ (512K) and Spectrum 128, I could theoretically create brilliantly long, smooth animations—even in interlace!
For compression, I used a small BASIC program, while decompression runs very quickly thanks to a small MC routine.
The question I faced was: how do I store the changes without needing a 12 KB buffer where information precedes each byte indicating whether it is modified or not? Pretty stupid, right? Since I couldn't decipher anything from the 68000 code, I really started thinking about it and finally came up with the definitive idea:
Since unchanged bytes and changed bytes always alternate, it was sufficient to use a marker byte to tell the computer whether the first sequence represents changed or unchanged bytes. After that, sequences of 2 bytes each follow:
- Bytes remain unchanged: (A 2-byte sequence represents the number of unchanged bytes—theoretically up to 65535, which means it would also work on the SAM Coupé. The destination counter is simply increased by the number of bytes.)
- Bytes are changed: (A 2-byte sequence—theoretically 1 byte would also do—representing the number of subsequent bytes to be transferred, simply copied with
LDIR.)
Not only is it very fast this way, but it is also ingeniously simple; even I was surprised by the solution! Can it really be that easy? Yes! My depacking routine is not necessarily the absolute optimum, but it gave me another opportunity to learn something about MC, and I learned... that while the speed is high, the crash risk is too!
In the meantime, I have further improved and optimized the program in order to use it sooner or later for my game projects. Based on this description, every coder should now know what such a Delta should look like—after all, if even an Austrian managed it... Well, nothing against the area here, but the only serious competition I had was Spectec, wherever he may be now.
Regarding Delta, I can also add that it requires a so-called keyframe, which ideally should be packed with another screen compressor; and if the differences between individual frames are quite large, you can additionally use a shrinker compressor, and the entire finished animation can still be "imploded".
I then modified the BASIC compression routine so that a single unchanged byte situated between several changed bytes is also saved as changed. This prevents decompression from being unnecessarily prolonged.
— Tiger's Claw
This was the first part of the compressor series. If anyone wants to continue it, no problem! Write to me! In the next part comes the regular compression routine (Shrinker). I would also be happy to see some example animations from you.
Delta Decompressor Assembly Routine:
LD HL,Comprscradr ; Address of compressed screen
LD DE,16384 ; Screen address
LD A,(HL) ; First byte into A
INC HL ; Increment address counter
CP 1 ; Compare A with 1
JR Z,vers ; If yes, changed bytes! Go to vers
Start: LD C,(HL) ; Load BC with contents of (HL)
INC HL
LD B,(HL)
INC HL
EX DE,HL ; Swap DE with HL, since
ADD HL,BC ; addition is only possible on HL
EX DE,HL ; Swap values back
vers: LD C,(HL) ; Load number of changed bytes
INC HL ; into BC
LD B,(HL)
INC HL
LDIR ; Copy all changed bytes
LD A,D ; High byte of Destination
CP 88 ; Compare with 88 (22528)
INC HL
JR Z,Ende ; If value is reached, end
JR Start ; Otherwise go back to Start
Ende: LD B,H ; For LET X=USR adr,
LD C,L ; X = next free byte
RET ; Return to BASIC
The program is also capable of running with interrupts (e.g. music) and can execute from any address. I hope my comments are helpful! I had to copy the program from a notepad with many alterations scribbled on it, so I hope everything is correct.
Regarding the accompanying BASIC program, I can give the following tips:
- Store the screen uncompressed somewhere in memory after compression to keep a reference for the next frame.
- Definitely compile the program, otherwise you'll be waiting for a long time.
Everyone should be able to write the BASIC program anyway. If any problems or suggestions for improvement from assembly pros arise, write to the ASC editorial team.
Share your thoughts about the article