shithub: wl3d

Download patch

ref: bb66e1f0f272824e5850e760a8788daaba7641a2
parent: 6638e8580dee0e8691a54da80058be66ab78bcd4
author: Konstantinn Bonnet <qu7uux@gmail.com>
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