Source to src/linear.asm
.386
.MODEL small
INCLUDE defs.inc
;============================================================================
;
; 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 graphics wrap vertically at 128 pixels
;============================================================================
.DATA
EXTRN _centery:DWORD
SCALEDEFINE MACRO number
dd vscale&number
ENDM
ALIGN 4
scalecalls LABEL
LINE = 0
REPT SCREENHEIGHT+1
SCALEDEFINE %LINE
LINE = LINE+1
ENDM
FUZZSCALEDEFINE MACRO number
dd fuzzvscale&number
ENDM
ALIGN 4
fuzzscalecalls LABEL
LINE = 0
REPT SCREENHEIGHT+1
FUZZSCALEDEFINE %LINE
LINE = LINE+1
ENDM
calladdr dd ?
;=================================
.CODE
;================
;
; R_DrawColumn
;
;================
PROC R_DrawColumn_
PUBLIC R_DrawColumn_
PUSHR
mov ebp,[_dc_yh]
mov ebx,ebp
mov edi,[_ylookup+ebx*4]
mov ebx,[_dc_x]
add edi,[_columnofs + ebx*4]
mov eax,[_dc_yl]
sub ebp,eax ; ebp = pixel count
or ebp,ebp
js done
mov ecx,[_dc_iscale]
sub eax,[_centery]
imul ecx
mov edx,[_dc_texturemid]
add edx,eax
shl edx,9 ; 7 significant bits, 25 frac
shl ecx,9 ; 7 significant bits, 25 frac
mov esi,[_dc_source]
mov eax,[_dc_colormap]
xor ebx,ebx
shld ebx,edx,7 ; get address of first location
call [scalecalls+4+ebp*4]
done:
POPR
ret
;============ HIGH DETAIL ============
SCALELABEL MACRO number
vscale&number:
ENDM
LINE = SCREENHEIGHT
REPT SCREENHEIGHT-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,7 ; get address of next location
mov ebx,edx
shr ebx,25
mov [edi-(LINE-1)*SCREENWIDTH],al ; draw a pixel to the buffer
LINE = LINE-1
ENDM
vscale1:
mov al,[esi+ebx]
mov al,[eax]
mov [edi],al
vscale0:
ret
ENDP
;================
;
; R_DrawFuzz
;
;================
PROC R_DrawFuzzColumn_
PUBLIC R_DrawFuzzColumn_
PUSHR
mov ebp,[_dc_yh]
mov ebx,ebp
mov edi,[_ylookup+ebx*4]
mov ebx,[_dc_x]
add edi,[_columnofs + ebx*4]
mov eax,[_dc_yl]
sub ebp,eax ; ebp = pixel count
or ebp,ebp
js fuzzdone
mov ecx,[_dc_iscale]
sub eax,[_centery]
imul ecx
mov edx,[_dc_texturemid]
add edx,eax
shl edx,9 ; 7 significant bits, 25 frac
shl ecx,9 ; 7 significant bits, 25 frac
mov esi,[_dc_source]
mov eax,[_dc_colormap]
xor ebx,ebx
shld ebx,edx,7 ;get address of first location
mov ebp, [fuzzscalecalls+4+ebp*4]
mov calladdr, ebp
mov ebp, ecx
xor ecx, ecx
call [calladdr]
fuzzdone:
POPR
ret
FUZZSCALELABEL MACRO number
fuzzvscale&number:
ENDM
LINE = SCREENHEIGHT
REPT SCREENHEIGHT-1
FUZZSCALELABEL %LINE
mov al, byte ptr [esi+ebx] ; get source pixel
add edx, ebp ; calculate next location
mov cl, byte ptr [edi-(LINE-1)*SCREENWIDTH]
mov ch, [eax]
add ecx, [_tinttable]
mov ebx, edx
shr ebx, 25
mov al, [ecx]
mov [edi-(LINE-1)*SCREENWIDTH],al ; draw a pixel to the buffer
xor ecx, ecx
LINE = LINE-1
ENDM
fuzzvscale1:
mov al,[esi+ebx]
mov cl, byte ptr [edi-(LINE-1)*SCREENWIDTH]
mov ch, [eax]
add ecx, [_tinttable]
mov al, [ecx]
mov [edi],al
fuzzvscale0:
ret
ENDP
;============================================================================
;
; unwound horizontal texture mapping code
;
; eax lighttable
; ebx scratch register
; ecx position 6.10 bits x, 6.10 bits y
; edx step 6.10 bits x, 6.10 bits y
; esi start of block
; edi dest
; ebp fff to mask bx
;
; ebp should by preset from ebx / ecx before calling
;============================================================================
OP_SHLD = 0fh
.DATA
MAPDEFINE MACRO number
dd hmap&number
ENDM
ALIGN 4
mapcalls LABEL
LINE = 0
REPT SCREENWIDTH+1
MAPDEFINE %LINE
LINE = LINE+1
ENDM
callpoint dd 0
returnpoint dd 0
.CODE
;================
;
; R_DrawSpan
;
; Horizontal texture mapping
;
;================
PROC R_DrawSpan_
PUBLIC R_DrawSpan_
PUSHR
IFE SKIPPRIMITIVES
mov eax,[_ds_x1]
mov ebx,[_ds_x2]
mov eax,[mapcalls+eax*4]
mov [callpoint],eax ; spot to jump into unwound
mov eax,[mapcalls+4+ebx*4]
mov [returnpoint],eax ; spot to patch a ret at
mov BYTE PTR [eax], OP_RET
;
; build composite position
;
mov ecx,[_ds_xfrac]
shl ecx,10
and ecx,0ffff0000h
mov eax,[_ds_yfrac]
shr eax,6
and eax,0ffffh
or ecx,eax
;
; build composite step
;
mov edx,[_ds_xstep]
shl edx,10
and edx,0ffff0000h
mov eax,[_ds_ystep]
shr eax,6
and eax,0ffffh
or edx,eax
mov esi,[_ds_source]
mov edi,[_ds_y]
mov edi,[_ylookup+edi*4]
add edi,[_columnofs]
mov eax,[_ds_colormap]
;
; feed the pipeline and jump in
;
mov ebp,0fffh ; used to mask off slop high bits from position
shld ebx,ecx,22 ; shift y units in
shld ebx,ecx,6 ; shift x units in
and ebx,ebp ; mask off slop bits
call [callpoint]
mov ebx,[returnpoint]
mov BYTE PTR [ebx],OP_MOVAL ; remove the ret patched in
ENDIF
POPR
ret
;============= HIGH DETAIL ============
.CODE
MAPLABEL MACRO number
hmap&number:
ENDM
LINE = 0
PCOL = 0
REPT SCREENWIDTH/4
PLANE = 0
REPT 4
MAPLABEL %LINE
LINE = LINE + 1
mov al,[esi+ebx] ; get source pixel
shld ebx,ecx,22 ; shift y units in
shld ebx,ecx,6 ; shift x units in
mov al,[eax] ; translate color
and ebx,ebp ; mask off slop bits
add ecx,edx ; position += step
mov [edi+PLANE+PCOL*4],al ; write pixel
PLANE = PLANE + 1
ENDM
PCOL = PCOL + 1
ENDM
hmap320:
ret
ENDP
END