1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
**
** $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
|