; MetaGraph 256 color modes drawing procs
; Copyright 1996 by Daniel Mahrenholz

INCLUDE	grdef.asm
INCLUDE metagr.def

IDEAL

INCLUDE	"MetaGlob.inc"
INCLUDe "MetaGr.con"

SEGMENT	Code	byte	public
ASSUME	cs: Code

P386

MASM

INCLUDE	grserv.asm

def_mapping32

IDEAL

LOCALS @@

PROC 	P_GetP_256 near

	xor	eax, eax
	xor	eax, eax
	pop	cx ax
	mov	bx, [MetaState]
	and	bx, ms_Draw
	jz	@@2

IFDEF	uMetaOrigin
	add	cx, [(TPoint MetaOrigin).x]
	add	ax, [(TPoint MetaOrigin).y]
ENDIF

	cmp	cx, [(TRect ClipRect).b.x]
	jnl	@@2
	cmp	cx, [(TRect ClipRect).a.x]
	jl	@@2
	cmp	ax, [(TRect ClipRect).b.y]
	jnl	@@2
	cmp	ax, [(TRect ClipRect).a.y]
	jl	@@2

	mul	[BytesPerLine32]
	add	eax, ecx
	add	eax, [ActiveLinear32]
	call	MapLinear32
	mov	di, ax
	mov	al, [fs:di]
	xor	ah, ah
	ret
@@2:
	xor	ax, ax
	ret
ENDP

MACRO	P_PointM Func

PROC	F_Point_256&Func near

	mov	eax, [fy]
	mov	ecx, [fx]
	mov	esi, [DColor256]
	jmp	F_Point_256&Func&_Entry

ENDP

PROC 	P_Point_256&Func near

	xor	eax, eax
	xor	edx, edx
	pop	si cx ax
	mov	bx, [MetaState]
	and	bx, ms_Draw
	jz	@@2

IFDEF	uMetaOrigin
	add	cx, [(TPoint MetaOrigin).x]
	add	ax, [(TPoint MetaOrigin).y]
ENDIF

	cmp	cx, [(TRect ClipRect).b.x]
	jnl	@@2
	cmp	cx, [(TRect ClipRect).a.x]
	jl	@@2
	cmp	ax, [(TRect ClipRect).b.y]
	jnl	@@2
	cmp	ax, [(TRect ClipRect).a.y]
	jl	@@2

F_Point_256&Func&_Entry:

	mul	[BytesPerLine32]
	add	eax, ecx
	add	eax, [ActiveLinear32]
	call	MapLinear32
	mov	di, ax
	mov	bx, si
	&Func	[(byte fs:di)], bh
@@2:
	ret
ENDP

ENDM

MACRO   P_VLM   Func

PROC 	P_VL_256&Func NEAR

	mov	ax, [MetaState]
	and	ax, ms_Draw
	jnz	@@2
	add	sp, 8
	ret
@@2:
	xor	eax, eax
	xor	edx, edx
	xor	ebx, ebx
	pop	bx ax di

IFDEF	uMetaOrigin
	add	bx, [(TPoint MetaOrigin).x]
	add	ax, [(TPoint MetaOrigin).y]
	add	di, [(TPoint MetaOrigin).y]
ENDIF

	cmp	bx, [(TRect ClipRect).a.x]
	jl	@@e
	cmp	bx, [(TRect ClipRect).b.x]
	jnl	@@e
	cmp	di, [(TRect ClipRect).a.y]
	jl	@@e
	cmp	di, [(TRect ClipRect).b.y]
	jl	@@4
	mov	di, [(TRect ClipRect).b.y]
	dec	di
@@4:
	cmp	ax, [(TRect ClipRect).b.y]
	jnl	@@e
	cmp	ax, [(TRect ClipRect).a.y]
	jnl	@@5
	mov	ax, [(TRect ClipRect).a.y]
@@5:
	push	[daLnStyle]
	pop	[Style]
	sub	di, ax
	mul	[BytesPerLine32]
	add	eax, ebx
	add	eax, [ActiveLinear32]
	inc	di
	mov	cx, di
	call	MapLinear32
	mov	edi, eax
	mov	ebx, [DColor256]
	test	[Style], 0ffffh
	jz	@@3
@@6:
	rol	[Style], 1
	jnc	@@nd
	&Func&	[fs:di], bh
@@nd:
	add	edi, [BytesPerLine32]
	MapNext32 edi, [WindowSize32]
	dec	cx
	jnz	@@6
	jmp	@@e
@@3:
	&Func&	[fs:di], bh
	add	edi, [BytesPerLine32]
	MapNext32 edi, [WindowSize32]
	dec	cx
	jnz	@@3
@@e:
	ret
ENDP

ENDM


MACRO	P_HLM 	Func

PROC	P_HL_256&Func NEAR

	pop	[ya] bx cx

	cmp	bx, cx
	jnl	@@1
	xchg	bx, cx
@@1:
	mov	[xa], cx
	mov	[xe], bx

	mov	ax, [MetaState]
	and	ax, ms_Draw
	jz	@@e

IFDEF	uMetaOrigin
	mov	ax, [(TPoint MetaOrigin).x]
	mov	bx, [(TPoint MetaOrigin).y]
	add	[xa], ax
	add	[xe], ax
	add	[ya], bx
ENDIF

	mov	ax, [(TRect ClipRect).a.x]
	mov	bx, [(TRect ClipRect).a.y]
	mov	cx, [(TRect ClipRect).b.x]
	mov	dx, [(TRect ClipRect).b.y]
	cmp	[ya], bx
	jl	@@e
	cmp	[ya], dx
	jnl	@@e
	cmp	[xa], cx
	jnl	@@e
	cmp	[xe], ax
	jl	@@e
	cmp	[xa], ax
	jge	@@4
	mov	[xa], ax
@@4:
	cmp	[xe], cx
	jl	@@5
	mov	[xe], cx
	dec	[xe]
@@5:
	movzx	eax, [ya]
	mul	[BytesPerLine32]
	movzx	ecx, [xa]
	add	eax, ecx
	add	eax, [ActiveLinear32]
	call	MapLinear32
	mov	es, dx
	mov	edi, eax
	sub	cx, [xe]
	neg	cx
        js      @@e
	inc	cx
	mov	eax, [HColor256]
	cmp 	[daLnStyle], 0ffffh		;;;; MK: MUST BE 'CMP'
	jnz	@@styled
	DoRepDest edi, [WindowSize32],,,DWORD,&Func&,,dx,edx
	retn
@@styled:
	cmp	[daLnStyle], 0
	je	@@e
	push	[daLnStyle]
	pop	[Style]
	mov	edx, edi
	and     ecx, 0ffffh
	add	edx, ecx
	sub	edx, [WindowSize32]
	js	@@st2
	mov	ecx, [WindowSize32]
	sub	ecx, edi
	jz	@@st5
@@st1:

	ror	[Style], 1
	jnc	@@st3
	&Func&bni
@@st3:
	inc	di
	dec	ecx
	jnz	@@st1
@@st5:
	mov	ecx, edx
	call	NextWindow32
	xor	edi, edi
@@st2:
	ror	[Style], 1
	jnc	@@st4
	&Func&bni
@@st4:
	inc	di
	dec	ecx
	jnz	@@st2
@@e:
	retn
ENDP

ENDM



MACRO	P_BarM Func

PROC	P_Bar_256&Func NEAR

	xor	ecx, ecx
	xor	eax, eax
	xor	ebx, ebx
	xor	esi, esi

	pop	si ax cx bx
        push    ebp

	cmp     si, [(TRect ClipRect).a.y]
	jl      @@e
	cmp     ax, [(TRect ClipRect).b.y]
	jnl     @@e
	cmp     cx, [(TRect ClipRect).a.x]
	jl      @@e
	cmp     bx, [(TRect ClipRect).b.x]
	jnl     @@e
	cmp     si, [(TRect ClipRect).b.y]
	jl      @@c1
	mov     si, [(TRect ClipRect).b.y]
	dec     si
@@c1:
	cmp     ax, [(TRect ClipRect).a.y]
	jnl     @@c2
	mov     ax, [(TRect ClipRect).a.y]
@@c2:
	cmp     cx, [(TRect ClipRect).b.x]
	jl      @@c3
	mov     cx, [(TRect ClipRect).b.x]
	dec     cx
@@c3:
	cmp     bx, [(TRect ClipRect).a.x]
	jnl     @@c4
	mov     bx, [(TRect ClipRect).a.x]
@@c4:

	sub	esi, eax
	js	@@e
	sub	ecx, ebx
	js	@@e
@@2:
	inc	esi
	mov	[yd], si
	inc	ecx
	mul	[BytesPerLine32]
	add	eax, [ActiveLinear32]
	add	eax, ebx

	call	MapLinear32
	mov	es, dx
	mov	edi, eax
	mov	ebx, [BytesPerLine32]
	sub	ebx, ecx
	mov	eax, [FColor256]
	mov	ebp, ecx
	push	ds
	pop	gs
	mov	si, [FillBase]
	mov	[FillCur], 8
@@st0:
	cmp	[(word gs:si)], 0ffffh
	jne	@@styled

@@3:
	DoRepDest edi, [WindowSize32],,,DWORD,&Func&,,dx,edx
	jmp	@@4

@@styled:
	cmp	[(word gs:si)], 0
	jne	@@stne
	add	edi, ecx
	jmp	@@4

@@stne:
	push	[(word gs:si)]
	pop	[Style]
	mov	edx, edi
	add	edx, ecx
	sub	edx, [WindowSize32]
	js	@@st2
	mov	ecx, [WindowSize32]
	sub	ecx, edi
	jz	@@st5
@@st1:
	ror	[Style], 1
	jnc	@@st3
	&Func&bni
@@st3:
	inc	edi
	dec	cx
	jnz	@@st1
@@st5:
	mov	ecx, edx
	call	NextWindow32
	xor	edi, edi
@@st2:
	ror	[Style], 1
	jnc	@@st4
	&Func&bni
@@st4:
	inc	edi
	dec	cx
	jnz	@@st2
@@4:
	add	edi, ebx
	MapNext32 edi, [WindowSize32]
	mov	ecx, ebp
	add	si, 2
	dec	[FillCur]
	jnz	@@fnl
	sub	si, 16
	mov	[FillCur], 8
@@fnl:
	dec	[yd]
	jnz	@@st0

@@e:
        pop     ebp
	retn

ENDP

ENDM

MACRO	P_LineM Func

PROC	P_Line_256&Func NEAR

	pop	dx cx bx ax

	LOCAL	flip, xmin, xmax, ymin, ymax, x1, x2, y1, y2, d: DWord, \
		diag: DWord, sd: DWOrd, xinc: DWord, yinc:DWord = LocalSize

	push	bp
	mov	bp, sp
	sub	sp, LocalSize

	push	[daLnStyle]
	pop	[Style]
	mov	[diag], 0
	mov	[flip], 0
	mov     [y1], dx
	mov	[ymin], dx
	mov	[y2], cx
	mov	[ymax], cx
	mov	[x1], bx
	mov	[xmin], bx
	mov	[x2], ax
	mov	[xmax], ax
	sub	cx, dx
	mov	[yd], cx
	jns	@@dt2
	neg	cx
	mov	dx, [ymin]
	xchg	dx, [ymax]
	mov	[ymin], dx
@@dt2:
	sub	ax, bx
	mov	[xd], ax
	jns	@@dt1
	neg	ax
	mov	bx, [xmin]
	xchg	bx, [xmax]
	mov	[xmin], bx
@@dt1:
	mov	bx, ax
	or	bx, cx
	jnz	@@np
	movsx	eax, [x1]
	mov	[fx], eax
	movsx	ebx, [y1]
	mov	[fy], ebx

	; clipping

	cmp	ax, [(TRect ClipRect).a.x]
	jl	@@e
	cmp	ax, [(TRect ClipRect).b.x]
	jnl	@@e
	cmp	bx, [(TRect ClipRect).a.y]
	jl	@@e
	cmp	bx, [(TRect ClipRect).b.y]
	jnl	@@e

	rol	[Style], 1
	jnc	@@e

	call	F_Point_256&Func
	jmp	@@e
@@np:
	cmp	ax, cx
	jg	@@xd
	jne	@@yd

	mov	[diag], 1
	test	[yd], 08000h
	jz	@@edz
	neg	[flip]
	mov	dx, [y1]
	xchg	[y2], dx
	mov	[y1], dx
	neg	[yd]
	mov	ax, [x1]
	xchg	ax, [x2]
	mov	[x1], ax
	neg	[xd]
@@edz:
	movzx	eax, [x1]
	mov	[fx], eax
	mov	[xinc], 1
	test	[xd], 08000h
	jz	@@edxz
	neg	[xinc]
	neg	[diag]
@@edxz:
	mov	eax, 080000000h
	jmp	@@ydcs

@@yd:

	; sort y-Coords for y1<y2
	; calculate d as dx/dy

	test	[yd], 08000h
	jz	@@ydz

	neg	[flip]
	mov	dx, [y1]
	xchg	[y2], dx
	mov	[y1], dx
	mov	dx, [x1]
	xchg	dx, [x2]
	mov	[x1], dx
	neg	[yd]
	neg	[xd]

@@ydz:
	movzx	eax, [x1]
	mov	[fx], eax
	mov	[xinc], 1
	test	[xd], 08000h
	jz	@@ydxz
	neg	[xinc]
@@ydxz:
	movsx	ebx, [yd]
	movsx	eax, [xd]
	mov	ecx, 080000000h
	imul	ecx
	idiv	ebx
	shr	ebx, 1
	cmp	bx, dx
	jge	@@ydc3
	inc	eax
@@ydc3:

@@ydcs:
	mov	[d], eax
	mov	[sd], 0
	; x-Clipping I

	mov	ax, [xmax]
	cmp	ax, [(TRect ClipRect).a.x]
	jl	@@e				; invisible
	mov	ax, [xmin]
	cmp	ax, [(TRect ClipRect).b.x]
	jge	@@e				; invisible

	; y-clipping

	mov	ax, [ymin]
	cmp	ax, [(TRect ClipRect).b.y]
	jge	@@e				; invisible
	mov	bx, [ymax]
	cmp	bx, [(Trect ClipRect).a.y]
	jl	@@e				; invisible
	mov	ax, [y1]
	cmp	ax, [(TRect ClipRect).a.y]
	jnl	@@ydc1

	; clip y1 to ClipRect.a.x
	neg	ax
	add	ax, [(TRect ClipRect).a.y]
	cwde
	test	[diag], 1
	jz	@@ydnodiag
	imul	[diag]
	mov	edx, eax
	jmp	@@ydc4
@@ydnodiag:
	shl	eax, 1
	imul	[d]
	shr	eax, 1
	test	[flip], 1
	jnz	@@ydc4
	neg	edx
@@ydc4:
	add	[fx], edx			; new starting x
	mov	[sd], eax			; rest
	mov	ax, [(TRect ClipRect).a.y]
	mov	[y1], ax

@@ydc1:
	mov	bx, [y2]
	cmp	bx, [(TRect ClipRect).b.y]
	jl	@@ydc2

	; clip y2 to ClipRect.b.y
	mov	ax, [(TRect ClipRect).b.y]
	mov	[y2], ax
@@ydc2:
	mov	ax, [y2]
	sub	ax, [y1]
        jnz     @@ydcnp
        ; only one linepoint to draw
	rol    [Style], 1
        jnc    @@e
	movsx	eax, [x1]
	mov	[fx], eax
        call   F_Point_256&Func
        jmp    @@e
@@ydcnp:
	mov	[yd], ax
	xor	eax, eax
	mov	ax, [y1]
	mov	[fy], eax
	test	[xinc], 08000000h
	jnz	@@ydloopb
	movzx	ecx, [(TRect ClipRect).a.x]

@@ydloop:
	cmp	[fx], ecx
	jge	@@ydloop2

	rol	[Style], 1
	inc	[fy]
	mov	esi, [d]
	add	[sd], esi
	jns	@@yd_nox		; 31bit-overflow

	mov	eax, [xinc]
	add	[fx], eax
	and	[sd], 07fffffffh

@@yd_nox:
	dec	[yd]
	jnz	@@ydloop
	jmp	@@e

@@ydloop2:
	movzx	ecx, [(TRect ClipRect).b.x]
@@ydl2s:
	cmp	[fx], ecx
	jge	@@e

	rol	[Style], 1
	jnc	@@ydl2nd
	push	cx
	call	F_Point_256&Func
	pop	cx
@@ydl2nd:
	inc	[fy]
	mov	esi, [d]
	add	[sd], esi
	jns	@@yd_nox2		; 31bit-overflow

	mov	eax, [xinc]
	add	[fx], eax
	and	[sd], 07fffffffh

@@yd_nox2:

	dec	[yd]
	jnz	@@ydl2s
	jmp	@@e

@@ydloopb:
	movzx	ecx, [(TRect ClipRect).b.x]
@@ydlbs:
	cmp	[fx], ecx
	jl	@@ydloopb2

	rol	[Style], 1
	inc	[fy]
	mov	esi, [d]
	add	[sd], esi
	jns	@@yd_noxb		; 31bit-overflow

	mov	eax, [xinc]
	add	[fx], eax
	and	[sd], 07fffffffh

@@yd_noxb:
	dec	[yd]
	jnz	@@ydlbs
	jmp	@@e

@@ydloopb2:
	movzx	ecx, [(TRect ClipRect).a.x]
@@ydlb2s:
	cmp	[fx], ecx
	jl	@@e

	rol	[Style], 1
	jnc	@@ydlb2nd
	push	cx
	call	F_Point_256&Func
	pop	cx
@@ydlb2nd:
	inc	[fy]
	mov	esi, [d]
	add	[sd], esi
	jns	@@yd_noxb2		; 31bit-overflow

	mov	eax, [xinc]
	add	[fx], eax
	and	[sd], 07fffffffh

@@yd_noxb2:

	dec	[yd]
	jnz	@@ydlb2s
	jmp	@@e

@@xd:

	test	[xd], 08000h
	jz	@@xdz

	mov	dx, [x1]
	xchg	[x2], dx
	mov	[x1], dx
	neg	[xd]
	mov	ax, [y1]
	xchg	ax, [y2]
	mov	[y1], ax
	neg	[yd]

@@xdz:
	movzx	eax, [y1]
	mov	[fy], eax
	mov	[yinc], 1		; Sp„ter  BytesPerLine
	test	[yd], 08000h
	jz	@@xdyz
	neg	[yinc]
@@xdyz:

	movsx	ebx, [xd]
	movsx	eax, [yd]
	mov	ecx, 080000000h
	imul	ecx
	idiv	ebx
	shr	ebx, 1
	cmp	bx, dx
	jge	@@xdc3
	inc	eax
@@xdc3:
	mov	[d], eax
	mov	[sd], 0
	; y-Clipping I

	mov	ax, [ymax]
	cmp	ax, [(TRect ClipRect).a.y]
	jl	@@e				; invisible
	mov	ax, [ymin]
	cmp	ax, [(TRect ClipRect).b.y]
	jge	@@e				; invisible

	; x-clipping

	mov	ax, [xmin]
	cmp	ax, [(TRect ClipRect).b.x]
	jge	@@e				; invisible
	mov	bx, [xmax]
	cmp	bx, [(Trect ClipRect).a.x]
	jl	@@e		; invisible
	mov	ax, [x1]
	cmp	ax, [(TRect ClipRect).a.x]
	jnl	@@xdc1

	; clip x1 to ClipRect.a.x
	neg	ax
	add	ax, [(TRect ClipRect).a.x]
	cwde
	test	[diag], 1
	jz	@@xdnodiag
	imul	[diag]
	mov	edx, eax
	jmp	@@xdc4
@@xdnodiag:
	shl	eax, 1
	imul	[d]
	shr	eax, 1
	test	[flip], 1
	jnz	@@xdc4
	neg	edx
@@xdc4:
	add	[fy], edx			; new starting y
	mov	[sd], eax			; rest
	mov	ax, [(TRect ClipRect).a.x]
	mov	[x1], ax

@@xdc1:
	mov	bx, [x2]
	cmp	bx, [(TRect ClipRect).b.x]
	jl	@@xdc2

	; clip x2 to ClipRect.b.x
	mov	ax, [(TRect ClipRect).b.x]
	mov	[x2], ax
@@xdc2:
	mov	ax, [x2]
	sub	ax, [x1]
        jnz     @@xdcnp
        ; only one linepoint to draw
        rol    [Style], 1
        jnc    @@e
	movsx	eax, [x1]
	mov	[fx], eax
        call   F_Point_256&Func
        jmp    @@e
@@xdcnp:
	mov	[xd], ax
	xor	eax, eax
	mov	ax, [x1]
	mov	[fx], eax
	test	[yinc], 08000000h
	jnz	@@xdloopb
	movzx	ecx, [(TRect ClipRect).a.y]

@@xdloop:
	cmp	[fy], ecx
	jge	@@xdloop2

	rol	[Style], 1
	inc	[fx]
	mov	esi, [d]
	add	[sd], esi
	jns	@@xd_noy		; 31bit-overflow

	mov	eax, [yinc]
	add	[fy], eax
	and	[sd], 07fffffffh

@@xd_noy:
	dec	[xd]
	jnz	@@xdloop
	jmp	@@e

@@xdloop2:
	movzx	ecx, [(TRect ClipRect).b.y]
@@xdl2s:
	cmp	[fy], ecx
	jge	@@e

	rol	[Style], 1
	jnc	@@xdl2nd
	push	cx
	call	F_Point_256&Func
	pop	cx
@@xdl2nd:
	inc	[fx]
	mov	esi, [d]
	add	[sd], esi
	jns	@@xd_noy2		; 31bit-overflow

	mov	eax, [yinc]
	add	[fy], eax
	and	[sd], 07fffffffh

@@xd_noy2:

	dec	[xd]
	jnz	@@xdl2s
	jmp	@@e

@@xdloopb:
	movzx	ecx, [(TRect ClipRect).b.y]
@@xdlbs:
	cmp	[fy], ecx
	jl	@@xdloopb2

	rol	[Style], 1
	inc	[fx]
	mov	esi, [d]
	add	[sd], esi
	jns	@@xd_noyb		; 31bit-overflow

	mov	eax, [yinc]
	add	[fy], eax
	and	[sd], 07fffffffh

@@xd_noyb:
	dec	[xd]
	jnz	@@xdlbs
	jmp	@@e

@@xdloopb2:
	movzx	ecx, [(TRect ClipRect).a.y]
@@xdlb2s:
	cmp	[fy], ecx
	jl	@@e

	rol	[Style], 1
	jnc	@@xdlb2nd
	push	cx
	call	F_Point_256&Func
	pop	cx
@@xdlb2nd:
	inc	[fx]
	mov	esi, [d]
	add	[sd], esi
	jns	@@xd_noyb2		; 31bit-overflow

	mov	eax, [yinc]
	add	[fy], eax
	and	[sd], 07fffffffh

@@xd_noyb2:

	dec	[xd]
	jnz	@@xdlb2s
	jmp	@@e
@@e:
	leave
	ret

ENDP

ENDM


MACRO	Transfer Op

  MACRO	&Op&SB

	PUSHSTATE
	IDEAL

	Op	[es:di], al
	inc	di

	POPSTATE

  ENDM

  MACRO	&Op&SW

	PUSHSTATE
	IDEAL

	Op	[es:di], ax
	add	di, 2

	POPSTATE

  ENDM

  MACRO	&Op&SD

	PUSHSTATE
	IDEAL

	Op	[es:di], eax
	add	di, 4

	POPSTATE

  ENDM


ENDM

MACRO	Transferni Name, Op

  MACRO	&Name&Bni

	PUSHSTATE
	IDEAL

	Op	[fs:di], al

	POPSTATE

  ENDM

  MACRO	&Name&Wni

	PUSHSTATE
	IDEAL

	Op	[fs:di], ax

	POPSTATE

  ENDM

  MACRO	&Name&Dni

	PUSHSTATE
	IDEAL

	Op	[fs:di], eax

	POPSTATE

  ENDM

ENDM

Transfer and
Transfer or
Transfer xor

Transferni ands, and
Transferni ors, or
Transferni xors, xor
Transferni stos, mov

P_PointM mov
P_PointM and
P_PointM xor
P_PointM or

P_VLM mov
P_VLM and
P_VLM xor
P_VLM or

P_HLM stos
P_HLM ands
P_HLM xors
P_HLM ors

P_BarM stos
P_BarM ands
P_BarM xors
P_BarM ors

P_LineM mov
P_LineM and
P_LineM xor
P_LineM or

ENDS

END