diff options
-rw-r--r-- | MovieDecode/MovieDecode.a | 455 | ||||
-rw-r--r-- | MovieDecode/MovieDecode.doc | 89 |
2 files changed, 544 insertions, 0 deletions
diff --git a/MovieDecode/MovieDecode.a b/MovieDecode/MovieDecode.a new file mode 100644 index 0000000..ab56892 --- /dev/null +++ b/MovieDecode/MovieDecode.a @@ -0,0 +1,455 @@ +** +** $Id: MovieDecode.a,v 1.1 93/05/22 13:42:47 chris Exp $ +** $Revision: 1.1 $ +** +** $Filename: MovieDecode/MovieDecode.a $ +** $Author: chris $ +** $Release: $ +** $Date: 93/05/22 13:42:47 $ +** +** Frame decoder for Sculpt/Animate MOVIE Format +** +** Author: Christian A. Weber, Bruggerweg 2, CH-8037 Zürich, Switzerland +** E-mail: chris@mighty.adsp.sub.org -or- weber@amiga.physik.unizh.ch +** +** COPYRIGHT © 1990-1993 BY CHRISTIAN A. WEBER. ALL RIGHTS RESERVED. +** NO PART OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR TRANSMITTED +** IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN PERMISSION +** OF THE AUTHOR. NO WARRANTY. USE AT YOUR OWN RISK. +** +** Note: I use the Devpac Assembler, but it should work with other +** Assemblers too. The code is pure and reentrant. V37 or newer +** is required. +** + + OPT O+,OW- ; Devpac: Optimize without warnings + + IDNT JDecode + SECTION text,CODE + + INCLUDE "exec/types.i" + INCLUDE "exec/memory.i" + INCLUDE "exec/macros.i" + INCLUDE "graphics/gfx.i" + + XDEF _InitJDecoder,_FreeJDecoder,_ModifyJFrame + + +* Memory used for the automatically generated player code + +MEMSIZE EQU 32000 + + +* Structure of an entry of "MoveTable" + + STRUCTURE TabEntry,0 + APTR dec_Template ; Pointer to template + WORD dec_TempSize ; Size of template + LABEL dec_SIZEOF + + +* For my ego :-) + + dc.b "J-Type ANIM Decoder V2.0 by Christian A. Weber",10,0 + + +******* MovieDecode/InitJDecoder ******************************************** +* +* NAME +* InitJDecoder -- Initialize the player code for a given animation +* +* SYNOPSIS +* handle = InitJDecoder(animtype) +* D0 D0 +* +* APTR InitJDecoder(ULONG animtype); +* +* FUNCTION +* Initializes the movie player for a given animation type. This is +* typically called once after loading the animation. After playing, +* FreeJDecoder() should be called (with the handle this function +* returns) to free any resources allocated by this function. +* +* INPUTS +* animtype - Bits 0 to 7: Number of bitplanes (1..6) +* Bit 16: mode 0 = "Move" (loop), 1 = "EOR" (ping-pong) +* +* RESULT +* Non-zero if everything was OK, NULL if no memory or bad animtype. +* +* BUGS +* +* SEE ALSO +* FreeJDecoder() +* +***************************************************************************** + +_InitJDecoder: movem.l d2-d7/a2-a6,-(SP) + move.l d0,d7 ; D7: type & depth + + *** Allocate memory for the player code + + move.l #MEMSIZE,d0 + moveq.l #MEMF_ANY,d1 + movea.l (4).W,a6 + JSRLIB AllocVec + tst.l d0 ; Memory OK ? + beq initerror ; no ---> + movea.l d0,a2 ; A2: Player code buffer + + *** Copy header of the player code into the allocated buffer + + movea.l a2,a3 ; Destination + lea Code(PC),a0 ; Source + moveq.l #(CodeEnd-Code)/2-1,d0 ; Size (words) - 1 +1$: move.w (a0)+,(a3)+ + dbf d0,1$ + + *** Create jump table for the different anim operands + +mktab: movea.l a3,a4 + moveq #3,d0 ; 4 types: Byte/Word/Long/Quad + moveq #Error-CodeEnd-2,d2 ; D2 : BRA to Error-Offset +1$: moveq #32,d1 ; 33 entries per table + move.l #$4EFB1002,(a4)+ ; JMP 02(PC,D1.W) + subq.w #4,d2 ; correct offset (negative) +2$: move.w #$6000,(a4)+ ; BRA.W + move.w d2,(a4)+ + subq.w #4,d2 ; correct offset (negative) + dbf d1,2$ + dbf d0,1$ + + *** Create decoding routines for the different anim operands + +mkroutines: lea MoveTable(PC),a1 + bclr #16,d7 ; EOR (reversible) mode ? + beq.b 1$ ; no ---> + lea EORTable(PC),a1 +1$: + addq.l #2,a3 ; BRA offsets of the jump table + moveq #3,d0 ; 4 types: Byte/Word/Long/Quad +.Loop1: moveq #0,d1 ; 10 routines: 1-8,16,32 lines + addq.l #4+4,a3 ; Skip JMP and first BRA + +.Loop2: move.w d1,d2 ; Number of repetitions-1 + cmpi.w #8,d1 + bne.b 2$ + moveq #16-1,d2 + lea 7*4(a3),a3 ; Skip vectors for 9 to 15 +2$: cmpi.w #9,d1 + bne.b 3$ + moveq #32-1,d2 + lea 15*4(a3),a3 ; Skip vectors for 17 to 31 +3$: move.w d2,d3 + addq.w #1,d3 ; D3: number of repetitions + + movea.l a4,a5 ; A5: Start of actual routine + move.w #$3018,(a4)+ ; MOVE.W (A0)+,D0 +.Loop3: movea.l dec_Template(a1),a0 ; Template + move.w dec_TempSize(a1),d4 ; Size of template in WORDs + mulu.w d7,d4 ; * number of bitplanes + bra.b .Dbf4 ; For dbf +.Loop4: move.w (a0)+,(a4)+ ; Copy the template +.Dbf4: dbf d4,.Loop4 + tst.w d2 ; Is this the last one ? + beq.b .NoAdd ; yes ---> don't generate ADD ins + move.w #$D047,(a4)+ ; ADD.W D7,D0 +.NoAdd: + dbf d2,.Loop3 + + *** If we're in BYTE mode with an odd number of planes we have + *** to insert an ADDQ.L #1,A0 instruction to word-align the + *** delta data. + + cmpi.b #3,d0 ; BYTE mode ? + bne.b 6$ ; no ---> no ADD required + btst #0,d7 ; Even number of bitplanes ? + beq.b 6$ ; yes ---> no ADD required + btst #0,d3 ; Even number of repetitions ? + beq.b 6$ ; yes ---> no ADD required + move.w #$5288,(a4)+ ; ADDQ.L #1,A0 +6$: + *** Insert the start of this routine into the BRA.W table + + move.l a4,d4 ; Jump Destination: before the DBF + sub.l a3,d4 ; minus table offset + move.w d4,(a3) ; gives offset of BRA + addq.w #4,a3 ; Pointer to next BRA + + move.w #$51CE,(a4)+ ; DBF D6, + move.l a5,d4 ; Branch destination: Start of routine + sub.l a4,d4 ; minus actual address + move.w d4,(a4)+ ; gives offset + + move.w #$6000,(a4)+ ; BRA.W + move.l a2,d4 ; Branch destination: MainLoop + sub.l a4,d4 ; minus actual address + move.w d4,(a4)+ ; gives offset + + addq.w #1,d1 ; increment number of repetitions + cmpi.w #10,d1 + blt.b .Loop2 + + addq.l #dec_SIZEOF,a1 ; Next template + dbf d0,.Loop1 + + *** Since we created some code, we have to clear the I-cache + + JSRLIB CacheClearU ; A6 is still holding ExecBase + + move.l a2,d0 ; Result: handle +initerror: + movem.l (SP)+,d2-d7/a2-a6 + rts + + +******* MovieDecode/FreeJDecoder ******************************************** +* +* NAME +* FreeJDecoder -- Free the player code for an animation +* +* SYNOPSIS +* FreeJDecoder(handle) +* D0 A0 +* +* VOID FreeJDecoder(APTR handle); +* +* FUNCTION +* Frees all resources which were allocated by InitJDecoder(). +* This is typically called once after playing an animation. +* +* INPUTS +* hande - result from InitJDecoder() ONLY! +* +* RESULT +* none +* +* BUGS +* +* SEE ALSO +* InitJDecoder() +* +***************************************************************************** + +_FreeJDecoder: move.l a6,-(SP) + + *** Free the memory we allocated in InitJDecoder() + + movea.l a0,a1 + movea.l (4).W,a6 + JSRLIB FreeVec + + movea.l (SP)+,a6 + rts + + +******* MovieDecode/ModifyJFrame ******************************************** +* +* NAME +* ModifyJFrame -- Apply delta data on an animation frame +* +* SYNOPSIS +* success = ModifyJFrame( deltas, bitmap, handle ) +* D0 A0 A1 A2 +* +* BOOL ModifyJFrame( APTR, struct BitMap *, APTR ); +* +* FUNCTION +* Generates a new animation frame by changing the frame before the +* currently displayed frame (for double-buffering, as usual). +* +* INPUTS +* deltas - pointer to the actual DLTA chunk data +* bitmap - BitMap to render into +* handle - player handle, from InitJDecoder() +* +* RESULT +* Non-zero if everything was OK, FALSE if an error occurred. +* +* BUGS +* +* SEE ALSO +* InitJDecoder(), FreeJDecoder() +* +***************************************************************************** + +_ModifyJFrame: movem.l d2-d7/a2-a6,-(SP) + + move.w bm_BytesPerRow(a1),d7 ; d7 : BytesPerRow + move.l a2,-(SP) ; Push address of player code + movem.l bm_Planes(a1),a1-a6 ; A1-A6: plane pointers + moveq.l #0,d0 ; Clear bitplane index pointer + rts ; ---> Do the code + + *** The following code fragment will be copied to the beginning + *** of the player code. It will be followed by the decoder + *** routines for the particular mode and bitplane depth. + +Code: +MainLoop: move.w (a0)+,d0 ; Number of bytes per entry + addq.l #2,a0 ; Skip type: 0=Move, 1=EOR + move.w (a0)+,d1 ; Number of rows of this width + cmpi.w #32,d1 ; More than 32 ? + bhi.b End ; yes ---> we can't handle this + lsl.w #2,d1 ; Adjust for table index + subq.w #1,d0 ; CODE 1: 1 Byte ? + beq.b DoBytes ; yep ---> + subq.w #1,d0 ; CODE 2: >1 Byte ? + bne.b End ; no ---> finished + + move.w (a0)+,d0 ; Number of bytes per entry + move.w (a0)+,d6 ; Number of n-rows entries + subq.w #4,d0 + beq DoBytes+68*4+2 ; 4 Bytes ---> + bcc DoBytes+102*4+2 ; 6 Bytes ---> (bcc == bhs) + bra DoBytes+34*4+2 ; 2 Bytes ---> + +Error: moveq #0,d0 ; Result: Error + bra.b Exit +End: moveq #1,d0 ; Result: Success +Exit: movem.l (SP)+,d2-d7/a2-a6 + rts + +DoBytes: move.w (a0)+,d6 ; Number of n-rows-entries +CodeEnd: + + *** Here are the templates for the various operations. + *** No code is generated for unused bitplanes. + +MoveByteTemplate: + move.b (a0)+,0(a1,d0.L) + move.b (a0)+,0(a2,d0.L) + move.b (a0)+,0(a3,d0.L) + move.b (a0)+,0(a4,d0.L) + move.b (a0)+,0(a5,d0.L) + move.b (a0)+,0(a6,d0.L) +MoveByteTemplateEnd: + +MoveWordTemplate: + move.w (a0)+,0(a1,d0.L) + move.w (a0)+,0(a2,d0.L) + move.w (a0)+,0(a3,d0.L) + move.w (a0)+,0(a4,d0.L) + move.w (a0)+,0(a5,d0.L) + move.w (a0)+,0(a6,d0.L) +MoveWordTemplateEnd: + +MoveLongTemplate: + move.l (a0)+,0(a1,d0.L) + move.l (a0)+,0(a2,d0.L) + move.l (a0)+,0(a3,d0.L) + move.l (a0)+,0(a4,d0.L) + move.l (a0)+,0(a5,d0.L) + move.l (a0)+,0(a6,d0.L) +MoveLongTemplateEnd: + +MoveQuadTemplate: + move.l (a0)+,0(a1,d0.L) + move.w (a0)+,4(a1,d0.L) + move.l (a0)+,0(a2,d0.L) + move.w (a0)+,4(a2,d0.L) + move.l (a0)+,0(a3,d0.L) + move.w (a0)+,4(a3,d0.L) + move.l (a0)+,0(a4,d0.L) + move.w (a0)+,4(a4,d0.L) + move.l (a0)+,0(a5,d0.L) + move.w (a0)+,4(a5,d0.L) + move.l (a0)+,0(a6,d0.L) + move.w (a0)+,4(a6,d0.L) +MoveQuadTemplateEnd: + +EORByteTemplate: + move.b (a0)+,d1 + eor.b d1,0(a1,d0.L) + move.b (a0)+,d1 + eor.b d1,0(a2,d0.L) + move.b (a0)+,d1 + eor.b d1,0(a3,d0.L) + move.b (a0)+,d1 + eor.b d1,0(a4,d0.L) + move.b (a0)+,d1 + eor.b d1,0(a5,d0.L) + move.b (a0)+,d1 + eor.b d1,0(a6,d0.L) +EORByteTemplateEnd: + +EORWordTemplate: + move.w (a0)+,d1 + eor.w d1,0(a1,d0.L) + move.w (a0)+,d1 + eor.w d1,0(a2,d0.L) + move.w (a0)+,d1 + eor.w d1,0(a3,d0.L) + move.w (a0)+,d1 + eor.w d1,0(a4,d0.L) + move.w (a0)+,d1 + eor.w d1,0(a5,d0.L) + move.w (a0)+,d1 + eor.w d1,0(a6,d0.L) +EORWordTemplateEnd: + +EORLongTemplate: + move.l (a0)+,d1 + eor.l d1,0(a1,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a2,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a3,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a4,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a5,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a6,d0.L) +EORLongTemplateEnd: + +EORQuadTemplate: + move.l (a0)+,d1 + eor.l d1,0(a1,d0.L) + move.w (a0)+,d1 + eor.w d1,4(a1,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a2,d0.L) + move.w (a0)+,d1 + eor.w d1,4(a2,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a3,d0.L) + move.w (a0)+,d1 + eor.w d1,4(a3,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a4,d0.L) + move.w (a0)+,d1 + eor.w d1,4(a4,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a5,d0.L) + move.w (a0)+,d1 + eor.w d1,4(a5,d0.L) + move.l (a0)+,d1 + eor.l d1,0(a6,d0.L) + move.w (a0)+,d1 + eor.w d1,4(a6,d0.L) +EORQuadTemplateEnd: + +MoveTable: dc.l MoveByteTemplate + dc.w (MoveByteTemplateEnd-MoveByteTemplate)/2/6 + dc.l MoveWordTemplate + dc.w (MoveWordTemplateEnd-MoveWordTemplate)/2/6 + dc.l MoveLongTemplate + dc.w (MoveLongTemplateEnd-MoveLongTemplate)/2/6 + dc.l MoveQuadTemplate + dc.w (MoveQuadTemplateEnd-MoveQuadTemplate)/2/6 + dc.l $43485721 +EORTable: dc.l EORByteTemplate + dc.w (EORByteTemplateEnd-EORByteTemplate)/2/6 + dc.l EORWordTemplate + dc.w (EORWordTemplateEnd-EORWordTemplate)/2/6 + dc.l EORLongTemplate + dc.w (EORLongTemplateEnd-EORLongTemplate)/2/6 + dc.l EORQuadTemplate + dc.w (EORQuadTemplateEnd-EORQuadTemplate)/2/6 + + + *** That's all folks! + + + END diff --git a/MovieDecode/MovieDecode.doc b/MovieDecode/MovieDecode.doc new file mode 100644 index 0000000..4eeacb4 --- /dev/null +++ b/MovieDecode/MovieDecode.doc @@ -0,0 +1,89 @@ +TABLE OF CONTENTS + +MovieDecode/FreeJDecoder +MovieDecode/InitJDecoder +MovieDecode/ModifyJFrame +MovieDecode/FreeJDecoder MovieDecode/FreeJDecoder + + NAME + FreeJDecoder -- Free the player code for an animation + + SYNOPSIS + FreeJDecoder(handle) + D0 A0 + + VOID FreeJDecoder(APTR handle); + + FUNCTION + Frees all resources which were allocated by InitJDecoder(). + This is typically called once after playing an animation. + + INPUTS + hande - result from InitJDecoder() ONLY! + + RESULT + none + + BUGS + + SEE ALSO + InitJDecoder() + +MovieDecode/InitJDecoder MovieDecode/InitJDecoder + + NAME + InitJDecoder -- Initialize the player code for a given animation + + SYNOPSIS + handle = InitJDecoder(animtype) + D0 D0 + + APTR InitJDecoder(ULONG animtype); + + FUNCTION + Initializes the movie player for a given animation type. This is + typically called once after loading the animation. After playing, + FreeJDecoder() should be called (with the handle this function + returns) to free any resources allocated by this function. + + INPUTS + animtype - Bits 0 to 7: Number of bitplanes (1..6) + Bit 16: mode 0 = "Move" (loop), 1 = "EOR" (ping-pong) + + RESULT + Non-zero if everything was OK, NULL if no memory or bad animtype. + + BUGS + + SEE ALSO + FreeJDecoder() + +MovieDecode/ModifyJFrame MovieDecode/ModifyJFrame + + NAME + ModifyJFrame -- Apply delta data on an animation frame + + SYNOPSIS + success = ModifyJFrame( deltas, bitmap, handle ) + D0 A0 A1 A2 + + BOOL ModifyJFrame( APTR, struct BitMap *, APTR ); + + FUNCTION + Generates a new animation frame by changing the frame before the + currently displayed frame (for double-buffering, as usual). + + INPUTS + deltas - pointer to the actual DLTA chunk data + bitmap - BitMap to render into + handle - player handle, from InitJDecoder() + + RESULT + Non-zero if everything was OK, FALSE if an error occurred. + + BUGS + + SEE ALSO + InitJDecoder(), FreeJDecoder() + +
\ No newline at end of file |