EnableAnimGadgets
		move.l	anim7gadget(pc),a0
		moveq	#0,d0
		bsr	ChangeGadMode
		rts

DisableAnimGadgets
		move.l	anim7gadget(pc),a0
		moveq	#1,d0
		bsr	ChangeGadMode
		rts

ActFrameNumber
		* Current-Frame-Textgadget aktualisieren..
		move.l	d7,-(sp)
		tst.l	window-j(a5)
		beq.s	.0
		move.l	sp,d7
		move.l	current_ftype(pc),-(sp)

		lea	animlstruct(pc),a0
		moveq	#0,d0
		move.w	(a0),d0
		beq.s	.11
		move.l	d0,-(sp)
		move.w	2(a0),d0
		move.l	d0,-(sp)
		move.l	#.text,-(sp)
		bra.s	.22

.11		move.l	#.text2,-(sp)

.22		move.l	anim1gadget(pc),-(sp)
		bsr	PrintFGad
		move.l	d7,sp
.0		move.l	(sp)+,d7
		rts
.text		dc.b	"%lu/%lu %s",0
.text2		dc.b	"%s",0
		even
current_ftype	; Zeiger auf Frame-Description oder NULL
		dc.l	0

		STRUCTURE AnimLStruct,0
		WORD als_frames
		WORD als_currentframe
		LONG als_pagesize
		WORD als_depth
		LONG als_modeid
		LONG als_fh
		LONG als_buf1
		LONG als_buf2
		LONG als_coltab
		LONG als_coltablen
		LONG als_loadbuf
		LABEL als_SIZEOF

animlstruct	ds.b	als_SIZEOF

* ersten Frame analysieren - Bilddaten herausfinden
AnimInitLoad
		movem.l	d2-d7/a2-a4/a6,-(sp)
		clr.w	FASTMEMflag-j(a5)
		lea	animlstruct(pc),a4
		lea	buf1,a3
		move.l	load.filehandle(pc),als_fh(a4)

		move.l	load.ftestbuf+4(pc),d4
		subq.l	#4,d4			;[d4] Filelänge

		move.l	als_fh(a4),d1
		move.l	a3,d2
		moveq	#12,d3
		move.l	dosbase(pc),a6
		LIBCALL	Read
		move.l	#falschelaenget,op.RC
		cmp.l	#12,d0
		bne	anim.err

		move.l	4(a3),d0
		subq.l	#4,d0
		move.l	d0,d7			;[d7] Bufferlänge
		moveq	#0,d1
		move.l	4.w,a6
		LIBCALL	AllocVec
		move.l	#nomemtext,op.RC
		move.l	d0,d6			;[d6] loadbuf
		beq	anim.err
		move.l	d0,als_loadbuf(a4)

		move.l	als_fh(a4),d1	* ersten Frame laden
		move.l	d6,d2
		move.l	d7,d3
		move.l	dosbase(pc),a6
		LIBCALL	Read
		move.l	#falschelaenget,op.RC
		cmp.l	d3,d0
		bne	anim.fileerr

		move.l	d6,a1		* Chunks finden
		add.l	d7,a1
		move.l	d6,a0
		move.l	#"BMHD",d1
		bsr	FindChunk
		move.l	#missingchunkt,op.RC
		move.l	d0,d5			;[d5] BMHD
		beq	anim.fileerr

		move.l	d6,a0
		move.l	#"BODY",d1
		bsr	FindChunk
		move.l	d0,load.bodychunk-j(a5)
		beq	anim.fileerr

		move.l	d6,a0
		move.l	#"CMAP",d1
		bsr	FindChunk
		move.l	d0,load.cmapchunk-j(a5)
		beq	anim.fileerr

		clr.l	als_modeid(a4)
		move.l	d6,a0
		move.l	#"CAMG",d1
		bsr	FindChunk
		tst.l	d0
		beq.s	.nocamg
		move.l	d0,a0
		move.l	8(a0),als_modeid(a4)

.nocamg		move.l	d5,a0
		bsr	GetILBMData
		move.l	d0,als_pagesize(a4)
		move.w	d4,load.pagesizexorg-j(a5)
		move.w	d1,als_depth(a4)
		move.b	d3,load.compression-j(a5)
		move.l	#unknowncompr,op.RC
		cmp.b	#1,d3
		bhi	anim.fileerr

		move.w	als_pagesize(a4),d1	* zwei Screenbuffer
		lsr.w	#3,d1			* besorgen und Bild
		move.w	als_depth(a4),d0	* in beide decrunchen !
		mulu.w	als_pagesize+2(a4),d0
		ext.l	d1
		mulu.l	d1,d0
		move.l	d0,load.rawmemlen-j(a5)
		move.l	#MEMF_CHIP!MEMF_PUBLIC,d1
		move.l	4.w,a6
		LIBCALL	AllocVec
		move.l	#nomemtext,op.RC
		move.l	d0,als_buf1(a4)
		beq	anim.fileerr
		move.l	load.rawmemlen(pc),d0
		move.l	#MEMF_CHIP!MEMF_PUBLIC,d1
		LIBCALL	AllocVec
		move.l	d0,als_buf2(a4)
		beq	anim.nobuf2

.decrunch	move.l	load.bodychunk(pc),a0
		move.l	als_buf1(a4),a1
		move.l	a1,a2
		add.l	load.rawmemlen(pc),a2
		tst.b	load.compression-j(a5)
		beq.s	.nocompression
		bsr	DecrunchBODY
		bra.s	.decrunchok
.nocompression	move.l	#ftype_ilbm0,current_ftype-j(a5)
		addq.w	#8,a0
.nocompression1	move.b	(a0)+,(a1)+
		cmp.l	a2,a1
		bne.s	.nocompression1

.decrunchok	move.l	als_buf1(a4),a0
		move.l	als_buf2(a4),a1
		move.l	a0,a2
		add.l	load.rawmemlen(pc),a2
.copy0		move.b	(a0)+,(a1)+
		cmp.l	a2,a0
		bne.s	.copy0

		move.l	load.cmapchunk(pc),a1	* ColorMap initialisieren
		move.l	4(a1),d0
		addq.w	#8,a1
		divu	#3,d0
		moveq	#0,d2
		bsr	MakeColorTable
		move.l	d0,als_coltab(a4)
		beq	anim.noct
		move.l	d1,als_coltablen(a4)

		move.l	4.w,a6
		move.l	d6,a1
		LIBCALL	FreeVec
		clr.l	als_loadbuf(a4)

* File durchscannen auf Anzahl der Frames

		clr.w	als_frames(a4)
		clr.w	als_currentframe(a4)

		move.l	dosbase(pc),a6		;aktuelle Position merken
		move.l	als_fh(a4),d1
		moveq	#0,d2
		moveq	#OFFSET_CURRENT,d3
		LIBCALL	Seek
		move.l	d0,d5			;[d5] Pos. des zw. Frames

.frameloop	moveq	#0,d0
		move.w	als_frames(a4),d0
		move.l	d0,-(sp)
		move.l	#.setgad0,-(sp)
		move.l	anim1gadget(pc),-(sp)
		bsr	PrintFGad
		add.w	#12,sp

		move.l	als_fh(a4),d1
		move.l	a3,d2
		moveq	#8,d3
		LIBCALL	Read
		cmp.w	#8,d0
		bne.s	.was_last
		move.l	als_fh(a4),d1
		move.l	4(a3),d2
		moveq	#OFFSET_CURRENT,d3
		LIBCALL	Seek
		addq.w	#1,als_frames(a4)
		bra.s	.frameloop
.was_last
		move.l	als_fh(a4),d1
		move.l	d5,d2
		moveq	#OFFSET_BEGINNING,d3
		LIBCALL	Seek

		subq.w	#2,als_frames(a4)

		move.l	als_buf1(a4),d0
		movem.l	(sp)+,d2-d7/a2-a4/a6
		rts

.setgad0	dc.b	"total %lu",0
		even

AnimClose	; clear all resources
		movem.l	d2-d7/a2-a4/a6,-(sp)
		lea	animlstruct(pc),a4

anim.nexterr	move.l	als_coltab(a4),a1
		move.l	4.w,a6
		LIBCALL	FreeVec
		clr.l	als_coltab(a4)

anim.noct	move.l	als_buf2(a4),a1
		move.l	4.w,a6
		LIBCALL	FreeVec
		clr.l	als_buf2(a4)

anim.nobuf2	move.l	als_buf1(a4),a1
		move.l	4.w,a6
		LIBCALL	FreeVec
		clr.l	als_buf1(a4)

anim.fileerr	move.l	als_loadbuf(a4),a1
		move.l	4.w,a6
		LIBCALL	FreeVec
		clr.l	als_loadbuf(a4)

anim.err	move.l	als_fh(a4),d1
		beq.s	.0
		move.l	dosbase(pc),a6
		LIBCALL	Close
		clr.l	als_fh(a4)

.0		clr.l	als_frames(a4)

		movem.l	(sp)+,d2-d7/a2-a4/a6
		moveq	#0,d0
		rts

AnimNextPicture	; get next animation picture
		; RETURNS d0 *buffer or NULL
		movem.l	d2-d7/a2-a4/a6,-(sp)
		lea	animlstruct(pc),a4
		lea	buf1,a3

		move.w	(a4),d0
		cmp.w	2(a4),d0
		beq	.was_last

		move.l	dosbase(pc),a6
		move.l	als_fh(a4),d1
		move.l	a3,d2
		moveq	#12,d3
		LIBCALL	Read
		cmp.w	#12,d0
		bne	.was_last

		move.l	4(a3),d0
		subq.l	#4,d0
		move.l	d0,d7			;[d7] Bufferlänge
		move.l	#MEMF_PUBLIC,d1
		move.l	4.w,a6
		LIBCALL	AllocVec
		move.l	d0,d6			;[d6] loadbuf
		move.l	d0,als_loadbuf(a4)
		beq	anim.nexterr

		move.l	als_fh(a4),d1	* nächste FORM laden
		move.l	d6,d2
		move.l	d7,d3
		move.l	dosbase(pc),a6
		LIBCALL	Read
		cmp.l	d3,d0
		bne	anim.nexterr

		movem.l	als_buf1(a4),a0/a1
		exg	a0,a1
		movem.l	a0/a1,als_buf1(a4)

		move.l	d6,a1		* Chunks finden
		add.l	d7,a1
		move.l	d6,a0
		move.l	#"ANHD",d1
		bsr	FindChunk
		move.l	d0,d5			;[d5] ANHD

		move.l	d6,a0
		move.l	#"DLTA",d1
		bsr	FindChunk
		move.l	d0,d4			;[d4] DLTA

		move.l	d6,a0
		move.l	#"CMAP",d1
		bsr	FindChunk
		move.l	d0,d3			;[d3] CMAP
		beq.s	.nonewcmap

		move.l	als_coltab(a4),a1
		clr.l	als_coltab(a4)
		move.l	4.w,a6
		LIBCALL	FreeVec		;alte Colortable freigeben
		move.l	d3,a1
		move.l	4(a1),d0
		addq.w	#8,a1
		divu	#3,d0
		moveq	#0,d2
		bsr	MakeColorTable	;neue Colortable erstellen
		move.l	d0,als_coltab(a4)
		beq	anim.nexterr
		move.l	d1,als_coltablen(a4)

.nonewcmap	;keine neue ColorTable - alte bleibt!
		move.l	d5,a2		* ANHD untersuchen
		move.b	8(a2),d0	;Kompressionsmethode...
		cmp.b	#5,d0
		beq.s	.dlta_five

		lea	unknowncompr(pc),a0
		bsr	type
		bra	anim.nexterr

.cont
		move.l	4.w,a6
		move.l	d6,a1
		LIBCALL	FreeVec		;FORM-Buffer wieder freigeben
		clr.l	als_loadbuf(a4)

		addq.w	#1,als_currentframe(a4)

		move.l	als_buf1(a4),d0
		bra.s	.ende
.was_last	moveq	#0,d0
.ende		movem.l	(sp)+,d2-d7/a2-a4/a6
		rts

.dlta_five	; ******** ANIM-OPT-5 **********
		moveq	#0,d0
		move.w	als_pagesize+2(a4),d0
		add.l	d0,d0
		add.l	d0,d0
		move.l	#MEMF_PUBLIC,d1
		move.l	4.w,a6
		LIBCALL	AllocVec
		move.l	d0,d2		;[d2] decdlta5tab
		beq	anim.nexterr

		move.l	d2,a0
		moveq	#0,d0
		move.w	als_pagesize(a4),d1
		mulu.w	als_depth(a4),d1
		lsr.l	#3,d1
		move.w	als_pagesize+2(a4),d3
		subq.w	#1,d3
.createtab	move.l	d0,(a0)+
		add.l	d1,d0
		dbra	d3,.createtab

		movem.l	d2-d7/a2-a6,-(sp)
		move.l	d4,a3
		move.l	als_buf1(a4),a4
		move.l	d2,a5
		bsr	DecrunchDLTA5
		movem.l	(sp)+,d2-d7/a2-a6

		move.l	d2,a1
		LIBCALL	FreeVec
		bra.s	.cont

DecrunchDLTA5	; a3 DLTA-Chunk
		; a4 Planes
		; a5 Lineoffsetaddtab
		move.l	#ftype_dlta5,current_ftype
		addq.w	#8,a3			; [a3] DLTA-Chunk
		move.l	a3,a2			; [a2] DLTA-Base
		move.w	animlstruct+als_depth(pc),d7
		subq.w	#1,d7			; [d7] Planescounter
		move.w	animlstruct+als_pagesize(pc),d6
		mulu.w	animlstruct+als_depth(pc),d6
		lsr.l	#3,d6			; [d6] Lineoffset
						; [a5] Lineoffsetaddtab
		move.w	#$81,d5			; [d5] Andvalue for UniqOps
						; [a4] Planes (Interleaved)
.planesloop	move.l	a2,a0
		move.l	(a3)+,d0
		beq.s	.skipplane
		add.l	d0,a0			; [a0] Planeops
		move.w	animlstruct+als_pagesize(pc),d4
		lsr.w	#3,d4
		subq.w	#1,d4			; [d4] Columnscounter

.columnsloop	move.l	a4,a1			; [a1] actual Planeaddr
		moveq	#0,d0
		move.b	(a0)+,d0		; [d0] NumColumnOps
		beq.s	.nextcolumn
		subq.w	#1,d0

.oploop		moveq	#0,d1
		move.b	(a0)+,d1		; [d1] Op
		bmi.s	.uniqop
		beq.s	.sameop

.skipop		add.l	(a5,d1.w*4),a1		* überspringen
		bra.s	.nextop

.uniqop		sub.w	d5,d1			* Bytefolge kopieren
.uniqoploop	move.b	(a0)+,(a1)
		add.l	d6,a1
		dbra	d1,.uniqoploop
		bra.s	.nextop

.sameop		move.b	(a0)+,d1		* ein Byte mehrmals kopieren
		subq.w	#1,d1
		move.b	(a0)+,d2
.sameoploop	move.b	d2,(a1)
		add.l	d6,a1
		dbra	d1,.sameoploop

.nextop		dbra	d0,.oploop

.nextcolumn	addq.w	#1,a4
		dbra	d4,.columnsloop

.nextplane	dbra	d7,.planesloop
		rts
.skipplane	move.w	animlstruct+als_pagesize(pc),d4
		lsr.w	#3,d4
		add.w	d4,a4
		bra.s	.nextplane
