gzdoom/code/linear.nas
1999-02-17 00:00:00 +00:00

337 lines
5.8 KiB
Text

;****************************************************************************
;*
;* Unwound vertical and horizontal scaling code based loosing on linear.asm
;* from the Heretic/Hexen source. This is probably as optimal as your going
;* to get on a 486. I've taken the liberty of bumping the screen height up
;* to 240 (so it will work with resolutions up to 320x240) and adding in
;* the use of dc_mask.
;*
;****************************************************************************
bits 32
%define SCREENWIDTH 320
%define SCREENHEIGHT 240
extern _dc_colormap
extern _dc_x
extern _dc_yl
extern _dc_yh
extern _dc_iscale
extern _dc_texturemid
extern _dc_source
extern _dc_mask
extern _dc_pitch
extern _ylookup
extern _columnofs
extern _centery
extern _ds_y
extern _ds_x1
extern _ds_x2
extern _ds_colormap
extern _ds_xfrac
extern _ds_yfrac
extern _ds_xstep
extern _ds_ystep
extern _ds_source
extern _ds_colsize
%define PUSHR pushad
%define POPR popad
;============================================================================
;
; unwound vertical scaling code
;
; eax light table pointer, 0 lowbyte overwritten
; ebx integral step value
; ecx integral scale value
; edx fractional scale value, lowbyte has mask
; 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 graphics wrap vertically at 128 pixels
;============================================================================
section .data
%macro SCALEDEFINE 1
dd vscale%1
%endmacro
%define scalesize (vscale2-vscale3)
%define scalepatchoffs (11)
align 4
scalecalls:
%assign LINE 0
%rep SCREENHEIGHT+1
SCALEDEFINE LINE
%assign LINE LINE+1
%endrep
calladdr dd 0
;=================================
section .text
GLOBAL _PatchUnrolled
EXTERN _detailyshift
_PatchUnrolled:
push ebx
push ebp
mov ebx,[_dc_pitch]
mov ecx,SCREENHEIGHT-1
mov ebp,vscale240+scalepatchoffs
mov eax,ecx
neg ebx
imul ebx
.loop mov [ebp],eax
sub eax,ebx
dec ecx
lea ebp,[ebp+scalesize]
jnz .loop
pop ebp
pop ebx
ret
align 16
;================
;
; R_DrawColumn
;
;================
GLOBAL _R_DrawColumnP_Unrolled
GLOBAL @R_DrawColumnP_Unrolled@0
@R_DrawColumnP_Unrolled@0:
_R_DrawColumnP_Unrolled:
PUSHR
mov edx,[_ylookup]
mov ebp,[_dc_yh]
mov ebx,ebp
mov edi,[edx+ebx*4]
mov edx,[_columnofs]
mov ebx,[_dc_x]
add edi,[edx+ebx*4]
mov eax,[_dc_yl]
sub ebp,eax ; ebp = pixel count
or ebp,ebp
js done
mov ebp,[scalecalls+4+ebp*4]
mov ebx,[_dc_iscale]
mov [calladdr],ebp
sub eax,[_centery]
imul ebx
mov edx,[_dc_texturemid]
mov ebp,ebx
add edx,eax
shl ebp,16
shr ebx,16
mov ecx,edx
shl edx,16
shr ecx,16
mov dl,[_dc_mask]
and ebx,[_dc_mask]
mov esi,[_dc_source]
mov eax,[_dc_colormap]
and ecx,edx ; get address of first location
jmp [calladdr]
done:
POPR
ret
%macro SCALELABEL 1
vscale%1:
%endmacro
%assign LINE SCREENHEIGHT
%rep SCREENHEIGHT-1
SCALELABEL LINE
mov al,[esi+ecx] ; get source pixel
add edx,ebp ; calculate next location
mov al,[eax] ; translate the color
adc ecx,ebx
mov [edi-(LINE-1)*SCREENWIDTH],al ; draw a pixel to the buffer
and ecx,edx
%assign LINE LINE-1
%endrep
vscale1:
mov al,[esi+ecx]
mov al,[eax]
mov [edi],al
vscale0:
POPR
ret
;============================================================================
;
; 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
;============================================================================
section .data
%macro MAPDEFINE 1
dd hmap%1
%endmacro
align 4
mapcalls:
%assign LINE SCREENWIDTH-1
%rep SCREENWIDTH
MAPDEFINE LINE
%assign LINE LINE-1
%endrep
callpoint dd 0
section .text
GLOBAL _PatchUnrolledColSize
%define mapsize (hmap1-hmap0)
%define mappatchoffs (mapsize-4)
_PatchUnrolledColSize:
mov eax,[_ds_colsize]
mov ecx,hmap0+mappatchoffs
mov edx,-(SCREENWIDTH-1)
imul edx
mov edx,SCREENWIDTH-1
.loop mov [ecx],eax
add eax,[_ds_colsize]
add ecx,mapsize
dec edx
jnz .loop
ret
;================
;
; R_DrawSpan
;
; Horizontal texture mapping
;
;================
GLOBAL _R_DrawSpanP_Unrolled
GLOBAL @R_DrawSpanP_Unrolled@0
align 16
@R_DrawSpanP_Unrolled@0:
_R_DrawSpanP_Unrolled:
PUSHR
mov edi,[_columnofs]
mov eax,[_ds_x1]
mov ebx,[_ds_x2]
mov edi,[edi+ebx*4]
sub ebx,eax
mov eax,[mapcalls+ebx*4]
mov [callpoint],eax ; spot to jump into unwound
mov eax,[_ylookup]
mov ebx,[_ds_y]
add edi,[eax+ebx*4]
;
; build composite position
;
mov ecx,[_ds_xfrac]
shl ecx,10
and ecx,0xffff0000
mov eax,[_ds_yfrac]
shr eax,6
and eax,0xffff
or ecx,eax
;
; build composite step
;
mov edx,[_ds_xstep]
shl edx,10
and edx,0xffff0000
mov eax,[_ds_ystep]
shr eax,6
and eax,0xffff
or edx,eax
mov esi,[_ds_source]
mov eax,[_ds_colormap]
;
; feed the pipeline and jump in
;
mov ebp,0xfff ; 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
jmp [callpoint]
%macro MAPLABEL 1
hmap%1:
%endmacro
%assign LINE 0
%assign PCOL SCREENWIDTH-1
%rep SCREENWIDTH-1
MAPLABEL LINE
%assign 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-PCOL],al ; write pixel
db 0x88,0x87
dd -PCOL
%assign PCOL PCOL-1
%endrep
hmap319:
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],al ; write pixel
hmap320:
POPR
ret