740 lines
15 KiB
NASM
740 lines
15 KiB
NASM
|
IDEAL
|
||
|
MODEL MEDIUM,C
|
||
|
P286
|
||
|
|
||
|
SCREENSEG = 0a000h
|
||
|
|
||
|
FINEANGLES = 3600
|
||
|
DEG90 = 900
|
||
|
DEG180 = 1800
|
||
|
DEG270 = 2700
|
||
|
DEG360 = 3600
|
||
|
|
||
|
OP_JLE = 07eh
|
||
|
OP_JGE = 07dh
|
||
|
|
||
|
EXTRN finetangent:DWORD ; far array, starts at offset 0
|
||
|
|
||
|
EXTRN HitHorizWall:FAR
|
||
|
EXTRN HitVertWall:FAR
|
||
|
EXTRN HitHorizDoor:FAR
|
||
|
EXTRN HitVertDoor:FAR
|
||
|
EXTRN HitHorizPWall:FAR
|
||
|
EXTRN HitVertPWall:FAR
|
||
|
|
||
|
|
||
|
DATASEG
|
||
|
|
||
|
EXTRN viewwidth:WORD
|
||
|
|
||
|
EXTRN tilemap:BYTE
|
||
|
EXTRN spotvis:BYTE
|
||
|
EXTRN pixelangle:WORD
|
||
|
|
||
|
|
||
|
EXTRN midangle:WORD
|
||
|
EXTRN angle:WORD
|
||
|
|
||
|
EXTRN focaltx:WORD
|
||
|
EXTRN focalty:WORD
|
||
|
EXTRN viewtx:WORD
|
||
|
EXTRN viewty:WORD
|
||
|
EXTRN viewx:DWORD
|
||
|
EXTRN viewy:DWORD
|
||
|
|
||
|
EXTRN xpartialup:WORD
|
||
|
EXTRN ypartialup:WORD
|
||
|
EXTRN xpartialdown:WORD
|
||
|
EXTRN ypartialdown:WORD
|
||
|
|
||
|
EXTRN tilehit:WORD
|
||
|
EXTRN pixx:WORD
|
||
|
EXTRN wallheight:WORD ; array of VIEWWIDTH entries
|
||
|
|
||
|
EXTRN xtile:WORD
|
||
|
EXTRN ytile:WORD
|
||
|
EXTRN xtilestep:WORD
|
||
|
EXTRN ytilestep:WORD
|
||
|
EXTRN xintercept:DWORD
|
||
|
EXTRN yintercept:DWORD
|
||
|
EXTRN xstep:DWORD
|
||
|
EXTRN ystep:DWORD
|
||
|
|
||
|
EXTRN doorposition:WORD ; table of door position values
|
||
|
|
||
|
|
||
|
EXTRN pwallpos:WORD ; amound a pushable wall has been moved
|
||
|
|
||
|
CODESEG
|
||
|
|
||
|
;-------------------
|
||
|
;
|
||
|
; xpartialbyystep
|
||
|
;
|
||
|
; multiplies long [ystep] (possibly negative), by word [xpartial] (in BX)
|
||
|
;
|
||
|
; returns dx:ax
|
||
|
; trashes bx,cx,di
|
||
|
;
|
||
|
;-------------------
|
||
|
|
||
|
PROC xpartialbyystep NEAR
|
||
|
;
|
||
|
; setup
|
||
|
;
|
||
|
mov ax,[WORD ystep]
|
||
|
mov cx,[WORD ystep+2]
|
||
|
or cx,cx ; is ystep negatice?
|
||
|
jns @@multpos
|
||
|
;
|
||
|
; multiply negative cx:ax by bx
|
||
|
;
|
||
|
neg cx
|
||
|
neg ax
|
||
|
sbb cx,0
|
||
|
|
||
|
mul bx ; fraction*fraction
|
||
|
mov di,dx ; di is low word of result
|
||
|
mov ax,cx ;
|
||
|
mul bx ; units*fraction
|
||
|
add ax,di
|
||
|
adc dx,0
|
||
|
|
||
|
neg dx
|
||
|
neg ax
|
||
|
sbb dx,0
|
||
|
ret
|
||
|
;
|
||
|
; multiply positive cx:ax by bx
|
||
|
;
|
||
|
EVEN
|
||
|
@@multpos:
|
||
|
mul bx ; fraction*fraction
|
||
|
mov di,dx ; di is low word of result
|
||
|
mov ax,cx ;
|
||
|
mul bx ; units*fraction
|
||
|
add ax,di
|
||
|
adc dx,0
|
||
|
|
||
|
ret
|
||
|
|
||
|
ENDP
|
||
|
|
||
|
|
||
|
|
||
|
;-------------------
|
||
|
;
|
||
|
; ypartialbyxstep
|
||
|
;
|
||
|
; multiplies long [xstep] (possibly negative), by word [ypartial] (in BP)
|
||
|
;
|
||
|
; returns dx:ax
|
||
|
; trashes cx,di,bp
|
||
|
;
|
||
|
;-------------------
|
||
|
|
||
|
PROC ypartialbyxstep NEAR
|
||
|
;
|
||
|
; setup
|
||
|
;
|
||
|
mov ax,[WORD xstep]
|
||
|
mov cx,[WORD xstep+2]
|
||
|
or cx,cx ; is ystep negatice?
|
||
|
jns @@multpos
|
||
|
;
|
||
|
; multiply negative cx:ax by bx
|
||
|
;
|
||
|
neg cx
|
||
|
neg ax
|
||
|
sbb cx,0
|
||
|
|
||
|
mul bp ; fraction*fraction
|
||
|
mov di,dx ; di is low word of result
|
||
|
mov ax,cx ;
|
||
|
mul bp ; units*fraction
|
||
|
add ax,di
|
||
|
adc dx,0
|
||
|
|
||
|
neg dx
|
||
|
neg ax
|
||
|
sbb dx,0
|
||
|
ret
|
||
|
;
|
||
|
; multiply positive cx:ax by bx
|
||
|
;
|
||
|
EVEN
|
||
|
@@multpos:
|
||
|
mul bp ; fraction*fraction
|
||
|
mov di,dx ; di is low word of result
|
||
|
mov ax,cx ;
|
||
|
mul bp ; units*fraction
|
||
|
add ax,di
|
||
|
adc dx,0
|
||
|
ret
|
||
|
|
||
|
ENDP
|
||
|
|
||
|
|
||
|
;============================
|
||
|
;
|
||
|
; AsmRefresh
|
||
|
;
|
||
|
;
|
||
|
;============================
|
||
|
|
||
|
PROC AsmRefresh
|
||
|
PUBLIC AsmRefresh
|
||
|
|
||
|
push si
|
||
|
push di
|
||
|
push bp
|
||
|
|
||
|
mov [pixx],0
|
||
|
;---------------------------------------------------------------------------
|
||
|
;
|
||
|
; Setup to trace a ray through pixx view pixel
|
||
|
;
|
||
|
; CX : angle of the ray through pixx
|
||
|
; ES : points to segment of finetangent array for this block of code
|
||
|
;
|
||
|
; Upon entrance to initialize block
|
||
|
;
|
||
|
; BX : xpartial
|
||
|
; BP : ypartial
|
||
|
;
|
||
|
;---------------------------------------------------------------------------
|
||
|
EVEN
|
||
|
pixxloop:
|
||
|
mov ax,SEG finetangent
|
||
|
mov es,ax
|
||
|
mov cx,[midangle] ; center of view area
|
||
|
mov bx,[pixx]
|
||
|
shl bx,1
|
||
|
add cx,[pixelangle+bx] ; delta for this pixel
|
||
|
cmp cx,0
|
||
|
jge not0
|
||
|
;----------
|
||
|
;
|
||
|
; -90 - -1 degree arc
|
||
|
;
|
||
|
;----------
|
||
|
add cx,FINEANGLES ; -90 is the same as 270
|
||
|
jmp entry360
|
||
|
|
||
|
not0:
|
||
|
cmp cx,DEG90
|
||
|
jge not90
|
||
|
;----------
|
||
|
;
|
||
|
; 0-89 degree arc
|
||
|
;
|
||
|
;----------
|
||
|
entry90:
|
||
|
mov [xtilestep],1 ; xtilestep = 1
|
||
|
mov [ytilestep],-1 ; ytilestep = -1
|
||
|
mov [BYTE cs:horizop],OP_JGE ; patch a jge in
|
||
|
mov [BYTE cs:vertop],OP_JLE ; patch a jle in
|
||
|
mov bx,DEG90-1
|
||
|
sub bx,cx
|
||
|
shl bx,2
|
||
|
mov ax,[es:bx]
|
||
|
mov dx,[es:bx+2]
|
||
|
mov [WORD xstep],ax
|
||
|
mov [WORD xstep+2],dx ; xstep = finetangent[DEG90-1-angle]
|
||
|
mov bx,cx
|
||
|
shl bx,2
|
||
|
mov ax,[es:bx]
|
||
|
mov dx,[es:bx+2]
|
||
|
neg dx
|
||
|
neg ax
|
||
|
sbb dx,0
|
||
|
mov [WORD ystep],ax
|
||
|
mov [WORD ystep+2],dx ; ystep = -finetangent[angle]
|
||
|
|
||
|
mov bx,[xpartialup] ; xpartial = xpartialup
|
||
|
mov bp,[ypartialdown] ; ypartial = ypartialdown
|
||
|
jmp initvars
|
||
|
|
||
|
not90:
|
||
|
cmp cx,DEG180
|
||
|
jge not180
|
||
|
;----------
|
||
|
;
|
||
|
; 90-179 degree arc
|
||
|
;
|
||
|
;----------
|
||
|
mov ax,-1
|
||
|
mov [xtilestep],ax ; xtilestep = -1
|
||
|
mov [ytilestep],ax ; ytilestep = -1
|
||
|
mov [BYTE cs:horizop],OP_JLE ; patch a jle in
|
||
|
mov [BYTE cs:vertop],OP_JLE ; patch a jle in
|
||
|
|
||
|
mov bx,cx
|
||
|
shl bx,2
|
||
|
mov ax,[es:bx-DEG90*4]
|
||
|
mov dx,[es:bx+2-DEG90*4]
|
||
|
neg dx
|
||
|
neg ax
|
||
|
sbb dx,0
|
||
|
mov [WORD xstep],ax
|
||
|
mov [WORD xstep+2],dx ; xstep = -finetangent[angle-DEG90]
|
||
|
mov bx,DEG180-1
|
||
|
sub bx,cx
|
||
|
shl bx,2
|
||
|
mov ax,[es:bx]
|
||
|
mov dx,[es:bx+2]
|
||
|
neg dx
|
||
|
neg ax
|
||
|
sbb dx,0
|
||
|
mov [WORD ystep],ax
|
||
|
mov [WORD ystep+2],dx ; ystep = -finetangent[DEG180-1-angle]
|
||
|
|
||
|
mov bx,[xpartialdown] ; xpartial = xpartialdown
|
||
|
mov bp,[ypartialdown] ; ypartial = ypartialdown
|
||
|
jmp initvars
|
||
|
|
||
|
not180:
|
||
|
cmp cx,DEG270
|
||
|
jge not270
|
||
|
;----------
|
||
|
;
|
||
|
; 180-269 degree arc
|
||
|
;
|
||
|
;----------
|
||
|
mov [xtilestep],-1 ; xtilestep = -1
|
||
|
mov [ytilestep],1 ; ytilestep = 1
|
||
|
mov [BYTE cs:horizop],OP_JLE ; patch a jle in
|
||
|
mov [BYTE cs:vertop],OP_JGE ; patch a jge in
|
||
|
|
||
|
mov bx,DEG270-1
|
||
|
sub bx,cx
|
||
|
shl bx,2
|
||
|
mov ax,[es:bx]
|
||
|
mov dx,[es:bx+2]
|
||
|
neg dx
|
||
|
neg ax
|
||
|
sbb dx,0
|
||
|
mov [WORD xstep],ax
|
||
|
mov [WORD xstep+2],dx ; xstep = -finetangent[DEG270-1-angle]
|
||
|
mov bx,cx
|
||
|
shl bx,2
|
||
|
mov ax,[es:bx-DEG180*4]
|
||
|
mov dx,[es:bx+2-DEG180*4]
|
||
|
mov [WORD ystep],ax
|
||
|
mov [WORD ystep+2],dx ; ystep = finetangent[angle-DEG180]
|
||
|
|
||
|
mov bx,[xpartialdown] ; xpartial = xpartialdown
|
||
|
mov bp,[ypartialup] ; ypartial = ypartialup
|
||
|
jmp initvars
|
||
|
|
||
|
|
||
|
not270:
|
||
|
cmp cx,DEG360
|
||
|
jge not360
|
||
|
;----------
|
||
|
;
|
||
|
; 270-359 degree arc
|
||
|
;
|
||
|
;----------
|
||
|
entry360:
|
||
|
mov ax,1
|
||
|
mov [xtilestep],ax ; xtilestep = 1
|
||
|
mov [ytilestep],ax ; ytilestep = 1
|
||
|
mov [BYTE cs:horizop],OP_JGE ; patch a jge in
|
||
|
mov [BYTE cs:vertop],OP_JGE ; patch a jge in
|
||
|
|
||
|
mov bx,cx
|
||
|
shl bx,2
|
||
|
mov ax,[es:bx-DEG270*4]
|
||
|
mov dx,[es:bx+2-DEG270*4]
|
||
|
mov [WORD xstep],ax
|
||
|
mov [WORD xstep+2],dx ; xstep = finetangent[angle-DEG270]
|
||
|
mov bx,DEG360-1
|
||
|
sub bx,cx
|
||
|
shl bx,2
|
||
|
mov ax,[es:bx]
|
||
|
mov dx,[es:bx+2]
|
||
|
mov [WORD ystep],ax
|
||
|
mov [WORD ystep+2],dx ; ystep = finetangent[DEG360-1-angle]
|
||
|
|
||
|
mov bx,[xpartialup] ; xpartial = xpartialup
|
||
|
mov bp,[ypartialup] ; ypartial = ypartialup
|
||
|
jmp initvars
|
||
|
|
||
|
|
||
|
not360:
|
||
|
;----------
|
||
|
;
|
||
|
; 360-449 degree arc
|
||
|
;
|
||
|
;----------
|
||
|
sub cx,FINEANGLES ; -449 is the same as 89
|
||
|
jmp entry90
|
||
|
|
||
|
;---------------------------------------------------------------------------
|
||
|
;
|
||
|
; initialise variables for intersection testing
|
||
|
;
|
||
|
;---------------------------------------------------------------------------
|
||
|
initvars:
|
||
|
call NEAR xpartialbyystep ; xpartial is in BX
|
||
|
add ax,[WORD viewy]
|
||
|
adc dx,[WORD viewy+2]
|
||
|
mov [WORD yintercept],ax
|
||
|
mov [WORD yintercept+2],dx
|
||
|
|
||
|
mov si,[focaltx]
|
||
|
add si,[xtilestep]
|
||
|
mov [xtile],si ; xtile = focaltx+xtilestep
|
||
|
shl si,6
|
||
|
add si,dx ; xspot = (xtile<<6) + yinttile
|
||
|
|
||
|
|
||
|
call NEAR ypartialbyxstep ; ypartial is in BP
|
||
|
add ax,[WORD viewx]
|
||
|
adc dx,[WORD viewx+2]
|
||
|
mov [WORD xintercept],ax
|
||
|
mov cx,dx
|
||
|
|
||
|
mov bx,[focalty]
|
||
|
add bx,[ytilestep]
|
||
|
mov bp,bx ; ytile = focalty+ytilestep
|
||
|
mov di,dx
|
||
|
shl di,6
|
||
|
add di,bx ; yspot = (xinttile<<6) + ytile
|
||
|
|
||
|
mov bx,[xtile]
|
||
|
mov dx,[WORD yintercept+2]
|
||
|
mov ax,SCREENSEG
|
||
|
mov es,ax ; faster than mov es,[screenseg]
|
||
|
|
||
|
|
||
|
;---------------------------------------------------------------------------
|
||
|
;
|
||
|
; trace along this angle until we hit a wall
|
||
|
;
|
||
|
; CORE LOOP!
|
||
|
;
|
||
|
; All variables are killed when a wall is hit
|
||
|
;
|
||
|
; AX : scratch
|
||
|
; BX : xtile
|
||
|
; CX : high word of xintercept
|
||
|
; DX : high word of yintercept
|
||
|
; SI : xspot (yinttile<<6)+xtile (index into tilemap and spotvis)
|
||
|
; DI : yspot (xinttile<<6)+ytile (index into tilemap and spotvis)
|
||
|
; BP : ytile
|
||
|
; ES : screenseg
|
||
|
;
|
||
|
;---------------------------------------------------------------------------
|
||
|
|
||
|
;-----------
|
||
|
;
|
||
|
; check intersections with vertical walls
|
||
|
;
|
||
|
;-----------
|
||
|
|
||
|
EVEN
|
||
|
vertcheck:
|
||
|
cmp dx,bp
|
||
|
vertop: ; 0x7e = jle (ytilestep==-1)
|
||
|
jle horizentry ; 0x7d = jge (ytilestep==1)
|
||
|
vertentry:
|
||
|
test [BYTE tilemap+si],0ffh ; tilehit = *((byte *)tilemap+xspot);
|
||
|
jnz hitvert
|
||
|
passvert:
|
||
|
mov [BYTE spotvis+si],1 ; *((byte *)spotvis+xspot) = true;
|
||
|
add bx,[xtilestep] ; xtile+=xtilestep
|
||
|
mov ax,[WORD ystep]
|
||
|
add [WORD yintercept],ax ; yintercept += ystep
|
||
|
adc dx,[WORD ystep+2]
|
||
|
mov si,bx
|
||
|
shl si,6
|
||
|
add si,dx ; xspot = (xtile<<6)+yinttile
|
||
|
jmp vertcheck
|
||
|
|
||
|
EVEN
|
||
|
hitvert:
|
||
|
mov al,[BYTE tilemap+si] ; tilehit = *((byte *)tilemap+xspot);
|
||
|
mov [BYTE tilehit],al
|
||
|
or al,al ; set flags
|
||
|
jns notvertdoor
|
||
|
jmp vertdoor
|
||
|
notvertdoor:
|
||
|
mov [WORD xintercept],0
|
||
|
mov [WORD xintercept+2],bx
|
||
|
mov [xtile],bx
|
||
|
mov [WORD yintercept+2],dx
|
||
|
mov [ytile],dx
|
||
|
call FAR HitVertWall
|
||
|
jmp nextpix
|
||
|
|
||
|
|
||
|
;-----------
|
||
|
;
|
||
|
; check intersections with horizontal walls
|
||
|
;
|
||
|
;-----------
|
||
|
EVEN
|
||
|
horizcheck:
|
||
|
cmp cx,bx
|
||
|
horizop: ; 0x7e = jle (xtilestep==-1)
|
||
|
jle vertentry ; 0x7d = jge (xtilestep==1)
|
||
|
horizentry:
|
||
|
test [BYTE tilemap+di],0ffh ; tilehit = *((byte *)tilemap+yspot);
|
||
|
jnz hithoriz
|
||
|
passhoriz:
|
||
|
mov [BYTE spotvis+di],1 ; *((byte *)spotvis+yspot) = true;
|
||
|
add bp,[ytilestep] ; ytile+=ytilestep
|
||
|
mov ax,[WORD xstep]
|
||
|
add [WORD xintercept],ax ; xintercept += xstep
|
||
|
adc cx,[WORD xstep+2]
|
||
|
mov di,cx
|
||
|
shl di,6
|
||
|
add di,bp ; yspot = (xinttile<<6)+ytile
|
||
|
jmp horizcheck
|
||
|
|
||
|
EVEN
|
||
|
hithoriz:
|
||
|
mov al,[BYTE tilemap+di] ; tilehit = *((byte *)tilemap+yspot);
|
||
|
mov [BYTE tilehit],al
|
||
|
or al,al ; set flags
|
||
|
js horizdoor
|
||
|
mov [WORD xintercept+2],cx
|
||
|
mov [xtile],cx
|
||
|
mov [WORD yintercept],0
|
||
|
mov [WORD yintercept+2],bp
|
||
|
mov [ytile],bp
|
||
|
call FAR HitHorizWall
|
||
|
jmp nextpix
|
||
|
|
||
|
;---------------------------------------------------------------------------
|
||
|
;
|
||
|
; next pixel over
|
||
|
;
|
||
|
;---------------------------------------------------------------------------
|
||
|
|
||
|
nextpix:
|
||
|
mov ax,[pixx]
|
||
|
inc ax
|
||
|
mov [pixx],ax
|
||
|
cmp ax,[viewwidth]
|
||
|
jge done
|
||
|
jmp pixxloop
|
||
|
done:
|
||
|
pop bp
|
||
|
pop di
|
||
|
pop si
|
||
|
retf
|
||
|
|
||
|
;===========================================================================
|
||
|
|
||
|
;=============
|
||
|
;
|
||
|
; hit a special horizontal wall, so find which coordinate a door would be
|
||
|
; intersected at, and check to see if the door is open past that point
|
||
|
;
|
||
|
;=============
|
||
|
horizdoor:
|
||
|
mov [xtile],bx ; save off live register variables
|
||
|
mov [WORD yintercept+2],dx
|
||
|
|
||
|
test al,040h ; both high bits set == pushable wall
|
||
|
jnz horizpushwall
|
||
|
|
||
|
mov bx,ax
|
||
|
and bx,7fh ; strip high bit
|
||
|
shl bx,1 ; index into word width door table
|
||
|
|
||
|
mov ax,[WORD xstep]
|
||
|
mov dx,[WORD xstep+2]
|
||
|
sar dx,1
|
||
|
rcr ax,1 ; half a step gets to door position
|
||
|
|
||
|
add ax,[WORD xintercept] ; add half step to current intercept pos
|
||
|
adc dx,cx ; CX hold high word of xintercept
|
||
|
|
||
|
cmp cx,dx ; is it still in the same tile?
|
||
|
je hithmid
|
||
|
;
|
||
|
; midpoint is outside tile, so it hit the side of the wall before a door
|
||
|
;
|
||
|
continuehoriz:
|
||
|
mov bx,[xtile] ; reload register variables
|
||
|
mov dx,[WORD yintercept+2]
|
||
|
jmp passhoriz ; continue tracing
|
||
|
;
|
||
|
; the trace hit the door plane at pixel position AX, see if the door is
|
||
|
; closed that much
|
||
|
;
|
||
|
hithmid:
|
||
|
cmp ax,[doorposition+bx] ; position of leading edge of door
|
||
|
jb continuehoriz
|
||
|
;
|
||
|
; draw the door
|
||
|
;
|
||
|
mov [WORD xintercept],ax ; save pixel intercept position
|
||
|
mov [WORD xintercept+2],cx
|
||
|
|
||
|
mov [WORD yintercept],8000h ; intercept in middle of tile
|
||
|
mov [WORD yintercept+2],bp
|
||
|
|
||
|
call FAR HitHorizDoor
|
||
|
jmp nextpix
|
||
|
|
||
|
;============
|
||
|
;
|
||
|
; hit a sliding horizontal wall
|
||
|
;
|
||
|
;============
|
||
|
|
||
|
horizpushwall:
|
||
|
mov ax,[WORD xstep+2] ; multiply xstep by pwallmove (0-63)
|
||
|
mul [pwallpos]
|
||
|
mov bx,ax
|
||
|
mov ax,[WORD xstep]
|
||
|
mul [pwallpos]
|
||
|
add dx,bx
|
||
|
|
||
|
sar dx,1 ; then divide by 64 to accomplish a
|
||
|
rcr ax,1 ; fixed point multiplication
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
|
||
|
add ax,[WORD xintercept] ; add partial step to current intercept
|
||
|
adc dx,cx ; CX hold high word of xintercept
|
||
|
|
||
|
cmp cx,dx ; is it still in the same tile?
|
||
|
jne continuehoriz ; no, it hit the side
|
||
|
|
||
|
;
|
||
|
; draw the pushable wall at the new height
|
||
|
;
|
||
|
mov [WORD xintercept],ax ; save pixel intercept position
|
||
|
mov [WORD xintercept+2],dx
|
||
|
|
||
|
mov [WORD yintercept+2],bp
|
||
|
mov [WORD yintercept],0
|
||
|
|
||
|
call FAR HitHorizPWall
|
||
|
jmp nextpix
|
||
|
|
||
|
|
||
|
|
||
|
;===========================================================================
|
||
|
|
||
|
;=============
|
||
|
;
|
||
|
; hit a special vertical wall, so find which coordinate a door would be
|
||
|
; intersected at, and check to see if the door is open past that point
|
||
|
;
|
||
|
;=============
|
||
|
vertdoor:
|
||
|
mov [xtile],bx ; save off live register variables
|
||
|
mov [WORD yintercept+2],dx
|
||
|
|
||
|
test al,040h ; both high bits set == pushable wall
|
||
|
jnz vertpushwall
|
||
|
|
||
|
mov bx,ax
|
||
|
and bx,7fh ; strip high bit
|
||
|
shl bx,1 ; index into word width doorposition
|
||
|
|
||
|
mov ax,[WORD ystep]
|
||
|
mov dx,[WORD ystep+2]
|
||
|
sar dx,1
|
||
|
rcr ax,1 ; half a step gets to door position
|
||
|
|
||
|
add ax,[WORD yintercept] ; add half step to current intercept pos
|
||
|
adc dx,[WORD yintercept+2]
|
||
|
|
||
|
cmp [WORD yintercept+2],dx ; is it still in the same tile?
|
||
|
je hitvmid
|
||
|
;
|
||
|
; midpoint is outside tile, so it hit the side of the wall before a door
|
||
|
;
|
||
|
continuevert:
|
||
|
mov bx,[xtile] ; reload register variables
|
||
|
mov dx,[WORD yintercept+2]
|
||
|
jmp passvert ; continue tracing
|
||
|
;
|
||
|
; the trace hit the door plane at pixel position AX, see if the door is
|
||
|
; closed that much
|
||
|
;
|
||
|
hitvmid:
|
||
|
cmp ax,[doorposition+bx] ; position of leading edge of door
|
||
|
jb continuevert
|
||
|
;
|
||
|
; draw the door
|
||
|
;
|
||
|
mov [WORD yintercept],ax ; save pixel intercept position
|
||
|
mov [WORD xintercept],8000h ; intercept in middle of tile
|
||
|
mov ax,[xtile]
|
||
|
mov [WORD xintercept+2],ax
|
||
|
|
||
|
call FAR HitVertDoor
|
||
|
jmp nextpix
|
||
|
|
||
|
;============
|
||
|
;
|
||
|
; hit a sliding vertical wall
|
||
|
;
|
||
|
;============
|
||
|
|
||
|
vertpushwall:
|
||
|
mov ax,[WORD ystep+2] ; multiply ystep by pwallmove (0-63)
|
||
|
mul [pwallpos]
|
||
|
mov bx,ax
|
||
|
mov ax,[WORD ystep]
|
||
|
mul [pwallpos]
|
||
|
add dx,bx
|
||
|
|
||
|
sar dx,1 ; then divide by 64 to accomplish a
|
||
|
rcr ax,1 ; fixed point multiplication
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
sar dx,1
|
||
|
rcr ax,1
|
||
|
|
||
|
add ax,[WORD yintercept] ; add partial step to current intercept
|
||
|
adc dx,[WORD yintercept+2]
|
||
|
|
||
|
cmp [WORD yintercept+2],dx ; is it still in the same tile?
|
||
|
jne continuevert ; no, it hit the side
|
||
|
|
||
|
;
|
||
|
; draw the pushable wall at the new height
|
||
|
;
|
||
|
mov [WORD yintercept],ax ; save pixel intercept position
|
||
|
mov [WORD yintercept+2],dx
|
||
|
|
||
|
mov bx,[xtile]
|
||
|
mov [WORD xintercept+2],bx
|
||
|
mov [WORD xintercept],0
|
||
|
|
||
|
call FAR HitVertPWall
|
||
|
jmp nextpix
|
||
|
|
||
|
|
||
|
|
||
|
ENDP
|
||
|
|
||
|
|
||
|
END
|
||
|
|
||
|
|