From 36c824864c02f0a3f62c8a1d365d1670835c8c96 Mon Sep 17 00:00:00 2001 From: "Christian A. Weber" Date: Tue, 12 May 1992 22:26:12 +0000 Subject: Initial revision --- Source/ModifyFrame.S | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 Source/ModifyFrame.S (limited to 'Source/ModifyFrame.S') diff --git a/Source/ModifyFrame.S b/Source/ModifyFrame.S new file mode 100644 index 0000000..46fe5ec --- /dev/null +++ b/Source/ModifyFrame.S @@ -0,0 +1,258 @@ +** +** $Id: $ +** $Revision: $ +** +** $Filename: ModifyFrame.S $ +** $Author: Christian A. Weber $ +** $Release: 19.1 $ +** $Date: 92/05/11 21:11:27 $ +** +** iff.library/IFFLib_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 IFFLib_ModifyFrame + SECTION text,CODE + + INCLUDE "IFFLib.i" + + XREF ClearError,SetError,FindChunkFunc + XDEF ModifyFrameFunc + + +******* iff.library/IFFLib_ModifyFrame ************************************** +* +* NAME +* IFFLib_ModifyFrame -- Modify an anim frame using a DLTA chunk +* +* SYNOPSIS +* success = IFFLib_ModifyFrame( modifyform, bitmap ) +* D0 A1 A0 +* +* BOOL IFFLib_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 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 pictures do not work, because I have no documentation +* about the compression scheme they use. +* I will implement some more compression types upon request. +* +* WARNINGS +* 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. +* +* BUGS +* +***************************************************************************** + +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 #IFF_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 #IFF_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 #IFF_UNKNOWNCOMPRESSION,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 #IFF_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 -- cgit v1.2.3