.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, <>, <,> mov eax,op1 imul [op2] shrd eax,edx,16 @exitp <> ENDP @Proc FIXEDDIV, <>, <,> mov eax,op1 cdq shld edx,eax,16 sal eax,16 idiv [op2] @exitp <> ENDP ;============================================================================ ; ; RF_BlitView ; ;============================================================================ @Proc RF_BlitView, 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 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, 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 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, 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 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, 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 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, 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 ENDP END