ravenengine/SOURCE/NEW_DRAW.ASM

475 lines
10 KiB
NASM

.386
.MODEL small
SKIPPRIMITIVES = 0 ; set to 1 to skip unwound drawing
INCLUDE viewsize.inc
INCLUDE macros.inc
SCREEN = 0a0000h
SCREENWIDTH = 320
PEL_WRITE_ADR = 03c8h
PEL_DATA = 03c9h
.DATA
EXTRN viewbuffer:WORD
EXTRN viewLocation:DWORD
EXTRN windowWidth:DWORD
EXTRN windowHeight:DWORD
.CODE
;============================================================================
;
; Fixed point math
;
;============================================================================
@Proc FIXEDMUL, <>, <<op1,DWORD>,<op2,DWORD>>
mov eax,op1
imul [op2]
shrd eax,edx,16
@exitp <>
ENDP
@Proc FIXEDDIV, <>, <<op1,DWORD>,<op2,DWORD>>
mov eax,op1
cdq
shld edx,eax,16
sal eax,16
idiv [op2]
@exitp <>
ENDP
;============================================================================
;
; RF_BlitView
;
;============================================================================
@Proc RF_BlitView, <ebx, esi, edi>
mov esi,OFFSET viewbuffer
mov edi,[viewLocation]
mov ebx,[windowHeight]
mov eax,SCREENWIDTH
sub eax,[windowWidth]
mov edx,eax
mov eax,[windowWidth]
shr eax,2
ALIGN 4
@@blitloop1:
mov ecx,eax
rep movsd
add edi,edx
dec ebx
jnz @@blitloop1
@exitp <ebx, esi, edi>
ENDP
;============================================================================
;
; Merge
;
; merge two parts of the unsorted array to the sorted array
;
;============================================================================
.DATA
EXTRN src1:DWORD
EXTRN src2:DWORD
EXTRN dest:DWORD
EXTRN size1:DWORD
EXTRN size2:DWORD
PUBLIC mergefrom1
PUBLIC finishfrom1
PUBLIC mergefrom2
PUBLIC finishfrom2
PUBLIC mergedone
.CODE
@Proc Merge, <ebx,esi,edi>
mov ebx,[src1]
mov esi,[src2]
mov edi,[dest]
mov ecx,[size1]
mov edx,[size2]
mov eax,[ebx]
cmp eax,[esi]
jb SHORT mergefrom2 ; if (*src1 < *src2) goto mergefrom2;
mergefrom1:
stosd
add ebx,4 ; *dest++ = *src1++;
mov eax,[ebx]
dec ecx
jz finishfrom2 ; if (!--size1) goto finishfrom2;
cmp eax,[esi]
ja SHORT mergefrom1 ; if (*src1 > *src2) goto mergefrom1;
mergefrom2:
movsd ; *dest++ = *src2++;
dec edx
jz finishfrom1 ; if (!--size2) goto finishfrom1;
cmp eax,[esi]
ja SHORT mergefrom1 ; if (*src1 > *src2) goto mergefrom1;
jmp SHORT mergefrom2
ALIGN 4
finishfrom2:
movsd ; *dest++ = *src2++;
dec edx ; while (size2--)
jnz SHORT finishfrom2
jmp SHORT mergedone
ALIGN 4
finishfrom1:
stosd
add ebx,4 ; *dest++ = *src1++;
mov eax,[ebx]
loop SHORT finishfrom1 ; while (size1--)
mergedone:
mov [dest],edi
@exitp <ebx, esi, edi>
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
;============================================================================
SCALELABEL MACRO number
vscale&number:
ENDM
LINE = MAXWINDOWHEIGHT
REPT MAXWINDOWHEIGHT-1
SCALELABEL %LINE
mov al,[esi+ebx] ; get source pixel
add edx,ecx ; calculate next location
mov al,[eax] ; translate the color
xor ebx,ebx
shld ebx,edx,16 ; get address of next location
mov [edi-(LINE-1)*MAXWINDOWWIDTH],al ; draw a pixel to the buffer
LINE = LINE-1
ENDM
vscale1:
mov al,[esi+ebx]
add edx,ecx
mov al,[eax]
mov [edi],al
vscale0:
ret
.DATA
SCALEDEFINE MACRO number
dd vscale&number
ENDM
ALIGN 4
scalecalls LABEL
LINE = 0
REPT MAXWINDOWHEIGHT+1
SCALEDEFINE %LINE
LINE = LINE+1
ENDM
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
PUBLIC sp_dest, sp_count, sp_fracstep, sp_frac, sp_source, sp_colormap
.CODE
;================
;
; ScalePost
;
;================
@Proc ScalePost, <ebx, esi, edi, ebp>
IFE SKIPPRIMITIVES
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_count]
call [scalecalls+ebp*4]
ENDIF
@exitp <ebx, esi, edi, ebp>
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
;============================================================================
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
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
mov [edi-(LINE-1)*MAXWINDOWWIDTH],al ; draw a pixel to the buffer
LINE = LINE-1
ENDM
mvscale1:
mov al,[esi+ebx]
add edx,ecx
mov al,[eax]
test al,0
jz mvscale0
mov [edi],al
mvscale0:
ret
.DATA
MSCALEDEFINE MACRO number
dd mvscale&number
ENDM
ALIGN 4
mscalecalls LABEL
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
;
;================
@Proc ScaleMaskedPost, <ebx, esi, edi, ebp>
IFE SKIPPRIMITIVES
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
call [mscalecall]
ENDIF
@exitp <ebx, esi, edi, ebp>
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
;============================================================================
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
MAPDEFINE MACRO number
dd hmap&number
ENDM
ALIGN 4
mapcalls LABEL
LINE = 0
REPT MAXWINDOWWIDTH+1
MAPDEFINE %LINE
LINE = LINE+1
ENDM
PUBLIC mapcalls
mapcall dd 0
;
; 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,mr_yfrac,mr_xstep,mr_ystep,mr_count
.CODE
;================
;
; MapRow
;
; Horizontal texture mapping
;
;================
@Proc MapRow, <ebx, esi, edi>
IFE SKIPPRIMITIVES
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
mov [mr_xfrac],ebx
shr ecx,10
mov [mr_yfrac],ecx
ENDIF
@exitp <ebx, esi, edi>
ENDP
END