
; GetPixel32Smooth(chunky:a0:PTR TO chunky,x:fp0:FLOAT,y:fp1:FLOAT)(LONG)

	machine	mc68020
	fpu	1

	xdef	_GetPixel32Smooth

_GetPixel32Smooth
	fmovem.x	fp2-fp3,-(a7)
	movem.l	d2-d6,-(a7)
	cmpa.l	#0,a0
	beq.w	.out
	ftst.x	fp0
	fblt.w	.out
	ftst.x	fp1
	fblt.w	.out
	fcmp.l	(a0),fp0
	fbge.w	.out
	fcmp.l	(4,a0),fp1
	fbge.w	.out

; fp0 and fp1 are float positions in the chunky and we want to get an exact
; interpolated value of the colour
	fmove.l	fp0,d0		; get integer x and y
	fmove.l	fp1,d1
	fsub.l	d0,fp0		; get the difference (0.0..1.0)
	fsub.l	d1,fp1

	muls.l	(a0),d3
	add.l	d0,d3
	lsl.l	#2,d3		; d1 now contains position in buffer
	movea.l	(8,a0),a1
	move.l	(0,a1,d3.l),d0	; x,y
	move.l	(1,a1,d3.l),d1	; x+1,y
	add.l	(a0),d3
	move.l	(-1,a1,d3.l),d2	; x,y+1
	move.l	(0,a1,d3.l),d3	; x+1,y+1
; here we got four colours:
;d0*--*d1
;  |  |
;d2*--*d3
	move.l	d0,d4
	bsr	UnPack32
	movem.l	d1-d3,-(a7)
	movem.l	d4-d6,-(a7)
	move.l	d1,d4
	bsr	UnPack32
	movem.l	(a7)+,d1-d3	; now I have d1,d2,d3 as colour x+1,y and d4,d5,d6 as colour x,y

	fmove.l	d4,fp3		; red
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d1,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d4		; a:=a*(1-t)+b*t

	fmove.l	d5,fp3		; green
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d2,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d5		; a:=a*(1-t)+b*t

	fmove.l	d6,fp3		; blue
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d3,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d6		; a:=a*(1-t)+b*t

	movem.l	(a7)+,d1-d3	; restore old values
	movem.l	d4-d6,-(a7)	; store first colour

	move.l	d2,d4
	bsr	UnPack32
	movem.l	d4-d6,-(a7)
	move.l	d3,d4
	bsr	UnPack32
	movem.l	(a7)+,d1-d3	; now I have d1,d2,d3 as colour x+1,y and d4,d5,d6 as colour x,y

	fmove.l	d4,fp3		; red
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d1,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d4		; a:=a*(1-t)+b*t

	fmove.l	d5,fp3		; green
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d2,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d5		; a:=a*(1-t)+b*t

	fmove.l	d6,fp3		; blue
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d3,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d6		; a:=a*(1-t)+b*t

	movem.l	(a7)+,d1-d3	; restore first colour (from d4,d5,d6)

	fmove.l	d4,fp3		; red
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d1,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d1		; b:=a*(1-t)+b*t

	fmove.l	d5,fp3		; green
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d2,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d2		; b:=a*(1-t)+b*t

	fmove.l	d6,fp3		; blue
	fmove.w	#1,fp2
	fsub	fp0,fp2
	fmul	fp2,fp3		; fp3:=a*(1-t)
	fmove.l	d3,fp2
	fmul	fp0,fp2		; fp2:=b*t
	fadd	fp3,fp2
	fmove.l	fp2,d3		; b:=a*(1-t)+b*t

	moveq	#0,d0
	swap	d1	; 00rr0000
	lsl	#8,d2	; 0000gg00
	or.l	d1,d0
	or.l	d2,d0
	or.l	d3,d0	; 00rrggbb

	movem.l	(a7)+,d2-d6
	fmovem.x	(a7)+,fp2-fp3
	rts
.out	moveq	#-1,d0
	movem.l	(a7)+,d2-d6
	fmovem.x	(a7)+,fp2-fp3
	rts

; UnPack32(d4:UL)(d4:L,d5:L,d6:L)
UnPack32
	clr.l	d5
	move.b	d4,d6
	lsr.l	#8,d4
	clr.l	d5
	move.b	d4,d5
	lsr.l	#8,d4
	andi.l	#$ff,d4	; clear alpha
	rts
