CnC_Red_Alert/CODE/KEYFBUFF.ASM.BAK

2740 lines
77 KiB
Plaintext

;
; Command & Conquer Red Alert(tm)
; Copyright 2025 Electronic Arts Inc.
;
; This program 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.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
;***************************************************************************
;** 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
;******************************** Includes *********************************
INCLUDE "gbuffer.inc"
;******************************** 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.
;
;---------------------------------------------------------------------------
MACRO USE func, varname
IF WANT
varname DD func
ELSE
varname DD Not_Supported
ENDIF
ENDM
; IFNB <varname>
; GLOBAL varname:DWORD
; ENDIF
;---------------------------------------------------------------------------
DATASEG
;---------------------------------------------------------------------------
; 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
CODESEG
;---------------------------------------------------------------------------
; 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
;---------------------------------------------------------------------------
global _Int3:near
proc _Int3 near
int 3
ret
endp
;***************************************************************************
;* 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. *
;*=========================================================================*
GLOBAL C Buffer_Frame_To_Page:NEAR
PROC Buffer_Frame_To_Page C near
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
cmp [ src ] , 0
jz ??real_out
;====================================================================
; 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
;--------------------------------------------------------------------
; SHAPE_FADING: DWORD fade_table[256], DWORD fade_count
;--------------------------------------------------------------------
??check_fading:
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
;--------------------------------------------------------------------
; 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 , [ (GraphicViewPort esi) . GVPWidth ] ; add width
add eax , [ (GraphicViewPort esi) . GVPXAdd ] ; add x add
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 , [ BufferFrameTable + ebx ] ; get table value
mov [ 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 , [ (GraphicViewPort esi) . 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,[ ( GraphicViewPort esi) . 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
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 , [ (GraphicViewPort esi) . GVPWidth ] ; get width into register
mov [ x1_pixel ] , eax
??dest_right_ok:
test dl , 0001b
jz ??do_blit
mov eax , [ (GraphicViewPort esi) . GVPHeight ] ; get width into register
mov [ y1_pixel ] , eax
??do_blit:
cld
mov eax , [ (GraphicViewPort esi) . GVPXAdd ]
add eax , [ (GraphicViewPort esi) . GVPWidth ]
mov edi , [ (GraphicViewPort esi) . 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
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:
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
; ********************************************************************
BF_Copy:
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
ret
;********************************************************************
;********************************************************************
BF_Trans:
; 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
ret
;********************************************************************
;********************************************************************
BF_Ghost:
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 , [ ??ghost_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Ghost_Trans:
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 , [ ??ghost_t_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Fading:
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 , [ ??fading_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Fading_Trans:
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 , [ ??fading_t_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Ghost_Fading:
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 , [ ??ghost_f_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Ghost_Fading_Trans:
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 , [ ??ghost_f_t_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Predator:
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 , [ ??predator_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Predator_Trans:
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 , [ ??predator_t_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Predator_Ghost:
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 , [ ??predator_g_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Predator_Ghost_Trans:
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 , [ ??predator_g_t_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Predator_Fading:
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 , [ ??predator_f_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Predator_Fading_Trans:
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 , [ ??predator_f_t_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Predator_Ghost_Fading:
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 , [ ??predator_g_f_reference - ??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
ret
;********************************************************************
;********************************************************************
BF_Predator_Ghost_Fading_Trans:
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 , [ ??predator_g_f_t_reference - ??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
ret
;********************************************************************
;********************************************************************
Not_Supported:
ret
ENDP Buffer_Frame_To_Page
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 ??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 ??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
??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