mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-02-05 21:34:30 +00:00
raycast: more hacking
This commit is contained in:
parent
ca7c9dcfb9
commit
1bf6734efa
@ -12,10 +12,14 @@ all: raycast.dsk
|
|||||||
$(DOS33):
|
$(DOS33):
|
||||||
cd ../../utils/dos33fs-utils && make
|
cd ../../utils/dos33fs-utils && make
|
||||||
|
|
||||||
raycast.dsk: $(DOS33) HELLO RAYCAST
|
raycast.dsk: $(DOS33) HELLO RAYCAST RAYMARCH RAYMARCH_TINY RAY.BAS
|
||||||
cp $(EMPTYDISK)/empty.dsk raycast.dsk
|
cp $(EMPTYDISK)/empty.dsk raycast.dsk
|
||||||
$(DOS33) -y raycast.dsk SAVE A HELLO
|
$(DOS33) -y raycast.dsk SAVE A HELLO
|
||||||
|
$(DOS33) -y raycast.dsk SAVE A RAY.BAS
|
||||||
$(DOS33) -y raycast.dsk BSAVE -a 0xc00 RAYCAST
|
$(DOS33) -y raycast.dsk BSAVE -a 0xc00 RAYCAST
|
||||||
|
$(DOS33) -y raycast.dsk BSAVE -a 0xc00 RAYMARCH
|
||||||
|
$(DOS33) -y raycast.dsk BSAVE -a 0xc00 RAYMARCH_TINY
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
@ -25,15 +29,39 @@ HELLO: hello.bas
|
|||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
RAY.BAS: ray.bas
|
||||||
|
$(TOKENIZE) < ray.bas > RAY.BAS
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
RAYCAST: raycast.o
|
RAYCAST: raycast.o
|
||||||
ld65 -o RAYCAST raycast.o -C $(LINKERSCRIPTS)/apple2_c00.inc
|
ld65 -o RAYCAST raycast.o -C $(LINKERSCRIPTS)/apple2_c00.inc
|
||||||
|
|
||||||
raycast.o: raycast.s
|
raycast.o: raycast.s
|
||||||
ca65 -o raycast.o raycast.s -l raycast.lst
|
ca65 -o raycast.o raycast.s -l raycast.lst
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
RAYMARCH: raymarch.o
|
||||||
|
ld65 -o RAYMARCH raymarch.o -C $(LINKERSCRIPTS)/apple2_c00.inc
|
||||||
|
|
||||||
|
raymarch.o: raymarch.s
|
||||||
|
ca65 -o raymarch.o raymarch.s -l raymarch.lst
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
RAYMARCH_TINY: raymarch_tiny.o
|
||||||
|
ld65 -o RAYMARCH_TINY raymarch_tiny.o -C $(LINKERSCRIPTS)/apple2_c00.inc
|
||||||
|
|
||||||
|
raymarch_tiny.o: raymarch_tiny.s
|
||||||
|
ca65 -o raymarch_tiny.o raymarch_tiny.s -l raymarch_tiny.lst
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *~ *.o HELLO RAYCAST *.lst
|
rm -f *~ *.o HELLO RAYCAST RAYMARCH RAYMARCH_TINY *.lst
|
||||||
|
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
10 GR
|
0GR
|
||||||
20 FOR Y=0 TO 39:Z=Y*0.04
|
1Z=H:FORI=0TO39:Z=Z+.04:X=SIN(Z)/2:Y=COS(Z)/2:D=0:R=P:S=Q
|
||||||
30 A=Z+H:XX=SIN(A)/2:YY=COS(A)/2:D=0:RX=PX:RY=PY
|
2D=D+1:R=R+X:S=S+Y:C=0:A=ABS(R):B=ABS(S):IFA>6ORB>6THENC=5
|
||||||
40 D=D+1:IF D>40 THEN 60
|
5IFA>3ANDA<5ANDB>3ANDB<5THENC=1
|
||||||
50 RX=RX+XX:RY=RY+YY
|
6IFC=0THEN2
|
||||||
55 C=0:IF ABS(RX)>16 OR ABS(RY)>16 THEN C=5
|
7U=40/D:IFU>19THENU=19
|
||||||
56 IF RX>4 AND RX<6 AND RY>4 AND RY<6 THEN C=1
|
8V=19-U:U=19+U:COLOR=7:VLIN0,VATI:COLOR=C:VLINV,UATI:COLOR=8:VLINU,39ATI:NEXT:H=H+.2:GOTO1
|
||||||
57 IF C=0 THEN 40
|
|
||||||
60 U=40/D:IF U>19 THEN U=19
|
|
||||||
70 V=19-U:COLOR=7:VLIN0,V AT Y
|
|
||||||
75 COLOR=C:VLINV,V+U+U AT Y
|
|
||||||
80 COLOR=8:VLIN V+U+U,39 AT Y
|
|
||||||
100 NEXT Y:H=H+0.2:GOTO 20
|
|
||||||
|
13
graphics/gr/raycast/ray_good.bas
Normal file
13
graphics/gr/raycast/ray_good.bas
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
10 GR
|
||||||
|
20 Z=H:FOR Y=0 TO 39:Z=Z+0.04
|
||||||
|
30 XX=SIN(Z)/2:YY=COS(Z)/2:D=0:RX=PX:RY=PY
|
||||||
|
40 D=D+1:IF D>40 THEN 60
|
||||||
|
50 RX=RX+XX:RY=RY+YY
|
||||||
|
55 C=0:IF ABS(RX)>16 OR ABS(RY)>16 THEN C=5
|
||||||
|
56 IF RX>4 AND RX<6 AND RY>4 AND RY<6 THEN C=1
|
||||||
|
57 IF C=0 THEN 40
|
||||||
|
60 U=40/D:IF U>19 THEN U=19
|
||||||
|
70 V=19-U:COLOR=7:VLIN0,V AT Y
|
||||||
|
75 COLOR=C:VLINV,V+U+U AT Y
|
||||||
|
80 COLOR=8:VLIN V+U+U,39 AT Y
|
||||||
|
100 NEXT Y:H=H+0.2:GOTO 20
|
8
graphics/gr/raycast/ray_more.bas
Normal file
8
graphics/gr/raycast/ray_more.bas
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
0GR
|
||||||
|
1Z=H:FORI=0TO39:Z=Z+.04:X=SIN(Z)/2:Y=COS(Z)/2:D=0:R=P:S=Q
|
||||||
|
2D=D+1:R=R+X:S=S+Y:C=0:A=ABS(R):B=ABS(S):IFA>8ORB>8THENC=5
|
||||||
|
5IFA>4ANDA<6ANDB>4ANDB<6THENC=1
|
||||||
|
6IFC=0ANDD<40THEN2
|
||||||
|
7U=40/D:IFU>19THENU=19
|
||||||
|
8V=19-U:U=19+U:COLOR=7:VLIN0,VATI:COLOR=C:VLINV,UATI:COLOR=8:VLINU,39ATI
|
||||||
|
9NEXT:H=H+.2:GOTO1
|
@ -1,7 +1,8 @@
|
|||||||
;---------------------------------------
|
;---------------------------------------
|
||||||
; based on 1bir - 1 block interactive raycaster
|
; based on 1bir - 1 block interactive raycaster for Commodore 64
|
||||||
; coded by huseyin kilic (wisdom)
|
; coded by huseyin kilic (wisdom) copyright (c) 2009-2013 crescent
|
||||||
; copyright (c) 2009-2013 crescent
|
;
|
||||||
|
; converted to Apple II by Vince `deater` Weaver
|
||||||
|
|
||||||
.include "hardware.inc"
|
.include "hardware.inc"
|
||||||
|
|
||||||
@ -23,7 +24,8 @@ PLAYERXH = $6a
|
|||||||
PLAYERY = $6b
|
PLAYERY = $6b
|
||||||
PLAYERYH = $6c
|
PLAYERYH = $6c
|
||||||
|
|
||||||
DISTANCE = $70 ; reset in $bc00 and $bc0f calls
|
DISTANCE = $70
|
||||||
|
NEWLOC = $71
|
||||||
|
|
||||||
ROWPTR = $d1
|
ROWPTR = $d1
|
||||||
ROWPTRH = $d2
|
ROWPTRH = $d2
|
||||||
@ -37,8 +39,6 @@ HEADING = $81
|
|||||||
SINADD = $9a
|
SINADD = $9a
|
||||||
COLORS = $b1 ; 3 bytes consecutively
|
COLORS = $b1 ; 3 bytes consecutively
|
||||||
|
|
||||||
; temp
|
|
||||||
CURRENTROW = $ff
|
|
||||||
|
|
||||||
; constants
|
; constants
|
||||||
sin_t = $1000
|
sin_t = $1000
|
||||||
@ -70,7 +70,7 @@ gensin_loop:
|
|||||||
sta sin_t,Y
|
sta sin_t,Y
|
||||||
iny
|
iny
|
||||||
clc
|
clc
|
||||||
] adc SINADD
|
adc SINADD
|
||||||
ldx SINADD
|
ldx SINADD
|
||||||
dec sincount_t,X
|
dec sincount_t,X
|
||||||
bne gensin_loop
|
bne gensin_loop
|
||||||
@ -125,11 +125,10 @@ loop_ray:
|
|||||||
; distance is reset on return from this call
|
; distance is reset on return from this call
|
||||||
jsr getsincos_copyplr2ray
|
jsr getsincos_copyplr2ray
|
||||||
|
|
||||||
|
|
||||||
; reset line row before each column gets drawn
|
; reset line row before each column gets drawn
|
||||||
; (needed in vertical line section)
|
; (needed in vertical line section)
|
||||||
; X is 0 here?
|
; X is 0 here?
|
||||||
stx CURRENTROW
|
stx DISTANCE
|
||||||
|
|
||||||
loop_dist:
|
loop_dist:
|
||||||
|
|
||||||
@ -209,7 +208,8 @@ vline_loop:
|
|||||||
; vline sky, 0 to FLOOR_SKY_HEIGHT
|
; vline sky, 0 to FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
; load color
|
; load color
|
||||||
lda #$77 ; sky blue
|
;lda #$77 ; sky blue
|
||||||
|
lda #$00 ; sky black
|
||||||
sta COLOR
|
sta COLOR
|
||||||
|
|
||||||
lda FLOOR_SKY_HEIGHT
|
lda FLOOR_SKY_HEIGHT
|
||||||
@ -315,21 +315,40 @@ done_user_input:
|
|||||||
; for x and y components and also because of
|
; for x and y components and also because of
|
||||||
; brute force approach
|
; brute force approach
|
||||||
addsteptopos:
|
addsteptopos:
|
||||||
|
ldx #$0
|
||||||
|
stx NEWLOC
|
||||||
|
|
||||||
ldx #$02
|
ldx #$02
|
||||||
loop_stepadd:
|
loop_stepadd:
|
||||||
lda STEPX,X ; & y
|
lda STEPX,X ; & y
|
||||||
ora #$7f ; sign extend 8 bit step value to 16 bit
|
ora #$7f ; sign extend 8 bit step value to 16 bit
|
||||||
bmi was_neg ; was negative *+4
|
bmi was_neg ; was negative
|
||||||
lda #$00
|
lda #$00
|
||||||
was_neg:
|
was_neg:
|
||||||
pha
|
pha
|
||||||
;clc
|
;clc
|
||||||
lda STEPX,x ; & y
|
lda STEPX,X ; & y
|
||||||
adc RAYPOSX,x ; & y
|
adc RAYPOSX,X ; & y
|
||||||
sta RAYPOSX,x ; & y
|
sta RAYPOSX,X ; & y
|
||||||
pla
|
pla
|
||||||
adc RAYPOSXH,x ; & y
|
|
||||||
sta RAYPOSXH,x ; & y
|
php
|
||||||
|
|
||||||
|
bcc blah ; no carry
|
||||||
|
|
||||||
|
cpx #2
|
||||||
|
bne blah
|
||||||
|
|
||||||
|
stx NEWLOC
|
||||||
|
|
||||||
|
|
||||||
|
blah:
|
||||||
|
plp
|
||||||
|
|
||||||
|
adc RAYPOSXH,X ; & y
|
||||||
|
sta RAYPOSXH,X ; & y
|
||||||
|
|
||||||
|
|
||||||
dex
|
dex
|
||||||
dex
|
dex
|
||||||
bpl loop_stepadd
|
bpl loop_stepadd
|
||||||
@ -346,11 +365,20 @@ was_neg:
|
|||||||
asl
|
asl
|
||||||
asl
|
asl
|
||||||
|
|
||||||
; by doing ora instead of adc, it is possible to have
|
|
||||||
; a closed area map in $ecb9
|
|
||||||
adc RAYPOSYH
|
adc RAYPOSYH
|
||||||
tax
|
tax
|
||||||
lda map_t,X
|
lda map_t,X
|
||||||
|
|
||||||
|
beq step_exit
|
||||||
|
|
||||||
|
ldx NEWLOC
|
||||||
|
cpx #2
|
||||||
|
bne step_exit
|
||||||
|
|
||||||
|
sec
|
||||||
|
sbc #$88
|
||||||
|
|
||||||
|
|
||||||
step_exit:
|
step_exit:
|
||||||
rts
|
rts
|
||||||
|
|
||||||
@ -368,15 +396,16 @@ getsincos_copyplr2ray:
|
|||||||
; copy player position to ray position for a start
|
; copy player position to ray position for a start
|
||||||
; through the basic rom
|
; through the basic rom
|
||||||
|
|
||||||
copyplr2ray: ; $bc00 in c64 kernel?
|
|
||||||
|
|
||||||
ldx #$05 ; copy 5 bytes, from 69..6D to 61..65
|
; copy 4 bytes, from 69,6A,6B,6C to 61,62,63,64
|
||||||
|
copyplr2ray:
|
||||||
|
|
||||||
|
ldx #$04
|
||||||
copyloop:
|
copyloop:
|
||||||
lda $68,X
|
lda $68,X
|
||||||
sta $60,X
|
sta $60,X
|
||||||
dex
|
dex
|
||||||
bne copyloop
|
bne copyloop
|
||||||
stx DISTANCE ; side effect, needed?
|
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
@ -407,17 +436,18 @@ stepandcopy:
|
|||||||
|
|
||||||
; yes, move player by
|
; yes, move player by
|
||||||
; copying ray position to player position
|
; copying ray position to player position
|
||||||
; through the basic rom
|
|
||||||
|
|
||||||
copyray2plr: ; BC0f in c64 ROM
|
copyray2plr:
|
||||||
|
|
||||||
ldx #$6
|
; Copy 61,62,63,64 to 69,6A,6B,6C
|
||||||
|
|
||||||
|
ldx #$4
|
||||||
r2_loop:
|
r2_loop:
|
||||||
lda $60,X
|
lda $60,X
|
||||||
sta $68,X
|
sta $68,X
|
||||||
dex
|
dex
|
||||||
bne r2_loop
|
bne r2_loop
|
||||||
stx DISTANCE
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
;---------------------------------------
|
;---------------------------------------
|
||||||
@ -446,19 +476,19 @@ map_t:
|
|||||||
|
|
||||||
map_t:
|
map_t:
|
||||||
.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
.byte $55,$00,$11,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$99,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$22,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$CC,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$22,$22,$22,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$CC,$CC,$CC,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$22,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$CC,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$33,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
.byte $55,$00,$99,$99,$11,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$99,$99,$11,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$EE,$00,$DD,$00,$CC,$00,$BB,$00,$AA,$00,$99,$00,$00,$ff
|
||||||
.byte $55,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$55
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||||
|
|
||||||
|
529
graphics/gr/raycast/raymarch.s
Normal file
529
graphics/gr/raycast/raymarch.s
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
;---------------------------------------
|
||||||
|
; based on 1bir - 1 block interactive raycaster for Commodore 64
|
||||||
|
; coded by huseyin kilic (wisdom) copyright (c) 2009-2013 crescent
|
||||||
|
;
|
||||||
|
; converted to Apple II by Vince `deater` Weaver
|
||||||
|
|
||||||
|
.include "hardware.inc"
|
||||||
|
|
||||||
|
; zero page
|
||||||
|
|
||||||
|
V2 = $2D
|
||||||
|
COLOR = $30
|
||||||
|
|
||||||
|
RAYPOSX = $61
|
||||||
|
RAYPOSXH = $62
|
||||||
|
RAYPOSY = $63
|
||||||
|
RAYPOSYH = $64
|
||||||
|
|
||||||
|
STEPX = $66 ; leave 1 byte between x and y
|
||||||
|
STEPY = $68
|
||||||
|
|
||||||
|
PLAYERX = $69
|
||||||
|
PLAYERXH = $6a
|
||||||
|
PLAYERY = $6b
|
||||||
|
PLAYERYH = $6c
|
||||||
|
|
||||||
|
DISTANCEL = $6F
|
||||||
|
DISTANCE = $70
|
||||||
|
NEWLOC = $71
|
||||||
|
HEIGHT = $73
|
||||||
|
HEIGHTL = $74
|
||||||
|
|
||||||
|
ROWPTR = $d1
|
||||||
|
ROWPTRH = $d2
|
||||||
|
LINEH_T = $d9
|
||||||
|
|
||||||
|
WALL_HEIGHT = $f8
|
||||||
|
FLOOR_SKY_HEIGHT= $f9
|
||||||
|
|
||||||
|
; external value dependencies
|
||||||
|
HEADING = $81
|
||||||
|
SINADD = $9a
|
||||||
|
COLORS = $b1 ; 3 bytes consecutively
|
||||||
|
|
||||||
|
|
||||||
|
; constants
|
||||||
|
sin_t = $1000
|
||||||
|
blocksize = $28
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; main
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
main:
|
||||||
|
jsr SETGR
|
||||||
|
bit FULLGR
|
||||||
|
|
||||||
|
lda #$20
|
||||||
|
sta HEADING
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; sin/cos table generator
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
; first generate sine for 0..63 (0..90 degrees)
|
||||||
|
|
||||||
|
lda #3
|
||||||
|
sta SINADD
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
tay
|
||||||
|
gensin_loop:
|
||||||
|
sta sin_t,Y
|
||||||
|
iny
|
||||||
|
clc
|
||||||
|
adc SINADD
|
||||||
|
ldx SINADD
|
||||||
|
dec sincount_t,X
|
||||||
|
bne gensin_loop
|
||||||
|
dec SINADD
|
||||||
|
bpl gensin_loop
|
||||||
|
|
||||||
|
; x = $00
|
||||||
|
; y = $40
|
||||||
|
|
||||||
|
; next generate
|
||||||
|
|
||||||
|
gensin_loop2:
|
||||||
|
lda sin_t,X
|
||||||
|
|
||||||
|
sta sin_t+$0100,X ; copy at $100 so cosine easier
|
||||||
|
|
||||||
|
sta sin_t-1+$40,Y ; store 90-180 degrees
|
||||||
|
|
||||||
|
eor #$ff ; invert
|
||||||
|
sta sin_t+$80,X ; store for 180-270 degrees
|
||||||
|
sta sin_t-1+$c0,Y ; store for 270-360 degrees
|
||||||
|
inx
|
||||||
|
dey
|
||||||
|
bpl gensin_loop2
|
||||||
|
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; raycaster
|
||||||
|
;---------------------------------------
|
||||||
|
loop_main:
|
||||||
|
; cast 40 rays for each screen column
|
||||||
|
; starting with rightmost one
|
||||||
|
; Y is used as global column index
|
||||||
|
; throughout the rest of the program
|
||||||
|
ldy #39
|
||||||
|
|
||||||
|
loop_ray:
|
||||||
|
; determine current ray's direction
|
||||||
|
; by taking player's current direction
|
||||||
|
; and fov into account
|
||||||
|
; fov is 40 b-rads out of 256 b-rads
|
||||||
|
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
adc HEADING
|
||||||
|
;sec
|
||||||
|
sbc #19+1 ; half of the fov (+1 because of sec)
|
||||||
|
tax
|
||||||
|
|
||||||
|
; get sin/cos values accordingly
|
||||||
|
; and copy player position to current ray position
|
||||||
|
; distance is reset on return from this call
|
||||||
|
jsr getsincos_copyplr2ray
|
||||||
|
|
||||||
|
; reset line row before each column gets drawn
|
||||||
|
; (needed in vertical line section)
|
||||||
|
; X is 0 here?
|
||||||
|
stx DISTANCEL
|
||||||
|
stx DISTANCE
|
||||||
|
|
||||||
|
loop_dist:
|
||||||
|
|
||||||
|
; step along current ray's path and find distance
|
||||||
|
clc
|
||||||
|
lda DISTANCEL
|
||||||
|
adc #$80
|
||||||
|
sta DISTANCEL
|
||||||
|
bcc nod
|
||||||
|
inc DISTANCE
|
||||||
|
nod:
|
||||||
|
; limit distance when it is needed in larger maps
|
||||||
|
; or open (wrapped) maps
|
||||||
|
|
||||||
|
; max distance = $29
|
||||||
|
; lda DISTANCE
|
||||||
|
; cmp #$29
|
||||||
|
; bcs skip_dist
|
||||||
|
|
||||||
|
; max distance = $40 (make sure ar is always 0 here)
|
||||||
|
; bit DISTANCE
|
||||||
|
; bvs skip_dist
|
||||||
|
|
||||||
|
; max DISTANCE = $80
|
||||||
|
lda DISTANCE
|
||||||
|
bmi skip_dist
|
||||||
|
|
||||||
|
jsr addsteptopos
|
||||||
|
|
||||||
|
; on return from last call, A is cell (block) value
|
||||||
|
; A == 0 means empty cell, so continue tracing
|
||||||
|
beq loop_dist
|
||||||
|
|
||||||
|
skip_dist:
|
||||||
|
; now A contains the value in reached map position
|
||||||
|
; (or last cell value fetched if max distance is reached)
|
||||||
|
|
||||||
|
; use A or X to colorize the block
|
||||||
|
; and #$07
|
||||||
|
; ora #$03
|
||||||
|
sta COLORS+1
|
||||||
|
|
||||||
|
; find out visible block height
|
||||||
|
; according to distance
|
||||||
|
ldx #$ff
|
||||||
|
|
||||||
|
; calculate visible block height through simple division
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta HEIGHT
|
||||||
|
sta HEIGHTL
|
||||||
|
height_loop:
|
||||||
|
inx
|
||||||
|
lda HEIGHTL
|
||||||
|
adc DISTANCEL
|
||||||
|
sta HEIGHTL
|
||||||
|
|
||||||
|
lda HEIGHT
|
||||||
|
adc DISTANCE
|
||||||
|
sta HEIGHT
|
||||||
|
|
||||||
|
cmp #<blocksize
|
||||||
|
bcc height_loop
|
||||||
|
|
||||||
|
dex
|
||||||
|
|
||||||
|
; lda #<blocksize
|
||||||
|
;loop_div:
|
||||||
|
; inx
|
||||||
|
; ; sec
|
||||||
|
; sbc DISTANCE
|
||||||
|
; bcs loop_div
|
||||||
|
|
||||||
|
; X = half of visible block height
|
||||||
|
txa
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; vertical line
|
||||||
|
;---------------------------------------
|
||||||
|
; Y = x position (screen column)
|
||||||
|
; A = half height (zero height is ok)
|
||||||
|
cmp #24 ; height > 24?
|
||||||
|
bcc vline_validheight
|
||||||
|
lda #23 ; make sure max height = 24
|
||||||
|
vline_validheight:
|
||||||
|
asl ; calculate full height
|
||||||
|
sta WALL_HEIGHT ; store for looping below
|
||||||
|
eor #$ff ; subtract full height from screen height
|
||||||
|
; sec ; (48 rows)
|
||||||
|
adc #48+1 ; +1 because of sec
|
||||||
|
lsr ; sky/floor heights are equal to each other
|
||||||
|
sta FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
|
; loop through 3 sections of one screen column
|
||||||
|
; i.e. sky - wall - floor
|
||||||
|
|
||||||
|
vline_loop:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;==========
|
||||||
|
; vline sky, 0 to FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
|
; load color
|
||||||
|
;lda #$77 ; sky blue
|
||||||
|
lda #$00 ; sky black
|
||||||
|
sta COLOR
|
||||||
|
|
||||||
|
lda FLOOR_SKY_HEIGHT
|
||||||
|
sta V2
|
||||||
|
lda #0
|
||||||
|
|
||||||
|
jsr VLINE ; VLINE A,$2D at Y (Y preserved, A=V2)
|
||||||
|
|
||||||
|
;=================
|
||||||
|
; vline wall, FLOOR_SKY_HEIGHT to FLOOR_SKY_HEIGHT+WALL_HEIGHT
|
||||||
|
|
||||||
|
ldx COLORS+1
|
||||||
|
stx COLOR
|
||||||
|
|
||||||
|
; A already FLOOR_SKY_HEIGHT
|
||||||
|
clc
|
||||||
|
adc WALL_HEIGHT
|
||||||
|
sta V2
|
||||||
|
|
||||||
|
lda FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
|
jsr VLINE ; VLINE A,$2D at Y
|
||||||
|
|
||||||
|
;=============
|
||||||
|
; vline floor, WALL_HEIGHT+FLOOR_SKY_HEIGHT to 47
|
||||||
|
|
||||||
|
ldx #$88
|
||||||
|
stx COLOR
|
||||||
|
|
||||||
|
; A already WALL_HEIGHT+FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
|
ldx #47
|
||||||
|
stx V2
|
||||||
|
|
||||||
|
jsr VLINE ; VLINE A,$2D at Y
|
||||||
|
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; advance to next ray/column
|
||||||
|
dey
|
||||||
|
bpl loop_ray
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; user input
|
||||||
|
;---------------------------------------
|
||||||
|
; common preparation code to set up sin/cos and
|
||||||
|
; to copy player position to ray position to trace movement
|
||||||
|
; direction to determine if player hits a block
|
||||||
|
; in case player actually tries to move forward or backwards
|
||||||
|
|
||||||
|
ldx HEADING
|
||||||
|
jsr getsincos_copyplr2ray
|
||||||
|
|
||||||
|
; get joystick 2 status (lowest 4 bits)
|
||||||
|
; and check each bit to determine action
|
||||||
|
|
||||||
|
lda KEYPRESS
|
||||||
|
beq done_user_input
|
||||||
|
|
||||||
|
cmp #'W'+$80
|
||||||
|
bne skip_j1
|
||||||
|
|
||||||
|
; try to move forward
|
||||||
|
pha
|
||||||
|
jsr stepandcopy
|
||||||
|
pla
|
||||||
|
|
||||||
|
skip_j1:
|
||||||
|
cmp #'S'+$80
|
||||||
|
bne skip_j2
|
||||||
|
|
||||||
|
; try to move backward
|
||||||
|
pha
|
||||||
|
jsr invertstepandcopy
|
||||||
|
pla
|
||||||
|
|
||||||
|
skip_j2:
|
||||||
|
cmp #'A'+$80
|
||||||
|
bne skip_j3
|
||||||
|
|
||||||
|
; turn right
|
||||||
|
dec HEADING
|
||||||
|
dec HEADING
|
||||||
|
|
||||||
|
skip_j3:
|
||||||
|
cmp #'D'+$80
|
||||||
|
bne done_user_input
|
||||||
|
|
||||||
|
; turn left
|
||||||
|
inc HEADING
|
||||||
|
inc HEADING
|
||||||
|
|
||||||
|
done_user_input:
|
||||||
|
bit KEYRESET ; clear keyboard buffer
|
||||||
|
|
||||||
|
; absolute jump, as carry is always 0 here
|
||||||
|
jmp loop_main
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; ray tracing subroutines
|
||||||
|
;---------------------------------------
|
||||||
|
; heart of tracing, very slow, because of looping
|
||||||
|
; for x and y components and also because of
|
||||||
|
; brute force approach
|
||||||
|
addsteptopos:
|
||||||
|
ldx #$0
|
||||||
|
stx NEWLOC
|
||||||
|
|
||||||
|
ldx #$02
|
||||||
|
loop_stepadd:
|
||||||
|
lda STEPX,X ; & y
|
||||||
|
ora #$7f ; sign extend 8 bit step value to 16 bit
|
||||||
|
bmi was_neg ; was negative
|
||||||
|
lda #$00
|
||||||
|
was_neg:
|
||||||
|
pha
|
||||||
|
;clc
|
||||||
|
lda STEPX,X ; & y
|
||||||
|
adc RAYPOSX,X ; & y
|
||||||
|
sta RAYPOSX,X ; & y
|
||||||
|
pla
|
||||||
|
|
||||||
|
php
|
||||||
|
|
||||||
|
bcc blah ; no carry
|
||||||
|
|
||||||
|
cpx #2
|
||||||
|
bne blah
|
||||||
|
|
||||||
|
stx NEWLOC
|
||||||
|
|
||||||
|
|
||||||
|
blah:
|
||||||
|
plp
|
||||||
|
|
||||||
|
adc RAYPOSXH,X ; & y
|
||||||
|
sta RAYPOSXH,X ; & y
|
||||||
|
|
||||||
|
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
bpl loop_stepadd
|
||||||
|
|
||||||
|
; A = RAYPOSXH
|
||||||
|
|
||||||
|
; calculate index to look up the map cell
|
||||||
|
; the map area is 8x8 bytes
|
||||||
|
; + instead of the usual y * 8 + x
|
||||||
|
; x * 8 + y done here, to save some bytes
|
||||||
|
; (just causing a flip of the map as a side effect)
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
|
||||||
|
adc RAYPOSYH
|
||||||
|
tax
|
||||||
|
lda map_t,X
|
||||||
|
|
||||||
|
beq step_exit
|
||||||
|
|
||||||
|
ldx NEWLOC
|
||||||
|
cpx #2
|
||||||
|
bne step_exit
|
||||||
|
|
||||||
|
sec
|
||||||
|
sbc #$88
|
||||||
|
|
||||||
|
|
||||||
|
step_exit:
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; getsincos_copyplr2ray
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
getsincos_copyplr2ray:
|
||||||
|
lda sin_t,X ; sin(x)
|
||||||
|
cmp #$80
|
||||||
|
ror
|
||||||
|
sta STEPX
|
||||||
|
|
||||||
|
lda sin_t+$40,X ; cos(x)
|
||||||
|
cmp #$80
|
||||||
|
ror
|
||||||
|
sta STEPY
|
||||||
|
|
||||||
|
|
||||||
|
; copy player position to ray position for a start
|
||||||
|
; through the basic rom
|
||||||
|
|
||||||
|
|
||||||
|
; copy 4 bytes, from 69,6A,6B,6C to 61,62,63,64
|
||||||
|
copyplr2ray:
|
||||||
|
|
||||||
|
ldx #$04
|
||||||
|
copyloop:
|
||||||
|
lda $68,X
|
||||||
|
sta $60,X
|
||||||
|
dex
|
||||||
|
bne copyloop
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
;======================================
|
||||||
|
; invert step and copy
|
||||||
|
;======================================
|
||||||
|
invertstepandcopy:
|
||||||
|
; invert step variables for backward motion
|
||||||
|
|
||||||
|
invertstepx: ; from BFB8 in C64 ROM
|
||||||
|
lda $66
|
||||||
|
eor #$ff
|
||||||
|
sta $66
|
||||||
|
|
||||||
|
invertstepy:
|
||||||
|
lda STEPY
|
||||||
|
eor #$ff
|
||||||
|
sta STEPY
|
||||||
|
|
||||||
|
;=======================================
|
||||||
|
; stepandcopy
|
||||||
|
;=======================================
|
||||||
|
stepandcopy:
|
||||||
|
; see if player can move to the direction desired
|
||||||
|
jsr addsteptopos
|
||||||
|
|
||||||
|
bne step_exit ; no, return without doing anything
|
||||||
|
|
||||||
|
; yes, move player by
|
||||||
|
; copying ray position to player position
|
||||||
|
|
||||||
|
copyray2plr:
|
||||||
|
|
||||||
|
; Copy 61,62,63,64 to 69,6A,6B,6C
|
||||||
|
|
||||||
|
ldx #$4
|
||||||
|
r2_loop:
|
||||||
|
lda $60,X
|
||||||
|
sta $68,X
|
||||||
|
dex
|
||||||
|
bne r2_loop
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; data
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
; number of sin additions (backwards)
|
||||||
|
sincount_t:
|
||||||
|
.byte 6,14,19,25
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
.if 0
|
||||||
|
|
||||||
|
map_t:
|
||||||
|
.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||||
|
.byte $55,$00,$00,$00,$00,$00,$00,$55
|
||||||
|
.byte $55,$00,$44,$00,$00,$00,$00,$55
|
||||||
|
.byte $55,$00,$00,$00,$00,$11,$00,$55
|
||||||
|
.byte $55,$22,$00,$00,$00,$00,$00,$55
|
||||||
|
.byte $55,$00,$00,$99,$00,$00,$00,$55
|
||||||
|
.byte $55,$00,$00,$00,$00,$00,$00,$55
|
||||||
|
.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||||
|
|
||||||
|
|
||||||
|
.endif
|
||||||
|
|
||||||
|
map_t:
|
||||||
|
.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$99,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$CC,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$CC,$CC,$CC,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$CC,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$99,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$EE,$00,$DD,$00,$CC,$00,$BB,$00,$AA,$00,$99,$00,$00,$ff
|
||||||
|
.byte $ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||||
|
.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||||
|
|
499
graphics/gr/raycast/raymarch_tiny.s
Normal file
499
graphics/gr/raycast/raymarch_tiny.s
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
;---------------------------------------
|
||||||
|
; based on 1bir - 1 block interactive raycaster for Commodore 64
|
||||||
|
; coded by huseyin kilic (wisdom) copyright (c) 2009-2013 crescent
|
||||||
|
;
|
||||||
|
; converted to Apple II by Vince `deater` Weaver
|
||||||
|
|
||||||
|
.include "hardware.inc"
|
||||||
|
|
||||||
|
; zero page
|
||||||
|
|
||||||
|
V2 = $2D
|
||||||
|
COLOR = $30
|
||||||
|
|
||||||
|
RAYPOSX = $61
|
||||||
|
RAYPOSXH = $62
|
||||||
|
RAYPOSY = $63
|
||||||
|
RAYPOSYH = $64
|
||||||
|
|
||||||
|
STEPX = $66 ; leave 1 byte between x and y
|
||||||
|
STEPY = $68
|
||||||
|
|
||||||
|
PLAYERX = $69
|
||||||
|
PLAYERXH = $6a
|
||||||
|
PLAYERY = $6b
|
||||||
|
PLAYERYH = $6c
|
||||||
|
|
||||||
|
DISTANCEL = $6F
|
||||||
|
DISTANCE = $70
|
||||||
|
NEWLOC = $71
|
||||||
|
HEIGHT = $73
|
||||||
|
HEIGHTL = $74
|
||||||
|
|
||||||
|
ROWPTR = $d1
|
||||||
|
ROWPTRH = $d2
|
||||||
|
LINEH_T = $d9
|
||||||
|
|
||||||
|
WALL_HEIGHT = $f8
|
||||||
|
FLOOR_SKY_HEIGHT= $f9
|
||||||
|
|
||||||
|
; external value dependencies
|
||||||
|
HEADING = $81
|
||||||
|
SINADD = $9a
|
||||||
|
COLORS = $b1 ; 3 bytes consecutively
|
||||||
|
|
||||||
|
|
||||||
|
; constants
|
||||||
|
sin_t = $1000
|
||||||
|
blocksize = $28
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; main
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
main:
|
||||||
|
jsr SETGR
|
||||||
|
bit FULLGR
|
||||||
|
|
||||||
|
lda #$20
|
||||||
|
sta HEADING
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; sin/cos table generator
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
; first generate sine for 0..63 (0..90 degrees)
|
||||||
|
|
||||||
|
lda #3
|
||||||
|
sta SINADD
|
||||||
|
|
||||||
|
lda #$00
|
||||||
|
tay
|
||||||
|
gensin_loop:
|
||||||
|
sta sin_t,Y
|
||||||
|
iny
|
||||||
|
clc
|
||||||
|
adc SINADD
|
||||||
|
ldx SINADD
|
||||||
|
dec sincount_t,X
|
||||||
|
bne gensin_loop
|
||||||
|
dec SINADD
|
||||||
|
bpl gensin_loop
|
||||||
|
|
||||||
|
; x = $00
|
||||||
|
; y = $40
|
||||||
|
|
||||||
|
; next generate
|
||||||
|
|
||||||
|
gensin_loop2:
|
||||||
|
lda sin_t,X
|
||||||
|
|
||||||
|
sta sin_t+$0100,X ; copy at $100 so cosine easier
|
||||||
|
|
||||||
|
sta sin_t-1+$40,Y ; store 90-180 degrees
|
||||||
|
|
||||||
|
eor #$ff ; invert
|
||||||
|
sta sin_t+$80,X ; store for 180-270 degrees
|
||||||
|
sta sin_t-1+$c0,Y ; store for 270-360 degrees
|
||||||
|
inx
|
||||||
|
dey
|
||||||
|
bpl gensin_loop2
|
||||||
|
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; raycaster
|
||||||
|
;---------------------------------------
|
||||||
|
loop_main:
|
||||||
|
; cast 40 rays for each screen column
|
||||||
|
; starting with rightmost one
|
||||||
|
; Y is used as global column index
|
||||||
|
; throughout the rest of the program
|
||||||
|
ldy #39
|
||||||
|
|
||||||
|
loop_ray:
|
||||||
|
; determine current ray's direction
|
||||||
|
; by taking player's current direction
|
||||||
|
; and fov into account
|
||||||
|
; fov is 40 b-rads out of 256 b-rads
|
||||||
|
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
adc HEADING
|
||||||
|
;sec
|
||||||
|
sbc #19+1 ; half of the fov (+1 because of sec)
|
||||||
|
tax
|
||||||
|
|
||||||
|
; get sin/cos values accordingly
|
||||||
|
; and copy player position to current ray position
|
||||||
|
; distance is reset on return from this call
|
||||||
|
jsr getsincos_copyplr2ray
|
||||||
|
|
||||||
|
; reset line row before each column gets drawn
|
||||||
|
; (needed in vertical line section)
|
||||||
|
; X is 0 here?
|
||||||
|
stx DISTANCEL
|
||||||
|
stx DISTANCE
|
||||||
|
|
||||||
|
loop_dist:
|
||||||
|
|
||||||
|
; step along current ray's path and find distance
|
||||||
|
clc
|
||||||
|
lda DISTANCEL
|
||||||
|
adc #$80
|
||||||
|
sta DISTANCEL
|
||||||
|
bcc nod
|
||||||
|
inc DISTANCE
|
||||||
|
nod:
|
||||||
|
; limit distance when it is needed in larger maps
|
||||||
|
; or open (wrapped) maps
|
||||||
|
|
||||||
|
; max distance = $29
|
||||||
|
lda DISTANCE
|
||||||
|
cmp #$29
|
||||||
|
bcs skip_dist
|
||||||
|
|
||||||
|
; max distance = $40 (make sure ar is always 0 here)
|
||||||
|
; bit DISTANCE
|
||||||
|
; bvs skip_dist
|
||||||
|
|
||||||
|
; max DISTANCE = $80
|
||||||
|
; lda DISTANCE
|
||||||
|
; bmi skip_dist
|
||||||
|
|
||||||
|
jsr addsteptopos
|
||||||
|
|
||||||
|
; on return from last call, A is cell (block) value
|
||||||
|
; A == 0 means empty cell, so continue tracing
|
||||||
|
beq loop_dist
|
||||||
|
|
||||||
|
skip_dist:
|
||||||
|
; now A contains the value in reached map position
|
||||||
|
; (or last cell value fetched if max distance is reached)
|
||||||
|
|
||||||
|
; use A or X to colorize the block
|
||||||
|
; and #$07
|
||||||
|
; ora #$03
|
||||||
|
sta COLORS+1
|
||||||
|
|
||||||
|
; find out visible block height
|
||||||
|
; according to distance
|
||||||
|
ldx #$ff
|
||||||
|
|
||||||
|
; calculate visible block height through simple division
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta HEIGHT
|
||||||
|
sta HEIGHTL
|
||||||
|
height_loop:
|
||||||
|
inx
|
||||||
|
lda HEIGHTL
|
||||||
|
adc DISTANCEL
|
||||||
|
sta HEIGHTL
|
||||||
|
|
||||||
|
lda HEIGHT
|
||||||
|
adc DISTANCE
|
||||||
|
sta HEIGHT
|
||||||
|
|
||||||
|
cmp #<blocksize
|
||||||
|
bcc height_loop
|
||||||
|
|
||||||
|
;dex
|
||||||
|
|
||||||
|
; lda #<blocksize
|
||||||
|
;loop_div:
|
||||||
|
; inx
|
||||||
|
; ; sec
|
||||||
|
; sbc DISTANCE
|
||||||
|
; bcs loop_div
|
||||||
|
|
||||||
|
; X = half of visible block height
|
||||||
|
txa
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; vertical line
|
||||||
|
;---------------------------------------
|
||||||
|
; Y = x position (screen column)
|
||||||
|
; A = half height (zero height is ok)
|
||||||
|
cmp #24 ; height > 24?
|
||||||
|
bcc vline_validheight
|
||||||
|
lda #23 ; make sure max height = 24
|
||||||
|
vline_validheight:
|
||||||
|
asl ; calculate full height
|
||||||
|
sta WALL_HEIGHT ; store for looping below
|
||||||
|
eor #$ff ; subtract full height from screen height
|
||||||
|
; sec ; (48 rows)
|
||||||
|
adc #48+1 ; +1 because of sec
|
||||||
|
lsr ; sky/floor heights are equal to each other
|
||||||
|
sta FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
|
; loop through 3 sections of one screen column
|
||||||
|
; i.e. sky - wall - floor
|
||||||
|
|
||||||
|
vline_loop:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;==========
|
||||||
|
; vline sky, 0 to FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
|
; load color
|
||||||
|
;lda #$77 ; sky blue
|
||||||
|
lda #$00 ; sky black
|
||||||
|
sta COLOR
|
||||||
|
|
||||||
|
lda FLOOR_SKY_HEIGHT
|
||||||
|
sta V2
|
||||||
|
lda #0
|
||||||
|
|
||||||
|
jsr VLINE ; VLINE A,$2D at Y (Y preserved, A=V2)
|
||||||
|
|
||||||
|
;=================
|
||||||
|
; vline wall, FLOOR_SKY_HEIGHT to FLOOR_SKY_HEIGHT+WALL_HEIGHT
|
||||||
|
|
||||||
|
ldx COLORS+1
|
||||||
|
stx COLOR
|
||||||
|
|
||||||
|
; A already FLOOR_SKY_HEIGHT
|
||||||
|
clc
|
||||||
|
adc WALL_HEIGHT
|
||||||
|
sta V2
|
||||||
|
|
||||||
|
lda FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
|
jsr VLINE ; VLINE A,$2D at Y
|
||||||
|
|
||||||
|
;=============
|
||||||
|
; vline floor, WALL_HEIGHT+FLOOR_SKY_HEIGHT to 47
|
||||||
|
|
||||||
|
ldx #$88
|
||||||
|
stx COLOR
|
||||||
|
|
||||||
|
; A already WALL_HEIGHT+FLOOR_SKY_HEIGHT
|
||||||
|
|
||||||
|
ldx #47
|
||||||
|
stx V2
|
||||||
|
|
||||||
|
jsr VLINE ; VLINE A,$2D at Y
|
||||||
|
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; advance to next ray/column
|
||||||
|
dey
|
||||||
|
bpl loop_ray
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; user input
|
||||||
|
;---------------------------------------
|
||||||
|
; common preparation code to set up sin/cos and
|
||||||
|
; to copy player position to ray position to trace movement
|
||||||
|
; direction to determine if player hits a block
|
||||||
|
; in case player actually tries to move forward or backwards
|
||||||
|
|
||||||
|
ldx HEADING
|
||||||
|
jsr getsincos_copyplr2ray
|
||||||
|
|
||||||
|
; get joystick 2 status (lowest 4 bits)
|
||||||
|
; and check each bit to determine action
|
||||||
|
|
||||||
|
lda KEYPRESS
|
||||||
|
beq done_user_input
|
||||||
|
|
||||||
|
cmp #'W'+$80
|
||||||
|
bne skip_j1
|
||||||
|
|
||||||
|
; try to move forward
|
||||||
|
pha
|
||||||
|
jsr stepandcopy
|
||||||
|
pla
|
||||||
|
|
||||||
|
skip_j1:
|
||||||
|
cmp #'S'+$80
|
||||||
|
bne skip_j2
|
||||||
|
|
||||||
|
; try to move backward
|
||||||
|
pha
|
||||||
|
jsr invertstepandcopy
|
||||||
|
pla
|
||||||
|
|
||||||
|
skip_j2:
|
||||||
|
cmp #'A'+$80
|
||||||
|
bne skip_j3
|
||||||
|
|
||||||
|
; turn right
|
||||||
|
dec HEADING
|
||||||
|
dec HEADING
|
||||||
|
|
||||||
|
skip_j3:
|
||||||
|
cmp #'D'+$80
|
||||||
|
bne done_user_input
|
||||||
|
|
||||||
|
; turn left
|
||||||
|
inc HEADING
|
||||||
|
inc HEADING
|
||||||
|
|
||||||
|
done_user_input:
|
||||||
|
bit KEYRESET ; clear keyboard buffer
|
||||||
|
|
||||||
|
; absolute jump, as carry is always 0 here
|
||||||
|
jmp loop_main
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; ray tracing subroutines
|
||||||
|
;---------------------------------------
|
||||||
|
; heart of tracing, very slow, because of looping
|
||||||
|
; for x and y components and also because of
|
||||||
|
; brute force approach
|
||||||
|
addsteptopos:
|
||||||
|
ldx #$0
|
||||||
|
stx NEWLOC
|
||||||
|
|
||||||
|
ldx #$02
|
||||||
|
loop_stepadd:
|
||||||
|
lda STEPX,X ; & y
|
||||||
|
ora #$7f ; sign extend 8 bit step value to 16 bit
|
||||||
|
bmi was_neg ; was negative
|
||||||
|
lda #$00
|
||||||
|
was_neg:
|
||||||
|
pha
|
||||||
|
;clc
|
||||||
|
lda STEPX,X ; & y
|
||||||
|
adc RAYPOSX,X ; & y
|
||||||
|
sta RAYPOSX,X ; & y
|
||||||
|
pla
|
||||||
|
|
||||||
|
php
|
||||||
|
|
||||||
|
bcc blah ; no carry
|
||||||
|
|
||||||
|
cpx #2
|
||||||
|
bne blah
|
||||||
|
|
||||||
|
stx NEWLOC
|
||||||
|
|
||||||
|
|
||||||
|
blah:
|
||||||
|
plp
|
||||||
|
|
||||||
|
adc RAYPOSXH,X ; & y
|
||||||
|
sta RAYPOSXH,X ; & y
|
||||||
|
|
||||||
|
|
||||||
|
dex
|
||||||
|
dex
|
||||||
|
bpl loop_stepadd
|
||||||
|
|
||||||
|
; A = RAYPOSXH
|
||||||
|
|
||||||
|
; calculate index to look up the map cell
|
||||||
|
; the map area is 8x8 bytes
|
||||||
|
; + instead of the usual y * 8 + x
|
||||||
|
; x * 8 + y done here, to save some bytes
|
||||||
|
; (just causing a flip of the map as a side effect)
|
||||||
|
|
||||||
|
and RAYPOSYH ; sierpinski
|
||||||
|
|
||||||
|
and #$f0
|
||||||
|
beq step_exit
|
||||||
|
|
||||||
|
lda #$CC
|
||||||
|
; jmp blargh
|
||||||
|
|
||||||
|
;make_zero:
|
||||||
|
; lda #$00
|
||||||
|
; beq step_exit
|
||||||
|
|
||||||
|
;blargh:
|
||||||
|
|
||||||
|
ldx NEWLOC
|
||||||
|
cpx #2
|
||||||
|
bne step_exit
|
||||||
|
|
||||||
|
sec
|
||||||
|
sbc #$88
|
||||||
|
|
||||||
|
|
||||||
|
step_exit:
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; getsincos_copyplr2ray
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
getsincos_copyplr2ray:
|
||||||
|
lda sin_t,X ; sin(x)
|
||||||
|
cmp #$80
|
||||||
|
ror
|
||||||
|
sta STEPX
|
||||||
|
|
||||||
|
lda sin_t+$40,X ; cos(x)
|
||||||
|
cmp #$80
|
||||||
|
ror
|
||||||
|
sta STEPY
|
||||||
|
|
||||||
|
|
||||||
|
; copy player position to ray position for a start
|
||||||
|
; through the basic rom
|
||||||
|
|
||||||
|
|
||||||
|
; copy 4 bytes, from 69,6A,6B,6C to 61,62,63,64
|
||||||
|
copyplr2ray:
|
||||||
|
|
||||||
|
ldx #$04
|
||||||
|
copyloop:
|
||||||
|
lda $68,X
|
||||||
|
sta $60,X
|
||||||
|
dex
|
||||||
|
bne copyloop
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
;======================================
|
||||||
|
; invert step and copy
|
||||||
|
;======================================
|
||||||
|
invertstepandcopy:
|
||||||
|
; invert step variables for backward motion
|
||||||
|
|
||||||
|
invertstepx: ; from BFB8 in C64 ROM
|
||||||
|
lda $66
|
||||||
|
eor #$ff
|
||||||
|
sta $66
|
||||||
|
|
||||||
|
invertstepy:
|
||||||
|
lda STEPY
|
||||||
|
eor #$ff
|
||||||
|
sta STEPY
|
||||||
|
|
||||||
|
;=======================================
|
||||||
|
; stepandcopy
|
||||||
|
;=======================================
|
||||||
|
stepandcopy:
|
||||||
|
; see if player can move to the direction desired
|
||||||
|
jsr addsteptopos
|
||||||
|
|
||||||
|
bne step_exit ; no, return without doing anything
|
||||||
|
|
||||||
|
; yes, move player by
|
||||||
|
; copying ray position to player position
|
||||||
|
|
||||||
|
copyray2plr:
|
||||||
|
|
||||||
|
; Copy 61,62,63,64 to 69,6A,6B,6C
|
||||||
|
|
||||||
|
ldx #$4
|
||||||
|
r2_loop:
|
||||||
|
lda $60,X
|
||||||
|
sta $68,X
|
||||||
|
dex
|
||||||
|
bne r2_loop
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
;---------------------------------------
|
||||||
|
; data
|
||||||
|
;---------------------------------------
|
||||||
|
|
||||||
|
; number of sin additions (backwards)
|
||||||
|
sincount_t:
|
||||||
|
.byte 6,14,19,25
|
||||||
|
;---------------------------------------
|
Loading…
x
Reference in New Issue
Block a user