;
; Copyright 2020 Electronic Arts Inc.
;
; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
; software: you can redistribute it and/or modify it under the terms of 
; the GNU General Public License as published by the Free Software Foundation, 
; either version 3 of the License, or (at your option) any later version.

; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
; in the hope that it will be useful, but with permitted additional restrictions 
; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
; distributed with this program. You should have received a copy of the 
; GNU General Public License along with permitted additional restrictions 
; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>.

;***************************************************************************
;**   C O N F I D E N T I A L --- W E S T W O O D   A S S O C I A T E S   **
;***************************************************************************
;*                                                                         *
;*                 Project Name : Command & Conquer                        *
;*                                                                         *
;*                    File Name : KEYFBUFF.ASM                             *
;*                                                                         *
;*                   Programmer : David R. Dettmer                         *
;*                                                                         *
;*                   Start Date : March 3, 1995                            *
;*                                                                         *
;*                  Last Update :                                          *
;*                                                                         *
;*-------------------------------------------------------------------------*
;* Functions:                                                              *
;*   Buffer_Frame_To_Page -- Copies a linear buffer to a virtual viewport  *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *

;********************** Model & Processor Directives ***********************
;IDEAL
;P386
;MODEL USE32 FLAT
;jumps

.MODEL FLAT
;.386

;******************************** Includes *********************************
;INCLUDE "gbuffer.inc"
;include	"profile.inc"

OPTIMAL_BYTE_COPY	equ	14

GraphicViewPort STRUCT 
GVPOffset		DD		?		; offset to virtual viewport
GVPWidth			DD		?		; width of virtual viewport
GVPHeight		DD		?		; height of virtual viewport
GVPXAdd			DD		?		; x mod to get to next line
GVPXPos			DD		?		; x pos relative to Graphic Buff
GVPYPos			DD		?		; y pos relative to Graphic Buff
GVPPitch		dd		?		; modulo of graphic view port
GVPBuffPtr		DD		?		; ptr to associated Graphic Buff
GraphicViewPort ENDS

;******************************** Equates **********************************

TRUE	equ	1			; Boolean 'true' value
FALSE	equ	0			; Boolean 'false' value

;*=========================================================================*/
;* The following are defines used to control what functions are linked	   *
;* in for Buffer_Frame_To_Page.						   *
;*=========================================================================*/
;USE_NORMAL		EQU	TRUE
;USE_HORZ_REV 		EQU	TRUE
;USE_VERT_REV 		EQU	TRUE
;USE_SCALING 		EQU	TRUE


FLAG_NORMAL		EQU	0
FLAG_TRANS		EQU	1
FLAG_GHOST		EQU	2
FLAG_FADING		EQU	4
FLAG_PREDATOR		EQU	8

FLAG_MASK		EQU	0Fh


SHAPE_NORMAL 		EQU	0000h		; Standard shape
;SHAPE_HORZ_REV 		EQU	0001h		; Flipped horizontally
;SHAPE_VERT_REV 		EQU	0002h		; Flipped vertically
;SHAPE_SCALING 		EQU	0004h		; Scaled (WORD scale_x, WORD scale_y)
;SHAPE_VIEWPORT_REL 	EQU	0010h		; Coords are window-relative
;SHAPE_WIN_REL 		EQU	0010h		; Coordinates are window relative instead of absolute.
SHAPE_CENTER 		EQU	0020h		; Coords are based on shape's center pt
SHAPE_TRANS		EQU	0040h		; has transparency

SHAPE_FADING 		EQU	0100h		; Fading effect (VOID * fading_table,
						;   WORD fading_num)
SHAPE_PREDATOR 		EQU	0200h		; Transparent warping effect
;SHAPE_COMPACT 		EQU	0400h		; Never use this bit
;SHAPE_PRIORITY 		EQU	0800h		; Use priority system when drawing
SHAPE_GHOST		EQU	1000h		; Shape is drawn ghosted
;SHAPE_SHADOW		EQU	2000h
SHAPE_PARTIAL  		EQU	4000h
;SHAPE_COLOR 		EQU	8000h		; Remap the shape's colors
						;   (VOID * color_table)


;
;.......................... Shadow Effect ..................................
;
SHADOW_COL		EQU	00FFh	; magic number for shadows

;......................... Priority System .................................
;
CLEAR_UNUSED_BITS  	EQU	0007h	; and with 0000-0111 to clear
					;  non-walkable high bit and
					;  scaling id bits
NON_WALKABLE_BIT  	EQU	0080h	; and with 1000-0000 to clear all
					;  but non-walkable bit
;
;......................... Predator Effect .................................
;
;PRED_MASK		EQU	0007h	; mask used for predator pixel puts
PRED_MASK		EQU	000Eh	; mask used for predator pixel puts


;---------------------------------------------------------------------------
;
; Use a macro to make code a little cleaner.
; The parameter varname is optional.
; Syntax to use macro is :
;  WANT equ expression
;  USE func [,varname]
; If the 'varname' is defined, a table declaration is created like:
;	GLOBAL	TableName:DWORD
; Then, the table entry is created:
;  If WANT is true, the table entry is created for the given function:
;	varname	DD	func
;  If WANT is not TRUE, a Not_Supported entry is put in the table:
;	varname	DD	Not_Supported
; The resulting tables look like:
;
;	GLOBAL	ExampTable:DWORD
;	ExampTable	DD	routine1
;			DD	routine2
;			DD	routine3
;			...
; Thus, each table is an array of function pointers.
;
;---------------------------------------------------------------------------
USE MACRO  func, varname
 IF WANT
  varname 	DD	func
 ELSE
  varname	DD	Not_Supported
 ENDIF
ENDM

prologue	macro
endm



epilogue macro 
endm


; IFNB <varname>
;	GLOBAL	varname:DWORD
; ENDIF

;---------------------------------------------------------------------------


.DATA

;---------------------------------------------------------------------------
; Predator effect variables
;---------------------------------------------------------------------------
; make table for negative offset and use the used space for other variables

BFPredNegTable	DW	-1, -3, -2, -5, -2, -4, -3, -1
	; 8 words below calculated
		DW	0, 0, 0, 0, 0, 0, 0, 0	; index ffffff00
		DD	0, 0, 0, 0		; index ffffff10
BFPredOffset	DD	0, 0, 0, 0		; index ffffff20
		DD	0, 0, 0, 0		; index ffffff30
	; partially faded predator effect value
BFPartialPred	DD	0, 0, 0, 0		; index ffffff40
BFPartialCount	DD	0, 0, 0, 0		; index ffffff50
		DD	0, 0, 0, 0		; index ffffff60
		DD	0, 0, 0, 0		; index ffffff70
		DD	0, 0, 0, 0		; index ffffff80
		DD	0, 0, 0, 0		; index ffffff90
		DD	0, 0, 0, 0		; index ffffffa0
		DD	0, 0, 0, 0		; index ffffffb0
		DD	0, 0, 0, 0		; index ffffffc0
		DD	0, 0, 0, 0		; index ffffffd0
		DD	0, 0, 0, 0		; index ffffffe0
		DD	0, 0, 0, 0		; index fffffff0
BFPredTable	DW	1, 3, 2, 5, 2, 3, 4, 1
;BFPredTable	DB	1, 3, 2, 5, 4, 3, 2, 1






		extern	C BigShapeBufferStart:dword
		extern	C UseBigShapeBuffer:dword
		extern	C TheaterShapeBufferStart:dword
		extern	C IsTheaterShape:dword
		;extern	C Single_Line_Trans_Entry:near
		;extern	C Next_Line:near
		extern	C MMX_Done:near
		extern	C MMXAvailable:dword
		;extern	C EndNewShapeJumpTable:byte
		;extern	C NewShapeJumpTable:dword


;**********************************************************************************
;
; Jump tables for new line header system
;
; Each line of shape data now has a header byte which describes the data on the line.
;

;
; Header byte control bits
;
BLIT_TRANSPARENT	=1
BLIT_GHOST		=2
BLIT_FADING		=4
BLIT_PREDATOR		=8
BLIT_SKIP		=16
BLIT_ALL		=BLIT_TRANSPARENT or BLIT_GHOST or BLIT_FADING or BLIT_PREDATOR or BLIT_SKIP


ShapeHeaderType	STRUCT

		draw_flags	dd	?
		shape_data	dd	?
		shape_buffer	dd	?

ShapeHeaderType	ENDS



;
; Global definitions for routines that draw a single line of a shape
;
		;extern	Short_Single_Line_Copy:near
		;extern	Single_Line_Trans:near
		;extern	Single_Line_Ghost:near
		;extern	Single_Line_Ghost_Trans:near
		;extern	Single_Line_Fading:near
		;extern	Single_Line_Fading_Trans:near
		;extern	Single_Line_Ghost_Fading:near
		;extern	Single_Line_Ghost_Fading_Trans:near
		;extern	Single_Line_Predator:near
		;extern	Single_Line_Predator_Trans:near
		;extern	Single_Line_Predator_Ghost:near
		;extern	Single_Line_Predator_Ghost_Trans:near
		;extern	Single_Line_Predator_Fading:near
		;extern	Single_Line_Predator_Fading_Trans:near
		;extern	Single_Line_Predator_Ghost_Fading:near
		;extern	Single_Line_Predator_Ghost_Fading_Trans:near
		;extern	Single_Line_Skip:near

		;extern	Single_Line_Single_Fade:near
		;extern	Single_Line_Single_Fade_Trans:near

;externdef AllFlagsJumpTable:dword
;
externdef NewShapeJumpTable:dword
externdef EndNewShapeJumpTable:byte
externdef CriticalFadeRedirections:dword
;externdef BufferFrameTable:dword

;externdef CriticalFadeRedirections:dword
;externdef CriticalFadeRedirections:dword
;externdef CriticalFadeRedirections:dword
;externdef BF_Copy:far ptr
;externdef BF_Trans:dword
;externdef BF_Ghost:dword
;externdef BF_Ghost_Trans:dword
;externdef BF_Fading:dword
;externdef BF_Fading_Trans:dword
;externdef BF_Ghost_Fading:dword
;externdef BF_Ghost_Fading_Trans:dword
;externdef BF_Predator:dword
;externdef BF_Predator_Trans:dword
;externdef BF_Predator_Ghost:dword
;externdef BF_Predator_Ghost_Trans:dword
;externdef BF_Predator_Fading:dword
;externdef BF_Predator_Fading_Trans:dword
;externdef BF_Predator_Ghost_Fading:dword
;externdef BF_Predator_Ghost_Fading_Trans:dword

externdef	C Single_Line_Trans:near
externdef	C Single_Line_Trans_Entry:near
externdef	C Next_Line:near


.CODE


;---------------------------------------------------------------------------
; Code Segment Tables:
; This code uses the USE macro to set up tables of function addresses.
; The tables have the following format:
; Tables defined are:
;	BufferFrameTable
;---------------------------------------------------------------------------

WANT	equ 	<TRUE>
USE	BF_Copy, BufferFrameTable

WANT	equ 	<TRUE>
USE	BF_Trans

WANT	equ 	<TRUE>
USE	BF_Ghost

WANT	equ 	<TRUE>
USE	BF_Ghost_Trans

WANT	equ 	<TRUE>
USE	BF_Fading

WANT	equ 	<TRUE>
USE	BF_Fading_Trans

WANT	equ 	<TRUE>
USE	BF_Ghost_Fading

WANT	equ 	<TRUE>
USE	BF_Ghost_Fading_Trans

WANT	equ 	<TRUE>
USE	BF_Predator

WANT	equ 	<TRUE>
USE	BF_Predator_Trans

WANT	equ 	<TRUE>
USE	BF_Predator_Ghost

WANT	equ 	<TRUE>
USE	BF_Predator_Ghost_Trans

WANT	equ 	<TRUE>
USE	BF_Predator_Fading

WANT	equ 	<TRUE>
USE	BF_Predator_Fading_Trans

WANT	equ 	<TRUE>
USE	BF_Predator_Ghost_Fading

WANT	equ 	<TRUE>
USE	BF_Predator_Ghost_Fading_Trans



.DATA

;NewShapeJumpTable label	near ptr		dword

;
; Jumptable for shape line drawing with no flags set
;

NewShapeJumpTable	dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
;CriticalFadeRedirections label		 dword
CriticalFadeRedirections		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with transparent flags set
;
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with ghost flags set
;

		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with ghost and transparent flags set
;

		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip





;
; Jumptable for shape line drawing routines with fading flag set
;

		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Single_Fade
		dd	Single_Line_Single_Fade
		dd	Single_Line_Fading
		dd	Single_Line_Fading
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Fading
		dd	Single_Line_Fading
		dd	Single_Line_Fading
		dd	Single_Line_Fading
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with fading and transparent flags set
;

		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Single_Fade
		dd	Single_Line_Single_Fade_Trans
		dd	Single_Line_Fading
		dd	Single_Line_Fading_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Fading
		dd	Single_Line_Fading_Trans
		dd	Single_Line_Fading
		dd	Single_Line_Fading_Trans
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with fading and ghost flags set
;

		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Single_Line_Single_Fade
		dd	Single_Line_Single_Fade
		dd	Single_Line_Ghost_Fading
		dd	Single_Line_Ghost_Fading
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Single_Line_Fading
		dd	Single_Line_Fading
		dd	Single_Line_Ghost_Fading
		dd	Single_Line_Ghost_Fading
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip



;
; Jumptable for shape line drawing routines with fading, transparent and ghost flags set
;

		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Single_Line_Single_Fade
		dd	Single_Line_Single_Fade_Trans
		dd	Single_Line_Ghost_Fading
		dd	Single_Line_Ghost_Fading_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Single_Line_Fading
		dd	Single_Line_Fading_Trans
		dd	Single_Line_Ghost_Fading
		dd	Single_Line_Ghost_Fading_Trans
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip






;
; Jumptable for shape line drawing with predator flag set
;

		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with transparent and predator flags set
;
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with ghost and predator flags set
;

		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with ghost and transparent and predator flags set
;

		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Predator_Ghost_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Predator_Ghost_Trans
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip





;
; Jumptable for shape line drawing routines with fading and predator flags set
;

		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Single_Fade
		dd	Single_Line_Single_Fade
		dd	Single_Line_Fading
		dd	Single_Line_Fading
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with fading and transparent and predator flags set
;

		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Single_Fade
		dd	Single_Line_Single_Fade_Trans
		dd	Single_Line_Fading
		dd	Single_Line_Fading_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Predator_Fading_Trans
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Predator_Fading_Trans
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


;
; Jumptable for shape line drawing routines with fading and ghost and predator flags set
;

		dd	Short_Single_Line_Copy
		dd	Short_Single_Line_Copy
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost
		dd	Single_Line_Single_Fade
		dd	Single_Line_Single_Fade
		dd	Single_Line_Ghost_Fading
		dd	Single_Line_Ghost_Fading
		dd	Single_Line_Predator
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Predator_Ghost_Fading
		dd	Single_Line_Predator_Ghost_Fading
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip







;
; Jumptable for shape line drawing routines with all flags set
;

AllFlagsJumpTable label dword
		dd	Short_Single_Line_Copy
		dd	Single_Line_Trans
		dd	Single_Line_Ghost
		dd	Single_Line_Ghost_Trans
		dd	Single_Line_Single_Fade
		dd	Single_Line_Single_Fade_Trans
		dd	Single_Line_Ghost_Fading
		dd	Single_Line_Ghost_Fading_Trans
		dd	Single_Line_Predator
		dd	Single_Line_Predator_Trans
		dd	Single_Line_Predator_Ghost
		dd	Single_Line_Predator_Ghost_Trans
		dd	Single_Line_Predator_Fading
		dd	Single_Line_Predator_Fading_Trans
		dd	Single_Line_Predator_Ghost_Fading
		dd	Single_Line_Predator_Ghost_Fading_Trans
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip
		dd	Single_Line_Skip


EndNewShapeJumpTable	db 0

.CODE



;---------------------------------------------------------------------------




;*********************************************************************************************
;* Set_Shape_Header -- create the line header bytes for a shape                              *
;*                                                                                           *
;* INPUT:	Shape width                                                                  *
;*              Shape height                                                                 *
;*              ptr to raw shape data                                                        *
;*              ptr to shape headers                                                         *
;*              shape flags                                                                  *
;*              ptr to translucency table                                                    *
;*              IsTranslucent                                                                *
;*                                                                                           *
;* OUTPUT:      none                                                                         *
;*                                                                                           *
;* Warnings:                                                                                 *
;*                                                                                           *
;* HISTORY:                                                                                  *
;*   11/29/95 10:09AM ST : Created.                                                          *
;*===========================================================================================*

		Setup_Shape_Header proc	C pixel_width:DWORD, pixel_height:DWORD, src:DWORD, headers:DWORD, flags:DWORD, Translucent:DWORD, IsTranslucent:DWORD

		;ARG	pixel_width 	:DWORD		; width of rectangle to blit
		;ARG	pixel_height	:DWORD		; height of rectangle to blit
		;ARG  	src         	:DWORD		; this is a member function
		;ARG	headers	    	:DWORD
		;ARG	flags		:DWORD
		;ARG	Translucent	:DWORD
		;ARG	IsTranslucent	:DWORD
		LOCAL	trans_count	:DWORD

		pushad


		mov	esi,[src]		;ptr to raw shape data
		mov	edi,[headers]		;ptr to headers we are going to set up
		mov	eax,[flags]
		and	eax,SHAPE_TRANS or SHAPE_FADING or SHAPE_PREDATOR or SHAPE_GHOST
		mov	[edi].ShapeHeaderType.draw_flags,eax 	;save old flags in header
		add	edi,size ShapeHeaderType
		mov	edx,[pixel_height]	;number of shape lines to scan

outer_loop:	mov	ecx,[pixel_width]	;number of pixels in shape line
		xor	bl,bl			;flag the we dont know anything about this line yet
		mov	[trans_count],0		;we havnt scanned any transparent pixels yet

;
; Scan one shape line to see what kind of data it contains
;
inner_loop:	xor	eax,eax
		mov	al,[esi]
		inc	esi

;
; Check for transparent pixel
;
		test	al,al
		jnz	not_transp
		test	[flags],SHAPE_TRANS
		jz	not_transp
		or	bl,BLIT_TRANSPARENT	;flag that pixel is transparent
		inc	[trans_count]		;keep count of the number of transparent pixels on the line
		jmp	end_lp

;
; Check for predator effect on this line
;
not_transp:	test	[flags],SHAPE_PREDATOR
		jz	not_pred
		or	bl,BLIT_PREDATOR

;
; Check for ghost effects
;
not_pred:	test	[flags],SHAPE_GHOST
		jz	not_ghost
		push	edi
		mov	edi,[IsTranslucent]
		cmp	byte ptr [edi+eax],-1
		pop	edi
		jz	not_ghost
		or	bl,BLIT_GHOST

;
; Check if fading is required
;
not_ghost:	test	[flags],SHAPE_FADING
		jz	end_lp
		or	bl,BLIT_FADING

end_lp:       dec	ecx
		jnz	inner_loop


;
; Interpret the info we have collected and decide which routine will be
; used to draw this line
;
		xor	bh,bh

		test	bl,BLIT_TRANSPARENT
		jz	no_transparencies
		or	bh,BLIT_TRANSPARENT
		mov	ecx,[pixel_width]
		cmp	ecx,[trans_count]
		jnz	not_all_trans

; all pixels in the line were transparent so we dont need to draw it at all
		mov	bh,BLIT_SKIP
		jmp	got_line_type

not_all_trans:
no_transparencies:
		mov	al,bl
		and	al,BLIT_PREDATOR
		or	bh,al
		mov	al,bl
		and	al,BLIT_GHOST
		or	bh,al
		mov	al,bl
		and	al,BLIT_FADING
		or	bh,al

;
; Save the line header and do the next line
;
got_line_type:mov	[edi],bh
		inc	edi

		dec	edx
		jnz	outer_loop


		popad
		ret

Setup_Shape_Header	endp	




;**************************************************************
;
; Macro to fetch the header of the next line and jump to the appropriate routine
;
next_line	macro

		add	edi , [ dest_adjust_width ]	;add in dest modulo
		dec	edx				;line counter
		jz	real_out			;return
		mov	ecx,[save_ecx]			;ecx is pixel count
		mov	eax,[header_pointer]		;ptr to next header byte
		mov	al,[eax]
		inc	[header_pointer]
		and	eax,BLIT_ALL			;Make sure we dont jump to some spurious address
							; if the header is wrong then its better to draw with the wrong
							; shape routine than to die
		shl	eax,2
		add	eax,[ShapeJumpTableAddress]	;get the address to jump to
		jmp	dword ptr [eax]			;do the jump

		endm






;***************************************************************************
;* VVC::TOPAGE -- Copies a linear buffer to a virtual viewport		   *
;*                                                                         *
;* INPUT:	WORD	x_pixel		- x pixel on viewport to copy from *
;*		WORD	y_pixel 	- y pixel on viewport to copy from *
;*		WORD	pixel_width	- the width of copy region	   *
;*		WORD	pixel_height	- the height of copy region	   *
;*		BYTE *	src		- buffer to copy from		   *
;*		VVPC *  dest		- virtual viewport to copy to	   *
;*                                                                         *
;* OUTPUT:      none                                                       *
;*                                                                         *
;* WARNINGS:    Coordinates and dimensions will be adjusted if they exceed *
;*	        the boundaries.  In the event that no adjustment is 	   *
;*	        possible this routine will abort.  If the size of the 	   *
;*		region to copy exceeds the size passed in for the buffer   *
;*		the routine will automatically abort.			   *
;*									   *
;* HISTORY:                                                                *
;*   06/15/1994 PWG : Created.                                             *
;*=========================================================================*
Buffer_Frame_To_Page proc C public USES eax ebx ecx edx esi edi x_pixel:DWORD, y_pixel:DWORD, pixel_width:DWORD, pixel_height:DWORD, src:DWORD, dest:DWORD, flags:DWORD

	;USES	eax,ebx,ecx,edx,esi,edi

	;*===================================================================
	;* define the arguements that our function takes.
	;*===================================================================
	;ARG	x_pixel     :DWORD		; x pixel position in source
	;ARG	y_pixel     :DWORD		; y pixel position in source
	;ARG	pixel_width :DWORD		; width of rectangle to blit
	;ARG	pixel_height:DWORD		; height of rectangle to blit
	;ARG    	src         :DWORD		; this is a member function
	;ARG	dest        :DWORD		; what are we blitting to

	;ARG	flags       :DWORD		; flags passed

	;*===================================================================
	; Define some locals so that we can handle things quickly
	;*===================================================================
	LOCAL	IsTranslucent		:DWORD	; ptr to the is_translucent table
	LOCAL	Translucent		:DWORD	; ptr to the actual translucent table
	LOCAL	FadingTable		:DWORD	; extracted fading table pointer
	LOCAL	FadingNum		:DWORD	; get the number of times to fade

	LOCAL	StashECX		:DWORD	; temp variable for ECX register

	LOCAL	jflags			:DWORD	; flags used to goto correct buff frame routine
	LOCAL	BufferFrameRout		:DWORD	; ptr to the buffer frame routine

	LOCAL	jmp_loc			:DWORD	; calculated jump location
	LOCAL	loop_cnt		:DWORD

	LOCAL 	x1_pixel		:DWORD
	LOCAL	y1_pixel		:DWORD
	LOCAL	scr_x			:DWORD
	LOCAL	scr_y			:DWORD
	LOCAL	dest_adjust_width	:DWORD
	LOCAL	scr_adjust_width	:DWORD
	LOCAL	header_pointer		:DWORD
	LOCAL	use_old_draw		:DWORD
	LOCAL	save_ecx		:DWORD
	LOCAL	ShapeJumpTableAddress	:DWORD
	LOCAL	shape_buffer_start	:DWORD

	prologue
	cmp	[ src ] , 0
	jz	real_out

	;
	; Save the line attributes pointers and
	; Modify the src pointer to point to the actual image
	;
	cmp	[UseBigShapeBuffer],0
	jz	do_args			;just use the old shape drawing system

	mov	edi,[src]
	mov	[header_pointer],edi

	mov	eax,[BigShapeBufferStart]
	cmp	[edi].ShapeHeaderType.shape_buffer,0
	jz	is_ordinary_shape
	mov	eax,[TheaterShapeBufferStart]
is_ordinary_shape:
	mov	[shape_buffer_start],eax

	mov	edi,[edi].ShapeHeaderType.shape_data
	add	edi,[shape_buffer_start]
	mov	[src],edi
	mov	[use_old_draw],0


	;====================================================================
	; Pull off optional arguments:
	; EDI is used as an offset from the 'flags' parameter, to point
	; to the optional argument currently being processed.
	;====================================================================
do_args:
	mov	edi , 4	 			; optional params start past flags
	mov	[ jflags ] , 0			; clear jump flags

check_centering:
	;-------------------------------------------------------------------
	; See if we need to center the frame
	;-------------------------------------------------------------------
	test	[ flags ] , SHAPE_CENTER	; does this need to be centered?
	je	check_trans			; if not the skip over this stuff

	mov	eax , [ pixel_width ]
	mov	ebx , [ pixel_height ]
	sar	eax , 1
	sar	ebx , 1
	sub	[ x_pixel ] , eax
	sub	[ y_pixel ] , ebx

check_trans:
	test	[ flags ] , SHAPE_TRANS
	jz	check_ghost

	or	[ jflags ] , FLAG_TRANS

	;--------------------------------------------------------------------
	; SHAPE_GHOST: DWORD is_translucent tbl
	;--------------------------------------------------------------------
check_ghost:
	test	[ flags ] , SHAPE_GHOST		; are we ghosting this shape
	jz	check_fading

	mov	eax , [ flags + edi ]
	or	[ jflags ] , FLAG_GHOST
	mov	[ IsTranslucent ] , eax		; save ptr to is_trans. tbl
	add	eax , 0100h			; add 256 for first table
	add	edi , 4				; next argument
	mov	[ Translucent ] , eax		; save ptr to translucent tbl



check_fading:
	;______________________________________________________________________
	; If this is the first time through for this shape then
	; set up the shape header
	;______________________________________________________________________
	pushad

	cmp	[UseBigShapeBuffer],0
	jz	new_shape

	mov	edi,[header_pointer]
	cmp	[edi].ShapeHeaderType.draw_flags,-1
	jz	setup_headers
	mov	eax,[flags]							 ;Redo the shape headers if this shape was
	and	eax,SHAPE_TRANS or SHAPE_FADING or SHAPE_PREDATOR or SHAPE_GHOST ;initially set up with different flags
	cmp	eax,[edi].ShapeHeaderType.draw_flags
	jz	no_header_setup
new_shape:
	mov	[use_old_draw],1
	jmp	no_header_setup

setup_headers:
	push	[IsTranslucent]
	push	[Translucent]
	push	[flags]
	push	[header_pointer]
	push	[src]
	push	[pixel_height]
	push	[pixel_width]
	call	Setup_Shape_Header
	add	esp,7*4
	mov	[ShapeJumpTableAddress], offset AllFlagsJumpTable
	jmp	headers_set
no_header_setup:

	xor	eax,eax
	test	[flags],SHAPE_PREDATOR
	jz	not_shape_predator
	or	al,BLIT_PREDATOR

not_shape_predator:
	test	[flags],SHAPE_FADING
	jz	not_shape_fading
	or	al,BLIT_FADING

not_shape_fading:

	test	[flags],SHAPE_TRANS
	jz	not_shape_transparent
	or	al,BLIT_TRANSPARENT

not_shape_transparent:

	test	[flags],SHAPE_GHOST
	jz	not_shape_ghost
	or	al,BLIT_GHOST

not_shape_ghost:

	 
      	shl	eax,7
       	add	eax, offset NewShapeJumpTable
	mov	[ShapeJumpTableAddress],eax
	;call	Init_New_Shape_Jump_Table_Address


headers_set:
	popad

	;--------------------------------------------------------------------
	; SHAPE_FADING: DWORD fade_table[256], DWORD fade_count
	;--------------------------------------------------------------------
	test	[ flags ] , SHAPE_FADING	; are we fading this shape
	jz	check_predator

	mov	eax , [ flags + edi ]
	mov	[ FadingTable ] , eax		; save address of fading tbl
	mov	eax , [ flags + edi + 4 ]	; get fade num
	or	[ jflags ] , FLAG_FADING
	and	eax , 03fh			; no need for more than 63
	add	edi , 8				; next argument
	cmp	eax , 0				; check if it's 0
	jnz	set_fading			; if not, store fade num

	and	[ flags ] , NOT SHAPE_FADING	; otherwise, don't fade

set_fading:
	mov	[ FadingNum ] , eax

	mov	ebx,[ShapeJumpTableAddress]
	mov	dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx],offset Single_Line_Single_Fade
	mov	dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx+4],offset Single_Line_Single_Fade_Trans
	cmp	eax,1
	jz	single_fade
	mov	dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx],offset Single_Line_Fading
	mov	dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx+4],offset Single_Line_Fading_Trans

single_fade:

	;--------------------------------------------------------------------
	; SHAPE_PREDATOR: DWORD init_pred_lookup_offset (0-7)
	;--------------------------------------------------------------------
check_predator:
	test	[ flags ] , SHAPE_PREDATOR	; is predator effect on
	jz	check_partial

	mov	eax , [ flags + edi ]		; pull the partial value
	or	[ jflags ] , FLAG_PREDATOR
	shl	eax , 1
	cmp	eax , 0
	jge	check_range

	neg	eax
	mov	ebx , -1
	and	eax , PRED_MASK			; keep entries within bounds
	mov	bl , al
	mov	eax , ebx			; will be ffffff00-ffffff07
	jmp	pred_cont

check_range:
	and	eax , PRED_MASK			; keep entries within bounds

pred_cont:
	add	edi , 4				; next argument
	mov	[ BFPredOffset ] , eax
	mov	[ BFPartialCount ] , 0		; clear the partial count
	mov	[ BFPartialPred ] , 100h	; init partial to off

pred_neg_init:
	mov  	esi , [ dest ]	    ; get ptr to dest
	mov	ebx, 7 * 2

pred_loop:
	movzx	eax , [ WORD PTR BFPredNegTable + ebx ]
	add	eax , [esi].GraphicViewPort.GVPWidth	; add width
	add	eax , [esi].GraphicViewPort.GVPXAdd	; add x add
	add	eax , [esi].GraphicViewPort.GVPPitch	; extra pitch of DD surface	ST - 9/29/95 1:08PM
	mov	[ WORD PTR BFPredNegTable + 16 + ebx ] , ax
	dec	ebx
	dec	ebx
	jge	pred_loop

	;--------------------------------------------------------------------
	; SHAPE_PARTIAL: DWORD partial_pred_value (0-255)
	;--------------------------------------------------------------------
check_partial:
	test	[ flags ] , SHAPE_PARTIAL		; is this a partial pred?
	jz	setupfunc

	mov	eax , [ flags + edi ]		; pull the partial value
	add	edi , 4				; next argument
	and	eax , 0ffh			; make sure 0-255
	mov	[ BFPartialPred ] , eax		; store it off

setupfunc:
	mov	ebx , [ jflags ]		; load flags value
	and	ebx , FLAG_MASK			; clip high bits
	add	ebx , ebx			; mult by 4 to get DWORD offset
	add	ebx , ebx
	mov	ebx , dword ptr [ BufferFrameTable + ebx ]	; get table value
	mov	dword ptr [ BufferFrameRout ] , ebx		; store it in the function pointer

; Clip dest Rectangle against source Window boundaries.

	mov	[ scr_x ] , 0
	mov	[ scr_y ] , 0
	mov  	esi , [ dest ]	    ; get ptr to dest
	xor 	ecx , ecx
	xor 	edx , edx
	mov	edi , [esi].GraphicViewPort.GVPWidth  ; get width into register
	mov	ebx , [ x_pixel ]
	mov	eax , [ x_pixel ]
	add	ebx , [ pixel_width ]
	shld	ecx , eax , 1
	mov	[ x1_pixel ] , ebx
	inc	edi
	shld	edx , ebx , 1
	sub	eax , edi
	sub	ebx , edi
	shld	ecx , eax , 1
	shld	edx , ebx , 1

	mov	edi,[esi].GraphicViewPort.GVPHeight ; get height into register
	mov	ebx , [ y_pixel ]
	mov	eax , [ y_pixel ]
	add	ebx , [ pixel_height ]
	shld	ecx , eax , 1
	mov	[ y1_pixel ] , ebx
	inc	edi
	shld	edx , ebx , 1
	sub	eax , edi
	sub	ebx , edi
	shld	ecx , eax , 1
	shld	edx , ebx , 1

	xor	cl , 5
	xor	dl , 5
	mov	al , cl
	test	dl , cl
	jnz	real_out

	or	al , dl
	jz	do_blit

	mov	[use_old_draw],1
	test	cl , 1000b
	jz	dest_left_ok

	mov	eax , [ x_pixel ]
	neg	eax
	mov	[ x_pixel ] , 0
	mov	[ scr_x ] , eax

dest_left_ok:
	test	cl , 0010b
	jz	dest_bottom_ok

	mov	eax , [ y_pixel ]
	neg	eax
	mov	[ y_pixel ] , 0
	mov	[ scr_y ] , eax

dest_bottom_ok:
	test	dl , 0100b
	jz	dest_right_ok

	mov	eax , [esi].GraphicViewPort.GVPWidth  ; get width into register
	mov	[ x1_pixel ] , eax

dest_right_ok:
	test	dl , 0001b
	jz	do_blit

	mov	eax , [esi].GraphicViewPort.GVPHeight  ; get width into register
	mov	[ y1_pixel ] , eax

do_blit:
	cld
	mov	eax , [esi].GraphicViewPort.GVPXAdd
	add	eax , [esi].GraphicViewPort.GVPPitch
	add	eax , [esi].GraphicViewPort.GVPWidth
	mov	edi , [esi].GraphicViewPort.GVPOffset

	mov	ecx , eax
	mul	[ y_pixel ]
	add	edi , [ x_pixel ]
	add	edi , eax

	add	ecx , [ x_pixel ]
	sub	ecx , [ x1_pixel ]
	mov	[ dest_adjust_width ] , ecx

	mov	esi , [ src ]
	mov	eax , [ pixel_width ]
	sub	eax , [ x1_pixel ]
	add	eax , [ x_pixel ]
	mov	[ scr_adjust_width ] , eax

	mov	eax , [ scr_y ]
	mul	[ pixel_width ]
	add	eax , [ scr_x ]
	add	esi , eax

;
; If the shape needs to be clipped then we cant handle it with the new header systen
; so draw it with the old shape drawer
;
	cmp	[use_old_draw],0
	jnz	use_old_stuff

	add	[header_pointer],size ShapeHeaderType
	mov	edx,[pixel_height]
	mov	ecx,[pixel_width]
	mov	eax,[header_pointer]
	mov	al,[eax]
	mov	[save_ecx],ecx
	inc	[header_pointer]
	and	eax,BLIT_ALL
	shl	eax,2
	add	eax,[ShapeJumpTableAddress]
	jmp	dword ptr [eax]


use_old_stuff:
	mov	edx , [ y1_pixel ]
	mov	eax , [ x1_pixel ]

	sub	edx , [ y_pixel ]
	jle	real_out

	sub	eax , [ x_pixel ]
	jle	real_out

	jmp	[ BufferFrameRout ]	; buffer frame to viewport routine

real_out:

	cmp	[MMXAvailable],0
	jz	no_mmx_cleanup
	call	MMX_Done

no_mmx_cleanup:
	epilogue

	ret


; ********************************************************************
; Forward bitblit only
; the inner loop is so efficient that
; the optimal consept no longer apply because
; the optimal byte have to by a number greather than 9 bytes
; ********************************************************************
;extern	BF_Copy:near

BF_Copy:
	prologue

	cmp	eax , 10
	jl	forward_loop_bytes

forward_loop_dword:
	mov	ecx , edi
	mov	ebx , eax
	neg	ecx
	and	ecx , 3
	sub	ebx , ecx
	rep	movsb
	mov	ecx , ebx
	shr	ecx , 2
	rep	movsd
	mov	ecx , ebx
	and	ecx , 3
	rep	movsb

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	forward_loop_dword

	ret

forward_loop_bytes:
	mov	ecx , eax
	rep	movsb
	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx					; decrement the height
	jnz	forward_loop_bytes
	
	epilogue

	ret


;********************************************************************
;********************************************************************

;		segment code page public use32 'code'	; Need stricter segment alignment
							; for pentium optimisations


;
; Expand the 'next_line' macro so we can jump to it
;
;
;  ST - 12/20/2018 3:48PM
Next_Line::	next_line



;*****************************************************************************
; Draw a single line with transparent pixels
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Trans::
		prologue

Single_Line_Trans_Entry::

slt_mask_map_lp:				; Pentium pipeline usage
						;Pipe	Cycles
		mov	al,[esi]		;U	1
		inc	esi			;Vee	1

		test	al,al			;U	1
		jz	slt_skip		;Vee	1/5

slt_not_trans:mov	[edi],al		;u 	1

		inc	edi			;vee	1
		dec	ecx			;u	1

		jnz	slt_mask_map_lp	;vee  (maybe)	1

slt_end_line:	epilogue
		next_line

		;align	32

slt_skip:	inc	edi
		dec	ecx
		jz	slt_skip_end_line

		mov	al,[esi]
		inc	esi
		test	al,al
		jz	slt_skip2
		mov	[edi],al
		inc	edi
		dec	ecx
		jnz	slt_mask_map_lp

		epilogue
		next_line

		;align	32

slt_skip2:	inc	edi
		dec	ecx
		jz	slt_end_line

;
; If we have hit two transparent pixels in a row then we go into
; the transparent optimised bit
;
slt_round_again:
	rept	64
		mov	al,[esi]   ;	;pipe 1
		inc	esi	   ;1	;pipe 2
		test	al,al	   ;	;pipe 1
		jnz	slt_not_trans;pipe 2 (not pairable in 1)
				   ;2
		inc	edi	   ;	;pipe 1
		dec	ecx	   ;3	;pipe 2
		jz	slt_end_line ;4	;pipe 1 (not pairable)
	endm			   ; best case is 4 cycles per iteration
		jmp	slt_round_again



slt_skip_end_line:
		epilogue
		next_line



;*****************************************************************************
; Draw a single line with no transparent pixels
;
; 11/29/95 10:21AM - ST
;
; We have to align the destination for cards that dont bankswitch correctly
; when you write non-aligned data.
;
		;align	32
Long_Single_Line_Copy:
		prologue

 rept 3
		test	edi,3
		jz	LSLC_aligned
		movsb
		dec	ecx
 endm

LSLC_aligned:
		mov	ebx,ecx

		shr	ecx,2
		rep	movsd
		and	ebx,3
		jz	proc_out
		movsb
		dec	bl
		jz	proc_out
		movsb
		dec	bl
		jz	proc_out
		movsb
proc_out:		epilogue
		next_line



;*****************************************************************************
; Draw a single short line with no transparent pixels
;
; 11/29/95 10:21AM - ST
;
		;align	32
Short_Single_Line_Copy:
		prologue
		cmp	ecx,16
		jge	Long_Single_Line_Copy
		mov	ebx,ecx
		rep	movsb
		mov	ecx,ebx
		epilogue
		next_line


;*****************************************************************************
; Skip a line of source that is all transparent
;
; 11/29/95 10:21AM - ST
;

		;align	32
Single_Line_Skip:
		prologue
		add	esi,ecx
		add	edi,ecx
		epilogue
		next_line



;*****************************************************************************
; Draw a single line with ghosting
;
; 11/29/95 10:21AM - ST
;
		;align	32
Single_Line_Ghost:

		prologue
		xor	eax,eax
slg_loop:	mov	al,[esi]
		mov	ebx,[IsTranslucent]
		inc	esi
		mov	bh,[eax+ebx]
		cmp	bh,-1
		jz	slg_store_pixel

		and	ebx,0ff00h
		mov	al,[edi]
		add	ebx,[Translucent]
		mov	al,[eax+ebx]

slg_store_pixel:
		mov	[edi],al

		inc	edi
		dec	ecx
		jnz	slg_loop
		epilogue
		next_line



;*****************************************************************************
; Draw a single line with transparent pixels and ghosting
;
; 11/29/95 10:21AM - ST
;
		;align	32
Single_Line_Ghost_Trans:
		prologue
		xor	eax,eax
;		cmp	ecx,3
;		ja	slgt4

slgt_loop:	mov	al,[esi]
		inc	esi
		test	al,al
		jz	slgt_transparent

slgt_not_transparent:
		mov	ebx,[IsTranslucent]
		mov	bh,[eax+ebx]
		cmp	bh,-1
		jz	slgt_store_pixel

		and	ebx,0ff00h
		mov	al,[edi]
		add	ebx,[Translucent]
		mov	al,[eax+ebx]

slgt_store_pixel:
		mov	[edi],al
		inc	edi
		dec	ecx
		jnz	slgt_loop
		epilogue
		next_line


		;align	32

slgt_transparent:
		inc	edi		;1
		dec	ecx		;2
		jz	slgt_out	;1 (not pairable)

slgt_round_again:
	rept	64
		mov	al,[esi]   ;	;pipe 1
		inc	esi	   ;1	;pipe 2
		test	al,al	   ;	;pipe 1
		jnz	slgt_not_transparent	;pipe 2 (not pairable in 1)
				   ;2
		inc	edi	   ;	;pipe 1
		dec	ecx	   ;3	;pipe 2
		jz	slgt_out ;4	;pipe 1 (not pairable)
	endm			   ; best case is 4 cycles per iteration
		jmp	slgt_round_again

slgt_out:	epilogue
		next_line



;
; Optimised video memory access version
;
		;align 	32

slgt4:        push	edx
		mov	edx,[edi]

	rept	4
	local	slgt4_store1
	local	slgt4_trans1
		mov	al,[esi]
		inc	esi
		test	al,al
		jz	slgt4_trans1

		mov	ebx,[IsTranslucent]
		mov	bh,[eax+ebx]
		cmp	bh,-1
		jz	slgt4_store1

		and	ebx,0ff00h
		mov	al,dl
		add	ebx,[Translucent]
		mov	al,[eax+ebx]

slgt4_store1:	mov	dl,al

slgt4_trans1:	ror	edx,8
	endm
		mov	[edi],edx
		pop	edx
		lea	edi,[edi+4]
		lea	ecx,[ecx+0fffffffch]
		cmp	ecx,3
		ja	slgt4
		test	ecx,ecx
		jnz	slgt_loop

		epilogue
		next_line










;*****************************************************************************
; Draw a single line with fading (colour remapping)
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Fading:
		prologue
		xor	eax,eax
		mov	ebx,[FadingTable]
		push	ebp
		mov	ebp,[FadingNum]
		push	ebp

slf_loop:	mov	al,[esi]
		inc	esi

		mov	ebp,[esp]

slf_fade_loop:mov	al,[ebx+eax]
		dec	ebp
		jnz	slf_fade_loop

		mov	[edi],al
		inc	edi

		dec	ecx
		jnz	slf_loop
		add	esp,4
		pop	ebp
		epilogue
		next_line


;*****************************************************************************
; Draw a single line with transparent pixels and fading (colour remapping)
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Fading_Trans:
		prologue
		xor	eax,eax
		mov	ebx,[FadingTable]
		push	ebp
		mov	ebp,[FadingNum]
		push	ebp

slft_loop:	mov	al,[esi]
		inc	esi
		test	al,al
		jz	slft_transparent

		mov	ebp,[esp]

slft_fade_loop:
		mov	al,[ebx+eax]
		dec	ebp
		jnz	slft_fade_loop

		mov	[edi],al
slft_transparent:
		inc	edi

		dec	ecx
		jnz	slft_loop
		add	esp,4
		pop	ebp
		epilogue
		next_line





;*****************************************************************************
; Draw a single line with a single fade level (colour remap)
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Single_Fade:
		prologue
		xor	eax,eax
		mov	ebx,[FadingTable]

slsf_loop:	mov	al,[esi]
		mov	al,[ebx+eax]
		mov	[edi],al
		inc	esi
		inc	edi

		dec	ecx
		jnz	slsf_loop
		epilogue
		next_line



;*****************************************************************************
; Draw a single line with transparent pixels and a single fade level (colour remap)
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Single_Fade_Trans:
		prologue
		xor	eax,eax
		mov	ebx,[FadingTable]

slsft_loop:	mov	al,[esi]
		inc	esi
		test	al,al
		jz	slsft_transparent
		mov	al,[ebx+eax]
		mov	[edi],al
		inc	edi
		dec	ecx
		jnz	slsft_loop
		epilogue
		next_line

		;align	32

slsft_transparent:
		inc	edi

		dec	ecx
		jz	slsft_next_line
		mov	al,[esi]
		inc	esi
		test	al,al
		jz	slsft_transparent
		mov	al,[ebx+eax]
		mov	[edi],al
		inc	edi
		dec	ecx
		jnz	slsft_loop

slsft_next_line:
		epilogue
		next_line





;*****************************************************************************
; Draw a single line with ghosting and fading (colour remapping)
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Ghost_Fading:

		prologue
		mov	[StashECX],ecx

SLGF_loop:	xor	eax,eax
		mov	al,[esi]
		mov	ebx,[IsTranslucent]
		mov	bh,[eax+ebx]
		cmp	bh,-1
		jz	slgf_do_fading

		and	ebx,0ff00h

		mov	al,[edi]
		add	ebx,[Translucent]
		mov	al,[ebx+eax]

slgf_do_fading:
		mov	ebx,[FadingTable]
		mov	ecx,[FadingNum]

slgf_fade_loop:
		mov	al,[eax+ebx]
		dec	ecx
		jnz	slgf_fade_loop

		mov	[edi],al
		inc	esi
		inc	edi

		dec	[StashECX]
		jnz	SLGF_loop
		epilogue
		next_line


;*****************************************************************************
; Draw a single line with transparent pixels, ghosting and fading
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Ghost_Fading_Trans:
		prologue
		mov	[StashECX],ecx
		xor	eax,eax

;		cmp	ecx,3
;		ja	slgft4

SLGFT_loop:	mov	al,[esi]
		inc	esi
		test	al,al
		jz	slgft_trans_pixel
		mov	ebx,[IsTranslucent]
		mov	bh,[eax+ebx]
		cmp	bh,-1
		jz	slgft_do_fading

		and	ebx,0ff00h

		mov	al,[edi]
		add	ebx,[Translucent]
		mov	al,[ebx+eax]

slgft_do_fading:
		mov	ebx,[FadingTable]
		mov	ecx,[FadingNum]

slgft_fade_loop:
		mov	al,[eax+ebx]
		dec	ecx
		jnz	slgft_fade_loop

		mov	[edi],al
slgft_trans_pixel:
		inc	edi

		dec	[StashECX]
		jnz	SLGFT_loop
		epilogue
		next_line


		;align	32

slgft4:	push	edx
		mov	edx,[edi]

	rept	4
	local	slgft4_fade
	local	slgft4_fade_lp
	local	slgft4_trans
		mov	al,[esi]
		inc	esi
		test	al,al
		jz	slgft4_trans
		mov	ebx,[IsTranslucent]
		mov	bh,[eax+ebx]
		cmp	bh,-1
		jz	slgft4_fade

		and	ebx,0ff00h

		mov	al,dl
		add	ebx,[Translucent]
		mov	al,[ebx+eax]

slgft4_fade:	mov	ebx,[FadingTable]
		mov	ecx,[FadingNum]

slgft4_fade_lp:	mov	al,[eax+ebx]
		dec	ecx
		jnz	slgft4_fade_lp

		mov	dl,al

slgft4_trans:	ror	edx,8
	endm
		mov	[edi],edx
		pop	edx
		lea	edi,[edi+4]
		sub	[StashECX],4
		jz	slgft4_out
		cmp	[StashECX],3
		ja	slgft4
		jmp	SLGFT_loop

slgft4_out:	epilogue
		next_line


;*****************************************************************************
; Draw a single line with predator effect
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Predator:

		prologue

slp_loop:	mov	al,[esi]

		mov	ebx,[BFPartialCount]
		add	ebx,[BFPartialPred]
		or	bh,bh
		jnz	slp_get_pred

		mov	[BFPartialCount] , ebx
		jmp	slp_skip_pixel

slp_get_pred:	xor	bh , bh
		mov	eax,[BFPredOffset]
		mov	[BFPartialCount] , ebx
		add	byte ptr [BFPredOffset],2
		mov	eax, dword ptr [BFPredTable+eax]
		and	byte ptr [BFPredOffset],PRED_MASK
		and	eax,0ffffh

		mov	al,[edi+eax]
		mov	[edi],al

slp_skip_pixel:
		inc	esi
		inc	edi

		dec	ecx
		jnz	slp_loop

		epilogue
		next_line




;*****************************************************************************
; Draw a single line with transparent pixels and predator effect
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Predator_Trans:

		prologue

slpt_loop:	mov	al,[esi]
		inc	esi
		test	al,al
		jz	slpt_skip_pixel

		mov	ebx,[BFPartialCount]
		add	ebx,[BFPartialPred]
		or	bh,bh
		jnz	slpt_get_pred

		mov	[BFPartialCount] , ebx
		jmp	slpt_skip_pixel

slpt_get_pred:xor	bh , bh
		mov	eax,[BFPredOffset]
		mov	[BFPartialCount] , ebx
		add	byte ptr [BFPredOffset],2
		mov	eax,dword ptr [BFPredTable+eax]
		and	byte ptr [BFPredOffset ] , PRED_MASK
		and	eax,0ffffh

		mov	al,[edi+eax]
		mov	[edi],al

slpt_skip_pixel:
		inc	edi

		dec	ecx
		jnz	slpt_loop

		epilogue
		next_line


;*****************************************************************************
; Draw a single line with predator and ghosting
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Predator_Ghost:

		prologue

slpg_loop:	mov	al,[esi]
		mov	ebx,[BFPartialCount]
		add	ebx,[BFPartialPred]
		test	bh,bh
		jnz	slpg_get_pred		; is this a predator pixel?

		mov	[BFPartialCount],ebx
		jmp	slpg_check_ghost

slpg_get_pred:
		xor	bh,bh
		mov	eax,[BFPredOffset]
		mov	[BFPartialCount],ebx
		add	byte ptr [BFPredOffset],2
		mov	eax,dword ptr [BFPredTable+eax ]
		and	byte ptr [BFPredOffset],PRED_MASK
		and	eax,0ffffh
		mov	al,[edi+eax]

slpg_check_ghost:
		mov	ebx,[IsTranslucent]
		mov	bh,[ebx+eax]
		cmp	bh,0ffh
		je	slpg_store_pixel

		xor	eax,eax
		and	ebx,0FF00h

		mov	al,[edi]
		add	ebx,[Translucent]

		mov	al,[ebx+eax]

slpg_store_pixel:
		mov	[edi],al
		inc	esi
		inc	edi

		dec	ecx
		jnz	slpg_loop

		epilogue
		next_line



;*****************************************************************************
; Draw a single line with transparent pixels, predator and ghosting
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Predator_Ghost_Trans:
		prologue

slpgt_loop:	mov	al,[esi]
		inc	esi
		test	al,al
		jz	slpgt_transparent

		mov	ebx,[BFPartialCount]
		add	ebx,[BFPartialPred]
		test	bh,bh
		jnz	slpgt_get_pred		; is this a predator pixel?

		mov	[BFPartialCount],ebx
		jmp	slpgt_check_ghost

slpgt_get_pred:
		xor	bh,bh
		mov	eax,[BFPredOffset]
		mov	[BFPartialCount],ebx
		add	byte ptr [BFPredOffset],2
		mov	eax,dword ptr [BFPredTable+eax ]
		and	byte ptr [BFPredOffset],PRED_MASK
		and	eax,0ffffh
		mov	al,[edi+eax]

slpgt_check_ghost:
		mov	ebx,[IsTranslucent]
		mov	bh,[ebx+eax]
		cmp	bh,0ffh
		je	slpgt_store_pixel

		xor	eax,eax
		and	ebx,0FF00h

		mov	al,[edi]
		add	ebx,[Translucent]

		mov	al,[ebx+eax]

slpgt_store_pixel:
		mov	[edi],al
slpgt_transparent:
		inc	edi

		dec	ecx
		jnz	slpgt_loop

		pop	ecx
		epilogue
		next_line


;*****************************************************************************
; Draw a single line with predator and fading
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Predator_Fading:

		prologue
		mov	[StashECX],ecx

slpf_loop:	mov	al,[esi]
		mov	ebx,[BFPartialCount]
		inc	esi
		add	ebx,[BFPartialPred]
		test	bh,bh
		jnz	slpf_get_pred

		mov	[BFPartialCount],ebx
		jmp	slpf_do_fading

slpf_get_pred:xor	bh,bh
		mov	eax,[BFPredOffset]
		mov	[BFPartialCount],ebx
		and	byte ptr [BFPredOffset],2
		mov	eax,dword ptr [BFPredTable+eax]
		and	byte ptr [BFPredOffset],PRED_MASK

		and	eax,0ffffh
		mov	al,[eax+edi]

slpf_do_fading:
		and	eax,255
		mov	ebx,[FadingTable]
		mov	ecx,[FadingNum]

slpf_fade_loop:
		mov	al,[eax+ebx]
		dec	ecx
		jnz	slpf_fade_loop

		mov	[edi],al
		inc	edi

		dec	[StashECX]
		jnz	slpf_loop

		epilogue
		next_line



;*****************************************************************************
; Draw a single line with transparent pixels, fading and predator
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Predator_Fading_Trans:
		prologue
		mov	[StashECX],ecx

slpft_loop:	mov	al,[esi]
		inc	esi
		test	al,al
		jz	slpft_transparent
		mov	ebx,[BFPartialCount]
		add	ebx,[BFPartialPred]
		test	bh,bh
		jnz	slpft_get_pred

		mov	[BFPartialCount],ebx
		jmp	slpft_do_fading

slpft_get_pred:
		xor	bh,bh
		mov	eax,[BFPredOffset]
		mov	[BFPartialCount],ebx
		and	byte ptr [BFPredOffset],2
		mov	eax,dword ptr [BFPredTable+eax]
		and	byte ptr [BFPredOffset],PRED_MASK

		and	eax,0ffffh
		mov	al,[eax+edi]

slpft_do_fading:
		and	eax,255
		mov	ebx,[FadingTable]
		mov	ecx,[FadingNum]

slpft_fade_loop:
		mov	al,[eax+ebx]
		dec	ecx
		jnz	slpft_fade_loop

		mov	[edi],al
slpft_transparent:
		inc	edi

		dec	[StashECX]
		jnz	slpft_loop

		epilogue
		next_line



;*****************************************************************************
; Draw a single line with predator, ghosting and fading
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Predator_Ghost_Fading:

		prologue
		mov	[StashECX],ecx

slpgf_loop:	mov	al,[esi]
		mov	ebx,[BFPartialCount]
		inc	esi
		add	ebx,[BFPartialPred]
		test	bh , bh
		jnz	slpgf_get_pred		; is this a predator pixel?

		mov	[BFPartialCount],ebx
		jmp	slpgf_check_ghost

slpgf_get_pred:
		xor	bh,bh
		mov	eax,[BFPredOffset]
		mov	[BFPartialCount],ebx
		add	byte ptr [BFPredOffset],2
		mov	eax,dword ptr [BFPredTable+eax]
		and	byte ptr [BFPredOffset],PRED_MASK
		and	eax,0ffffh

		mov	al,[edi+eax]

slpgf_check_ghost:
		and	eax,255
		mov	ebx,[IsTranslucent]
		mov	bh,[ebx+eax]
		cmp	bh,0ffh
		je	slpgf_do_fading

		and	ebx , 0FF00h

		mov	al,[edi]
		add	ebx,[Translucent]

		mov	al,[ebx+eax]

slpgf_do_fading:
		xor	eax,eax
		mov	ebx,[FadingTable]
		mov	ecx,[FadingNum]

slpgf_fade_loop:
		mov	al,[ebx+eax]
		dec	ecx
		jnz	slpgf_fade_loop

slpgf_store_pixel:
		mov	[edi],al
		inc	edi

		dec	[StashECX]
		jnz	slpgf_loop

		epilogue
		next_line



;*****************************************************************************
; Draw a single line with transparent pixels, predator, ghosting and fading
;
; 11/29/95 10:21AM - ST
;
		;align	32

Single_Line_Predator_Ghost_Fading_Trans:

		prologue
		mov	[StashECX],ecx

slpgft_loop:	mov	al,[esi]
		inc	esi
		test	al,al
		jz	slpgft_transparent

		mov	ebx,[BFPartialCount]
		add	ebx,[BFPartialPred]
		test	bh , bh
		jnz	slpgft_get_pred		; is this a predator pixel?

		mov	[BFPartialCount],ebx
		jmp	slpgft_check_ghost

slpgft_get_pred:
		xor	bh,bh
		mov	eax,[BFPredOffset]
		mov	[BFPartialCount],ebx
		add	byte ptr [BFPredOffset],2
		mov	eax,dword ptr [BFPredTable+eax]
		and	byte ptr [BFPredOffset],PRED_MASK
		and	eax,0ffffh

		mov	al,[edi+eax]

slpgft_check_ghost:
		and	eax,255
		mov	ebx,[IsTranslucent]
		mov	bh,[ebx+eax]
		cmp	bh,0ffh
		je	slpgft_do_fading

		and	ebx , 0FF00h

		mov	al,[edi]
		add	ebx,[Translucent]

		mov	al,[ebx+eax]

slpgft_do_fading:
		xor	eax,eax
		mov	ebx,[FadingTable]
		mov	ecx,[FadingNum]

slpgft_fade_loop:
		mov	al,[ebx+eax]
		dec	ecx
		jnz	slpgft_fade_loop

slpgft_store_pixel:
		mov	[edi],al
slpgft_transparent:
		inc	edi

		dec	[StashECX]
		jnz	slpgft_loop

		epilogue
		next_line




;		ends		;end of strict alignment segment

;	       	codeseg



;extern	BF_Trans:near

BF_Trans:

	prologue
; calc the code location to skip to 10 bytes per REPT below!!!!
	mov	ecx , eax
	and	ecx , 01fh
	lea	ecx , [ ecx + ecx * 4 ]		; quick multiply by 5
	neg	ecx
	shr	eax , 5
	lea	ecx , [ trans_reference + ecx * 2 ] ; next multiply by 2
	mov	[ loop_cnt ] , eax
	mov	[ jmp_loc ] , ecx

trans_loop:
	mov	ecx , [ loop_cnt ]
	jmp	[ jmp_loc ]

; the following code should NOT be changed without changing the calculation
; above!!!!!!

trans_line:

	REPT	32
	local	trans_pixel
		mov	bl , [ esi ]
		inc	esi
		test	bl , bl
		jz	trans_pixel

		mov	[ edi ] , bl

	trans_pixel:
		inc	edi
	ENDM

trans_reference:
	dec	ecx
	jge	trans_line

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	trans_loop
	epilogue

	ret

;********************************************************************
;********************************************************************

;extern	BF_Ghost:near
BF_Ghost:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx, [offset ghost_reference]
	sub	ecx, [offset ghost_line]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ ghost_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

ghost_loop:
	mov	ecx , [ loop_cnt ]
	jmp	[ jmp_loc ]

ghost_line:

	REPT	32
	local	store_pixel
		mov	al , [ esi ]
		inc	esi
		mov	ebx , [ IsTranslucent ]		; is it a translucent color?
		mov	bh , BYTE PTR [ ebx + eax ]
		cmp	bh , 0ffh
		je	store_pixel

		and	ebx , 0FF00h			; clear all of ebx except bh
							; we have the index to the translation table
							; ((trans_colour * 256) + dest colour)
		mov	al , [ edi ]			; mov pixel at destination to al
		add	ebx , [ Translucent ]		; get the ptr to it!
							; Add the (trans_color * 256) of the translation equ.
		mov	al , BYTE PTR [ ebx + eax ]	; get new pixel in al

	store_pixel:
		mov	[ edi ] , al
		inc	edi

	ENDM

ghost_reference:
	dec	ecx
	jge	ghost_line

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	ghost_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Ghost_Trans:near
BF_Ghost_Trans:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset ghost_t_reference ]
	sub	ecx, [ offset ghost_t_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ ghost_t_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

ghost_t_loop:
	mov	ecx , [ loop_cnt ]
	jmp	[ jmp_loc ]

ghost_t_line:

	REPT	32
	local	transp_pixel
	local	store_pixel
		mov	al , [ esi ]
		inc	esi
		test	al , al
		jz	transp_pixel

		mov	ebx , [ IsTranslucent ]		; is it a translucent color?
		mov	bh , BYTE PTR [ ebx + eax ]
		cmp	bh , 0ffh
		je	store_pixel

		and	ebx , 0FF00h			; clear all of ebx except bh
							; we have the index to the translation table
							; ((trans_colour * 256) + dest colour)
		mov	al , [ edi ]			; mov pixel at destination to al
		add	ebx , [ Translucent ]		; get the ptr to it!
							; Add the (trans_color * 256) of the translation equ.
		mov	al , BYTE PTR [ ebx + eax ]	; get new pixel in al

	store_pixel:
		mov	[ edi ] , al

	transp_pixel:
		inc	edi

	ENDM

ghost_t_reference:
	dec	ecx
	jge	ghost_t_line

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	ghost_t_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Fading:near
BF_Fading:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset fading_reference ]
	sub	ecx, [ offset fading_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ fading_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

fading_loop:
	mov	ecx , [ loop_cnt ]
	mov	[ StashECX ] , ecx		; preserve ecx for later
	mov	ebx , [ FadingTable ]		; run color through fading table
	jmp	[ jmp_loc ]

fading_line_begin:
	mov	[ StashECX ] , ecx		; preserve ecx for later

fading_line:

	REPT	32
	local	fade_loop
		mov	al , [ esi ]
		inc	esi
		mov	ecx , [ FadingNum ]

	fade_loop:
		mov	al, byte ptr [ebx + eax]
		dec	ecx
		jnz	fade_loop

		mov	[ edi ] , al
		inc	edi

	ENDM

fading_reference:
	mov	ecx , [ StashECX ]		; restore ecx for main draw loop
	dec	ecx
	jge	fading_line_begin

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	fading_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Fading_Trans:near
BF_Fading_Trans:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset fading_t_reference ]
	sub	ecx, [ offset fading_t_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ fading_t_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

fading_t_loop:
	mov	ecx , [ loop_cnt ]
	mov	[ StashECX ] , ecx		; preserve ecx for later
	mov	ebx , [ FadingTable ]		; run color through fading table
	jmp	[ jmp_loc ]

fading_t_line_begin:
	mov	[ StashECX ] , ecx		; preserve ecx for later

fading_t_line:

	REPT	32
	local	transp_pixel
	local	fade_loop
		mov	al , [ esi ]
		inc	esi
		test	al , al
		jz	transp_pixel

		mov	ecx , [ FadingNum ]

	fade_loop:
		mov	al, byte ptr [ebx + eax]
		dec	ecx
		jnz	fade_loop

		mov	[ edi ] , al

	transp_pixel:
		inc	edi

	ENDM

fading_t_reference:
	mov	ecx , [ StashECX ]		; restore ecx for main draw loop
	dec	ecx
	jge	fading_t_line_begin

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	fading_t_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Ghost_Fading:near
BF_Ghost_Fading:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset ghost_f_reference ]
	sub	ecx, [ offset ghost_f_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ ghost_f_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

ghost_f_loop:
	mov	ecx , [ loop_cnt ]
	mov	[ StashECX ] , ecx		; preserve ecx for later
	jmp	[ jmp_loc ]

ghost_f_line_begin:
	mov	[ StashECX ] , ecx		; preserve ecx for later

ghost_f_line:

	REPT	32
	local	store_pixel
	local	do_fading
	local	fade_loop
		mov	al , [ esi ]
		inc	esi
		mov	ebx , [ IsTranslucent ]		; is it a lucent color?
		mov	bh , byte ptr [ ebx + eax ]
		cmp	bh , 0ffh
		je	do_fading

		and	ebx , 0FF00h			; clear all of ebx except bh
							; we have the index to the lation table
							; ((_colour * 256) + dest colour)
		mov	al , [ edi ]			; mov pixel at destination to al
		add	ebx , [ Translucent ]		; get the ptr to it!
							; Add the (_color * 256) of the lation equ.
		mov	al , byte ptr [ ebx + eax ]	; get new pixel in al
; DRD		jmp	store_pixel

	do_fading:
		mov	ebx , [ FadingTable ]		; run color through fading table
		mov	ecx , [ FadingNum ]

	fade_loop:
		mov	al, byte ptr [ebx + eax]
		dec	ecx
		jnz	fade_loop

	store_pixel:
		mov	[ edi ] , al
		inc	edi

	ENDM

ghost_f_reference:
	mov	ecx , [ StashECX ]		; restore ecx for main draw loop
	dec	ecx
	jge	ghost_f_line_begin

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	ghost_f_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Ghost_Fading_Trans:near
BF_Ghost_Fading_Trans:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset ghost_f_t_reference ]
	sub	ecx, [ offset ghost_f_t_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ ghost_f_t_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

ghost_f_t_loop:
	mov	ecx , [ loop_cnt ]
	mov	[ StashECX ] , ecx		; preserve ecx for later
	jmp	[ jmp_loc ]

ghost_f_t_line_begin:
	mov	[ StashECX ] , ecx		; preserve ecx for later

ghost_f_t_line:

	REPT	32
	local	transp_pixel
	local	store_pixel
	local	do_fading
	local	fade_loop
		mov	al , [ esi ]
		inc	esi
		test	al , al
		jz	transp_pixel

		mov	ebx , [ IsTranslucent ]		; is it a translucent color?
		mov	bh , byte ptr [ ebx + eax ]
		cmp	bh , 0ffh
		je	do_fading

		and	ebx , 0FF00h			; clear all of ebx except bh
							; we have the index to the translation table
							; ((trans_colour * 256) + dest colour)
		mov	al , [ edi ]			; mov pixel at destination to al
		add	ebx , [ Translucent ]		; get the ptr to it!
							; Add the (trans_color * 256) of the translation equ.
		mov	al , byte ptr [ ebx + eax ]	; get new pixel in al
; DRD		jmp	store_pixel

	do_fading:
		mov	ebx , [ FadingTable ]		; run color through fading table
		mov	ecx , [ FadingNum ]

	fade_loop:
		mov	al, byte ptr [ebx + eax]
		dec	ecx
		jnz	fade_loop

	store_pixel:
		mov	[ edi ] , al

	transp_pixel:
		inc	edi

	ENDM

ghost_f_t_reference:
	mov	ecx , [ StashECX ]		; restore ecx for main draw loop
	dec	ecx
	jge	ghost_f_t_line_begin

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	ghost_f_t_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Predator:near
BF_Predator:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset predator_reference ]
	sub	ecx, [offset predator_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ predator_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

predator_loop:
	mov	ecx , [ loop_cnt ]
	jmp	[ jmp_loc ]

predator_line:

	REPT	32
	local	get_pred
	local	skip_pixel
		mov	al , [ esi ]
		inc	esi
		mov	ebx , [ BFPartialCount ]
		add	ebx , [ BFPartialPred ]
		or	bh , bh
		jnz	get_pred		; is this a predator pixel?

		mov	[ BFPartialCount ] , ebx
		jmp	skip_pixel

	get_pred:
		xor	bh , bh
		mov	eax, [ BFPredOffset ]
		mov	[ BFPartialCount ] , ebx
		add	BYTE PTR [ BFPredOffset ] , 2
		movzx	eax , WORD PTR [ BFPredTable + eax ]
		and	BYTE PTR [ BFPredOffset ] , PRED_MASK
						; pick up a color offset a pseudo-
						;  random amount from the current
		movzx	eax , BYTE PTR [ edi + eax ]	;  viewport address

;		xor	bh , bh
;		mov	eax , [ BFPredValue ]	; pick up a color offset a pseudo-
;						;  random amount from the current
;		mov	[ BFPartialCount ] , ebx
;		mov	al , [ edi + eax ]	;  viewport address

		mov	[ edi ] , al

	skip_pixel:
		inc	edi

	ENDM

predator_reference:
	dec	ecx
	jge	predator_line

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	predator_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Predator_Trans:near
BF_Predator_Trans:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset predator_t_reference ]
	sub	ecx, [ offset predator_t_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ predator_t_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

predator_t_loop:
	mov	ecx , [ loop_cnt ]
	jmp	[ jmp_loc ]

predator_t_line:

	REPT	32
	local	trans_pixel
	local	get_pred
	local	store_pixel
		mov	al , [ esi ]
		inc	esi
		test	al , al
		jz	trans_pixel

		mov	ebx , [ BFPartialCount ]
		add	ebx , [ BFPartialPred ]
		or	bh , bh
		jnz	get_pred		; is this a predator pixel?

		mov	[ BFPartialCount ] , ebx
		jmp	store_pixel

	get_pred:
		xor	bh , bh
		mov	eax, [ BFPredOffset ]
		mov	[ BFPartialCount ] , ebx
		add	BYTE PTR [ BFPredOffset ] , 2
		movzx	eax , WORD PTR [ BFPredTable + eax ]
		and	BYTE PTR [ BFPredOffset ] , PRED_MASK
						; pick up a color offset a pseudo-
						;  random amount from the current
		movzx	eax , BYTE PTR [ edi + eax ]	;  viewport address

	store_pixel:
		mov	[ edi ] , al

	trans_pixel:
		inc	edi

	ENDM

predator_t_reference:
	dec	ecx
	jge	predator_t_line

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	predator_t_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Predator_Ghost:near
BF_Predator_Ghost:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset predator_g_reference ]
	sub	ecx, [ offset predator_g_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ predator_g_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

predator_g_loop:
	mov	ecx , [ loop_cnt ]
	jmp	[ jmp_loc ]

predator_g_line:

	REPT	32
	local	get_pred
	local	check_ghost
	local	store_pixel
		mov	al , [ esi ]
		mov	ebx , [ BFPartialCount ]
		inc	esi
		add	ebx , [ BFPartialPred ]
		or	bh , bh
		jnz	get_pred		; is this a predator pixel?

		mov	[ BFPartialCount ] , ebx
		jmp	check_ghost

	get_pred:
		xor	bh , bh
		mov	eax, [ BFPredOffset ]
		mov	[ BFPartialCount ] , ebx
		add	BYTE PTR [ BFPredOffset ] , 2
		movzx	eax , WORD PTR [ BFPredTable + eax ]
		and	BYTE PTR [ BFPredOffset ] , PRED_MASK
						; pick up a color offset a pseudo-
						;  random amount from the current
		movzx	eax , BYTE PTR [ edi + eax ]	;  viewport address

	check_ghost:
		mov	ebx , [ IsTranslucent ]		; is it a translucent color?
		mov	bh , BYTE PTR [ ebx + eax ]
		cmp	bh , 0ffh
		je	store_pixel

		and	ebx , 0FF00h			; clear all of ebx except bh
							; we have the index to the translation table
							; ((trans_colour * 256) + dest colour)
		mov	al , [ edi ]			; mov pixel at destination to al
		add	ebx , [ Translucent ]		; get the ptr to it!
							; Add the (trans_color * 256) of the translation equ.
		mov	al , BYTE PTR [ ebx + eax ]	; get new pixel in al

	store_pixel:
		mov	[ edi ] , al
		inc	edi

	ENDM

predator_g_reference:
	dec	ecx
	jge	predator_g_line

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	predator_g_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Predator_Ghost_Trans:near
BF_Predator_Ghost_Trans:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset predator_g_t_reference ]
	sub	ecx, [ offset predator_g_t_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ predator_g_t_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

predator_g_t_loop:
	mov	ecx , [ loop_cnt ]
	jmp	[ jmp_loc ]

predator_g_t_line:

	REPT	32
	local	trans_pixel
	local	get_pred
	local	check_ghost
	local	store_pixel
		mov	al , [ esi ]
		inc	esi
		test	al , al
		jz	trans_pixel

		mov	ebx , [ BFPartialCount ]
		add	ebx , [ BFPartialPred ]
		or	bh , bh
		jnz	get_pred		; is this a predator pixel?

		mov	[ BFPartialCount ] , ebx
		jmp	check_ghost

	get_pred:
		xor	bh , bh
		mov	eax, [ BFPredOffset ]
		mov	[ BFPartialCount ] , ebx
		add	BYTE PTR [ BFPredOffset ] , 2
		movzx	eax , WORD PTR [ BFPredTable + eax ]
		and	BYTE PTR [ BFPredOffset ] , PRED_MASK
						; pick up a color offset a pseudo-
						;  random amount from the current
		movzx	eax , BYTE PTR [ edi + eax ]	;  viewport address

	check_ghost:
		mov	ebx , [ IsTranslucent ]		; is it a translucent color?
		mov	bh , BYTE PTR [ ebx + eax ]
		cmp	bh , 0ffh
		je	store_pixel

		and	ebx , 0FF00h			; clear all of ebx except bh
							; we have the index to the translation table
							; ((trans_colour * 256) + dest colour)
		mov	al , [ edi ]			; mov pixel at destination to al
		add	ebx , [ Translucent ]		; get the ptr to it!
							; Add the (trans_color * 256) of the translation equ.
		mov	al , BYTE PTR [ ebx + eax ]	; get new pixel in al

	store_pixel:
		mov	[ edi ] , al

	trans_pixel:
		inc	edi

	ENDM

predator_g_t_reference:
	dec	ecx
	jge	predator_g_t_line

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	predator_g_t_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Predator_Fading:near
BF_Predator_Fading:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset predator_f_reference ]
	sub	ecx, [ offset predator_f_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ predator_f_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

predator_f_loop:
	mov	ecx , [ loop_cnt ]
	mov	[ StashECX ] , ecx		; preserve ecx for later
	jmp	[ jmp_loc ]

predator_f_line_begin:
	mov	[ StashECX ] , ecx		; preserve ecx for later

predator_f_line:

	REPT	32
	local	get_pred
	local	do_fading
	local	fade_loop
		mov	al , [ esi ]
		mov	ebx , [ BFPartialCount ]
		inc	esi
		add	ebx , [ BFPartialPred ]
		or	bh , bh
		jnz	get_pred		; is this a predator pixel?

		mov	[ BFPartialCount ] , ebx
		jmp	do_fading

	get_pred:
		xor	bh , bh
		mov	eax, [ BFPredOffset ]
		mov	[ BFPartialCount ] , ebx
		add	BYTE PTR [ BFPredOffset ] , 2
		movzx	eax , WORD PTR [ BFPredTable + eax ]
		and	BYTE PTR [ BFPredOffset ] , PRED_MASK
						; pick up a color offset a pseudo-
						;  random amount from the current
		movzx	eax , BYTE PTR [ edi + eax ]	;  viewport address

	do_fading:
		mov	ebx , [ FadingTable ]		; run color through fading table
		mov	ecx , [ FadingNum ]

	fade_loop:
		mov	al, byte ptr [ebx + eax]
		dec	ecx
		jnz	fade_loop

		mov	[ edi ] , al
		inc	edi

	ENDM

predator_f_reference:
	mov	ecx , [ StashECX ]		; restore ecx for main draw loop
	dec	ecx
	jge	predator_f_line_begin

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	predator_f_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Predator_Fading_Trans:near
BF_Predator_Fading_Trans:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset predator_f_t_reference ]
	sub	ecx, [ offset predator_f_t_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ predator_f_t_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

predator_f_t_loop:
	mov	ecx , [ loop_cnt ]
	mov	[ StashECX ] , ecx		; preserve ecx for later
	jmp	[ jmp_loc ]

predator_f_t_line_begin:
	mov	[ StashECX ] , ecx		; preserve ecx for later

predator_f_t_line:

	REPT	32
	local	trans_pixel
	local	get_pred
	local	do_fading
	local	fade_loop
		mov	al , [ esi ]
		inc	esi
		test	al , al
		jz	trans_pixel

		mov	ebx , [ BFPartialCount ]
		add	ebx , [ BFPartialPred ]
		or	bh , bh
		jnz	get_pred		; is this a predator pixel?

		mov	[ BFPartialCount ] , ebx
		jmp	do_fading

	get_pred:
		xor	bh , bh
		mov	eax, [ BFPredOffset ]
		mov	[ BFPartialCount ] , ebx
		add	BYTE PTR [ BFPredOffset ] , 2
		movzx	eax , WORD PTR [ BFPredTable + eax ]
		and	BYTE PTR [ BFPredOffset ] , PRED_MASK
						; pick up a color offset a pseudo-
						;  random amount from the current
		movzx	eax , BYTE PTR [ edi + eax ]	;  viewport address

	do_fading:
		mov	ebx , [ FadingTable ]		; run color through fading table
		mov	ecx , [ FadingNum ]

	fade_loop:
		mov	al, byte ptr [ebx + eax]
		dec	ecx
		jnz	fade_loop

		mov	[ edi ] , al

	trans_pixel:
		inc	edi

	ENDM

predator_f_t_reference:
	mov	ecx , [ StashECX ]		; restore ecx for main draw loop
	dec	ecx
	jge	predator_f_t_line_begin

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	predator_f_t_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Predator_Ghost_Fading:near
BF_Predator_Ghost_Fading:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset predator_g_f_reference ]
	sub	ecx, [ offset predator_g_f_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ predator_g_f_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

predator_g_f_loop:
	mov	ecx , [ loop_cnt ]
	mov	[ StashECX ] , ecx		; preserve ecx for later
	jmp	[ jmp_loc ]

predator_g_f_line_begin:
	mov	[ StashECX ] , ecx		; preserve ecx for later

predator_g_f_line:

	REPT	32
	local	get_pred
	local	check_ghost
	local	store_pixel
	local	do_fading
	local	fade_loop
		mov	al , [ esi ]
		mov	ebx , [ BFPartialCount ]
		inc	esi
		add	ebx , [ BFPartialPred ]
		or	bh , bh
		jnz	get_pred		; is this a predator pixel?

		mov	[ BFPartialCount ] , ebx
		jmp	check_ghost

	get_pred:
		xor	bh , bh
		mov	eax, [ BFPredOffset ]
		mov	[ BFPartialCount ] , ebx
		add	BYTE PTR [ BFPredOffset ] , 2
		movzx	eax , WORD PTR [ BFPredTable + eax ]
		and	BYTE PTR [ BFPredOffset ] , PRED_MASK
						; pick up a color offset a pseudo-
						;  random amount from the current
		movzx	eax , BYTE PTR [ edi + eax ]	;  viewport address

	check_ghost:
		mov	ebx , [ IsTranslucent ]		; is it a translucent color?
		mov	bh , BYTE PTR [ ebx + eax ]
		cmp	bh , 0ffh
		je	do_fading

		and	ebx , 0FF00h			; clear all of ebx except bh
							; we have the index to the translation table
							; ((trans_colour * 256) + dest colour)
		mov	al , [ edi ]			; mov pixel at destination to al
		add	ebx , [ Translucent ]		; get the ptr to it!
							; Add the (trans_color * 256) of the translation equ.
		mov	al , BYTE PTR [ ebx + eax ]	; get new pixel in al
; DRD		jmp	store_pixel

	do_fading:
		mov	ebx , [ FadingTable ]		; run color through fading table
		mov	ecx , [ FadingNum ]

	fade_loop:
		mov	al, byte ptr [ebx + eax]
		dec	ecx
		jnz	fade_loop

	store_pixel:
		mov	[ edi ] , al
		inc	edi

	ENDM

predator_g_f_reference:
	mov	ecx , [ StashECX ]		; restore ecx for main draw loop
	dec	ecx
	jge	predator_g_f_line_begin

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	predator_g_f_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

;extern	BF_Predator_Ghost_Fading_Trans:near
BF_Predator_Ghost_Fading_Trans:

	prologue
	mov	ebx , eax			; width

	; NOTE: the below calculation assumes a group of instructions is
	;	less than 256 bytes

	; get length of the 32 groups of instructions

	lea	ecx , [ offset predator_g_f_t_reference ]
	sub	ecx, [ offset predator_g_f_t_line ]

	shr	ebx , 5				; width / 32
	shr	ecx , 5				; length of instructions / 32
	and	eax , 01fh			; mod of width / 32
	mul	cl				; calc offset to start of group
	neg	eax				; inverse of width
	mov	[ loop_cnt ] , ebx		; save width / 32
	lea	ecx , [ predator_g_f_t_reference + eax ]
	mov	eax , 0
	mov	[ jmp_loc ] , ecx

predator_g_f_t_loop:
	mov	ecx , [ loop_cnt ]
	mov	[ StashECX ] , ecx		; preserve ecx for later
	jmp	[ jmp_loc ]

predator_g_f_t_line_begin:
	mov	[ StashECX ] , ecx		; preserve ecx for later

predator_g_f_t_line:

	REPT	32
	local	trans_pixel
	local	get_pred
	local	check_ghost
	local	store_pixel
	local	do_fading
	local	fade_loop
		mov	al , [ esi ]
		inc	esi
		test	al , al
		jz	trans_pixel

		mov	ebx , [ BFPartialCount ]
		add	ebx , [ BFPartialPred ]
		or	bh , bh
		jnz	get_pred		; is this a predator pixel?

		mov	[ BFPartialCount ] , ebx
		jmp	check_ghost

	get_pred:
		xor	bh , bh
		mov	eax, [ BFPredOffset ]
		mov	[ BFPartialCount ] , ebx
		add	BYTE PTR [ BFPredOffset ] , 2
		movzx	eax , WORD PTR [ BFPredTable + eax ]
		and	BYTE PTR [ BFPredOffset ] , PRED_MASK
						; pick up a color offset a pseudo-
						;  random amount from the current
		movzx	eax , BYTE PTR [ edi + eax ]	;  viewport address

	check_ghost:
		mov	ebx , [ IsTranslucent ]		; is it a translucent color?
		mov	bh , BYTE PTR [ ebx + eax ]
		cmp	bh , 0ffh
		je	do_fading

		and	ebx , 0FF00h			; clear all of ebx except bh
							; we have the index to the translation table
							; ((trans_colour * 256) + dest colour)
		mov	al , [ edi ]			; mov pixel at destination to al
		add	ebx , [ Translucent ]		; get the ptr to it!
							; Add the (trans_color * 256) of the translation equ.
		mov	al , BYTE PTR [ ebx + eax ]	; get new pixel in al
; DRD		jmp	store_pixel

	do_fading:
		mov	ebx , [ FadingTable ]		; run color through fading table
		mov	ecx , [ FadingNum ]

	fade_loop:
		mov	al, byte ptr [ebx + eax]
		dec	ecx
		jnz	fade_loop

	store_pixel:
		mov	[ edi ] , al

	trans_pixel:
		inc	edi

	ENDM

predator_g_f_t_reference:
	mov	ecx , [ StashECX ]		; restore ecx for main draw loop
	dec	ecx
	jge	predator_g_f_t_line_begin

	add	esi , [ scr_adjust_width ]
	add	edi , [ dest_adjust_width ]
	dec	edx
	jnz	predator_g_f_t_loop

	epilogue
	ret


;********************************************************************
;********************************************************************

Not_Supported:
	ret

Buffer_Frame_To_Page	ENDP	


end

externdef	C CPUType:byte



;*********************************************************************************************
;* Detect_MMX_Availability -- Detect the presence of MMX technology.                         *
;*                                                                                           *
;*                                                                                           *
;* INPUT:	Nothing                                                                      *
;*                                                                                           *
;* OUTPUT:      True if MMX technology is available.                                         *
;*                                                                                           *
;* Warnings:                                                                                 *
;*                                                                                           *
;* Note: Based in part on CPUID32.ASM by Intel                                               *
;*                                                                                           *
;* HISTORY:                                                                                  *
;*   05/19/96 ST : Created.                                                                  *
;*===========================================================================================*

Detect_MMX_Availability proc C

		local	idflag:byte
		local	local_cputype:byte

;assume processor is at least 386
;
;check whether AC bit in eflags can be toggled.
;If not then processor is 386

		mov	[idflag],0

		pushfd			;get Eflags in EAX
		pop	eax
		mov	ecx,eax		;save eflags
		xor	eax,40000h	;toggle AC bit in eflags
		push	eax		;new eflags on stack
		popfd			;move new value into eflags
		pushfd			;get new eflags back into eax
		pop	eax
		xor	eax,ecx		;if AC bit not toggled then CPU=386
		mov	[local_cputype],3
		jz	@@end_get_cpu	;cpu is 386

		push	ecx
		popfd			;restore AC bit in eflags


;processor is at least 486
;
;Check for ability to set/clear ID flag in EFLAGS
;ID flag indicates ability of processor to execute the CPUID instruction.
;486 not guaranteed to have CPUID inst?
;
		mov	[local_cputype],4
		mov	eax,ecx		;original EFLAGS
		xor	eax,200000h	;toggle ID bit
		push	eax
		popfd
		pushfd
		pop	eax
		xor	eax,ecx		;check if still toggled
		jz	@@end_get_cpu


;       Execute CPUID instruction to determine vendor, family,
;       model and stepping.
;

		mov	[idflag],1	;flag ID is available

		xor	eax,eax
		cpuid

		mov	dword ptr [VendorID],ebx
		mov	dword ptr [VendorID+4],edx
		mov	dword ptr [VendorID+8],ecx
		mov	dword ptr [VendorID+12]," "

		cmp	eax,1		;check if 1 is valid
		jl	@@end_get_cpu	;inp for cpuid inst.

		xor	eax,eax
		inc	eax

		cpuid		;get stepping, model and family

		and     ax,0f00H
		shr     ax,08H

		mov	[local_cputype],al

@@end_get_cpu:	mov	al,[local_cputype]
		mov	[CPUType],al


;
; We have the CPU type in al now.
; If we arent on at least a pentium then we can assume there is no MMX
;
		cmp	al,5
		jl	@@no_mmx

		mov	eax,1
		cpuid
		test	edx,00800000h
		jz	@@no_mmx

;
; MMX detected - return true
;
		mov	eax,1
		ret


@@no_mmx:	xor	eax,eax
		ret


Detect_MMX_Availability endp



;*********************************************************************************************
;* Init_MMX -- Do any special inits required for MMX support                                 *
;*                                                                                           *
;*                                                                                           *
;* INPUT:	Nothing                                                                      *
;*                                                                                           *
;* OUTPUT:      None                                                                         *
;*                                                                                           *
;* Warnings:                                                                                 *
;*                                                                                           *
;* HISTORY:                                                                                  *
;*   05/19/96 ST : Created.                                                                  *
;*===========================================================================================*

Init_MMX	proc C

		mov	edi,offset NewShapeJumpTable
		mov	ecx,offset EndNewShapeJumpTable
		sub	ecx,edi
		shr	ecx,2
		mov	eax,offset Single_Line_Trans
		mov	ebx,offset MMX_Single_Line_Trans
		cld


@@patch_loop:   repnz	scasd
		jnz	@@done
		mov	[edi-4],ebx
		test	ecx,ecx
		jnz	@@patch_loop

@@done:		ret

Init_MMX	endp






;*********************************************************************************************
;* MMX_Done -- Restores floating point capability after MMX usage                            *
;*                                                                                           *
;*                                                                                           *
;* INPUT:	Nothing                                                                      *
;*                                                                                           *
;* OUTPUT:      None                                                                         *
;*                                                                                           *
;* Warnings:                                                                                 *
;*                                                                                           *
;* HISTORY:                                                                                  *
;*   05/19/96 ST : Created.                                                                  *
;*===========================================================================================*

MMX_Done	proc C

		emms
		ret

MMX_Done	endp







		code segment page public use32 'code'	; Need stricter segment alignment
							; for pentium optimisations


;*********************************************************************************************
;* MMX_Single_Line_Trans -- draw a single line of transparent pixels using MMX technology    *
;*                                                                                           *
;*                                                                                           *
;* INPUT:	Esi - ptr to source data                                                     *
;*              Edi - ptr to destination data                                                *
;*              Ecx - width to draw in bytes                                                 *
;*                                                                                           *
;* OUTPUT:      None                                                                         *
;*                                                                                           *
;* Warnings:                                                                                 *
;*                                                                                           *
;* HISTORY:                                                                                  *
;*   05/19/96 ST : Created.                                                                  *
;*===========================================================================================*

		align	16

MMX_Single_Line_Trans proc near

;
; If we are doing less than 8 bytes then dont use MMX
;
		cmp	ecx,8
		jge	@@mmx_loop
		push	offset Single_Line_Trans_Entry
		ret

;
; Use MMX instructions to mask 8 bytes at once
;
; Creates a bitmask based on the source bytes equality with zero and then uses this to mask
; out the source bytes in the destination data. The advatage that MMX gives us is that there is
; no 'test for zero then jump' required to mask.
;
		align	64		;MMX instructions like 64 byte alignment!

@@mmx_loop:
		movq	mm0,[esi]	; move 8 bytes of source into mm0
		pxor	mm1,mm1		; zero out mm1
		pcmpeqb mm1,mm0		; compare mm0 with 0. Bits get set in mm1
		lea	esi,[esi+8]     ; adjust the source data pointer
		pand	mm1,[edi]	; and in the destination data to throw away the bytes which arent zero in the source
		sub	ecx,8		; adjust the byte counter
		por	mm1,mm0         ; or in the source with the destination data
		movq	[edi],mm1       ; write back the destination data
		lea	edi,[edi+8]	; adjust the destination pointer

		cmp	ecx,8
		jg	@@mmx_loop

;
; Jump to the approprite code for drawing the end of this line or going to the next one
;
		push	offset Next_Line
		jcxz   	@@next_line
		push	offset Single_Line_Trans_Entry
@@next_line:	ret


MMX_Single_Line_Trans endp


code ends

		.data

CPUType		db	0
VendorID	db	"Not available",0,0,0,0,0,0











END

;***************************************************************************
;**   C O N F I D E N T I A L --- W E S T W O O D   A S S O C I A T E S   **
;***************************************************************************
;*                                                                         *
;*                 Project Name : Westwood Library                         *
;*                                                                         *
;*                    File Name : KEYFBUFF.ASM                             *
;*                                                                         *
;*                   Programmer : Phil W. Gorrow                           *
;*                                                                         *
;*                   Start Date : July 16, 1992                            *
;*                                                                         *
;*                  Last Update : October 2, 1994   [JLB]                  *
;*                                                                         *
;*-------------------------------------------------------------------------*
;* Functions:                                                              *
;*   BUFFER_FRAME_TO_LOGICPAGE --                                          *
;*   Normal_Draw -- Function that writes a normal pixel line               *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *

;	IDEAL
;	P386
;IDEAL_MODE	EQU	1
;	INCLUDE "wwlib.i"

	;-------------------------------------------------------------------
	; Extern all the library variables that this module requires
	;-------------------------------------------------------------------

	EXTRN	C MaskPage:WORD
	EXTRN	C BackGroundPage:WORD

	;-------------------------------------------------------------------
	; Define all the equates that this module requires
	;-------------------------------------------------------------------

WIN_X		EQU	0		; offset for the x coordinate
WIN_Y		EQU	2		; offset for the y coordinate
WIN_WIDTH	EQU	4		; offset for the window width
WIN_HEIGHT	EQU	6		; offset for the window height
BYTESPERROW	EQU	320		; number of bytes per row

FLAG_NORMAL		EQU	0		; flag for normal draw

FLAG_GHOST		EQU	1		; This flag enables the ghost
FLAG_PRIORITY_TRANS	EQU	2		; flag for priority and transparent
FLAG_TRANS		EQU	4		; flag for transparent draw
FLAG_PRIORITY		EQU	8		; flag for priority draw

						; fx on the above flags

FLAG_MASK		EQU	15		; used to and of uneeded bits

SHAPE_NORMAL		EQU	0000h		; Standard shape.
;SHAPE_HORZ_REV		EQU	0001h		; Flipped horizontally.
;SHAPE_VERT_REV		EQU	0002h		; Flipped vertically.
;SHAPE_SCALING		EQU	0004h		; Scaled (WORD scale_x, WORD scale_y)

SHAPE_WIN_REL		EQU	0010h		; Coordinates are window relative instead of absolute.
SHAPE_CENTER		EQU	0020h		; Coordinates are based on shape's center point.
SHAPE_TRANS		EQU	0040h		; has transparency


;SHAPE_FADING		EQU	0100h		; Fading effect active (VOID * fading_table, WORD fading_num).
;SHAPE_PREDATOR		EQU	0200h		; Transparent warping effect.
;SHAPE_COMPACT		EQU	0400h		; Never use this bit.
SHAPE_PRIORITY		EQU	0800h		; Use priority system when drawing.

SHAPE_GHOST		EQU	1000h		; Transluscent table process.
;SHAPE_SHADOW		EQU	2000h		; 
;SHAPE_PARTIAL 		EQU	4000h		; 
;SHAPE_COLOR		EQU	8000h		; Remap the shape's colors (VOID * color_table).


; MBL MOD 12.1.92

CLEAR_NON_WALK_BIT_AND_SCALE_BITS	EQU	7	; Makes it one AND per pixel in Priority_Trans display
CLEAR_NON_WALK_BIT    	EQU	7fh	; and with 0111-1111 to clear non-walkable high bit
CLEAR_SCALE_BITS  	EQU	87h	; and with 1000-0111 to clear scaling id bits
NON_WALKABLE_BIT  	EQU	80h	; and with 1000-0000 to clear all but non-walkable bit

; END MBL MOD


	CODESEG

	;   1 = GHOST (all odd entrys are prefixed with Ghost_)
	;   2 = BLAAAH
	;   4 = Trans (prfx)
	;   8 = Prior (prfx)


;---------------------------------------------------------------------------
; Define the table of different line draw types
;---------------------------------------------------------------------------

LineTable	DW	WSA_Normal_Draw			;0
		DW	Ghost_Normal_Draw		;1
		DW	0				;2
		DW	0				;3

		DW	Transparent_Draw		;4
		DW	Ghost_Transparent_Draw		;5
		DW	0				;6
		DW	0				;7

		DW	Priority_Draw			;8
		DW	Ghost_Priority_Draw		;9
		DW	0				;10
		DW	0				;11

		DW	Priority_Transparent_Draw	;12
		DW	Ghost_Priority_Transparent_Draw	;13
		DW	0				;14
		DW	0				;15



;***************************************************************************
;* BUFFER_FRAME_TO_LOGICPAGE --                                            *
;*                                                                         *
;*                                                                         *
;*                                                                         *
;* INPUT:                                                                  *
;*                                                                         *
;* OUTPUT:                                                                 *
;*                                                                         *
;* WARNINGS:                                                               *
;*                                                                         *
;* HISTORY:                                                                *
;*   07/16/1992 PWG : Created.                                             *
;*=========================================================================*
	PUBLIC	C Buffer_Frame_To_LogicPage
	PROC	C Buffer_Frame_To_LogicPage FAR USES ax bx ecx dx ds esi es edi

	;-------------------------------------------------------------------
	; Define the arguements that our program takes.
	;-------------------------------------------------------------------

	ARG	x_pixel:WORD		; x pixel position to draw at
	ARG	y_pixel:WORD		; y pixel position to draw at
	ARG	pixel_w:WORD		; pixel width of draw region
	ARG	pixel_h:WORD		; pixel height of draw region
	ARG	win:WORD		; window to clip around
	ARG	flags:WORD		; flags that this routine will take
	ARG	buffer:DWORD		; pointer to the buffer with data
	ARG	args:WORD

	;-------------------------------------------------------------------
	; Define the local variables that our program uses
	;-------------------------------------------------------------------

	LOCAL	IsTranslucent:DWORD	; ptr to the is_translucent table
	LOCAL	Translucent:DWORD	; ptr to the actual translucent table

	LOCAL	win_x1:WORD		; clip window left x pixel position
	LOCAL	win_x2:WORD		; clip window right x pixel position
	LOCAL	win_y1:WORD		; clip window top y pixel position
	LOCAL	win_y2:WORD		; clip window bottom y pixel position
	LOCAL	clipleft:WORD		; number of pixels to clip on left
	LOCAL	clipright:WORD		; number of pixels to clip on right
	LOCAL	nextline:WORD		; offset to the next line
	LOCAL	putmiddle:WORD 		; routine to call to put the middle
	LOCAL	maskpage:WORD		; location of the depth masks
	LOCAL   background:WORD		; location of the background data
	LOCAL   jflags:WORD		; location of the background data

	LOCAL	priority:BYTE		; the priority level of the back

	push	fs

	xor	ecx,ecx

	;--------------------------------------------------------------------
	; Check to see if we have supplied any GHOST tables.
	;--------------------------------------------------------------------
	push	di

	mov	di,6
	mov	[jflags],0

ghost:
	test	[flags],SHAPE_GHOST	; are we ghosting this shape
	jz	short no_ghost	; if not then skip and do more

	or	[jflags],FLAG_GHOST

	les	ax,dword ptr [buffer + di]

	; get the "are we really translucent?" table
	mov	[WORD PTR IsTranslucent],ax
	mov	[WORD PTR IsTranslucent + 2],es
	add	ax,0100h		; add to offset for tables

	; get the "ok we are translucent!!" table
	mov	[WORD PTR Translucent],ax
	mov	[WORD PTR Translucent + 2],es

	add	di,4

no_ghost:

	pop	di

	;-------------------------------------------------------------------
	; See if we need to center the frame
	;-------------------------------------------------------------------
	test	[flags],SHAPE_CENTER	; does this need to be centered?
	je	short no_centering	; if not the skip over this stuff

	mov	ax,[pixel_w]
	mov	bx,[pixel_h]
	sar	ax,1
	sar	bx,1
	sub	[x_pixel],ax
	sub	[y_pixel],bx

no_centering:
	mov	ax,[flags]
	and	ax,SHAPE_PRIORITY+SHAPE_TRANS
	cmp	ax,SHAPE_PRIORITY+SHAPE_TRANS
	jne	short test_trans

	or	[jflags],FLAG_PRIORITY_TRANS
	jmp	short priority

	;-------------------------------------------------------------------
	; Get the trans information if we need to get it
	;-------------------------------------------------------------------
test_trans:
	test	[flags],SHAPE_TRANS	; does this draw use transparencies?
	je	short test_priority	; if not the skip over this junk

	or	[jflags],FLAG_TRANS

test_priority:
	;-------------------------------------------------------------------
	; Get the priority information if we need to get it
	;-------------------------------------------------------------------
	test	[flags],SHAPE_PRIORITY	; does this draw use priorities?
	je	short no_priority	; if not the skip over this junk

	or	[jflags],FLAG_PRIORITY

priority:
	mov	ax,[BackGroundPage]	; get the background page from ds
	mov	[background],ax		;    and store it on the stack
	mov	ax,[MaskPage]		; get the mask page from ds
	mov	[maskpage],ax		;    and store it on the stack
	mov	ax,[WORD PTR buffer + 4]; get the priority level from args
	mov	[priority],al		;    and store it in a local

	;-------------------------------------------------------------------
	; Get the draw routine that we are going to draw with
	;-------------------------------------------------------------------
no_priority:
;	mov	bx,[flags]		; load in the current flags byte
;	and	bx,FLAG_MASK		; prevent lockup on bad value
	mov	bx,[jflags]		; load in the jump table flags
	shl	bx,1
	mov	ax,[WORD PTR LineTable + bx]	; get the offset of the skip table
	mov	[putmiddle],ax		; store off the new offset

	;-------------------------------------------------------------------
	; Get a pointer to the logic page to where we will draw our buffer
	;-------------------------------------------------------------------
	push	[LogicPage]		; push the current logic page
	call	FAR PTR Get_Page	; get the physical page address
	add	sp,2			; pull the parameter from the stack
	mov	es,dx			; store the address in the dest

	;--------------------------------------------------------------------
	; Point DI to the beginning of the window that we need to look at.
	;   that way we can access all of the info through di.
	;--------------------------------------------------------------------
	mov	si,OFFSET WindowList	; get the offset of the window list
	mov	cl,4			; shift 3 times = multiply by 16
	mov	ax,[win]		; get the window number we are using
	shl	ax,cl			; each window is 8 words long
	add	si,ax			; add that into the offset of window

	;--------------------------------------------------------------------
	; Place all the clipping values on the stack so our function will
	; be truly re-entrant and will not need to shadow these values.
	;--------------------------------------------------------------------
	mov	cl,3			; to convert x to pixel mult by 8
	mov	ax,[si + WIN_X]		; get the left clip position
	shl	ax,cl			; convert to a pixel x position
	mov	[win_x1],ax		; store the left edge of window
	mov	[win_x2],ax

	mov	ax,[si + WIN_WIDTH]	; get the width of the window
	shl	ax,cl			; convert to a pixel width
	add	[win_x2],ax		; add to get the right window edge

	mov	ax,[si + WIN_Y]		; get the win y coordinate to clip
	mov	[win_y1],ax		; and save it onto the stack

	add	ax,[si + WIN_HEIGHT]	; calculate the bottom win y coord
	mov	[win_y2],ax		; and save it onto the stack

	test	[flags],SHAPE_WIN_REL	; is this window relative?
	je	short get_buffer	; if not the skip over

	mov	ax,[win_x1]		; get left edge of window
	add	[x_pixel],ax		; add to x pixel position
	mov	ax,[win_y1]		; get top edge of window
	add	[y_pixel],ax		; add to y pixel position

	;--------------------------------------------------------------------
	; Get a pointer to the source buffer so we can handle the clipping
	;--------------------------------------------------------------------
get_buffer:
	lds	si,[buffer]		; get a pointer to the buffer

	;--------------------------------------------------------------------
	; Check the top of our shape and clip any lines that are necessary
	;--------------------------------------------------------------------
	mov	ax,[y_pixel]		; get the y_pixel draw position
	sub	ax,[win_y1]		; subtract out the window y top
	jns	short check_bottom		;   skip if y below window top
	add	ax,[pixel_h]		; add in the height of the region
	jg	short clip_top		; if positive then clip top lines

jump_exit:
	jmp	proc_exit			; otherwise completely clipped

clip_top:
	xchg	[pixel_h],ax
	sub	ax,[pixel_h]
	add	[y_pixel],ax
	mul	[pixel_w]		; convert to number of bytes to skip
	add	si,ax			; skip past the necessary bytes

	;--------------------------------------------------------------------
	; Check the bottom of our shape and clip it if necessary
	;--------------------------------------------------------------------
check_bottom:
	mov	ax,[win_y2]		; get the bottom y of the window
	sub	ax,[y_pixel]		; subtract of the y to draw at
	js	jump_exit		; if its signed then nothing to draw
	jz	jump_exit		; if its zero then nothing to draw

	cmp	ax,[pixel_h]		; if more room to draw then height
	jae	short clip_x_left		;   then go check the left clip
	mov	[pixel_h],ax		; clip all but amount that will fit

clip_x_left:
	mov	[clipleft],0		; clear clip on left of region
	mov	ax,[x_pixel]		; get the pixel x of draw region
	sub	ax,[win_x1]		; pull out the window coordinate
	jns	short clip_x_right
	neg	ax			; negate to get amnt to skip in buf
	mov	[clipleft],ax		; store it in the left clip info
	add	[x_pixel],ax		; move to the edge of the window
	sub	[pixel_w],ax		; pull it out of the pixel width

clip_x_right:
	mov	[clipright],0		; clear clip on right of region
	mov	ax,[win_x2]		; get the window x of clip region
	sub	ax,[x_pixel]		; subtract the draw edge of region
	js	jump_exit		; if its negative then get out
	jz	jump_exit		; if its zero then get out

	cmp	ax,[pixel_w]		; is space available larger than w
	jae	short draw_prep		;   if so then go get drawing


	xchg	[pixel_w],ax		; amt to draw in pixel_w (wid in ax)
	sub	ax,[pixel_w]		; pull out the amount to draw
	mov	[clipright],ax		; this is the amount to clip on right

draw_prep:
	push	si			; save off source pos in buffer
	push	ds			;   both offset and segment
	mov	ax,@data
	mov	ds,ax
	mov	bx,[y_pixel]
	shl	bx,1			; shift left by 1 for word table look
	lds	si,[YTable]	; get the address of the ytable
	mov	di,[ds:si+bx]		; look up the multiplied value
	pop	ds			; restore source pos in buffer
	pop	si			;   both offset and segment

	add	di,[x_pixel]		; add in the x pixel position
	mov	[nextline],di		; save it off in the next line

 	;--------------------------------------------------------------------
	; Now determine the type of the shape and process it in the proper
	;   way.
	;--------------------------------------------------------------------
	mov	dx,[pixel_h]

	; Check to see if the WSA is the screen width and there is no
	; clipping. In this case, then a special single call to the
	; line processing routine is possible.
	mov	ax,[clipleft]
	add	ax,[clipright]
	jne	short top_of_loop
	cmp	[pixel_w],BYTESPERROW
	jne	short top_of_loop

	;------------------------------------
	; The width of the WSA is the screen width, so just process as
	; one large WSA line.
	mov	ax,BYTESPERROW
	imul	dx
	mov	cx,ax
	call	[putmiddle]
	jmp	short proc_exit

	;------------------------------------
	; Process line by line.
top_of_loop:
	add	si,[clipleft]		; skip whats necessary on left edge
	mov	cx,[pixel_w]		; get the width we need to draw

	; Copy the source to the destination as appropriate. This routine can
	; trash AX, BX, CX, and DI. It must properly modify SI to point one byte past
	; the end of the data.
	call	[putmiddle]

	add	si,[clipright]		; skip past the left clip
	add	[nextline],BYTESPERROW
	mov	di,[nextline]

	dec	dx
	jnz	top_of_loop

proc_exit:
	pop	fs
	ret
	ENDP


;***************************************************************************
;* NORMAL_DRAW -- Function that writes a normal pixel line                 *
;*                                                                         *
;* INPUT:	cx    - number of pixels to write                          *
;*		ds:si - buffer which holds the pixels to write		   *
;*		es:di - place to put the pixels we are writing		   *
;*                                                                         *
;* OUTPUT:      ds:si - points to next pixel past last pixel read          *
;*		es:di - points to next pixel past last pixel written	   *
;*                                                                         *
;* WARNINGS:    none                                                       *
;*                                                                         *
;* HISTORY:                                                                *
;*   07/17/1992 PWG : Created.                                             *
;*=========================================================================*

	PROC	NOLANGUAGE WSA_Normal_Draw NEAR

 IF 1
 	; This version is marginally faster than the later version.
 	mov	ax,cx
	shr	cx,2
	rep movsd
	and	ax,011b
	mov	cx,ax
	shr	cx,1
	rep movsw
	adc	cx,cx
	rep movsb
	ret

 ELSE

	shr	cx,1			; convert to words (odd pix in carry)
	rep	movsw			; write out the needed words
	adc	cx,0			; add the carry into cx
	rep	movsb			; write out the odd byte if any
	ret
 ENDIF

	ENDP


;***************************************************************************
;* TRANSPARENT_DRAW -- Function that writes a transparent pixel line       *
;*                                                                         *
;* INPUT:	cx    - number of pixels to write                          *
;*		ds:si - buffer which holds the pixels to write		   *
;*		es:di - place to put the pixels we are writing		   *
;*                                                                         *
;* OUTPUT:      ds:si - points to next pixel past last pixel read          *
;*		es:di - points to next pixel past last pixel written	   *
;*                                                                         *
;* WARNINGS:    none                                                       *
;*                                                                         *
;* HISTORY:                                                                *
;*   07/17/1992 PWG : Created.                                             *
;*   10/02/1994 JLB : Optimized for 250% speed improvement.                *
;*=========================================================================*
	PROC	NOLANGUAGE Transparent_Draw NEAR

 IF 1
	; Preserve DX since it is used as a scratch register.
	push	dx

loop:
	; Swap DS:SI and ES:DI back in preparation for the REP SCASB
	; instruction.
	xchg	di,si
	mov	dx,es
	mov	ax,ds
	mov	ds,dx
	mov	es,ax

	; Remember the bytes remaining in order to calculate the position
	; of the scan when it stops.
	mov	bx,cx

	; Scan looking for a non-zero value in the source buffer.
	xor	al,al
	repe scasb

	; When the loop ends, if the EQ flag is set then the scanning is
	; complete. Jump to the end of the routine in order to fixup the
	; pointers.
	je	short fini

	; Advance the destination pointer by the amount necessary to match
	; the source movement. DS:SI points to where data should be written.
	add	si,bx
	inc	cx		; SCASB leaves CX one too low, fix it.
	dec	di		; SCASB leaves DI one byte too far, fix it.
	sub	si,cx

	; Scan for the duration of non-zero pixels. This yields a count which
	; is used to copy the source data to the destination. Preserve DI.
	mov	dx,di
	mov	bx,cx
	repne scasb
	mov	di,dx

	; Set BX to equal the number of bytes to copy from source to dest.
	inc	cx		; SCASB leaves CX one too low, fix it.
	sub	bx,cx

	; Move the data from ES:DI to DS:SI for BX bytes.
	xchg	cx,bx		; Make CX=bytes to move, BX=bytes remaining.

	; Swap DS:SI and ES:DI in preparation for the REP MOV instruction.
	xchg	di,si
	mov	dx,es
	mov	ax,ds
	mov	ds,dx
	mov	es,ax

	; Move the data from source to dest. First try to move double
	; words. Then copy the remainder bytes (if any). Putting jumps in
	; this section doesn't result in any savings -- oh well.
	mov	ax,cx
	shr	cx,2
	rep movsd
	and	ax,0011b
	mov	cx,ax
	shr	cx,1
	rep movsw
	adc	cx,cx
	rep movsb

	; Restore CX with the remaining bytes to process.
	mov	cx,bx

	; If there are more bytes to process, then loop back.
	or	cx,cx
	jne	short loop

fini:
	; Swap ES:DI and DS:SI back to original orientation.
	mov	ax,ds
	mov	bx,es
	mov	es,ax
	mov	ds,bx
	xchg	di,si

	; Restore DX and return.
	pop	dx
	ret

 ELSE

loop_top:
	lodsb
	or	al,al
	jz	short skip

	mov	[es:di],al		; store the pixel to the screen
skip:
	inc	di
	loop	loop_top
	ret

 ENDIF

	ENDP


;***************************************************************************
;* PRIORITY_DRAW -- Function that writes a pixels if they are in front of  *
;*		    the given plate.					   *
;*                                                                         *
;* INPUT:	cx    - number of pixels to write                          *
;*		ds:si - buffer which holds the pixels to write		   *
;*		es:di - place to put the pixels we are writing		   *
;*                                                                         *
;* OUTPUT:      ds:si - points to next pixel past last pixel read          *
;*		es:di - points to next pixel past last pixel written	   *
;*                                                                         *
;* WARNINGS:    none                                                       *
;*                                                                         *
;* HISTORY:                                                                *
;*   07/17/1992 PWG : Created.                                             *
;*   12/01/1992 MBL : Updated to work with latest mask data encoding.      *
;*   17/01/1993 MCC : Updated for 386, and optimized			   *
;*=========================================================================*

	PROC	NOLANGUAGE Priority_Draw NEAR

	mov	fs,[background]		; get the SEG of the background page
	mov	gs,[maskpage]		; get the SEG of the mask info
	mov	ah,[priority]		; keep a copy of priority varible for faster cmp


loop_top:
	lodsb				; get the pixel to draw on the screen

					; get the mask byte for our pixel
	mov	bl,[ds:di]
					; get rid of non-walkable bit and
					; get rid of scaling id bits
	and	bl,CLEAR_NON_WALK_BIT_AND_SCALE_BITS

	cmp	ah,bl			; are we more toward the front?
	jge	short out_pixel	; if so then write the pixel

	mov	al,[fs:di]		; get the pixel to write
out_pixel:
	stosb				; write the pixel and inc the DI
	loop	loop_top
	ret

	ENDP


;***************************************************************************
;* PRIORITY_TRANSPARENT_DRAW -- Function that writes a pixels if they are  *
;*		    in front of the given plate.  It also deals with	   *
;*		    transparent pixels.					   *
;*                                                                         *
;* INPUT:	cx    - number of pixels to write                          *
;*		ds:si - buffer which holds the pixels to write		   *
;*		es:di - place to put the pixels we are writing		   *
;*                                                                         *
;* OUTPUT:      ds:si - points to next pixel past last pixel read          *
;*		es:di - points to next pixel past last pixel written	   *
;*                                                                         *
;* WARNINGS:    none                                                       *
;*                                                                         *
;* HISTORY:                                                                *
;*   07/17/1992 PWG : Created.                                             *
;*   12/01/1992 MBL : Updated to work with latest mask data encoding.      *
;*   17/01/1993 MCC : Updated for 386, and optimized			   *
;*=========================================================================*

	PROC	NOLANGUAGE Priority_Transparent_Draw NEAR

	mov	fs,[background]		; get the SEG of the background page
	mov	gs,[maskpage]		; get the SEG of the mask info
	mov	ah,[priority]		; keep a copy of priority varible for faster cmp

loop_top:
	lodsb				; get the pixel on the screen
	or	al,al			; check to see if al is transparent
	je	short write_back	; if it is go write background

	mov	bl,[gs:di]		; get the mask byte for our pixel

					; get rid of non-walkable bit and
					; get rid of scaling id bits
	and	bl,CLEAR_NON_WALK_BIT_AND_SCALE_BITS

	cmp	ah,bl			; are we more toward the front?
	jge	short out_pixel	; if so then write the pixel

write_back:
	mov	al,[fs:di]		; get the pixel to write
out_pixel:
	stosb				; write the pixel
	loop	loop_top
	ret

	ENDP


;***************************************************************************
;* GHOST_NORMAL_DRAW -- Function that writes a normal pixel line           *
;*                                                                         *
;* INPUT:	cx    - number of pixels to write                          *
;*		ds:si - buffer which holds the pixels to write		   *
;*		es:di - place to put the pixels we are writing		   *
;*                                                                         *
;* OUTPUT:      ds:si - points to next pixel past last pixel read          *
;*		es:di - points to next pixel past last pixel written	   *
;*                                                                         *
;* WARNINGS:    none                                                       *
;*                                                                         *
;* HISTORY:                                                                *
;*   05/27/1993 MCC : Created.                                             *
;*=========================================================================*

	PROC	NOLANGUAGE Ghost_Normal_Draw NEAR

loop_top:
	lodsb

;---
	; Ok, find out if the colour is a Translucent colour
	push	ax
	push 	ds

	lds	bx,[IsTranslucent]
	mov	ah,al			; preserve real pixel
	xlat				; get new al (transluecent pixel
	xchg	ah,al			; get real pixel back into AL just in case
	cmp	ah,255
	je	short normal_pixel		; is it a translucent ?
					; if we get passed here value in
					; AH should be 0-15

	; yes, it is a translucent colour so goto our translucent translation
	; table and set up a ptr to the correct table

	mov	al,[es:di]
					; mov pixel at destination to al and we have
					; the index to the translation table
					; ((trans_colour * 256) + dest colour)
	lds	bx,[Translucent]	; get the ptr to it!
	add	bh,ah			; Add the (trans_color * 256) of the translation equ.
					; XLAT only uses AL so no need to clear AH
	xlat				; get new pixel in AL

normal_pixel:
	pop	ds
	pop	bx
	mov	ah,bh
;---

	mov	[es:di],al		; store the pixel to the screen

skip:
	inc	di
	loop	loop_top

	ret

	ENDP


;***************************************************************************
;* GHOST_TRANSPARENT_DRAW -- Function that writes a transparent pixel line *
;*                                                                         *
;* INPUT:	cx    - number of pixels to write                          *
;*		ds:si - buffer which holds the pixels to write		   *
;*		es:di - place to put the pixels we are writing		   *
;*                                                                         *
;* OUTPUT:      ds:si - points to next pixel past last pixel read          *
;*		es:di - points to next pixel past last pixel written	   *
;*                                                                         *
;* WARNINGS:    none                                                       *
;*                                                                         *
;* HISTORY:                                                                *
;*   05/27/1993 MCC : Created.                                             *
;*=========================================================================*
	PROC	NOLANGUAGE Ghost_Transparent_Draw NEAR

loop_top:
	lodsb
	or	al,al
	jz	short skip

;---
	; Ok, find out if the colour is a Translucent colour
	push	ax
	push 	ds

	lds	bx,[IsTranslucent]
	mov	ah,al			; preserve real pixel
	xlat				; get new al (transluecent pixel
	xchg	ah,al			; get real pixel back into AL just in case
	cmp	ah,255
	je	short normal_pixel		; is it a translucent ?
					; if we get passed here value in
					; AH should be 0-15

	; yes, it is a translucent colour so goto our translucent translation
	; table and set up a ptr to the correct table

	mov	al,[es:di]
					; mov pixel at destination to al and we have
					; the index to the translation table
					; ((trans_colour * 256) + dest colour)
	lds	bx,[Translucent]	; get the ptr to it!
	add	bh,ah			; Add the (trans_color * 256) of the translation equ.
					; XLAT only uses AL so no need to clear AH
	xlat				; get new pixel in AL

normal_pixel:
	pop	ds
	pop	bx
	mov	ah,bh
;---

	mov	[es:di],al		; store the pixel to the screen

skip:
	inc	di
	loop	loop_top
	ret

	ENDP


;***************************************************************************
;* GHOST_PRIORITY_DRAW -- Function that writes a pixels if they are in fron*
;*		    the given plate.					   *
;*                                                                         *
;* INPUT:	cx    - number of pixels to write                          *
;*		ds:si - buffer which holds the pixels to write		   *
;*		es:di - place to put the pixels we are writing		   *
;*                                                                         *
;* OUTPUT:      ds:si - points to next pixel past last pixel read          *
;*		es:di - points to next pixel past last pixel written	   *
;*                                                                         *
;* WARNINGS:    none                                                       *
;*                                                                         *
;* HISTORY:                                                                *
;*   07/17/1992 PWG : Created.                                             *
;*   12/01/1992 MBL : Updated to work with latest mask data encoding.      *
;*   05/27/1993 MCC : Updated to use the new Ghosting fx		   *
;*   17/01/1993 MCC : Updated for 386, and optimized			   *
;*=========================================================================*
	PROC	NOLANGUAGE Ghost_Priority_Draw NEAR

	mov	fs,[background]		; get the SEG of the background page
	mov	gs,[maskpage]		; get the SEG of the mask info
	mov	ah,[priority]		; keep a copy of priority varible for faster cmp


loop_top:
	lodsb				; get the pixel to draw on the screen
					; get the mask byte for our pixel
	mov	bl,[ds:di]
					; get rid of non-walkable bit and
					; get rid of scaling id bits
	and	bl,CLEAR_NON_WALK_BIT_AND_SCALE_BITS
	cmp	ah,bl			; are we more toward the front?
	jge	short out_pixel	; if so then write the pixel

	mov	al,[fs:di]		; get the pixel to write
out_pixel:
	stosb				; write the pixel and inc the DI
	loop	loop_top

	ret

	ENDP


;***************************************************************************
;* GHOST_PRIORITY_TRANSPARENT_DRAW -- Function that writes a pixels if they*
;*		    in front of the given plate.  It also deals with	   *
;*		    transparent pixels.					   *
;*                                                                         *
;* INPUT:	cx    - number of pixels to write                          *
;*		ds:si - buffer which holds the pixels to write		   *
;*		es:di - place to put the pixels we are writing		   *
;*                                                                         *
;* OUTPUT:      ds:si - points to next pixel past last pixel read          *
;*		es:di - points to next pixel past last pixel written	   *
;*                                                                         *
;* WARNINGS:    none                                                       *
;*                                                                         *
;* HISTORY:                                                                *
;*   07/17/1992 PWG : Created.                                             *
;*   12/01/1992 MBL : Updated to work with latest mask data encoding.      *
;*   05/27/1993 MCC : Updated to use the new Ghosting fx		   *
;*   17/01/1993 MCC : Updated for 386, and optimized			   *
;*=========================================================================*
	PROC	NOLANGUAGE Ghost_Priority_Transparent_Draw NEAR

	mov	fs,[background]		; get the SEG of the background page
	mov	gs,[maskpage]		; get the SEG of the mask info
	mov	ah,[priority]		; keep a copy of priority varible for faster cmp

loop_top:
	lodsb				; get the pixel on the screen
	or	al,al			; check to see if al is transparent
	je	short write_back	;   if it is go write background
	mov	bl,[gs:di]		; get the mask byte for our pixel
					; get rid of non-walkable bit and
					; get rid of scaling id bits
	and	bl,CLEAR_NON_WALK_BIT_AND_SCALE_BITS
	cmp	ah,bl			; are we more toward the front?
	jge	short out_pixel	; if so then write the pixel
write_back:
	mov	al,[fs:di]		; get the pixel to write
out_pixel:
	stosb				; write the pixel
	loop	loop_top

	ret

	ENDP

	END

