greed/CODE/RA_DRAW.ASM
2014-12-12 00:00:00 +00:00

508 lines
12 KiB
NASM

;***************************************************************************/
;* */
;* */
;* Raven 3D Engine */
;* Copyright (C) 1995 by Softdisk Publishing */
;* */
;* Original Design: */
;* John Carmack of id Software */
;* */
;* Enhancements by: */
;* Robert Morgan of Channel 7............................Main Engine Code */
;* Todd Lewis of Softdisk Publishing......Tools,Utilities,Special Effects */
;* John Bianca of Softdisk Publishing..............Low-level Optimization */
;* Carlos Hasan..........................................Music/Sound Code */
;* */
;* */
;***************************************************************************/
.386
.MODEL small
SKIPPRIMITIVES = 0 ; set to 1 to skip unwound drawing
INCLUDE viewsize.inc
INCLUDE macros.inc
SCREENWIDTH = 320
PEL_WRITE_ADR = 03c8h
PEL_DATA = 03c9h
.DATA
EXTRN viewbuffer:WORD
EXTRN viewLocation:DWORD
EXTRN viewylookup;DWORD
EXTRN windowSize:DWORD
EXTRN windowWidth:DWORD
EXTRN windowHeight:DWORD
.CODE
;============================================================================
;
; RF_BlitView
;
;============================================================================
public RF_BlitView
RF_BlitView proc near
push ebx
push esi
push edi
mov esi, OFFSET viewbuffer
mov edi, [viewLocation]
mov eax, [windowWidth]
cmp eax, SCREENWIDTH
jne @@slowblit
mov ecx, [windowSize]
shr ecx, 2
rep movsd
pop edi
pop esi
pop ebx
ret
ALIGN 4
@@slowblit:
mov ebx, [windowHeight]
mov edx, SCREENWIDTH
sub edx, eax
shr eax, 2
ALIGN 4
@@blitloop1:
mov ecx, eax
rep movsd
add edi, edx
dec ebx
jnz @@blitloop1
pop edi
pop esi
pop edi
ret
RF_BlitView endp
;============================================================================
;
; unwound vertical scaling code
;
; eax light table pointer, 0 lowbyte overwritten
; ebx all 0, low byte overwritten
; ecx fractional step value
; edx fractional scale value
; esi start of source pixels
; edi bottom pixel in screenbuffer to blit into
;
; ebx should be set to 0 0 0 dh to feed the pipeline
;============================================================================
; the assembler creates vscale<MAXWINDOWHEIGHT-1>: numbers of the following
; code segement. LINE is used as the arg to SCALELABEL. there exists
; vscale<MAXWINDOWHEIGHT: to vscale0: units of code. vscale0 is used as
; the exit point.
SCALELABEL MACRO number
vscale&number:
ENDM
LINE = MAXWINDOWHEIGHT
REPT MAXWINDOWHEIGHT - 1
SCALELABEL %LINE ; LINE represents how many
; ypixels need to be drawn
mov al,[esi+ebx] ; get source pixel
add edx, ecx ; calculate next location
and edx, ebp ; ebp=sp_loopvalue
mov al,[eax] ; translate the color
xor ebx,ebx ; clear ebx
shld ebx,edx,16 ; get address of next location
mov [edi-(LINE-1)*MAXWINDOWWIDTH],al
LINE = LINE - 1
ENDM
vscale1:
mov al,[esi+ebx]
mov al,[eax]
mov [edi],al
vscale0:
ret
.DATA
; the following 2 macros allocate a block of dd or 4 byte locations that are
; ALIGN'ed on a 4 byte or 32 bit boundary. the starting 4 bytes may be
; referred to as scalecalls. the others may not because in the macro
; SCALEDEFINE they are not given a name. the label scalecalls refers to a
; position in the code which happens to be the start of the allocated block. there are
; MAXWINDOWHEIGHT + 1 4 byte word's are allocated and each word is initialized
; with the address of vscale<LINE>:. the value of LINE ranges from 0 to
; MAXWINDOWWIDTH. scalecalls is made visible to the other modules with the
; PUBLIC directive.
SCALEDEFINE MACRO number
dd vscale&number
ENDM
ALIGN 4
scalecalls LABEL UNKNOWN
LINE = 0
REPT MAXWINDOWHEIGHT + 1
SCALEDEFINE %LINE
LINE = LINE + 1
ENDM
scalecall dd 0
PUBLIC scalecalls
;=================================================
;
; parameters for RN_ScalePost
;
sp_dest dd 0
sp_count dd 0
sp_fracstep dd 0
sp_frac dd 0
sp_source dd 0
sp_colormap dd 0
sp_loopvalue dd 0
sp_call dd 0
PUBLIC sp_dest, sp_count, sp_fracstep, sp_frac, sp_source, sp_colormap, sp_loopvalue
.CODE
;================
;
; ScalePost
;
;================
PUBLIC ScalePost
ScalePost proc near
IFE SKIPPRIMITIVES
push ebp
mov ebp,[sp_count]
mov eax,[scalecalls+ebp*4]
mov [sp_call],eax
mov edx,[sp_frac]
mov ecx,[sp_fracstep]
mov esi,[sp_source]
mov eax,[sp_colormap]
mov edi,[sp_dest]
xor ebx,ebx
shld ebx,edx,16 ; get address of first location
mov ebp, [sp_loopvalue]
dec ebp
call [sp_call]
ENDIF
pop ebp
ret
ScalePost endp
;============================================================================
@Proc GetScaleRoutines
mov eax,OFFSET vscale200
@exitp
ENDP
;
;============================================================================
;
; unwound masked vertical scaling code
;
; eax light table pointer, 0 lowbyte overwritten
; ebx all 0, low byte overwritten
; ecx all 0, low byte overwritten
; edx fractional scale value
; esi start of source pixels
; edi bottom pixel in screenbuffer to blit into
; ebp fractional step value
;
; ebx should be set to 0 0 0 dh to feed the pipeline
;============================================================================
; the assembler creates mvscale<MAXWINDOWHEIGHT-1>: numbers of the following
; code segement. all sections of the code are ALINGN'ed on a 32 bit
; boundary. LINE is used as the arg to MSCALELABEL. there exists
; mvscale<MAXWINDOWHEIGHT: to mvscale0: units of code. mvscale0 is used as
; the exit point.
ALIGN 4
MSCALELABEL MACRO number
mvscale&number:
ENDM
LINE = MAXWINDOWHEIGHT
REPT MAXWINDOWHEIGHT - 1
MSCALELABEL %LINE
mov al,[esi+ebx] ; get source pixel
add edx,ebp ; calculate next location
and edx, [sp_loopvalue]
mov cl,al ; save original color for jcxz
mov al,[eax] ; translate the color
xor ebx,ebx
shld ebx,edx,16 ; get address of next location
jcxz $+9 ; jumps 14 bytes to start of next macro
mov [edi-(LINE-1)*MAXWINDOWWIDTH],al ; draw a pixel to the buffer
LINE = LINE - 1
ENDM
mvscale1:
jcxz mvscale0
mov [edi], al
mvscale0:
ret
.DATA
; the following 2 macros allocate a block of dd or 4 byte locations that are
; ALIGN'ed on a 4 byte or 32 bit boundary. the starting 4 bytes may be
; referred to as mscalecalls. the others may not because in the macro
; MSCALEDEFINE they are not given a name. the label mscalecalls refers to a
; position in the code which happens to be the start of the allocated block. there are
; MAXWINDOWHEIGHT + 1 4 byte word's are allocated and each word is initialized
; with the address of mvscalev<LINE:. the value of LINE ranges from 0 to
; to MAXWINDOWHEIGHT. mscalecalls is made visible to the other modules with
; the PUBLIC directive.
MSCALEDEFINE MACRO number
dd mvscale&number
ENDM
ALIGN 4
mscalecalls LABEL UNKNOWN
LINE = 0
REPT MAXWINDOWHEIGHT + 1
MSCALEDEFINE %LINE
LINE = LINE + 1
ENDM
PUBLIC mscalecalls
mscalecall dd 0
.CODE
;================
;
; ScaleMaskedPost
;
; Same parameters as ScalePost, but 0 pixels are not drawn
;
;================
PUBLIC ScaleMaskedPost
ScaleMaskedPost proc near
IFE SKIPPRIMITIVES
push ebp
mov ebp,[sp_count]
mov eax,[mscalecalls+ebp*4]
mov [mscalecall],eax
mov edx,[sp_frac]
mov ebp,[sp_fracstep]
mov esi,[sp_source]
mov eax,[sp_colormap]
mov edi,[sp_dest]
xor ebx,ebx
xor ecx,ecx
shld ebx,edx,16 ; get address of first location
dec [sp_loopvalue]
call [mscalecall]
ENDIF
pop ebp
ret
ScaleMaskedPost endp
;============================================================================
@Proc GetMScaleRoutines
mov eax,OFFSET mvscale200
@exitp
ENDP
;============================================================================
;
; unwound horizontal texture mapping code
;
; eax lighttable
; ebx xtotal 6 bits units 26 bits frac
; ecx ytotal 6 bits units 26 bits frac
; edx xstep
; esi start of block
; edi dest
; ebp scratch offset
;
; [ystep]
;
; ebp should by preset from ebx / ecx before calling
;============================================================================
; the assembler creates hmap<MAXWINDOWWIDTH>: numbers of the following
; code segement. all sections of the code are not ALINGN'ed on a 32 bit
; boundary. LINE is used as the arg to MAPLABEL. there exists
; hmapMAXWINDOWWIDTH: to hmap0: units of code. map0 is used as the exit
; point.
MAPLABEL MACRO number
hmap&number:
ENDM
LINE = MAXWINDOWWIDTH
REPT MAXWINDOWWIDTH
MAPLABEL %LINE
mov al,[esi+ebp] ; get source pixel
add ebx,edx ; xtotal += xstep
add ecx,[ystep] ; ytotal += ystep
xor ebp,ebp
mov al,[eax] ; translate color
shld ebp,ecx,6 ; shift in new y/x position
shld ebp,ebx,6
mov [edi-(LINE-1)],al ; write pixel
LINE = LINE - 1
ENDM
hmap0:
ret
.DATA
ystep dd 0
mapcall dd 0
; the following 2 macros allocate a block of dd or 4 byte locations that are
; ALIGN'ed on a 4 byte or 32 bit boundary. the starting 4 bytes may be
; referred to as mapcalls. the others may not because in the macro MAPDEFINE
; they are not given a name. the label mapcalls refers to a position in the
; code which happens to be the start of the allocated block. there are
; MAXWINDOWWIDTH + 1 4 byte word's are allocated and each word is initialized
; with the address of hmap<LINE>:. the value of LINE ranges from 0 to
; MAXWINDOWWIDTH. mapcalls is made visible to the other modules with the
; PUBLIC directive.
MAPDEFINE MACRO number
dd hmap&number
ENDM
ALIGN 4
mapcalls LABEL UNKNOWN
LINE = 0
REPT MAXWINDOWWIDTH + 1
MAPDEFINE %LINE
LINE = LINE + 1
ENDM
PUBLIC mapcalls
;
; parameters for RN_MapLine
;
mr_dest dd 0 ; pointer to first pixel in view buffer
mr_count dd 0
mr_picture dd 0 ; pointer to 4096 pixel block
mr_colormap dd 0 ; page aligned light table
mr_xfrac dd 0 ; 16 frac bits
mr_yfrac dd 0 ; 16 frac bits
mr_xstep dd 0
mr_ystep dd 0
PUBLIC mr_dest, mr_picture, mr_colormap, mr_xfrac
PUBLIC mr_yfrac, mr_xstep, mr_ystep, mr_count
.CODE
;================
;
; MapRow
;
; Horizontal texture mapping
;
;================
PUBLIC MapRow
MapRow proc near
IFE SKIPPRIMITIVES
push ebp
mov eax,[mr_count]
mov ebx,[mapcalls+eax*4]
mov [mapcall],ebx ; spot to jump into unwound
mov edi,[mr_dest]
add edi,[mr_count]
dec edi
mov eax,[mr_ystep]
shl eax,10
mov [ystep],eax
mov eax,[mr_colormap]
mov ebx,[mr_xfrac]
shl ebx,10
mov ecx,[mr_yfrac]
shl ecx,10
mov edx,[mr_xstep]
shl edx,10
mov esi,[mr_picture]
xor ebp,ebp
shld ebp,ecx,6
shld ebp,ebx,6 ; do first step for pipeline
call [mapcall]
shr ebx,10 ; Rob - these are put back to continue
mov [mr_xfrac],ebx ; for later posts
shr ecx,10 ; very strange!!
mov [mr_yfrac],ecx ;
ENDIF
pop ebp
ret
MapRow endp
END