ref: bb66e1f0f272824e5850e760a8788daaba7641a2
parent: 6638e8580dee0e8691a54da80058be66ab78bcd4
author: Konstantinn Bonnet <[email protected]>
date: Mon Feb 15 02:28:31 EST 2016
further shuffle
--- a/dr.asm
+++ /dev/null
@@ -1,739 +1,0 @@
- 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
-
-
--- /dev/null
+++ b/draw.asm
@@ -1,0 +1,739 @@
+ 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
+
+
--- a/head.h
+++ /dev/null
@@ -1,34 +1,0 @@
-// ID_HEAD.H
-
-
-#define EXTENSION "WLF"
-#define WOLF
-
-#define TEXTGR 0
-#define CGAGR 1
-#define EGAGR 2
-#define VGAGR 3
-
-#define GRMODE VGAGR
-
-#include "VERSION.H"
-
-typedef enum {false,true} boolean;
-typedef unsigned char byte;
-typedef unsigned int word;
-typedef unsigned long longword;
-typedef byte * Ptr;
-
-typedef struct
- {
- int x,y;
- } Point;
-
-typedef struct
- {
- Point ul,lr;
- } Rect;
-
-
-void Quit (char *error); // defined in user program
-
--- a/heads.h
+++ b/heads.h
@@ -1,21 +1,3 @@
-// ID_GLOB.H
-
-
-#include <ALLOC.H>
-#include <CTYPE.H>
-#include <DOS.H>
-#include <ERRNO.H>
-#include <FCNTL.H>
-#include <IO.H>
-#include <MEM.H>
-#include <PROCESS.H>
-#include <STDIO.H>
-#include <STDLIB.H>
-#include <STRING.H>
-#include <SYS\STAT.H>
-#include <VALUES.H>
-#include <DIR.H>
-#define __ID_GLOB__
#include "VERSION.H"
//--------------------------------------------------------------------------
@@ -71,15 +53,6 @@
typedef unsigned long longword;
typedef byte * Ptr;
-typedef struct
- {
- int x,y;
- } Point;
-typedef struct
- {
- Point ul,lr;
- } Rect;
-
#define nil ((void *)0)
@@ -121,3 +94,4 @@
#define SETFONTCOLOR(f,b) fontcolor=f;backcolor=b;
+#define EXTENSION "WLF"
--- a/oldscale.c
+++ /dev/null
@@ -1,737 +1,0 @@
-// WL_SCALE.C
-
-#include "WL_DEF.H"
-#pragma hdrstop
-
-#define OP_RETF 0xcb
-
-/*
-=============================================================================
-
- GLOBALS
-
-=============================================================================
-*/
-
-t_compscale _seg *scaledirectory[MAXSCALEHEIGHT+1];
-long fullscalefarcall[MAXSCALEHEIGHT+1];
-
-int maxscale,maxscaleshl2;
-
-/*
-=============================================================================
-
- LOCALS
-
-=============================================================================
-*/
-
-t_compscale _seg *work;
-unsigned BuildCompScale (int height, memptr *finalspot);
-
-int stepbytwo;
-
-//===========================================================================
-
-/*
-==============
-=
-= BadScale
-=
-==============
-*/
-
-void far BadScale (void)
-{
- Quit ("BadScale called!");
-}
-
-
-/*
-==========================
-=
-= SetupScaling
-=
-==========================
-*/
-
-void SetupScaling (int maxscaleheight)
-{
- int i,x,y;
- byte far *dest;
-
- maxscaleheight/=2; // one scaler every two pixels
-
- maxscale = maxscaleheight-1;
- maxscaleshl2 = maxscale<<2;
-
-//
-// free up old scalers
-//
- for (i=1;i<MAXSCALEHEIGHT;i++)
- {
- if (scaledirectory[i])
- MM_FreePtr (&(memptr)scaledirectory[i]);
- if (i>=stepbytwo)
- i += 2;
- }
- memset (scaledirectory,0,sizeof(scaledirectory));
-
- MM_SortMem ();
-
-//
-// build the compiled scalers
-//
- stepbytwo = viewheight/2; // save space by double stepping
- MM_GetPtr (&(memptr)work,20000);
- if (mmerror)
- return;
-
- for (i=1;i<=maxscaleheight;i++)
- {
- BuildCompScale (i*2,&(memptr)scaledirectory[i]);
- if (mmerror)
- {
- MM_FreePtr (&(memptr)work);
- return;
- }
- if (i>=stepbytwo)
- i+= 2;
- }
- MM_FreePtr (&(memptr)work);
-
-//
-// compact memory and lock down scalers
-//
- MM_SortMem ();
- for (i=1;i<=maxscaleheight;i++)
- {
- MM_SetLock (&(memptr)scaledirectory[i],true);
- fullscalefarcall[i] = (unsigned)scaledirectory[i];
- fullscalefarcall[i] <<=16;
- fullscalefarcall[i] += scaledirectory[i]->codeofs[0];
- if (i>=stepbytwo)
- {
- scaledirectory[i+1] = scaledirectory[i];
- fullscalefarcall[i+1] = fullscalefarcall[i];
- scaledirectory[i+2] = scaledirectory[i];
- fullscalefarcall[i+2] = fullscalefarcall[i];
- i+=2;
- }
- }
- scaledirectory[0] = scaledirectory[1];
- fullscalefarcall[0] = fullscalefarcall[1];
-
-//
-// check for oversize wall drawing
-//
- for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)
- fullscalefarcall[i] = (long)BadScale;
-
-}
-
-//===========================================================================
-
-/*
-========================
-=
-= BuildCompScale
-=
-= Builds a compiled scaler object that will scale a 64 tall object to
-= the given height (centered vertically on the screen)
-=
-= height should be even
-=
-= Call with
-= ---------
-= DS:SI Source for scale
-= ES:DI Dest for scale
-=
-= Calling the compiled scaler only destroys AL
-=
-========================
-*/
-
-unsigned BuildCompScale (int height, memptr *finalspot)
-{
- byte far *code;
-
- int i;
- long fix,step;
- unsigned src,totalscaled,totalsize;
- int startpix,endpix,toppix;
-
-
- step = ((long)height<<16) / 64;
- code = &work->code[0];
- toppix = (viewheight-height)/2;
- fix = 0;
-
- for (src=0;src<=64;src++)
- {
- startpix = fix>>16;
- fix += step;
- endpix = fix>>16;
-
- if (endpix>startpix)
- work->width[src] = endpix-startpix;
- else
- work->width[src] = 0;
-
-//
-// mark the start of the code
-//
- work->codeofs[src] = FP_OFF(code);
-
-//
-// compile some code if the source pixel generates any screen pixels
-//
- startpix+=toppix;
- endpix+=toppix;
-
- if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
- continue;
-
- //
- // mov al,[si+src]
- //
- *code++ = 0x8a;
- *code++ = 0x44;
- *code++ = src;
-
- for (;startpix<endpix;startpix++)
- {
- if (startpix >= viewheight)
- break; // off the bottom of the view area
- if (startpix < 0)
- continue; // not into the view area
-
- //
- // mov [es:di+heightofs],al
- //
- *code++ = 0x26;
- *code++ = 0x88;
- *code++ = 0x85;
- *((unsigned far *)code)++ = startpix*SCREENBWIDE;
- }
-
- }
-
-//
-// retf
-//
- *code++ = 0xcb;
-
- totalsize = FP_OFF(code);
- MM_GetPtr (finalspot,totalsize);
- if (mmerror)
- return 0;
- _fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);
-
- return totalsize;
-}
-
-
-/*
-=======================
-=
-= ScaleLine
-=
-= linescale should have the high word set to the segment of the scaler
-=
-=======================
-*/
-
-extern int slinex,slinewidth;
-extern unsigned far *linecmds;
-extern long linescale;
-extern unsigned maskword;
-
-byte mask1,mask2,mask3;
-
-
-void near ScaleLine (void)
-{
-asm mov cx,WORD PTR [linescale+2]
-asm mov es,cx // segment of scaler
-
-asm mov bp,WORD PTR [linecmds]
-asm mov dx,SC_INDEX+1 // to set SC_MAPMASK
-
-asm mov bx,[slinex]
-asm mov di,bx
-asm shr di,2 // X in bytes
-asm add di,[bufferofs]
-asm and bx,3
-asm shl bx,3
-asm add bx,[slinewidth] // bx = (pixel*8+pixwidth)
-asm mov al,BYTE [mapmasks3-1+bx] // -1 because pixwidth of 1 is first
-asm mov ds,WORD PTR [linecmds+2]
-asm or al,al
-asm jz notthreebyte // scale across three bytes
-asm jmp threebyte
-notthreebyte:
-asm mov al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first
-asm or al,al
-asm jnz twobyte // scale across two bytes
-
-//
-// one byte scaling
-//
-asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
-asm out dx,al // set map mask register
-
-scalesingle:
-
-asm mov bx,[ds:bp] // table location of rtl to patch
-asm or bx,bx
-asm jz linedone // 0 signals end of segment list
-asm mov bx,[es:bx]
-asm mov dl,[es:bx] // save old value
-asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
-asm mov si,[ds:bp+4] // table location of entry spot
-asm mov ax,[es:si]
-asm mov WORD PTR ss:[linescale],ax // call here to start scaling
-asm mov si,[ds:bp+2] // corrected top of shape for this segment
-asm add bp,6 // next segment list
-
-asm mov ax,SCREENSEG
-asm mov es,ax
-asm call ss:[linescale] // scale the segment of pixels
-
-asm mov es,cx // segment of scaler
-asm mov BYTE PTR es:[bx],dl // unpatch the RETF
-asm jmp scalesingle // do the next segment
-
-
-//
-// done
-//
-linedone:
-asm mov ax,ss
-asm mov ds,ax
-return;
-
-//
-// two byte scaling
-//
-twobyte:
-asm mov ss:[mask2],al
-asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
-asm mov ss:[mask1],al
-
-scaledouble:
-
-asm mov bx,[ds:bp] // table location of rtl to patch
-asm or bx,bx
-asm jz linedone // 0 signals end of segment list
-asm mov bx,[es:bx]
-asm mov cl,[es:bx] // save old value
-asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
-asm mov si,[ds:bp+4] // table location of entry spot
-asm mov ax,[es:si]
-asm mov WORD PTR ss:[linescale],ax // call here to start scaling
-asm mov si,[ds:bp+2] // corrected top of shape for this segment
-asm add bp,6 // next segment list
-
-asm mov ax,SCREENSEG
-asm mov es,ax
-asm mov al,ss:[mask1]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm inc di
-asm mov al,ss:[mask2]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm dec di
-
-asm mov es,WORD PTR ss:[linescale+2] // segment of scaler
-asm mov BYTE PTR es:[bx],cl // unpatch the RETF
-asm jmp scaledouble // do the next segment
-
-
-//
-// three byte scaling
-//
-threebyte:
-asm mov ss:[mask3],al
-asm mov al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first
-asm mov ss:[mask2],al
-asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
-asm mov ss:[mask1],al
-
-scaletriple:
-
-asm mov bx,[ds:bp] // table location of rtl to patch
-asm or bx,bx
-asm jz linedone // 0 signals end of segment list
-asm mov bx,[es:bx]
-asm mov cl,[es:bx] // save old value
-asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
-asm mov si,[ds:bp+4] // table location of entry spot
-asm mov ax,[es:si]
-asm mov WORD PTR ss:[linescale],ax // call here to start scaling
-asm mov si,[ds:bp+2] // corrected top of shape for this segment
-asm add bp,6 // next segment list
-
-asm mov ax,SCREENSEG
-asm mov es,ax
-asm mov al,ss:[mask1]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm inc di
-asm mov al,ss:[mask2]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm inc di
-asm mov al,ss:[mask3]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm dec di
-asm dec di
-
-asm mov es,WORD PTR ss:[linescale+2] // segment of scaler
-asm mov BYTE PTR es:[bx],cl // unpatch the RETF
-asm jmp scaletriple // do the next segment
-
-
-}
-
-
-/*
-=======================
-=
-= ScaleShape
-=
-= Draws a compiled shape at [scale] pixels high
-=
-= each vertical line of the shape has a pointer to segment data:
-= end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
-= top of virtual line with segment in proper place
-= start of segment pixel*2, used to jsl into compiled scaler
-= <repeat>
-=
-= Setup for call
-= --------------
-= GC_MODE read mode 1, write mode 2
-= GC_COLORDONTCARE set to 0, so all reads from video memory return 0xff
-= GC_INDEX pointing at GC_BITMASK
-=
-=======================
-*/
-
-static long longtemp;
-
-void ScaleShape (int xcenter, int shapenum, unsigned height)
-{
- t_compshape _seg *shape;
- t_compscale _seg *comptable;
- unsigned scale,srcx,stopx,tempx;
- int t;
- unsigned far *cmdptr;
- boolean leftvis,rightvis;
-
-
- shape = PM_GetSpritePage (shapenum);
-
- scale = height>>3; // low three bits are fractional
- if (!scale || scale>maxscale)
- return; // too close or far away
- comptable = scaledirectory[scale];
-
- *(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call
- *(((unsigned *)&linecmds)+1)=(unsigned)shape; // seg of shape
-
-//
-// scale to the left (from pixel 31 to shape->leftpix)
-//
- srcx = 32;
- slinex = xcenter;
- stopx = shape->leftpix;
- cmdptr = &shape->dataofs[31-stopx];
-
- while ( --srcx >=stopx && slinex>0)
- {
- (unsigned)linecmds = *cmdptr--;
- if ( !(slinewidth = comptable->width[srcx]) )
- continue;
-
- if (slinewidth == 1)
- {
- slinex--;
- if (slinex<viewwidth)
- {
- if (wallheight[slinex] >= height)
- continue; // obscured by closer wall
- ScaleLine ();
- }
- continue;
- }
-
- //
- // handle multi pixel lines
- //
- if (slinex>viewwidth)
- {
- slinex -= slinewidth;
- slinewidth = viewwidth-slinex;
- if (slinewidth<1)
- continue; // still off the right side
- }
- else
- {
- if (slinewidth>slinex)
- slinewidth = slinex;
- slinex -= slinewidth;
- }
-
-
- leftvis = (wallheight[slinex] < height);
- rightvis = (wallheight[slinex+slinewidth-1] < height);
-
- if (leftvis)
- {
- if (rightvis)
- ScaleLine ();
- else
- {
- while (wallheight[slinex+slinewidth-1] >= height)
- slinewidth--;
- ScaleLine ();
- }
- }
- else
- {
- if (!rightvis)
- continue; // totally obscured
-
- while (wallheight[slinex] >= height)
- {
- slinex++;
- slinewidth--;
- }
- ScaleLine ();
- break; // the rest of the shape is gone
- }
- }
-
-
-//
-// scale to the right
-//
- slinex = xcenter;
- stopx = shape->rightpix;
- if (shape->leftpix<31)
- {
- srcx = 31;
- cmdptr = &shape->dataofs[32-shape->leftpix];
- }
- else
- {
- srcx = shape->leftpix-1;
- cmdptr = &shape->dataofs[0];
- }
- slinewidth = 0;
-
- while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth)
- {
- (unsigned)linecmds = *cmdptr++;
- if ( !(slinewidth = comptable->width[srcx]) )
- continue;
-
- if (slinewidth == 1)
- {
- if (slinex>=0 && wallheight[slinex] < height)
- {
- ScaleLine ();
- }
- continue;
- }
-
- //
- // handle multi pixel lines
- //
- if (slinex<0)
- {
- if (slinewidth <= -slinex)
- continue; // still off the left edge
-
- slinewidth += slinex;
- slinex = 0;
- }
- else
- {
- if (slinex + slinewidth > viewwidth)
- slinewidth = viewwidth-slinex;
- }
-
-
- leftvis = (wallheight[slinex] < height);
- rightvis = (wallheight[slinex+slinewidth-1] < height);
-
- if (leftvis)
- {
- if (rightvis)
- {
- ScaleLine ();
- }
- else
- {
- while (wallheight[slinex+slinewidth-1] >= height)
- slinewidth--;
- ScaleLine ();
- break; // the rest of the shape is gone
- }
- }
- else
- {
- if (rightvis)
- {
- while (wallheight[slinex] >= height)
- {
- slinex++;
- slinewidth--;
- }
- ScaleLine ();
- }
- else
- continue; // totally obscured
- }
- }
-}
-
-
-
-/*
-=======================
-=
-= SimpleScaleShape
-=
-= NO CLIPPING, height in pixels
-=
-= Draws a compiled shape at [scale] pixels high
-=
-= each vertical line of the shape has a pointer to segment data:
-= end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
-= top of virtual line with segment in proper place
-= start of segment pixel*2, used to jsl into compiled scaler
-= <repeat>
-=
-= Setup for call
-= --------------
-= GC_MODE read mode 1, write mode 2
-= GC_COLORDONTCARE set to 0, so all reads from video memory return 0xff
-= GC_INDEX pointing at GC_BITMASK
-=
-=======================
-*/
-
-void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
-{
- t_compshape _seg *shape;
- t_compscale _seg *comptable;
- unsigned scale,srcx,stopx,tempx;
- int t;
- unsigned far *cmdptr;
- boolean leftvis,rightvis;
-
-
- shape = PM_GetSpritePage (shapenum);
-
- scale = height>>1;
- comptable = scaledirectory[scale];
-
- *(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call
- *(((unsigned *)&linecmds)+1)=(unsigned)shape; // seg of shape
-
-//
-// scale to the left (from pixel 31 to shape->leftpix)
-//
- srcx = 32;
- slinex = xcenter;
- stopx = shape->leftpix;
- cmdptr = &shape->dataofs[31-stopx];
-
- while ( --srcx >=stopx )
- {
- (unsigned)linecmds = *cmdptr--;
- if ( !(slinewidth = comptable->width[srcx]) )
- continue;
-
- slinex -= slinewidth;
- ScaleLine ();
- }
-
-
-//
-// scale to the right
-//
- slinex = xcenter;
- stopx = shape->rightpix;
- if (shape->leftpix<31)
- {
- srcx = 31;
- cmdptr = &shape->dataofs[32-shape->leftpix];
- }
- else
- {
- srcx = shape->leftpix-1;
- cmdptr = &shape->dataofs[0];
- }
- slinewidth = 0;
-
- while ( ++srcx <= stopx )
- {
- (unsigned)linecmds = *cmdptr++;
- if ( !(slinewidth = comptable->width[srcx]) )
- continue;
-
- ScaleLine ();
- slinex+=slinewidth;
- }
-}
-
-
-
-
-//
-// bit mask tables for drawing scaled strips up to eight pixels wide
-//
-// down here so the STUPID inline assembler doesn't get confused!
-//
-
-
-byte mapmasks1[4][8] = {
-{1 ,3 ,7 ,15,15,15,15,15},
-{2 ,6 ,14,14,14,14,14,14},
-{4 ,12,12,12,12,12,12,12},
-{8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };
-
-byte mapmasks2[4][8] = {
-{0 ,0 ,0 ,0 ,1 ,3 ,7 ,15},
-{0 ,0 ,0 ,1 ,3 ,7 ,15,15},
-{0 ,0 ,1 ,3 ,7 ,15,15,15},
-{0 ,1 ,3 ,7 ,15,15,15,15} };
-
-byte mapmasks3[4][8] = {
-{0 ,0 ,0 ,0 ,0 ,0 ,0 ,0},
-{0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},
-{0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},
-{0 ,0 ,0 ,0 ,0 ,1 ,3 ,7} };
-
-
-unsigned wordmasks[8][8] = {
-{0x0080,0x00c0,0x00e0,0x00f0,0x00f8,0x00fc,0x00fe,0x00ff},
-{0x0040,0x0060,0x0070,0x0078,0x007c,0x007e,0x007f,0x807f},
-{0x0020,0x0030,0x0038,0x003c,0x003e,0x003f,0x803f,0xc03f},
-{0x0010,0x0018,0x001c,0x001e,0x001f,0x801f,0xc01f,0xe01f},
-{0x0008,0x000c,0x000e,0x000f,0x800f,0xc00f,0xe00f,0xf00f},
-{0x0004,0x0006,0x0007,0x8007,0xc007,0xe007,0xf007,0xf807},
-{0x0002,0x0003,0x8003,0xc003,0xe003,0xf003,0xf803,0xfc03},
-{0x0001,0x8001,0xc001,0xe001,0xf001,0xf801,0xfc01,0xfe01} };
-
-int slinex,slinewidth;
-unsigned far *linecmds;
-long linescale;
-unsigned maskword;
-
--- a/us.h
+++ b/us.h
@@ -118,6 +118,6 @@
extern int US_CheckParm(char *parm,char **strings),
US_RndT(void);
- void USL_PrintInCenter(char far *s,Rect r);
+ void USL_PrintInCenter(char far *s,Rct r);
char *USL_GiveSaveName(word game);
#endif
--- a/us1.c
+++ b/us1.c
@@ -348,17 +348,14 @@
//
///////////////////////////////////////////////////////////////////////////
void
-USL_PrintInCenter(char far *s,Rect r)
+USL_PrintInCenter(char far *s,Rectangle r)
{
- word w,h,
- rw,rh;
+ word w,h;
USL_MeasureString(s,&w,&h);
- rw = r.lr.x - r.ul.x;
- rh = r.lr.y - r.ul.y;
- px = r.ul.x + ((rw - w) / 2);
- py = r.ul.y + ((rh - h) / 2);
+ px = r.min.x + ((Dx(r) - w) / 2);
+ py = r.min.y + ((Dy(r) - h) / 2);
USL_DrawString(s);
}
@@ -370,14 +367,7 @@
void
US_PrintCentered(char far *s)
{
- Rect r;
-
- r.ul.x = WindowX;
- r.ul.y = WindowY;
- r.lr.x = r.ul.x + WindowW;
- r.lr.y = r.ul.y + WindowH;
-
- USL_PrintInCenter(s,r);
+ USL_PrintInCenter(s,Rect(WindowX,WindowY,WindowW+WindowX,WindowH+WindowY);
}
///////////////////////////////////////////////////////////////////////////
--- a/vl.c
+++ b/vl.c
@@ -4,7 +4,7 @@
#include <alloc.h>
#include <mem.h>
#include <string.h>
-#include "ID_HEAD.H"
+#include "ID_HEADS.H"
#include "ID_VL.H"
#pragma hdrstop