REM ============================================
REM SEGMENT-BASED 3D RAYCASTER - Stress Test
REM BazzBasic - https://github.com/EkBass/BazzBasic
REM
REM ~50 wall segments in 20x20 unit space.
REM Mix of orthogonal, diagonal, and angled walls.
REM ============================================
REM === CONSTANTS ===
LET SCREEN_W# = 640
LET SCREEN_H# = 480
LET HALF_H# = 240
LET FOV# = 60
LET HALF_FOV# = 30
LET NUM_RAYS# = 180
LET MOVE_SPEED# = 0.15
LET ROT_SPEED# = 5
LET FPS_INTERVAL# = 1000
LET WALL_HEIGHT_SCALE# = 0.8
LET MIN_DIST# = 0.1
LET BRIGHT_FACTOR# = 12
LET MIN_BRIGHT# = 20
REM Minimap (smaller scale for bigger map)
LET MM_SCALE# = 7
LET MM_OX# = 490
LET MM_OY# = 10
REM === WALL DATA ===
DIM wall$
LET wallCount$ = 0
GOSUB [sub:buildMap]
REM === PLAYER ===
LET px$ = 3
LET py$ = 3
LET pAngle$ = 45
REM === WORKING VARS ===
LET key$ = 0, nx$ = 0, ny$ = 0
LET ray$ = 0, rayRatio$ = 0, rayAngle$ = 0
LET rdx$ = 0, rdy$ = 0
LET w$ = 0, wx1$ = 0, wy1$ = 0, wx2$ = 0, wy2$ = 0
LET segDx$ = 0, segDy$ = 0
LET den$ = 0, t$ = 0, u$ = 0
LET closestDist$ = 0, closestWall$ = 0
LET angleDiff$ = 0, corrDist$ = 0
LET wallHeight$ = 0, wallTop$ = 0, wallBottom$ = 0
LET brightness$ = 0
LET screenX$ = 0, screenX2$ = 0
LET wR$ = 0, wG$ = 0, wB$ = 0
LET frameCount$ = 0, lastFps$ = 0, fps$ = 0, currentTime$ = 0
LET lx1$ = 0, ly1$ = 0, lx2$ = 0, ly2$ = 0
LET mpx$ = 0, mpy$ = 0, mdx$ = 0, mdy$ = 0
REM === INIT ===
SCREEN 12
VSYNC(FALSE)
FastTrig(TRUE)
lastFps$ = TICKS
REM === MAIN LOOP ===
LET running$ = TRUE
WHILE running$
key$ = INKEY
IF key$ = KEY_UP# THEN
nx$ = px$ + FastCos(pAngle$) * MOVE_SPEED#
ny$ = py$ + FastSin(pAngle$) * MOVE_SPEED#
px$ = nx$
py$ = ny$
ENDIF
IF key$ = KEY_DOWN# THEN
nx$ = px$ - FastCos(pAngle$) * MOVE_SPEED#
ny$ = py$ - FastSin(pAngle$) * MOVE_SPEED#
px$ = nx$
py$ = ny$
ENDIF
IF key$ = KEY_LEFT# THEN
pAngle$ = pAngle$ - ROT_SPEED#
IF pAngle$ < 0 THEN pAngle$ = pAngle$ + 360
ENDIF
IF key$ = KEY_RIGHT# THEN
pAngle$ = pAngle$ + ROT_SPEED#
IF pAngle$ >= 360 THEN pAngle$ = pAngle$ - 360
ENDIF
IF key$ = KEY_ESC# THEN running$ = FALSE
SCREENLOCK ON
LINE (0, 0)-(SCREEN_W#, HALF_H#), RGB(30, 30, 70), BF
LINE (0, HALF_H#)-(SCREEN_W#, SCREEN_H#), RGB(45, 45, 45), BF
GOSUB [sub:Render]
GOSUB [sub:Minimap]
frameCount$ = frameCount$ + 1
currentTime$ = TICKS
IF currentTime$ - lastFps$ >= FPS_INTERVAL# THEN
fps$ = frameCount$ / ((currentTime$ - lastFps$) / 1000)
frameCount$ = 0
lastFps$ = currentTime$
ENDIF
COLOR 15, 0
LOCATE 1, 1
PRINT "FPS: "; INT(fps$); " Walls: "; wallCount$; " "
SCREENLOCK OFF
SLEEP 1
WEND
FastTrig(FALSE)
CLS
END
REM ============================================
REM RENDER
REM ============================================
[sub:Render]
FOR ray$ = 0 TO NUM_RAYS# - 1
rayRatio$ = ray$ / NUM_RAYS#
rayAngle$ = pAngle$ - HALF_FOV# + (rayRatio$ * FOV#)
IF rayAngle$ < 0 THEN rayAngle$ = rayAngle$ + 360
IF rayAngle$ >= 360 THEN rayAngle$ = rayAngle$ - 360
rdx$ = FastCos(rayAngle$)
rdy$ = FastSin(rayAngle$)
closestDist$ = 9999
closestWall$ = -1
FOR w$ = 0 TO wallCount$ - 1
wx1$ = wall$(w$, 0)
wy1$ = wall$(w$, 1)
wx2$ = wall$(w$, 2)
wy2$ = wall$(w$, 3)
segDx$ = wx2$ - wx1$
segDy$ = wy2$ - wy1$
den$ = rdx$ * segDy$ - rdy$ * segDx$
IF den$ <> 0 THEN
t$ = ((wx1$ - px$) * segDy$ - (wy1$ - py$) * segDx$) / den$
u$ = ((wx1$ - px$) * rdy$ - (wy1$ - py$) * rdx$) / den$
IF t$ > 0 AND u$ >= 0 AND u$ <= 1 THEN
IF t$ < closestDist$ THEN
closestDist$ = t$
closestWall$ = w$
ENDIF
ENDIF
ENDIF
NEXT
IF closestWall$ >= 0 THEN
angleDiff$ = rayAngle$ - pAngle$
IF angleDiff$ > 180 THEN angleDiff$ = angleDiff$ - 360
IF angleDiff$ < -180 THEN angleDiff$ = angleDiff$ + 360
corrDist$ = closestDist$ * FastCos(angleDiff$)
IF corrDist$ < MIN_DIST# THEN corrDist$ = MIN_DIST#
wallHeight$ = (HALF_H# / corrDist$) * WALL_HEIGHT_SCALE#
IF wallHeight$ > SCREEN_H# THEN wallHeight$ = SCREEN_H#
wallTop$ = HALF_H# - wallHeight$
wallBottom$ = HALF_H# + wallHeight$
brightness$ = 255 - (corrDist$ * BRIGHT_FACTOR#)
IF brightness$ < MIN_BRIGHT# THEN brightness$ = MIN_BRIGHT#
IF brightness$ > 255 THEN brightness$ = 255
wR$ = wall$(closestWall$, 4) * brightness$ / 255
wG$ = wall$(closestWall$, 5) * brightness$ / 255
wB$ = wall$(closestWall$, 6) * brightness$ / 255
screenX$ = INT(rayRatio$ * SCREEN_W#)
screenX2$ = INT((ray$ + 1) / NUM_RAYS# * SCREEN_W#)
LINE (screenX$, wallTop$)-(screenX2$, wallBottom$), RGB(wR$, wG$, wB$), BF
ENDIF
NEXT
RETURN
REM ============================================
REM MINIMAP
REM ============================================
[sub:Minimap]
LINE (MM_OX# - 2, MM_OY# - 2)-(MM_OX# + 20 * MM_SCALE# + 2, MM_OY# + 20 * MM_SCALE# + 2), RGB(0, 0, 0), BF
FOR w$ = 0 TO wallCount$ - 1
lx1$ = MM_OX# + wall$(w$, 0) * MM_SCALE#
ly1$ = MM_OY# + wall$(w$, 1) * MM_SCALE#
lx2$ = MM_OX# + wall$(w$, 2) * MM_SCALE#
ly2$ = MM_OY# + wall$(w$, 3) * MM_SCALE#
LINE (lx1$, ly1$)-(lx2$, ly2$), RGB(wall$(w$, 4), wall$(w$, 5), wall$(w$, 6))
NEXT
mpx$ = MM_OX# + px$ * MM_SCALE#
mpy$ = MM_OY# + py$ * MM_SCALE#
CIRCLE (mpx$, mpy$), 3, RGB(255, 255, 0), 1
mdx$ = mpx$ + FastCos(pAngle$) * 10
mdy$ = mpy$ + FastSin(pAngle$) * 10
LINE (mpx$, mpy$)-(mdx$, mdy$), RGB(255, 255, 0)
RETURN
REM ============================================
REM MAP - 20x20 area, ~50 wall segments
REM ============================================
[sub:buildMap]
LET i$ = 0
REM ==============================
REM OUTER WALLS (stone grey)
REM ==============================
wall$(i$,0)=0 : wall$(i$,1)=0 : wall$(i$,2)=20 : wall$(i$,3)=0 : wall$(i$,4)=150 : wall$(i$,5)=150 : wall$(i$,6)=150
i$ = i$ + 1
wall$(i$,0)=20 : wall$(i$,1)=0 : wall$(i$,2)=20 : wall$(i$,3)=20 : wall$(i$,4)=130 : wall$(i$,5)=130 : wall$(i$,6)=130
i$ = i$ + 1
wall$(i$,0)=20 : wall$(i$,1)=20 : wall$(i$,2)=0 : wall$(i$,3)=20 : wall$(i$,4)=150 : wall$(i$,5)=150 : wall$(i$,6)=150
i$ = i$ + 1
wall$(i$,0)=0 : wall$(i$,1)=20 : wall$(i$,2)=0 : wall$(i$,3)=0 : wall$(i$,4)=130 : wall$(i$,5)=130 : wall$(i$,6)=130
i$ = i$ + 1
REM ==============================
REM ROOM 1 - top left (brick red)
REM Rectangular room with diagonal entry
REM ==============================
wall$(i$,0)=1 : wall$(i$,1)=5 : wall$(i$,2)=6 : wall$(i$,3)=5 : wall$(i$,4)=190 : wall$(i$,5)=70 : wall$(i$,6)=50
i$ = i$ + 1
wall$(i$,0)=6 : wall$(i$,1)=5 : wall$(i$,2)=6 : wall$(i$,3)=1 : wall$(i$,4)=180 : wall$(i$,5)=60 : wall$(i$,6)=40
i$ = i$ + 1
REM Diagonal entry wall
wall$(i$,0)=6 : wall$(i$,1)=5 : wall$(i$,2)=8 : wall$(i$,3)=3 : wall$(i$,4)=200 : wall$(i$,5)=80 : wall$(i$,6)=60
i$ = i$ + 1
REM ==============================
REM ROOM 2 - top right (blue steel)
REM Angled chamber
REM ==============================
wall$(i$,0)=12 : wall$(i$,1)=1 : wall$(i$,2)=12 : wall$(i$,3)=6 : wall$(i$,4)=60 : wall$(i$,5)=80 : wall$(i$,6)=190
i$ = i$ + 1
wall$(i$,0)=12 : wall$(i$,1)=6 : wall$(i$,2)=15 : wall$(i$,3)=8 : wall$(i$,4)=70 : wall$(i$,5)=90 : wall$(i$,6)=200
i$ = i$ + 1
wall$(i$,0)=15 : wall$(i$,1)=8 : wall$(i$,2)=18 : wall$(i$,3)=6 : wall$(i$,4)=60 : wall$(i$,5)=80 : wall$(i$,6)=180
i$ = i$ + 1
wall$(i$,0)=18 : wall$(i$,1)=6 : wall$(i$,2)=18 : wall$(i$,3)=1 : wall$(i$,4)=70 : wall$(i$,5)=90 : wall$(i$,6)=200
i$ = i$ + 1
REM ==============================
REM CENTRAL CORRIDOR (dark green)
REM Runs diagonally across map
REM ==============================
wall$(i$,0)=7 : wall$(i$,1)=7 : wall$(i$,2)=13 : wall$(i$,3)=13 : wall$(i$,4)=50 : wall$(i$,5)=160 : wall$(i$,6)=60
i$ = i$ + 1
wall$(i$,0)=8 : wall$(i$,1)=6 : wall$(i$,2)=14 : wall$(i$,3)=12 : wall$(i$,4)=40 : wall$(i$,5)=140 : wall$(i$,6)=50
i$ = i$ + 1
REM ==============================
REM OCTAGONAL PILLAR center-left (purple)
REM ==============================
wall$(i$,0)=4 : wall$(i$,1)=9 : wall$(i$,2)=5 : wall$(i$,3)=8.5 : wall$(i$,4)=160 : wall$(i$,5)=50 : wall$(i$,6)=170
i$ = i$ + 1
wall$(i$,0)=5 : wall$(i$,1)=8.5 : wall$(i$,2)=5.5 : wall$(i$,3)=9 : wall$(i$,4)=170 : wall$(i$,5)=60 : wall$(i$,6)=180
i$ = i$ + 1
wall$(i$,0)=5.5 : wall$(i$,1)=9 : wall$(i$,2)=5.5 : wall$(i$,3)=10 : wall$(i$,4)=160 : wall$(i$,5)=50 : wall$(i$,6)=170
i$ = i$ + 1
wall$(i$,0)=5.5 : wall$(i$,1)=10 : wall$(i$,2)=5 : wall$(i$,3)=10.5 : wall$(i$,4)=170 : wall$(i$,5)=60 : wall$(i$,6)=180
i$ = i$ + 1
wall$(i$,0)=5 : wall$(i$,1)=10.5 : wall$(i$,2)=4 : wall$(i$,3)=10.5 : wall$(i$,4)=160 : wall$(i$,5)=50 : wall$(i$,6)=170
i$ = i$ + 1
wall$(i$,0)=4 : wall$(i$,1)=10.5 : wall$(i$,2)=3.5 : wall$(i$,3)=10 : wall$(i$,4)=170 : wall$(i$,5)=60 : wall$(i$,6)=180
i$ = i$ + 1
wall$(i$,0)=3.5 : wall$(i$,1)=10 : wall$(i$,2)=3.5 : wall$(i$,3)=9 : wall$(i$,4)=160 : wall$(i$,5)=50 : wall$(i$,6)=170
i$ = i$ + 1
wall$(i$,0)=3.5 : wall$(i$,1)=9 : wall$(i$,2)=4 : wall$(i$,3)=9 : wall$(i$,4)=170 : wall$(i$,5)=60 : wall$(i$,6)=180
i$ = i$ + 1
REM ==============================
REM ROOM 3 - bottom left (warm orange)
REM Triangular room
REM ==============================
wall$(i$,0)=1 : wall$(i$,1)=13 : wall$(i$,2)=7 : wall$(i$,3)=13 : wall$(i$,4)=220 : wall$(i$,5)=140 : wall$(i$,6)=50
i$ = i$ + 1
wall$(i$,0)=7 : wall$(i$,1)=13 : wall$(i$,2)=4 : wall$(i$,3)=18 : wall$(i$,4)=200 : wall$(i$,5)=120 : wall$(i$,6)=40
i$ = i$ + 1
wall$(i$,0)=4 : wall$(i$,1)=18 : wall$(i$,2)=1 : wall$(i$,3)=13 : wall$(i$,4)=210 : wall$(i$,5)=130 : wall$(i$,6)=45
i$ = i$ + 1
REM ==============================
REM ROOM 4 - bottom right (cyan/teal)
REM Irregular polygon
REM ==============================
wall$(i$,0)=13 : wall$(i$,1)=14 : wall$(i$,2)=17 : wall$(i$,3)=14 : wall$(i$,4)=50 : wall$(i$,5)=190 : wall$(i$,6)=180
i$ = i$ + 1
wall$(i$,0)=17 : wall$(i$,1)=14 : wall$(i$,2)=19 : wall$(i$,3)=16 : wall$(i$,4)=60 : wall$(i$,5)=200 : wall$(i$,6)=190
i$ = i$ + 1
wall$(i$,0)=19 : wall$(i$,1)=16 : wall$(i$,2)=18 : wall$(i$,3)=19 : wall$(i$,4)=50 : wall$(i$,5)=180 : wall$(i$,6)=170
i$ = i$ + 1
wall$(i$,0)=18 : wall$(i$,1)=19 : wall$(i$,2)=14 : wall$(i$,3)=19 : wall$(i$,4)=60 : wall$(i$,5)=200 : wall$(i$,6)=190
i$ = i$ + 1
wall$(i$,0)=14 : wall$(i$,1)=19 : wall$(i$,2)=13 : wall$(i$,3)=17 : wall$(i$,4)=50 : wall$(i$,5)=190 : wall$(i$,6)=180
i$ = i$ + 1
wall$(i$,0)=13 : wall$(i$,1)=17 : wall$(i$,2)=13 : wall$(i$,3)=14 : wall$(i$,4)=60 : wall$(i$,5)=200 : wall$(i$,6)=190
i$ = i$ + 1
REM ==============================
REM ZIGZAG WALL center-bottom (golden)
REM ==============================
wall$(i$,0)=7 : wall$(i$,1)=15 : wall$(i$,2)=9 : wall$(i$,3)=14 : wall$(i$,4)=220 : wall$(i$,5)=190 : wall$(i$,6)=50
i$ = i$ + 1
wall$(i$,0)=9 : wall$(i$,1)=14 : wall$(i$,2)=10 : wall$(i$,3)=16 : wall$(i$,4)=210 : wall$(i$,5)=180 : wall$(i$,6)=40
i$ = i$ + 1
wall$(i$,0)=10 : wall$(i$,1)=16 : wall$(i$,2)=12 : wall$(i$,3)=15 : wall$(i$,4)=220 : wall$(i$,5)=190 : wall$(i$,6)=50
i$ = i$ + 1
REM ==============================
REM SMALL PILLARS (white)
REM ==============================
REM Pillar 1 at (16,3) - square
wall$(i$,0)=15.5 : wall$(i$,1)=2.5 : wall$(i$,2)=16.5 : wall$(i$,3)=2.5 : wall$(i$,4)=220 : wall$(i$,5)=220 : wall$(i$,6)=220
i$ = i$ + 1
wall$(i$,0)=16.5 : wall$(i$,1)=2.5 : wall$(i$,2)=16.5 : wall$(i$,3)=3.5 : wall$(i$,4)=200 : wall$(i$,5)=200 : wall$(i$,6)=200
i$ = i$ + 1
wall$(i$,0)=16.5 : wall$(i$,1)=3.5 : wall$(i$,2)=15.5 : wall$(i$,3)=3.5 : wall$(i$,4)=220 : wall$(i$,5)=220 : wall$(i$,6)=220
i$ = i$ + 1
wall$(i$,0)=15.5 : wall$(i$,1)=3.5 : wall$(i$,2)=15.5 : wall$(i$,3)=2.5 : wall$(i$,4)=200 : wall$(i$,5)=200 : wall$(i$,6)=200
i$ = i$ + 1
REM Pillar 2 at (10,10) - diamond
wall$(i$,0)=10 : wall$(i$,1)=9.3 : wall$(i$,2)=10.7 : wall$(i$,3)=10 : wall$(i$,4)=220 : wall$(i$,5)=220 : wall$(i$,6)=220
i$ = i$ + 1
wall$(i$,0)=10.7 : wall$(i$,1)=10 : wall$(i$,2)=10 : wall$(i$,3)=10.7 : wall$(i$,4)=200 : wall$(i$,5)=200 : wall$(i$,6)=200
i$ = i$ + 1
wall$(i$,0)=10 : wall$(i$,1)=10.7 : wall$(i$,2)=9.3 : wall$(i$,3)=10 : wall$(i$,4)=220 : wall$(i$,5)=220 : wall$(i$,6)=220
i$ = i$ + 1
wall$(i$,0)=9.3 : wall$(i$,1)=10 : wall$(i$,2)=10 : wall$(i$,3)=9.3 : wall$(i$,4)=200 : wall$(i$,5)=200 : wall$(i$,6)=200
i$ = i$ + 1
REM ==============================
REM CURVED-ISH WALL (light red)
REM Approximated arc with segments
REM ==============================
wall$(i$,0)=1 : wall$(i$,1)=7 : wall$(i$,2)=2 : wall$(i$,3)=8 : wall$(i$,4)=200 : wall$(i$,5)=80 : wall$(i$,6)=80
i$ = i$ + 1
wall$(i$,0)=2 : wall$(i$,1)=8 : wall$(i$,2)=2.5 : wall$(i$,3)=9.5 : wall$(i$,4)=190 : wall$(i$,5)=70 : wall$(i$,6)=70
i$ = i$ + 1
wall$(i$,0)=2.5 : wall$(i$,1)=9.5 : wall$(i$,2)=2 : wall$(i$,3)=11 : wall$(i$,4)=200 : wall$(i$,5)=80 : wall$(i$,6)=80
i$ = i$ + 1
wall$(i$,0)=2 : wall$(i$,1)=11 : wall$(i$,2)=1 : wall$(i$,3)=12 : wall$(i$,4)=190 : wall$(i$,5)=70 : wall$(i$,6)=70
i$ = i$ + 1
REM ==============================
REM ALCOVE top-center (dark red)
REM ==============================
wall$(i$,0)=8 : wall$(i$,1)=1 : wall$(i$,2)=8 : wall$(i$,3)=3 : wall$(i$,4)=160 : wall$(i$,5)=40 : wall$(i$,6)=40
i$ = i$ + 1
wall$(i$,0)=8 : wall$(i$,1)=3 : wall$(i$,2)=10 : wall$(i$,3)=3 : wall$(i$,4)=150 : wall$(i$,5)=35 : wall$(i$,6)=35
i$ = i$ + 1
wall$(i$,0)=10 : wall$(i$,1)=3 : wall$(i$,2)=10 : wall$(i$,3)=1 : wall$(i$,4)=160 : wall$(i$,5)=40 : wall$(i$,6)=40
i$ = i$ + 1
wallCount$ = i$
RETURN