| A PoC for a full resolution, full speed (25fps) movie player for the ZX Spectrum |
| Lunes, 07 de Julio de 2008 19:23 | |
|
How is this possible? Previous research in this subject had been made by "decicoder" (an active member of the OTLA project) that led to the Zinetrix program, which was bravely able to load a series of screen$ at a very high speed, giving the illusion of movement (instructions in spanish). This topic has been discussed at WOS forum also. Some members have shown some demos of what seems to be videos "downgraded" to the speccy resolution and later played on a PC/Mac. What I want to show to you it's a real and humble Spectrum 48K playing a 2 minute video, at full resolution (256x192) and full speed (25 fps). Needless to say that this comes with a little help named... DivIDE. This is the system I've used: a standard Spectrum 48K, a tiny TV set (and a capture card to show you the video with more detail) and a DivIDE interface with a CF card installed.
The DivIDE operates under the Fatware firmware. The CF has two partitions: one is FAT16, and contains all my game/utilities collection. There's another partition which is "unknown" to Linux and Windows. This partition holds a movie in SCR format. The Spectrum runs a program that check the MBR of the Compact Flash, searching for a partition of type "ED" (the partition type I've chosen for holding movie data). If it finds one, it retrieves the movie starting LBA address and length from the partition table.
Starting at this LBA address, each frame fills exactly 12 sectors (12*512 = 6144 bytes). It's only pixel data, no attributes yet. So, at each loop, the player HALT's to best syncronize with the vertical retrace, and reads 12 sectors from the CF, directly into the screen buffer (address 16384). Then, LBA counters get updated until the last frame is reached. To get the maximum speed, actual sector reads have been made using 512 INI's, coded in this fashion: ReadBufferNS proc
local BucleReadSector
ld c,DATA
BucleReadSector rept 512
ini
endm
call WaitDrdSet
dec de
ld a,d
or e
jp nz,BucleReadSector
ret
endp
A call to WaitDrdSet is performed to wait until the DRD bit is set, which signals that the next sector is available to be read from the sector buffer at the CF. DE holds the read sector count and HL holds the starting address for storing data from the CF. Finally, C holds the DivIDE data register port address. And now for the movie making process. You will need:
1. Load the movie into VirtualDub. Set to Full Processing mode. Remove the audio track. Apply a filter to resize the movie to 256x192 pixels. Set compression to "Uncompressed RGB". Save the resulting AVI. 2. Load this AVI into BMP2SCR. Choose a suitable SCR mode, such as B/W OrdDith or B/W ErrDiff. Save as SCR/MLT and press "Save now". You will end up with a huge collection of SCR files. 3. Open a console (DOS shell) and go to the directory with the SCR files. Do a COPY/B *.SCR VIDEO.DAT To join every SCR file (that is, every frame) in sequence, to form a single file (the fact that I've used a .DAT extension has nothing to do with the VideoCD standard. It's only a coincidence). That file will be our "movie". If you want to skip these steps, use the video file I have generated for the demo below. 4. Take the length of the VIDEO.DAT file and divide it by 512 to get the number of contiguous sectors it will need. Write down that number. 5 Fire up tour favorite disk partition program. The Linux fdisk program is all I need for this: create a partition and set its length to be the number of sectors you have just written down in the previous step. Change the partition type to be EDh. This will be our "movie partition". 6. If you have used Linux for the previous step, you will given a block device which represent the partition just created, for example, /dev/sdb2 (yours may be different, beware). Assuming you have copied VIDEO.DAT anywhere on your Linux box, to actually transfer the video file into the Compact Flash, do a dd if=/path/to/your/video.dat of=/dev/sdb2 bs=512 Don't forget to change /dev/sdb2 with the right block device for your "movie partition". 7. Plug the Compact Flash in the DivIDE, turn on your Spectrum, run the player program, and enjoy! Here you have a demonstration: I've chosen to load the program via tape instead of using the DivIDE, but this is only because I didn't want to shut off the computer (to remove the CF and load it with the updated version) every time I tried a new version of the program. To prove to you that this is a real Spectrum, I've started recording the TV set with a camera, and then switched to a capture card connected to the same Spectrum, to give you more details.
By the way: the bizarre video showed in this demo have been created and produced by Peliculas Pendelton. One of the men behind the curtain for these series of shorts is the mighty Javier Fesser. Here you can watch (and hear) the original series |



Info about fast IDE access:
http://www.worldofspectrum.org/forums/showthread.php?t=18137&highlight=divide+video
http://www.worldofspectrum.org/forums/showthread.php?t=17768
- ZX Spectrum 128K+
- Kempston Mouse Turbo
- PC Keyboard Interface
- MB02+IDE
But I think it's more interesting to write a routine that can play a custom designed compressed video format, so the video can be stored in a smaller file (not partition), and be played with more different devices.
Although I think a DMA chip is needed for this. But this can take months to develop...
Cheers!
Ben
Also, it sould be great to add a small header to the file, with some information as version number, number of frames, length of frame in bytes...