         Just How Many Paint Routines Are There?
         ---------------------------------------

Replay has lots of paint routines. Indeed, it makes life a little worse for
itself by providing routines for decompressors which produce <=8bpp (both
colour mapped by painter and colour mapped by decompressor), ones which produce
<=16bpp (both colour mapped by painter and colour mapped by decompressor) and
the 'normal' ones which produce 32bpp (colour mapped by decompressor only). But
basically it has a routine for each interesting screen mode - and this isn't
all the modes which a RiscPC is capable of. Replay limits itself to modes with
one of five pixel magnifications: 1x1, 2x2, 2x1, 1x2 and 2x4. If it supported
all of these magnifications at each output pixel depth - 1, 2, 4, 8, 16 and
32bpp - then it would have 30 drivers, but it doesn't support all the
magnifications in all the depths.

depth/mag:
-----
  1                    1x1       2x1, 2x2
  2                    1x1,      2x1, 2x2
  4                    1x1,      2x1, 2x2
  8                    1x1, 1x2, 2x1, 2x2, 2x4
 16                    1x1, 1x2, 2x1, 2x2, 2x4
 32                    1x1, 1x2, 2x1, 2x2, 2x4

This would lead to 24 drivers. However there are also interpolated versions of
some of the drivers - Replay is capable of doing horizontal only interpolation,
or of doing both horizontal and vertical interpolation in 16bpp and 32bpp output
modes. And there are special undithered drivers for 8 and 16 bit per pixel modes.
This adds another 15 drivers:

depth/mag:
-----
  1                    1x1       2x1, 2x2
  2                    1x1,      2x1, 2x2
  4                    1x1,      2x1, 2x2
  8                    1x1, 1x2, 2x1, 2x2, 2x4
  8 undithered                        2x2
 16                    1x1, 1x2, 2x1, 2x2, 2x4
 16 undithered              1x2, 2x1, 2x2, 2x4
 16 horiz interp                 2x1, 2x2, 2x4
 16 horiz/vert interp                 2x2, 2x4
 32                    1x1, 1x2, 2x1, 2x2, 2x4
 32 horiz interp                 2x1, 2x2, 2x4
 32 horiz/vert interp                 2x2, 2x4

There are 39 drivers. Each set of paint routines for a screen mode,
interpolation and magnification state is stored in a file (in
MovingLine.PaintCode) whose name represents the above information - for example
the routine 'd322xI2y' is 'depth 32 bits per pixel, 2 times magnification in x
direction by interpolation, 2 times magnification in y direction by
replication'. (The undithered drivers for 16 bits per pixel are stored in the
normal d162x2y (etc) files and accessed via szmul%=2, paintmap% FALSE (a
normally invalid combination for 32 bits of output), similarly the extra
undithered driver for 8 bits per pixel is in d82x2y) The code is assembled at
run time and can thus contain explicit knowledge of screen mode dependent
variables such as the number of bytes per line on the screen - due to an
extreme shortage of registers this gets compiled into ADD immediate
instructions in some routines (the x4 vertical ones). The bilinear
interpolating drivers also end up compiling the source movie x size (in order
to access successive lines of the source) into the code.

In the file procedure PROCd has a set of routines to paint consecutive pixels
in a row, called to assemble code at runtime. The variable szmul% is 1, 2 or 4
depending on the size of values coming from the decompressor. The variable
paintmap% is FALSE or TRUE to indicate that the painter should do the colour
conversion using r14 as the base register for the colour table and FNplook(,,)
to compile the colour lookup. The variable incno% is how many pixels got
painted - by default 8 - by the routine (a few routines can only manage to do 4
pixels, a few routines check to see if they can do 16 pixels). The procedure
FNplook(dest,src,base reg=14) can be used to lookup pixels in the szmul%=1
case. The constant rowbytes% is how many bytes in a RISC OS screen row. The
procedure FNaddmacro(dest,src,offset) can be used to add values which do not
necessarily fit in an immediate constant (such as the value of rowbytes%!). The
variable slow% can be used to limit just how expensive some operations are (for
example, failing to paint all the lines in the 2x4 case!). r0 is the base of
the decompressed frame, r2 is the output for alternate lines (if the
magnification in the y direction is more than 1), r11 is the output for normal
lines, r14 is the colour map base register when paintmap% is true and is free
otherwise, r3 is in use, r13 is a stack (so the painting algorithm usually uses
r1, r4, r5, r6, r7, r8, r9, r10, r12). r12 is preloaded to &ff for szmul%=1 and
to &ffff0000 for szmul%=2, but can be overwritten. Changing the default of 8
and any initial constants are set up with PROCsetinc. Additional procedures
PROCdr8, PROCdr7, PROCdr6, PROCdr5, PROCdr4, PROCdr3, PROCdr2, PROCdr1 allow
for a potential accuracy of 1 source pixel. If the default is larger than 8
(e.g. 16), then PROCdr8 is used to paint multiples of 8. For interpolating
painters, PROCd and PROCdr<incno> will both be used so as to get the right
hand edge correct (so its expected that you'll have PROCd which does 8 and
PROCdr8 in an interpolating painter). At some point PROCdlN may exist.

PROCs2al has a set of routines to paint two adjacent pixels into a word aligned
destination. Registers:

r0: frame base
r1: destination
r2: shape list
r3: number to move-1
r4: destination second row
r5: pixel
r6: second pixel
r7:
r8: &ffff
r9:
r10:
r11: screen start
r12: pixel translation table for source=bytes?

PROCs2unal does the same for unaligned destination.

PROCs1 paints just one pixel into a destination of unknown alignment. The pixel
is in r5.

Paint routines are not necessarily called for every frame in the decompressed
movie (its that slow% variable again, folks!). If the computer can't cope with
painting a frame exactly on time (network packet, disc IO interrupts etc) then
a frame (or more) maybe skipped.
