summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MovieDecode/MovieDecode.a455
-rw-r--r--MovieDecode/MovieDecode.doc89
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