v2.1.0 - order relic options
ci/woodpecker/push/c64 Pipeline was successful

This commit is contained in:
2026-08-29 11:21:31 +02:00
parent b155b46dca
commit 266c9ae84c
6 changed files with 305 additions and 34 deletions
+10 -3
View File
@@ -30,7 +30,7 @@ cells, an animated exit portal, a raster color band behind the
status row, and a fade to black between all screens. The menu floats status row, and a fade to black between all screens. The menu floats
over a dark maze backdrop under the big gold-washed title. over a dark maze backdrop under the big gold-washed title.
The options screen adds two optional twists: The options screen adds three optional twists:
- **worker gun** - player 1 shoots a bullet with fire/`space`; a hit - **worker gun** - player 1 shoots a bullet with fire/`space`; a hit
enemy respawns on a random cell after a pause. enemy respawns on a random cell after a pause.
@@ -38,6 +38,13 @@ The options screen adds two optional twists:
denied until the bar on the status row drains (pixel by pixel) and denied until the bar on the status row drains (pixel by pixel) and
the readout flips back from *wait* to *ready* (the cursor also the readout flips back from *wait* to *ready* (the cursor also
turns red while recharging). turns red while recharging).
- **relic order** - numbered relics lie scattered over the corridors
and the worker has to gather them *in order*, 1 first, then 2, and
so on, before the portal will take him. Until the last one is his
the exit stays sealed (a dull grey, and bumping into it blips the
border red); the relic he is after next pulses white, and the
status row counts them off next to the portal glyph. Every level
adds one more: two on level 1 up to nine on level 8.
Screens: TTG intro (ported from rabbitc64) -> pyramid title card Screens: TTG intro (ported from rabbitc64) -> pyramid title card
(the pyramid, the trapped worker and the pulsing sun of Ra) -> main (the pyramid, the trapped worker and the pulsing sun of Ra) -> main
@@ -60,8 +67,8 @@ Test builds can boot straight into one state:
``` ```
acme -DAUTOPLAY=1 -f cbm -o blessingofra.prg main.asm acme -DAUTOPLAY=1 -f cbm -o blessingofra.prg main.asm
# also: AUTOOPTIONS, AUTOSTORY, AUTOPYRAMID, AUTOCREDITS, # also: AUTOOPTIONS, AUTOSTORY, AUTOPYRAMID, AUTOCREDITS,
# AUTOWIN, AUTOLOSE; add -DFORCEOPTS=1 to start with both # AUTOWIN, AUTOLOSE; add -DFORCEOPTS=1 to start with all
# options turned on # three options turned on
``` ```
## Files ## Files
+3
View File
@@ -97,6 +97,8 @@ CH_POST = $e1 ; bolted plate: fixed pivot post
CH_EXIT = $e2 ; the portal out (4 animated glyph frames) CH_EXIT = $e2 ; the portal out (4 animated glyph frames)
CH_FLOOR = $20 ; space: corridor CH_FLOOR = $20 ; space: corridor
CH_BAR = $e3 ; 7 chars: a bar cell 1-7 pixels full CH_BAR = $e3 ; 7 chars: a bar cell 1-7 pixels full
CH_RELIC = $31 ; the relics wear their order: '1'-'9'
NRELIC = 9 ; most relics on a level (level 8)
; ---- the actors are hardware sprites ---- ; ---- the actors are hardware sprites ----
SP_RUN = 0 ; player 1, the worker SP_RUN = 0 ; player 1, the worker
@@ -113,6 +115,7 @@ COL_HILITE = YELLOW ; walls the cursor's spin would move
COL_SCARAB = CYAN ; the scarabs COL_SCARAB = CYAN ; the scarabs
COL_SCORP = LRED ; the scorpions COL_SCORP = LRED ; the scorpions
COL_STING = PURPLE ; the venom sting COL_STING = PURPLE ; the venom sting
COL_RELIC = LBLUE ; the numbered relics (relic order option)
STATCOL = BROWN ; background band behind the status row STATCOL = BROWN ; background band behind the status row
; ---- game timing ---- ; ---- game timing ----
+2 -1
View File
@@ -14,7 +14,8 @@
; intro.asm - TTG boot logo (ported from rabbitc64) ; intro.asm - TTG boot logo (ported from rabbitc64)
; pyramid.asm - title card: the pyramid and the sun of ra ; pyramid.asm - title card: the pyramid and the sun of ra
; menu.asm - main menu over a dark maze backdrop ; menu.asm - main menu over a dark maze backdrop
; options.asm - optional extras: worker gun, spin cooldown ; options.asm - optional extras: worker gun, spin cooldown,
; relic order
; story.asm - the legend + who steers what ; story.asm - the legend + who steers what
; credits.asm - the crew (content from rabbitc64, new look) ; credits.asm - the crew (content from rabbitc64, new look)
; play.asm - maze generation + the game itself ; play.asm - maze generation + the game itself
+1 -1
View File
@@ -6,5 +6,5 @@
"site": "https://git.teletypegames.org/games/labyrintwo", "site": "https://git.teletypegames.org/games/labyrintwo",
"repo": "https://git.teletypegames.org/games/blessingofra", "repo": "https://git.teletypegames.org/games/blessingofra",
"license": "MIT", "license": "MIT",
"version": "2.0.0" "version": "2.1.0"
} }
+36 -16
View File
@@ -4,11 +4,14 @@
; respawns elsewhere after a pause ; respawns elsewhere after a pause
; spin cooldown - ra needs a recharge between two spins, ; spin cooldown - ra needs a recharge between two spins,
; shown on the status row ; shown on the status row
; relic order - numbered relics have to be collected in
; order before the portal opens, one more
; of them on every level
; start level - which level a fresh run begins on (1-8) ; start level - which level a fresh run begins on (1-8)
; the settings live here and survive between levels ; the settings live here and survive between levels
; ----------------------------------------------------------- ; -----------------------------------------------------------
OPT_ITEMS = 4 OPT_ITEMS = 5
options_init: options_init:
jsr clear_screen jsr clear_screen
@@ -17,7 +20,8 @@ options_init:
+prtext 21, 6, LGREY, txt_oh1, txt_oh1e-txt_oh1 +prtext 21, 6, LGREY, txt_oh1, txt_oh1e-txt_oh1
+prtext 22, 4, LGREY, txt_oh2, txt_oh2e-txt_oh2 +prtext 22, 4, LGREY, txt_oh2, txt_oh2e-txt_oh2
+prtext 23, 5, LGREY, txt_oh3, txt_oh3e-txt_oh3 +prtext 23, 2, LGREY, txt_oh3, txt_oh3e-txt_oh3
+prtext 24, 5, LGREY, txt_oh4, txt_oh4e-txt_oh4
lda #0 lda #0
sta optsel sta optsel
@@ -56,7 +60,7 @@ ou_udrel:
sta udheld sta udheld
ou_udend: ou_udend:
; the three lines, the picked one in yellow ; the option lines, the picked one in yellow
ldx #0 ldx #0
oo_items: oo_items:
txa txa
@@ -68,11 +72,14 @@ oo_items:
cpx #OPT_ITEMS cpx #OPT_ITEMS
bne oo_items bne oo_items
; the current values next to the three settings ; the current value next to each setting
ldx opt_shoot ldx opt_shoot
lda #10 lda #7
jsr put_oval jsr put_oval
ldx opt_cool ldx opt_cool
lda #10
jsr put_oval
ldx opt_relic
lda #13 lda #13
jsr put_oval jsr put_oval
lda opt_level ; the start level as a digit lda opt_level ; the start level as a digit
@@ -83,6 +90,7 @@ oo_items:
; blinking '>' cursor in front of the picked line ; blinking '>' cursor in front of the picked line
lda #$20 lda #$20
sta SCREEN+7*40+7
sta SCREEN+10*40+7 sta SCREEN+10*40+7
sta SCREEN+13*40+7 sta SCREEN+13*40+7
sta SCREEN+16*40+7 sta SCREEN+16*40+7
@@ -110,10 +118,12 @@ ou_fire:
jsr start_edge jsr start_edge
beq ou_done beq ou_done
lda optsel lda optsel
cmp #3 cmp #4
beq ou_back beq ou_back
cmp #2 cmp #3
beq ou_tlevel beq ou_tlevel
cmp #2
beq ou_trelic
cmp #1 cmp #1
beq ou_tcool beq ou_tcool
lda opt_shoot lda opt_shoot
@@ -125,6 +135,11 @@ ou_tcool:
eor #1 eor #1
sta opt_cool sta opt_cool
jmp ou_tsfx jmp ou_tsfx
ou_trelic:
lda opt_relic
eor #1
sta opt_relic
jmp ou_tsfx
ou_tlevel: ou_tlevel:
ldx opt_level ; cycle 1-8, wrapping back to 1 ldx opt_level ; cycle 1-8, wrapping back to 1
inx inx
@@ -179,15 +194,15 @@ put_oval:
jmp print_text jmp print_text
; ---- option tables ---- ; ---- option tables ----
oitem_lo: !byte <txt_ogun, <txt_ocool, <txt_olev, <txt_oback oitem_lo: !byte <txt_ogun, <txt_ocool, <txt_orel, <txt_olev, <txt_oback
oitem_hi: !byte >txt_ogun, >txt_ocool, >txt_olev, >txt_oback oitem_hi: !byte >txt_ogun, >txt_ocool, >txt_orel, >txt_olev, >txt_oback
oitem_len: !byte 10, 13, 11, 4 oitem_len: !byte 10, 13, 11, 11, 4
oitem_row: !byte 10, 13, 16, 19 oitem_row: !byte 7, 10, 13, 16, 19
ocur_lo: ; cursor cells: column 7 of those rows ocur_lo: ; cursor cells: column 7 of those rows
!byte <(SCREEN+10*40+7), <(SCREEN+13*40+7) !byte <(SCREEN+7*40+7), <(SCREEN+10*40+7), <(SCREEN+13*40+7)
!byte <(SCREEN+16*40+7), <(SCREEN+19*40+7) !byte <(SCREEN+16*40+7), <(SCREEN+19*40+7)
ocur_hi: ocur_hi:
!byte >(SCREEN+10*40+7), >(SCREEN+13*40+7) !byte >(SCREEN+7*40+7), >(SCREEN+10*40+7), >(SCREEN+13*40+7)
!byte >(SCREEN+16*40+7), >(SCREEN+19*40+7) !byte >(SCREEN+16*40+7), >(SCREEN+19*40+7)
ovtx_lo: !byte <txt_off, <txt_on ovtx_lo: !byte <txt_off, <txt_on
ovtx_hi: !byte >txt_off, >txt_on ovtx_hi: !byte >txt_off, >txt_on
@@ -196,6 +211,7 @@ ovcol: !byte LGREY, LGREEN
; ---- option texts ---- ; ---- option texts ----
txt_ogun: !scr "worker gun" txt_ogun: !scr "worker gun"
txt_ocool: !scr "spin cooldown" txt_ocool: !scr "spin cooldown"
txt_orel: !scr "relic order"
txt_olev: !scr "start level" txt_olev: !scr "start level"
txt_oback: !scr "back" txt_oback: !scr "back"
txt_on: !scr "on " txt_on: !scr "on "
@@ -204,16 +220,20 @@ txt_oh1: !scr "gun: p1 fire shoots a bullet"
txt_oh1e: txt_oh1e:
txt_oh2: !scr "cooldown: spins need a recharge" txt_oh2: !scr "cooldown: spins need a recharge"
txt_oh2e: txt_oh2e:
txt_oh3: !scr "start: a fresh run's first level" txt_oh3: !scr "relics: grab the numbers in order"
txt_oh3e: txt_oh3e:
txt_oh4: !scr "start: a fresh run's first level"
txt_oh4e:
; ---- the settings themselves (session-wide) ---- ; ---- the settings themselves (session-wide) ----
!ifdef FORCEOPTS { ; test builds start with both turned on !ifdef FORCEOPTS { ; test builds start with them all on
opt_shoot: !byte 1 opt_shoot: !byte 1
opt_cool: !byte 1 opt_cool: !byte 1
opt_relic: !byte 1
} else { } else {
opt_shoot: !byte 0 ; 0 = classic game, 1 = the worker shoots opt_shoot: !byte 0 ; 0 = classic game, 1 = the worker shoots
opt_cool: !byte 0 ; 1 = spins need a recharge opt_cool: !byte 0 ; 1 = spins need a recharge
opt_relic: !byte 0 ; 1 = collect the relics in order first
} }
opt_level: !byte 1 ; a fresh run's first level: 1-8 opt_level: !byte 1 ; a fresh run's first level: 1-8
optsel: !byte 0 ; picked line: 0-3 optsel: !byte 0 ; picked line: 0-4
+253 -13
View File
@@ -22,6 +22,10 @@
; random cell after RESPAWN_TIME frames ; random cell after RESPAWN_TIME frames
; opt_cool - a spin starts a COOL_TIME recharge, shown as ; opt_cool - a spin starts a COOL_TIME recharge, shown as
; a draining 1/8-step bar on the status row ; a draining 1/8-step bar on the status row
; opt_relic - numbered relics are scattered over the cells;
; the worker must pick them up in order before
; the portal will take him, one more relic each
; level (2 on level 1 up to 9 on level 8)
; ;
; screen layout: status on row 0 (over the colored raster ; screen layout: status on row 0 (over the colored raster
; band), the centered lattice on rows 1-23, hints on row 24 ; band), the centered lattice on rows 1-23, hints on row 24
@@ -37,7 +41,10 @@ play_init:
sta SCREEN+6 sta SCREEN+6
lda #YELLOW lda #YELLOW
sta COLRAM+6 sta COLRAM+6
lda opt_relic ; relic mode keeps its own counter here
bne pi_goal
+prtext 0, 34, LGREY, txt_goal, txt_goale-txt_goal +prtext 0, 34, LGREY, txt_goal, txt_goale-txt_goal
pi_goal:
+prtext 24, 4, DGREY, txt_hint, txt_hinte-txt_hint +prtext 24, 4, DGREY, txt_hint, txt_hinte-txt_hint
lda mzsize ; this level's lattice: a square lda mzsize ; this level's lattice: a square
@@ -150,6 +157,7 @@ ps_exit:
lda #COL_STING lda #COL_STING
sta SPRCOL+SP_STING sta SPRCOL+SP_STING
jsr place_relics ; first: the enemies then avoid their cells
jsr spawn_enemies jsr spawn_enemies
; input state: fire still held from the previous screen ; input state: fire still held from the previous screen
@@ -530,6 +538,165 @@ sn_free:
etypecol: !byte COL_SCARAB, COL_SCORP etypecol: !byte COL_SCARAB, COL_SCORP
; ============================================================
; the relics (relic order option) - numbered treasures on the
; maze cells; the worker must collect them in order before
; the portal will let him out
; ============================================================
; ---- scatter this level's relics over random cells: one
; more each level, 2 on level 1 up to 9 on level 8 ----
place_relics:
lda #0
sta rnext
sta rcount
sta ri
lda opt_relic
beq pl_done
lda mzsize ; level 1-8 -> 2-9 relics
sec
sbc #MZMIN-2
sta rcount
pl_one:
jsr rand8
and #$0f
cmp mzcw
bcs pl_one
asl ; cell column -> screen column
sec
adc offx
sta ttx
pl_ry:
jsr rand8
and #$0f
cmp mzch
bcs pl_ry
asl
sec
adc offy
sta tty
lda ttx ; never on the worker's own starting cell...
cmp px
bne pl_free
lda tty
cmp py
beq pl_one
pl_free:
jsr relic_at ; ...nor on a cell already holding one
bcs pl_one
ldx ri
lda ttx
sta rlx,x
lda tty
sta rly,x
jsr draw_relic
inc ri
lda ri
cmp rcount
bne pl_one
pl_done:
rts
; ---- stamp relic X on (ttx, tty): its order is its digit ----
draw_relic:
txa
clc
adc #CH_RELIC
pha
ldx tty
jsr row_ptr
ldy ttx
pla
sta (scrlo),y
lda #COL_RELIC
sta (collo),y
rts
; ---- C set when one of the ri placed relics sits on
; (ttx, tty) - the placement loop's duplicate check ----
relic_at:
ldx ri
beq rlk_no
rlk_loop:
dex
lda rlx,x
cmp ttx
bne rlk_next
lda rly,x
cmp tty
beq rlk_yes
rlk_next:
cpx #0
bne rlk_loop
rlk_no:
clc
rts
rlk_yes:
sec
rts
; ---- the worker stepped onto a cell: if it holds the relic
; that is next in the order, it goes into his hands ----
take_relic:
lda opt_relic
beq tk_done
ldx rnext
cpx rcount
bcs tk_done ; all of them already in hand
lda rlx,x
cmp px
bne tk_done
lda rly,x
cmp py
bne tk_done
ldx py ; the cell goes back to plain corridor
jsr row_ptr
ldy px
lda #CH_FLOOR
sta (scrlo),y
lda #BLACK
sta (collo),y
inc rnext
lda #4 ; a white border blip marks the find
sta bflash
lda #WHITE
sta bcolor
lda #SFX_SELECT
jmp sfx_play
tk_done:
rts
; ---- C set when the portal will take the worker: always in
; the classic game, once every relic is his in relic mode ----
exit_open:
lda opt_relic
beq eo_yes
lda rnext
cmp rcount
bcc eo_no
eo_yes:
sec
rts
eo_no:
clc
rts
; ---- C set when the char in A can be walked or flown
; through: the corridor floor and the relics lying on it ----
open_ch:
cmp #CH_FLOOR
beq oc_yes
cmp #CH_RELIC ; the relic digits sit on open floor
bcc oc_no
cmp #CH_RELIC+NRELIC
bcs oc_no
oc_yes:
sec
rts
oc_no:
clc
rts
; ============================================================ ; ============================================================
; one frame of play ; one frame of play
; ============================================================ ; ============================================================
@@ -570,6 +737,7 @@ pu_nocool:
jsr upd_cursor jsr upd_cursor
jsr upd_flash jsr upd_flash
jsr upd_status jsr upd_status
jsr upd_goal
jsr upd_clock jsr upd_clock
jmp upd_sprites jmp upd_sprites
pu_end: pu_end:
@@ -658,9 +826,9 @@ ur_try:
ldy ttx ldy ttx
lda (scrlo),y lda (scrlo),y
cmp #CH_EXIT cmp #CH_EXIT
beq ur_win beq ur_exit
cmp #CH_FLOOR jsr open_ch
bne ur_stop ; a wall or a post: blocked bcc ur_stop ; a wall or a post: blocked
jsr enemy_at ; walking into an enemy still hurts jsr enemy_at ; walking into an enemy still hurts
bcs ur_dead bcs ur_dead
lda es_on ; and so does the venom sting lda es_on ; and so does the venom sting
@@ -676,12 +844,17 @@ ur_go:
sta px sta px
lda tty lda tty
sta py sta py
jmp take_relic ; the cell may hold the next relic
ur_stop: ur_stop:
rts rts
ur_win: ur_exit:
jsr exit_open
bcc ur_sealed
lda #1 lda #1
sta endflag sta endflag
rts rts
ur_sealed: ; relics still out there: the portal is shut
jmp deny_blip
ur_dead: ur_dead:
lda #2 lda #2
sta endflag sta endflag
@@ -703,8 +876,8 @@ upd_shot:
jsr row_ptr jsr row_ptr
ldy ttx ldy ttx
lda (scrlo),y lda (scrlo),y
cmp #CH_FLOOR jsr open_ch
beq sh_open bcs sh_open
lda #0 ; a wall (or the portal) stops it lda #0 ; a wall (or the portal) stops it
sta s_on sta s_on
jmp sh_spawn jmp sh_spawn
@@ -881,7 +1054,7 @@ do_rotate:
lda cool lda cool
beq dr_ready beq dr_ready
dr_deny: dr_deny:
jmp rot_deny ; still recharging / a slot is taken jmp deny_blip ; still recharging / a slot is taken
dr_ready: dr_ready:
lda kx ; nobody may stand in the four slots lda kx ; nobody may stand in the four slots
sta ttx sta ttx
@@ -961,8 +1134,10 @@ dr_ready:
dr_nocool: dr_nocool:
lda #SFX_ROTATE lda #SFX_ROTATE
jmp sfx_play jmp sfx_play
rot_deny: ; ---- red border blip + buzz: a denied spin, or the worker
lda #6 ; red border blip on a denied spin ; knocking on a portal the relics have not opened yet ----
deny_blip:
lda #6
sta bflash sta bflash
lda #RED lda #RED
sta bcolor sta bcolor
@@ -1126,8 +1301,8 @@ en_norun:
jsr row_ptr jsr row_ptr
ldy ttx ldy ttx
lda (scrlo),y lda (scrlo),y
cmp #CH_FLOOR jsr open_ch
beq en_open bcs en_open
sec sec
rts rts
en_open: en_open:
@@ -1247,8 +1422,8 @@ ust_norun:
jsr row_ptr jsr row_ptr
ldy ttx ldy ttx
lda (scrlo),y lda (scrlo),y
cmp #CH_FLOOR jsr open_ch
beq ust_fly bcs ust_fly
lda #0 ; a wall swallows it lda #0 ; a wall swallows it
sta es_on sta es_on
rts rts
@@ -1268,6 +1443,8 @@ upd_flash:
ldx exrow ldx exrow
jsr row_ptr jsr row_ptr
ldy excol ldy excol
jsr exit_open
bcc uf_exlock
lda framectr lda framectr
and #8 and #8
bne uf_exw bne uf_exw
@@ -1275,6 +1452,9 @@ upd_flash:
jmp uf_exset jmp uf_exset
uf_exw: uf_exw:
lda #WHITE lda #WHITE
jmp uf_exset
uf_exlock:
lda #DGREY ; sealed while a relic is still missing
uf_exset: uf_exset:
sta (collo),y sta (collo),y
lda rotflash ; the spun walls flash, then re-highlight lda rotflash ; the spun walls flash, then re-highlight
@@ -1298,6 +1478,29 @@ uf_hot:
lda #COL_HILITE lda #COL_HILITE
uf_cset: uf_cset:
sta SPRCOL+SP_CUR sta SPRCOL+SP_CUR
; fall through: the relic he is after next pulses white
relic_blink:
lda opt_relic
beq rb_done
ldx rnext
cpx rcount
bcs rb_done
lda rlx,x
sta ptmp
lda rly,x
tax
jsr row_ptr
ldy ptmp
lda framectr
and #8
bne rb_white
lda #COL_RELIC
jmp rb_set
rb_white:
lda #WHITE
rb_set:
sta (collo),y
rb_done:
rts rts
; ---- status row: the spin recharge readout (cooldown option) ; ---- status row: the spin recharge readout (cooldown option)
@@ -1350,6 +1553,38 @@ us_clr:
bpl us_clr bpl us_clr
rts rts
; ---- relic mode's readout in the goal corner: relics in
; hand / relics on the level, next to the portal glyph; green
; once the last one is his ----
upd_goal:
lda opt_relic
bne ug_show
rts
ug_show:
lda rnext
ora #$30
sta SCREEN+34
lda #$2f ; '/'
sta SCREEN+35
lda rcount
ora #$30
sta SCREEN+36
lda #$20
sta SCREEN+37
lda #CH_EXIT
sta SCREEN+38
jsr exit_open
lda #LRED
bcc ug_col
lda #LGREEN
ug_col:
ldx #4
ug_loop:
sta COLRAM+34,x
dex
bpl ug_loop
rts
; ---- the run clock, live on the status row ---- ; ---- the run clock, live on the status row ----
upd_clock: upd_clock:
lda tmin lda tmin
@@ -1529,6 +1764,9 @@ exrow: !byte 0 ; screen row of the exit portal
endflag: !byte 0 ; 0 = playing, 1 = escaped, 2 = caught endflag: !byte 0 ; 0 = playing, 1 = escaped, 2 = caught
cool: !byte 0 ; spin recharge frames left (cooldown option) cool: !byte 0 ; spin recharge frames left (cooldown option)
rotflash:!byte 0 ; frames the freshly spun walls stay white rotflash:!byte 0 ; frames the freshly spun walls stay white
rcount: !byte 0 ; relics on this level (relic order option)
rnext: !byte 0 ; the one he must pick up next
ri: !byte 0 ; relic placement loop index
s_on: !byte 0 ; bullet in flight? s_on: !byte 0 ; bullet in flight?
sx: !byte 0 ; bullet position and heading sx: !byte 0 ; bullet position and heading
sy: !byte 0 sy: !byte 0
@@ -1579,6 +1817,8 @@ ex: !fill NENEMIES, 0 ; enemy positions and headings
ey: !fill NENEMIES, 0 ey: !fill NENEMIES, 0
edir: !fill NENEMIES, 0 edir: !fill NENEMIES, 0
edead: !fill NENEMIES, 0 ; respawn countdown, 0 = alive edead: !fill NENEMIES, 0 ; respawn countdown, 0 = alive
rlx: !fill NRELIC, 0 ; relic positions (screen col / row)
rly: !fill NRELIC, 0
; ---- maze generator buffers ---- ; ---- maze generator buffers ----
visited: !fill NCELLS, 0 visited: !fill NCELLS, 0