** ** $Id: ModifyFrame.S,v 21.1 92/05/15 03:21:45 chris Exp $ ** $Revision: 21.1 $ ** ** $Filename: ModifyFrame.S $ ** $Author: chris $ ** $Date: 92/05/15 03:21:45 $ ** ** iff.library/IFFL_ModifyFrame ** ** COPYRIGHT (C) 1987-1992 BY CHRISTIAN A. WEBER, BRUGGERWEG 2, ** CH-8037 ZUERICH, SWITZERLAND. 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 PER- ** MISSION OF THE AUTHOR. USE AT YOUR OWN RISK. ** IDNT IFFL_ModifyFrame SECTION text,CODE INCLUDE "IFFLib.i" XREF ClearError,SetError,FindChunkFunc XDEF ModifyFrameFunc ******* iff.library/IFFL_ModifyFrame **************************************** * * NAME * IFFL_ModifyFrame -- Modify an anim frame using a DLTA chunk * * SYNOPSIS * success = IFFL_ModifyFrame( modifyform, bitmap ) * D0 A1 A0 * * BOOL IFFL_ModifyFrame( VOID *, struct BitMap * ) * * FUNCTION * Uses the DLTA chunk of the supplied FORM to modify the planes-data * of the bitmap. Usually, playback of ANIMs will require two buffers, * and double-buffering between them. So the data in the bitmap must * be two frames back, and the DLTA chunk is used to modify the hidden * frame to the next frame to be shown. * * INPUTS * modifyform - pointer to the FORM containing the actual DLTA chunk * bitmap - Pointer to a properly initialized BitMap structure, * the planes must contain the image which was displayed * to frames back (using double-buffering) * * RESULT * Non-zero if OK, 0 if error; call IFFL_IFFError() to know the reason * of the failure * * RESTRICTIONS * Currently, only compression type 5 (Byte Vertical Delta Mode) is * implemented. If you have animations which use modes 1 to 4, try * loading them with DPaint III and saving them again. * Sculpt-Animate ('J' type ANIM, Movie format) support will be * added soon. * I will implement some more compression types upon request. * * NOTE * This routine needs at least 820 bytes of stack. * The size of the bitmap is not checked by this routine, the planes * must have at least the size described in the BMHD of the anim * file. * * SEE ALSO * IFFL_IFFError() * ***************************************************************************** ModifyFrameFunc: movem.l d2-d7/a2-a6,-(SP) movea.l a6,a5 ; A5: IFFBase für SetError() movea.l a1,a4 ; A4: IFFFile move.w bm_BytesPerRow(a0),d3 ; D3: BytesPerRow move.w bm_Rows(a0),d4 ; D4: Rows moveq.l #0,d5 move.b bm_Depth(a0),d5 ; D5: Depth lea bm_Planes(a0),a3 ; A3: Plane-Array *** Multiplikations-Tabelle aufbauen move.w d4,d7 ; bm_Rows add.w d7,d7 ; D7: StackFrameSize suba.w d7,SP ; StackFrame erstellen movea.l SP,a0 ; MultTable moveq.l #0,d0 ; Reset offset move.w d4,d1 ; bm_Rows bra.s 2$ ; Für dbf 1$: move.w d0,(a0)+ add.w d3,d0 ; Offset += BytesPerRow 2$: dbf d1,1$ *** Testen ob's ein ILBM-FORM ist cmpi.l #'ILBM',8(a4) ; ILBM-Form ? beq.s 3$ ; ja ---> moveq #IFFL_ERROR_NOILBM,d0 ; Fehlernummer bra .Error 3$: *** AnimHeader suchen und nach A2 move.l #'ANHD',d0 movea.l a4,a1 ; IFF-File bsr FindChunkFunc ;; tst.l d0 bne.s 4$ ; gefunden ---> moveq #IFFL_ERROR_NOANHD,d0 ; Fehlernummer bra .Error 4$: addq.l #8,d0 ; ANHD.... überhüpfen movea.l d0,a2 ; A2: AnimHeader *** Compression-Mode testen und entsprechende Routine nach A6 move.b anh_Operation(a2),d0 cmpi.b #5,d0 ; SuperDuperZapperMode ? bne.s 5$ ; nein ---> lea MakePlane(PC),a6 bra.s 6$ 5$: moveq #IFFL_ERROR_BADCOMPRESSION,d0 bra.s .Error 6$: *** DLTA-Chunk finden und nach A4 movea.l a4,a1 ; IFFFile move.l #'DLTA',d0 bsr FindChunkFunc ; Start der Daten bne.s 7$ ; gefunden ---> moveq #IFFL_ERROR_NODLTA,d0 ; Fehlernummer bra .Error 7$: addq.l #8,d0 ; DLTA.... überhüpfen movea.l d0,a4 ; A4: Delta-Chunk *** Alle Planes verändern movea.l SP,a2 ; Y-Multiplikationstabelle moveq.l #0,d2 ; D2: Offset-Zeiger (hmm..) bra.s 9$ ; Für dbf .PlaneLoop: move.l 0(a4,d2.w),d0 ; n-ter Offset beq.s 8$ ; Null ---> Plane bleibt movea.l a4,a0 ; Delta-Daten-Start adda.l d0,a0 ; Offset dazu movea.l (a3),a1 ; nächste Destination-Plane move.w d3,d0 ; BytesPerRow für Decruncher jsr (a6) ; Tada, Plane verändern 8$: addq.w #4,d2 ; Offset erhöhen addq.l #4,a3 ; Next Plane 9$: dbf d5,.PlaneLoop bsr ClearError ; IFFError rücksetzen, D0:=1 bra.s .Ende ; ---> .Error: bsr SetError ; IFFError setzen, clr.l d0 .Ende: adda.w d7,SP ; Stack aufräumen movem.l (SP)+,d2-d7/a2-a6 rts ***************************************************************************** *** Mit Daten (A0) Plane (A1) verändern, A2=Multiplikationstabelle MakePlane: movem.l d0-d5/a0-a1/a3,-(SP) move.w d0,d2 ; BytesPerRow move.w d2,d4 ; Kolonnen-Zähler bra ColumnDbf ; für dbf ColumnLoop: movea.l a1,a3 ; Destination-Pointer moveq.l #0,d0 move.b (a0)+,d0 ; # Befehle dieser Kolonne bra OpLoopDbf ; für dbf OpLoop: moveq.l #0,d1 move.b (a0)+,d1 ; Nächster Befehl bmi CopyBytes ; CopyBytes-Run ---> beq RepByte ; RepeatByte-Run ---> *** SkipLines-Befehl add.w d1,d1 ; Anzahl Linien zu überhüpfen adda.w 0(a2,d1.w),a3 ; Destination neu setzen bra OpLoopDbf ; ---> Nächster Befehl *** RepeatByte-Befehl RepByte: move.b (a0)+,d1 ; Anzahl move.b (a0)+,d3 ; Zu repetierender Wert move.w d1,d5 ; Anzahl Durchläufe .. asr.w #3,d5 andi.w #7,d1 ; .. und Rest berechnen add.w d1,d1 add.w d1,d1 neg.w d1 jmp 32+RepLoop(PC,d1.w) ; 8*sizeof move/add RepLoop: move.b d3,(a3) adda.w d2,a3 move.b d3,(a3) adda.w d2,a3 move.b d3,(a3) adda.w d2,a3 move.b d3,(a3) adda.w d2,a3 move.b d3,(a3) adda.w d2,a3 move.b d3,(a3) adda.w d2,a3 move.b d3,(a3) adda.w d2,a3 move.b d3,(a3) adda.w d2,a3 dbf d5,RepLoop bra OpLoopDbf ; ---> Nächster Befehl *** CopyBytes-Befehl CopyBytes: andi.w #$7f,d1 ; Anzahl Bytes zu kopieren move.w d1,d5 ; Anzahl Durchläufe .. asr.w #3,d5 andi.w #7,d1 ; .. und Rest berechnen add.w d1,d1 add.w d1,d1 neg.w d1 jmp 32+CopyBytesLoop(PC,d1.w) CopyBytesLoop: move.b (a0)+,(a3) adda.w d2,a3 move.b (a0)+,(a3) adda.w d2,a3 move.b (a0)+,(a3) adda.w d2,a3 move.b (a0)+,(a3) adda.w d2,a3 move.b (a0)+,(a3) adda.w d2,a3 move.b (a0)+,(a3) adda.w d2,a3 move.b (a0)+,(a3) adda.w d2,a3 move.b (a0)+,(a3) adda.w d2,a3 dbf d5,CopyBytesLoop OpLoopDbf: dbf d0,OpLoop ColumnCont: addq.l #1,a1 ; Destination erhöhen ColumnDbf: dbf d4,ColumnLoop ; Nächste Kolonne ---> movem.l (SP)+,d0-d5/a0-a1/a3 rts END