changeset 47:90d91aa004d5

Decoded dungeon display routines
author William Astle <lost@l-w.ca>
date Sat, 27 Dec 2014 14:19:27 -0700
parents e8eee008ad42
children 47bc11e767f8
files dod.s
diffstat 1 files changed, 161 insertions(+), 159 deletions(-) [+]
line wrap: on
line diff
--- a/dod.s	Sat Dec 27 13:07:49 2014 -0700
+++ b/dod.s	Sat Dec 27 14:19:27 2014 -0700
@@ -72,6 +72,10 @@
 		fcb \1
 		endm
 
+; set lighting for render
+setlighting	macro noexpand
+		dod S00
+		endm
 ; draw a graphic with graphic data at (X)
 drawgraphic	macro noexpand
 		dod S01
@@ -842,15 +846,15 @@
 		lda V26F			; get "passed out" fade state
 		clr V275			; undo special light level checking
 LC38E		clrb				; default to full bright
-		suba #7
-		suba V28B
-		bge LC39F			; brif adjusted light level >= 0
-		decb				; change to dark
-		cmpa #$f9			; are we in a special light level range?
-		ble LC39F			; brif not - use the calculated value (dark)
-		ldx #LCB96			; point to end of table of pixel masks
+		suba #7				; adjust level based on the order of the table used
+		suba V28B			; subtract render distance from light level
+		bge LC39F			; brif adjusted light level >= 0 - means we can see everything
+		decb				; change to dark default
+		cmpa #$f9			; are we in a partial visible range?
+		ble LC39F			; brif not - use the default value (dark)
+		ldx #LCB96			; point to end of table of pixel masks, used for powers of two levels
 		ldb a,x				; fetch value from pixel mask (1, 2, 4, 8, 16, 32)
-LC39F		stb lightlevel			; save new light level (full bright or dark)
+LC39F		stb lightlevel			; save new light level (full bright, dark, or partial)
 		rts				; return to caller
 ; SWI 1 routine
 ;***********************************************************************************************************
@@ -2421,136 +2425,133 @@
 		ldd #$3c24			; symbol for displaying a hole
 		bsr LCE1D			; go display symbol
 		bra LCE38			; go check another entry
-LCE47		pshs a,x
-		ldx #LCF48
-		tst V273
-		bne LCE5C
-		leax >1,x
-		tst V274
-LCE56		bne LCE5C
-		leax $fff5,x
-LCE5C		lda V28B
-		lda a,x
-		sta V24F
-		sta V250
-		puls a,x,pc
+LCE47		pshs a,x			; save registers
+		ldx #LCF48			; point to lighting level constants
+		tst V273			; is this a half step render?
+		bne LCE5C			; brif not
+		leax >1,x			; move ahead in the render scale constants
+		tst V274			; is it a half step back?
+LCE56		bne LCE5C			; brif not
+		leax >-11,x			; move to backstep levels
+LCE5C		lda V28B			; get distance to render
+		lda a,x				; get scale factor for the distance
+		sta V24F			; save horizontal scaling factor
+		sta V250			; save vertical scaling factor
+		puls a,x,pc			; restore registers and return
 ; This is the routine that shows the regular dungeon view.
-LCE66		cleargfx2
-		clr V28B
-		ldd playerloc
-		std V27C
-LCE6E		bsr LCE47
-		ldd V27C
-		jsr LCC7B
-		lda ,x
-		ldu #neighbourbuff
-		ldx #4
-LCE7D		tfr a,b
-		andb #3
-		stb 4,u
-		stb ,u+
-		lsra
-		lsra
-		leax -1,x
-		bne LCE7D
-		ldb facing
-		ldu #neighbourbuff
-		leau b,u
-		ldy #LDBDE
-LCE96		lda ,y+
-		bmi LCED8
-		ldb a,u
-		lslb
-		cmpb #4
-		bne LCEA9
-		ldx b,y
-		dec V275
-		bsr LCECE
-		ldb #6
-LCEA9		ldx b,y
-		bsr LCECE
-		leay 8,y
-		bra LCE96
-LCEB1		rts
-LCEB2		tfr x,y
-		tst b,u
-		bne LCEB1
-		addb facing
-		stb V28A
-		ldd V27C
-		jsr LD11B
-		jsr LCF82
-		beq LCEB1
-		exg x,y
-LCEC8		tst 2,y
-		beq LCECE
+LCE66		cleargfx2			; clear the graphics area
+		clr V28B			; set render distance to immediate
+		ldd playerloc			; get player location
+		std V27C			; save current render location
+LCE6E		bsr LCE47			; calculate scaling factor for current render location
+		ldd V27C			; fetch render location
+		jsr LCC7B			; get maze pointer
+		lda ,x				; get maze data for current location
+		ldu #neighbourbuff		; point to neighbor calculation buffer
+		ldx #4				; check four directions
+LCE7D		tfr a,b				; save door info
+		andb #3				; check low 2 bits
+		stb 4,u				;= save twice so we can handle rotation without special cases
+		stb ,u+				;=
+		lsra				;* shift room data to next direction
+		lsra				;*
+		leax -1,x			; have we done all four directions?
+		bne LCE7D			; brif not
+		ldb facing			; get the direction we're facing
+		ldu #neighbourbuff		; point to neighbor table
+		leau b,u			; offset neighbor table
+		ldy #LDBDE			; point to direction rendering table (pointers to graphic elements)
+LCE96		lda ,y+				; get table entry flag/direction
+		bmi LCED8			; brif end of table
+		ldb a,u				; get direction data
+		lslb				; two bytes per door type
+		cmpb #4				; is it a magic door?
+		bne LCEA9			; brif not
+		ldx b,y				; fetch graphic pointer
+		dec V275			; flag to render to magic light
+		bsr LCECE			; go draw the magic door
+		ldb #6				; change type to wall (invisible magic door)
+LCEA9		ldx b,y				; get graphic
+		bsr LCECE			; draw the graphic
+		leay 8,y			; move to next table entry
+		bra LCE96			; go handle another direction
+LCEB1		rts				; return to caller
+LCEB2		tfr x,y				; save graphic pointer
+		tst b,u				; is there a door in that direction?
+		bne LCEB1			; brif so
+		addb facing			; calculate real direction
+		stb V28A			; save real direction
+		ldd V27C			; fetch render location
+		jsr LD11B			; get new coordinates and room pointer
+		jsr LCF82			; get creature in room
+		beq LCEB1			; brif no creature in room
+		exg x,y				; save creature pointer in Y, get original graphic pointer back
+LCEC8		tst 2,y				; is creature magical?
+		beq LCECE			; brif not - use physical ight
+		dec V275			; render magic light
+LCECE		pshs u				; save registers
+		setlighting			; set light level
+		ldu screendraw			; point to drawing screen
+		drawgraphic			; draw the selected graphic
+		puls u,pc			; restore registers and return
+LCED8		ldd V27C			; get render location
+		jsr LCF82			; get creature in room
+		beq LCEEB			; brif no creature
+		tfr x,y				; save creature pointer
+		ldb 13,y			; get creature tpe
+		lslb				; double it
+		ldx #LDAA3			; point to creature graphics table
+		ldx b,x				; get graphic data
+		bsr LCEC8			; go render graphic
+LCEEB		ldb #3				; right hand
+		ldx #LDCB0			; point to graphic
+		bsr LCEB2			; go render graphic if there's a door
+		ldb #1				; left hand
+		ldx #LDCB9			; point to graphic
+		bsr LCEB2			; go render graphic if there's a door
+		ldx #LDD3C			; point to graphic
+		ldd V27C			; get current location
+		jsr LCFE1			; get hole information
+		bmi LCF09			; brif no hole
+		ldx #LDCC2			; point to graphic table for holes
+		lsla				; two bytes per pointer entry
+		ldx a,x				; get actual graphic for the hole present
+LCF09		bsr LCECE			; go render the graphic
+		clr V291			; reset object iterator
+LCF0D		ldd V27C			; get current room
+		jsr LCF53			; fetch next object on floor
+		beq LCF24			; brif no more objects
+		lda 10,x			; get object type
+		lsla				; double it - two bytes per pointer entry
+		ldx #LD9EE			; point to object images
+		ldx a,x				; get correct graphic image
 		dec V275
-LCECE		pshs u
-		dod S00
-		ldu screendraw
-		drawgraphic
-		puls u,pc
-LCED8		ldd V27C
-		jsr LCF82
-		beq LCEEB
-		tfr x,y
-		ldb 13,y
-		lslb
-		ldx #LDAA3
-		ldx b,x
-		bsr LCEC8
-LCEEB		ldb #3
-		ldx #LDCB0
-		bsr LCEB2
-		ldb #1
-		ldx #LDCB9
-		bsr LCEB2
-		ldx #LDD3C
-		ldd V27C
-		jsr LCFE1
-		bmi LCF09
-		ldx #LDCC2
-		lsla
-		ldx a,x
-LCF09		bsr LCECE
-		clr V291
-LCF0D		ldd V27C
-		jsr LCF53
-		beq LCF24
-		lda 10,x
-		lsla
-		ldx #LD9EE
-		ldx a,x
-		dec V275
-		bsr LCECE
-		bsr LCECE
-		bra LCF0D
-LCF24		tst ,u
-		bne LCF3D
-		lda facing
-		sta V28A
-		ldd V27C
-		jsr LD11B
-		std V27C
-		inc V28B
-		lda V28B
-		cmpa #9
-		lble LCE6E
-LCF3D		rts
-LCF3E		fcb $c8,$80,$50,$32
-		fcb $1f,$14
-LCF44		fcb $0c,$08,$04,$02
-LCF48		fcb $ff,$9c,$64,$41
-		fcb $28,$1a,$10,$0a
-LCF50		fcb $06,$03,$01
-LCF53		bsr LCF63
-		beq LCF62
-		cmpd 2,x
-		bne LCF53
-		tst 5,x
-		bne LCF53
-		andcc #$fb
-LCF62		rts
+		bsr LCECE			; render object
+		bsr LCECE			; render the object
+		bra LCF0D			; go handle another object in the room
+LCF24		tst ,u				; any door looking forward?
+		bne LCF3D			; brif so
+		lda facing			; get direction facing
+		sta V28A			; save direction going
+		ldd V27C			; get current direction
+		jsr LD11B			; get pointer in that direction
+		std V27C			; save new location
+		inc V28B			; bump render distance (next room going forward)
+		lda V28B			; get distance
+		cmpa #9				; is it 9 steps out?
+		lble LCE6E			; brif 9 or less - render another room
+LCF3D		rts				; return to caller
+; These are the scale factors used for rendering rooms.
+		fcb $c8,$80,$50,$32,$1f,$14,$0c,$08,$04,$02
+LCF48		fcb $ff,$9c,$64,$41,$28,$1a,$10,$0a,$06,$03,$01
+LCF53		bsr LCF63			; fetch next object in iteration
+		beq LCF62			; brif no object
+		cmpd 2,x			; is object at desired location
+		bne LCF53			; brif not - try again
+		tst 5,x				; is object in inventory?
+		bne LCF53			; brif so - not in room
+		andcc #$fb			; clear Z for found
+LCF62		rts				; return to caller
 LCF63		pshs a				; save register
 		lda currentlevel		; fetch current level
 		ldx V292			; fetch object pointer
@@ -2610,21 +2611,21 @@
 		ldb #4				; put in 10Hz list
 		jsr LC21D			; go add to scheduling list
 		puls a,b,x,y,u,pc		; restore registers and return
-LCFE1		pshs a,b,x,u
-		ldu holetabptr
-		bsr LCFF2
-		tsta
-		bpl LCFEE
-		bsr LCFF2
-		adda #2
-LCFEE		sta ,s
-		puls a,b,x,u,pc
-LCFF2		lda ,u+
-		bmi LCFFC
-		ldx ,u++
-		cmpx 2,s
-		bne LCFF2
-LCFFC		rts
+LCFE1		pshs a,b,x,u			; save registers
+		ldu holetabptr			; point to hole table for this level (going up)
+		bsr LCFF2			; see if there is a hole for this room
+		tsta				; is there a hole?
+		bpl LCFEE			; brif so - return info
+		bsr LCFF2			; check for this level going down
+		adda #2				; flag the hole as down
+LCFEE		sta ,s				; save hole information for return
+		puls a,b,x,u,pc			; restore registers and return
+LCFF2		lda ,u+				; fetch hole flags
+		bmi LCFFC			; brif end of table entries
+		ldx ,u++			; get location for the hole
+		cmpx 2,s			; does it match the current location?
+		bne LCFF2			; brif not - try another entry
+LCFFC		rts				; return to caller
 ; This is the "hole/ladder" table. Each entry is suffixed by $80. Each set specifies the
 ; holes and ladders between two levels. The first is between levels 1 and 2. The second is
 ; between levels 2 and 3. And so on. You will not that the table includes references to
@@ -3510,9 +3511,9 @@
 		cmpu #LCE66			; is it the regular dungeon display
 		bne LD6B9			; brif not - don't show turning
 		ldx #$8080			; scale factors of 1.0
-		stx V24F
-		clr V28B
-		dod S00
+		stx V24F			; set horizontal and vertical scale factors to 1.0
+		clr V28B			; set render distance to 0 (immediate)
+		setlighting			; set light level for rendering
 		cleargfx1			; clear screen
 		ldx #LD6C6			; point to outline graphic
 		drawgraphic			; draw it
@@ -4167,11 +4168,12 @@
 		fcb $fc
 		fcb $4c,$22,$4e,$44,$00
 		fcb $fe
-LDCC2		fcb 221,14
-		fcb 220,202
-		fcb 221,42
-		fcb 220,208
-		fcb $fb
+; Table of pointers to hole/ladder graphics
+LDCC2		fdb LDD0E
+		fdb LDCCA
+		fdb LDD2A
+		fdb LDCD0
+LDCCA		fcb $fb
 		fdb LDCD6
 		fcb $fd
 		fdb LDD0E