;---------------T----------T-----------------------T
; AGAiff
;
; Last Change > 26.7.1994
; Include > saveiff.s
; 26.07.1994	Files werden jetzt beim Saven gecruncht.

saveIFF
		clr.b	saveiff_compression-j(a5)

		bsr	CutRangeI
		move.l	#nomemtext,op.RC
		move.l	d0,d7
		beq	.nostuff

		movem.w	save.range(pc),d0-d3
		sub.w	d0,d2
		sub.w	d1,d3
		lsr.w	#4,d2
		addq.w	#1,d2
		add.w	d2,d2
		addq.w	#1,d3
		mulu.w	load.depth(pc),d3
		swap	d3
		move.w	d2,d3

		move.l	d3,d6
		move.w	d3,d0
		cmp.w	#8,d0
		bcs.s	.nocrunch
		add.w	d0,d0		;2mal soviel Speicher zum Crunchen..
		swap	d3
		mulu.w	d3,d0
		swap	d3
		moveq	#0,d1
		move.l	4.w,a6
		LIBCALL	AllocVec
		move.l	d0,saveiff.crunchmem-j(a5)
		beq.s	.nocrunch
		move.l	d0,a1
		move.l	d7,a2
		move.w	d3,d0
		moveq	#0,d4
		move.w	d0,d4
		swap	d3
		mulu.w	d3,d0
		move.l	d0,saveiff.uncrunchlen-j(a5)

		moveq	#0,d2
		subq.w	#1,d3
.crunchloop
		move.l	a2,a0
		move.l	d4,d0
		bsr	CrunchByteRun1
		add.l	d0,d2
		add.l	d4,a2
		dbra	d3,.crunchloop

		move.l	saveiff.uncrunchlen(pc),d0
		cmp.l	d2,d0
		bcs.s	.cont
		move.b	#1,saveiff_compression-j(a5)
		move.l	d2,d0
		addq.l	#1,d0
		and.w	#$fffe,d0
		bra.s	.cont

.nocrunch	move.w	d6,d0
		swap	d6
		mulu.w	d6,d0

.cont		move.l	d0,saveiff_dat2+4-j(a5)	;BODY-Länge

		move.l	4.w,a6			* Get CMAP memory
		move.l	colortable(pc),a3
		move.w	(a3),d0
		mulu.w	#3,d0
		move.l	d0,saveiff_cmapl-j(a5)
		moveq	#0,d1
		LIBCALL	AllocVec
		move.l	#nomemtext,op.RC
		move.l	d0,saveiff_cmap-j(a5)
		beq	.nocmap

		move.w	(a3),d1	;CMAP-Chunk erstellen
		addq.w	#4,a3
		move.l	d0,a4
		subq.w	#1,d1
.loop0		move.b	(a3),(a4)+
		move.b	4(a3),(a4)+
		move.b	8(a3),(a4)+
		lea	12(a3),a3
		dbra	d1,.loop0
		move.l	saveiff_cmapl(pc),saveiff_datcmapl-j(a5) ;CMAP-Länge

		move.l	saveiff_dat2+4(pc),d0
		add.l	saveiff_datcmapl(pc),d0
		add.l	#saveiff_datl,d0
		move.l	d0,saveiff_dat+4-j(a5)	;FORM-Länge eintragen

		move.b	load.depth+1(pc),saveiff_datdepth-j(a5)

		movem.w	save.range(pc),d0-d3
		sub.w	d0,d2
		sub.w	d1,d3
		addq.w	#1,d2
		addq.w	#1,d3
		movem.w	d2/d3,saveiff_datpicsize-j(a5)

		move.l	gfxbase(pc),a6	;AUFLÖSUNG rausfinden
		sub.l	a0,a0
		lea	buf1,a1
		moveq	#88,d0
		move.l	#DTAG_DIMS,d1
		move.l	load.modeid(pc),d2
		move.l	d2,saveiff_datmodeid-j(a5)
		LIBCALL	GetDisplayInfoData
		tst.l	d0
		beq.s	.002
		lea	buf1,a0
		movem.w	26(a0),d0-d3
		sub.w	d0,d2
		sub.w	d1,d3
		addq.w	#1,d2
		addq.w	#1,d3
		movem.w	d2/d3,saveiff_datresolution-j(a5)

.002		bsr	OpenSaveFile
		beq	.nofile

		move.l	save.filehandle(pc),d1	;Fileheader
		move.l	#saveiff_dat,d2
		move.l	#saveiff_datl,d3
		bsr	ExtWrite
	
		move.l	save.filehandle(pc),d1	;CMAP-Chunk
		move.l	saveiff_cmap(pc),d2
		move.l	saveiff_cmapl(pc),d3
		bsr	ExtWrite
	
		move.l	save.filehandle(pc),d1	;BODY-Chunk
		move.l	#saveiff_dat2,d2
		moveq	#8,d3
		bsr	ExtWrite
	
		move.l	saveiff_dat2+4(pc),d3
		move.l	d7,d2
		tst.b	saveiff_compression
		beq.s	.saveunc
		move.l	saveiff.crunchmem(pc),d2
.saveunc	bsr	ExtWrite
		clr.l	op.RC

		bsr	CloseSaveFile

.nofile		move.l	4.w,a6
		move.l	saveiff_cmap(pc),a1
		LIBCALL	FreeVec
		clr.l	saveiff_cmap
	
.nocmap		move.l	4.w,a6
		move.l	saveiff.crunchmem(pc),a1
		LIBCALL	FreeVec
		clr.l	saveiff.crunchmem

		move.l	d7,a1
		LIBCALL	FreeVec

.nostuff	move.l	op.RC(pc),d0
		beq.s	.ok
		move.l	d0,a0
		bsr	type
		moveq	#0,d0
		rts
.ok		moveq	#-1,d0
		rts

* -- CrunchByteRun1.s
* -- Convert data to cmpByteRun1 compression.
*
*	control bytes:
*	 [0..127]   : followed by n+1 bytes of data.
*	 [-1..-127] : followed by byte to be repeated (-n)+1 times.
*	 -128       : NOOP.
*
* 26.07.1994 by Michael Krause - RST/C()MPLEX

; Ich gebe zu, das Ding hier ist sehr schlecht gemacht, aber ich hab'
; mir vorher keine Gedanken über den Algorithmus gemacht, sondern einfach
; drauflosgecodet... naja der ANIM-5-Cruncher ist dafür umso besser :)

CrunchByteRun1	; a0 original data
		; a1 crunched data
		; d0 length of orginal data
		; RETURNS d0 length of crunched data
		movem.l	d2-d7/a2-a6,-(sp)
		move.l	a1,d7
.mainloop	move.l	a0,a2
		move.b	(a0)+,d2		;[d2] Remember1
		move.b	(a0)+,d3		;[d3] Remember2
		subq.l	#2,d0
		bmi.s	.copy_d2	* Ende
		beq.s	.copy_d2d3	* Ende
		moveq	#2,d4			;[d4] Counter
		cmp.b	d2,d3			* ersten 2 untersch. --> copy
		bne.s	.copy
		moveq	#3,d4
		move.b	(a0)+,d5
		subq.l	#1,d0
		beq.s	.copy_d2d3d5	* Ende
		cmp.b	d3,d5
		beq.s	.run			* ersten 3 gleich --> crunch
		move.b	d3,d2
		move.b	d5,d3

.copy		cmp.w	#128,d4
		beq.s	.copyit
		move.b	(a0)+,d5		;[d5] current Byte
		cmp.b	d2,d5
		bne.s	.copycont
		cmp.b	d3,d5
		beq.s	.copystop
.copycont	addq.w	#1,d4			* weiterkopieren
		move.b	d3,d2
		move.b	d5,d3
		subq.l	#1,d0
		bne.s	.copy
		bra.s	.copy_end	* Ende
.copystop	subq.w	#3,d4			* jetzt folgen 3 gleiche Bytes
		subq.w	#3,a0
		addq.l	#2,d0
		move.b	d4,(a1)+
.copystopl0	move.b	(a2)+,(a1)+
		dbra	d4,.copystopl0
		bra.s	.mainloop
.copyit		subq.w	#1,d4			* 128 Bytes voll
		move.b	d4,(a1)+
.copyitl0	move.b	(a2)+,(a1)+
		dbra	d4,.copyitl0
		bra.s	.mainloop

.run		move.b	(a0)+,d5		;[d5] current Byte
		cmp.w	#128,d4
		beq.s	.runstop
		cmp.b	d3,d5
		bne.s	.runstop
		addq.w	#1,d4			* Bytes immer noch gleich
		subq.l	#1,d0
		bne.s	.run
		bra.s	.run_end	* Ende
.runstop	neg.w	d4			* jetzt folgt anderes Byte
		addq.w	#1,d4			* oder 128 Bytes sind voll.
		move.b	d4,(a1)+
		move.b	d3,(a1)+
		subq.w	#1,a0
		bra.s	.mainloop

.copy_d2	clr.b	(a1)+
		move.b	d2,(a1)+
		bra.s	.ende
.copy_d2d3	move.b	#1,(a1)+
		move.b	d2,(a1)+
		move.b	d3,(a1)+
		bra.s	.ende
.copy_d2d3d5	cmp.b	d2,d5
		bne.s	.copy_d2d3d5.1
		move.b	#-2,(a1)+
		move.b	d2,(a1)+
		bra.s	.ende
.copy_d2d3d5.1	move.b	#2,(a1)+
		move.b	d2,(a1)+
		move.b	d3,(a1)+
		move.b	d4,(a1)+
		bra.s	.ende
.copy_end	subq.w	#1,d4			* Rest kopieren
		move.b	d4,(a1)+
.copy_endl0	move.b	(a2)+,(a1)+
		dbra	d4,.copy_endl0
		bra.s	.ende
.run_end	neg.w	d4			* Rest crunchen
		addq.w	#1,d4
		move.b	d4,(a1)+
		move.b	d3,(a1)+

.ende		move.l	a1,d0
		sub.l	d7,d0
		movem.l	(sp)+,d2-d7/a2-a6
		rts


saveiff_cmap	dc.l	0
saveiff_cmapl	dc.l	0
saveiff.crunchmem dc.l	0
saveiff.uncrunchlen dc.l	0

saveiff_dat	dc.b	"FORM",0,0,0,0,"ILBM","BMHD",0,0,0,$14
saveiff_datpicsize
		dc.w	320,200,0,0
saveiff_datdepth
		dc.b	5,0
saveiff_compression
		dc.b	0,0
		dc.w	0
		dc.b	0,0
saveiff_datresolution
		dc.w	320,200
		dc.b	"CAMG",0,0,0,4
saveiff_datmodeid
		dc.l	0
		dc.b	"CMAP"
saveiff_datcmapl
		dc.l	0
saveiff_datl	equ	*-saveiff_dat
saveiff_dat2	dc.b	"BODY",0,0,0,0
