summaryrefslogtreecommitdiff
path: root/Source/ModifyFrame.S
diff options
context:
space:
mode:
authorChristian A. Weber <chris@gna.ch>1992-05-12 22:26:12 +0000
committerChristian A. Weber <chris@gna.ch>1992-05-12 22:26:12 +0000
commit36c824864c02f0a3f62c8a1d365d1670835c8c96 (patch)
treef3f433e4af522925d4c91f56865d38efaf83a456 /Source/ModifyFrame.S
downloadiff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.tar.gz
iff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.tar.bz2
iff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.zip
Initial revision
Diffstat (limited to 'Source/ModifyFrame.S')
-rw-r--r--Source/ModifyFrame.S258
1 files changed, 258 insertions, 0 deletions
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