10 KiB
.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