blessing of ra
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
# Makefile – C64 project builder (ACME + VICE)
|
||||
# -----------------------------------------
|
||||
|
||||
PROJECT = labyrintwo
|
||||
PROJECT = blessingofra
|
||||
|
||||
ASM = acme
|
||||
EMU = x64sc
|
||||
|
||||
@@ -1,51 +1,65 @@
|
||||
# labyrintwo (LabyrinTwo)
|
||||
# Blessing of Ra
|
||||
|
||||
**LabyrinTwo** - a two-player maze duel for the Commodore 64
|
||||
**Blessing of Ra** - a two-player pyramid escape for the Commodore 64
|
||||
(ACME + VICE), in the same spirit as [rabbitc64](../rabbitc64).
|
||||
|
||||
A fresh maze carves itself on screen at the start of every round on
|
||||
a 39x23 lattice where the walls are exactly as wide as the corridors.
|
||||
**Player 1** (joystick 2, or `w a s d`) runs the corridors toward the
|
||||
green exit portal while dodging the roaming enemies. **Player 2**
|
||||
(joystick 1, or `i j k l`) rides the corners of the walls with a
|
||||
bracket cursor - fire (or `return`) spins the four wall pieces around
|
||||
the cursor by 90 degrees, reshaping the maze in real time. A spin is
|
||||
denied while anyone is standing in one of the four slots (the border
|
||||
blips red); the spun pieces flash white.
|
||||
The legend: when the great pyramid rose, a worker was sealed in its
|
||||
peak. He prayed to Ra until the sun god took pity - now Ra bends the
|
||||
pyramid's labyrinth walls to lead him out.
|
||||
|
||||
The look: brick walls and bolted pivot posts from a custom RAM
|
||||
charset, every actor (runner, cursor, bullet, enemies) a hardware
|
||||
sprite gliding smoothly between the cells, an animated exit portal,
|
||||
a raster color band behind the status row, and a fade to black
|
||||
between all screens. The menu floats over a dark maze backdrop.
|
||||
**Player 1** (joystick 2, or `w a s d`) is the worker, running the
|
||||
corridors toward the green exit portal. **Player 2** (joystick 1, or
|
||||
`i j k l`) is Ra: a bracket cursor rides the corners of the walls -
|
||||
fire (or `return`) spins the four wall pieces around the cursor by
|
||||
90 degrees, reshaping the maze in real time. A spin is denied while
|
||||
anyone is standing in one of the four slots (the border blips red);
|
||||
the spun pieces flash white.
|
||||
|
||||
Eight levels, each maze one cell bigger than the last: a square that
|
||||
starts at 4x4 cells and grows to 11x11 - the tallest square lattice
|
||||
the screen fits - always centered on screen. One more enemy joins
|
||||
each level (up to four): the cyan **scarabs** roam the corridors,
|
||||
and the light-red **scorpions** also spit a venom sting whenever
|
||||
they line up with the worker - the purple drop flies down the
|
||||
corridor until a wall swallows it.
|
||||
|
||||
The look: a desert palette of sandstone walls and brown pivot posts
|
||||
from a custom RAM charset, every actor (worker, cursor, bullet,
|
||||
sting, enemies) a hardware sprite gliding smoothly between the
|
||||
cells, an animated exit portal, a raster color band behind the
|
||||
status row, and a fade to black between all screens. The menu floats
|
||||
over a dark maze backdrop under the big gold-washed title.
|
||||
|
||||
The options screen adds two optional twists:
|
||||
|
||||
- **runner 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.
|
||||
- **spin cooldown** - each spin starts a recharge; further spins are
|
||||
denied until the bar on the status row drains (pixel by pixel) and
|
||||
the readout flips back from *wait* to *ready* (the cursor also
|
||||
turns red while recharging).
|
||||
|
||||
Screens: TTG intro (ported from rabbitc64) -> main menu
|
||||
(play / options / rules / controls / credits) -> game -> win (back
|
||||
to the menu) or game over (fire retries with a fresh maze, `m` backs
|
||||
out to the menu).
|
||||
Screens: TTG intro (ported from rabbitc64) -> pyramid title card
|
||||
(the pyramid, the trapped worker and the pulsing sun of Ra) -> main
|
||||
menu (play / options / story / credits) -> game -> next level, and
|
||||
after the last one the escape screen (back to the menu); game over
|
||||
lets fire retry the same level with a fresh maze, `m` backs out to
|
||||
the menu. The story screen tells the legend and lists who steers
|
||||
what.
|
||||
|
||||
## Build & run
|
||||
|
||||
```
|
||||
make deps # macOS: brew install acme vice
|
||||
make build # -> labyrintwo.prg
|
||||
make build # -> blessingofra.prg
|
||||
make run # build + launch in x64sc
|
||||
```
|
||||
|
||||
Test builds can boot straight into one state:
|
||||
|
||||
```
|
||||
acme -DAUTOPLAY=1 -f cbm -o labyrintwo.prg main.asm
|
||||
# also: AUTOOPTIONS, AUTORULES, AUTOCONTROLS, AUTOCREDITS,
|
||||
acme -DAUTOPLAY=1 -f cbm -o blessingofra.prg main.asm
|
||||
# also: AUTOOPTIONS, AUTOSTORY, AUTOPYRAMID, AUTOCREDITS,
|
||||
# AUTOWIN, AUTOLOSE; add -DFORCEOPTS=1 to start with both
|
||||
# options turned on
|
||||
```
|
||||
@@ -56,15 +70,16 @@ acme -DAUTOPLAY=1 -f cbm -o labyrintwo.prg main.asm
|
||||
the border/status-band raster work
|
||||
- `defs.asm` - registers, constants, zero page, macros
|
||||
- `intro.asm` - TTG boot logo with the gold color wash
|
||||
- `pyramid.asm` - title card: the pyramid, the worker, the sun of Ra
|
||||
- `menu.asm` - main menu card over a dark maze backdrop
|
||||
- `options.asm` - the optional extras and their toggle screen
|
||||
- `rules.asm` - how to play
|
||||
- `controls.asm` - joystick + keyboard mappings
|
||||
- `story.asm` - the legend of the worker and Ra + the controls
|
||||
- `credits.asm` - the crew
|
||||
- `play.asm` - maze generation (recursive backtracker, animated)
|
||||
+ the game
|
||||
- `play.asm` - maze geometry + generation (recursive backtracker,
|
||||
animated) + the game and its eight growing levels
|
||||
- `win.asm` / `over.asm` - end screens
|
||||
- `common.asm` - shared routines: printing, big block font, input, RNG
|
||||
- `common.asm` - shared routines: printing, big block font, the
|
||||
title wash, input, RNG
|
||||
- `sound.asm` - single-voice SID SFX driver
|
||||
- `gfx.asm` - RAM charset with the custom tiles, the sprite engine,
|
||||
the portal animation and the fade-to-black transition
|
||||
|
||||
+41
-3
@@ -356,10 +356,48 @@ bigmap: ; screen code (a=1..z=26) -> glyph index
|
||||
!byte 0, 7, 8, 9, 10, 11, 0, 12, 13, 14 ; k-t
|
||||
!byte 20, 18, 21, 0, 15, 0 ; u-z
|
||||
|
||||
; ---- gold wash over the two big title lines (rows 1-5 and
|
||||
; 7-11): only the $a0 letter blocks are recolored, so it is
|
||||
; safe over any backdrop ----
|
||||
wash_title:
|
||||
inc washphase
|
||||
lda #0
|
||||
sta g8row
|
||||
wt_row:
|
||||
ldx g8row
|
||||
lda wtrows,x
|
||||
tax
|
||||
jsr row_ptr
|
||||
lda washphase
|
||||
lsr ; half speed keeps the shimmer gentle
|
||||
clc
|
||||
adc g8row
|
||||
and #15
|
||||
tax
|
||||
lda washtbl,x
|
||||
sta rtmp
|
||||
ldy #39
|
||||
wt_col:
|
||||
lda (scrlo),y
|
||||
cmp #$a0 ; only touch the letter blocks
|
||||
bne wt_skip
|
||||
lda rtmp
|
||||
sta (collo),y
|
||||
wt_skip:
|
||||
dey
|
||||
bpl wt_col
|
||||
inc g8row
|
||||
lda g8row
|
||||
cmp #10
|
||||
bne wt_row
|
||||
rts
|
||||
|
||||
wtrows: !byte 1, 2, 3, 4, 5, 7, 8, 9, 10, 11
|
||||
|
||||
; ---- shared texts (screen codes) ----
|
||||
; the title is split so the two words can wear two colors
|
||||
txt_t1: !scr "labyrin"
|
||||
txt_t2: !scr "two"
|
||||
; the title is split so the two lines can be placed apart
|
||||
txt_t1: !scr "blessing"
|
||||
txt_t2: !scr "of ra"
|
||||
txt_ttgname: !scr "teletype games"
|
||||
txt_presents:!scr "presents"
|
||||
txt_return: !scr "fire = return"
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
; -----------------------------------------------------------
|
||||
; controls.asm - who steers what: joystick and keyboard
|
||||
; mappings for both players, one static card; fire returns
|
||||
; -----------------------------------------------------------
|
||||
|
||||
controls_init:
|
||||
jsr clear_screen
|
||||
|
||||
+prbig 1, 4, WHITE, txt_controls, 8
|
||||
|
||||
+prtext 8, 9, LGREEN, txt_c1, txt_c1e-txt_c1
|
||||
+prtext 10, 6, WHITE, txt_c2, txt_c2e-txt_c2
|
||||
+prtext 11, 6, LGREY, txt_c2b, txt_c2be-txt_c2b
|
||||
|
||||
+prtext 13, 6, LBLUE, txt_c3, txt_c3e-txt_c3
|
||||
+prtext 15, 6, WHITE, txt_c4, txt_c4e-txt_c4
|
||||
+prtext 17, 10, WHITE, txt_c5, txt_c5e-txt_c5
|
||||
|
||||
+prtext 20, 5, LGREY, txt_c6, txt_c6e-txt_c6
|
||||
|
||||
+setupd controls_update
|
||||
rts
|
||||
|
||||
controls_update:
|
||||
; blink the return prompt
|
||||
lda framectr
|
||||
and #32
|
||||
bne co_hide
|
||||
+prtext 22, 13, YELLOW, txt_return, 13
|
||||
jmp co_input
|
||||
co_hide:
|
||||
+prtext 22, 13, YELLOW, txt_blank, 13
|
||||
co_input:
|
||||
jsr start_edge
|
||||
beq co_stay
|
||||
+fadeto menu_init
|
||||
co_stay:
|
||||
rts
|
||||
|
||||
; ---- controls texts ----
|
||||
txt_controls: !scr "controls"
|
||||
txt_c1: !scr "player 1 - the runner"
|
||||
txt_c1e:
|
||||
txt_c2: !scr "move: joystick 2 or w a s d"
|
||||
txt_c2e:
|
||||
txt_c2b: !scr "gun: fire or space, if enabled"
|
||||
txt_c2be:
|
||||
txt_c3: !scr "player 2 - the wall spinner"
|
||||
txt_c3e:
|
||||
txt_c4: !scr "move: joystick 1 or i j k l"
|
||||
txt_c4e:
|
||||
txt_c5: !scr "spin: fire or return"
|
||||
txt_c5e:
|
||||
txt_c6: !scr "menus: fire, space or return"
|
||||
txt_c6e:
|
||||
@@ -45,7 +45,7 @@ SFX_ROTATE = 2 ; wall spin: noise whoosh
|
||||
SFX_DENY = 3 ; blocked spin: low buzz
|
||||
SFX_WIN = 4 ; escape: rising jingle
|
||||
SFX_LOSE = 5 ; caught: descending sweep
|
||||
SFX_SHOT = 6 ; gun fired: short high tick
|
||||
SFX_SHOT = 6 ; gun / scorpion sting: short high tick
|
||||
SFX_HIT = 7 ; enemy hit: noise burst
|
||||
NSFX = 8
|
||||
|
||||
@@ -75,34 +75,45 @@ JOY_RIGHT = 8
|
||||
JOY_FIRE = 16
|
||||
|
||||
; ---- the maze ----
|
||||
; 19x11 cells on a 39x23 char lattice (screen rows 1-23):
|
||||
; cell = odd column, even row (walkable)
|
||||
; post = even column, odd row (pivot, always solid)
|
||||
; a lattice of (2*cells+1) chars per side, centered on rows
|
||||
; 1-23; local coordinates inside the lattice:
|
||||
; cell = odd column, odd row (walkable)
|
||||
; post = even column, even row (pivot, always solid)
|
||||
; slot = the rest: wall pieces that spin around the posts
|
||||
; wall thickness therefore equals corridor width: one cell
|
||||
MAZE_CW = 19 ; cells across
|
||||
MAZE_CH = 11 ; cells down
|
||||
; the levels are squares, one cell bigger each level: MZMIN
|
||||
; up to MZMAX (11x11 cells = 23x23 chars, the tallest square
|
||||
; the screen fits); the menu backdrop uses the full lattice
|
||||
MZMIN = 4 ; level 1: 4x4 cells
|
||||
MZMAX = 11 ; level 8: 11x11 cells
|
||||
MAZE_CW = 19 ; the largest lattice: the menu backdrop
|
||||
MAZE_CH = 11
|
||||
NCELLS = MAZE_CW * MAZE_CH
|
||||
NENEMIES = 4
|
||||
NENEMIES = 4 ; enemy sprite slots (a level uses 1-4)
|
||||
|
||||
; ---- characters (the custom tiles live in the RAM charset) ----
|
||||
CH_WALL = $e0 ; brick block: spinnable wall piece
|
||||
CH_WALL = $e0 ; sandstone block: spinnable wall piece
|
||||
CH_POST = $e1 ; bolted plate: fixed pivot post
|
||||
CH_EXIT = $e2 ; the portal out (4 animated glyph frames)
|
||||
CH_FLOOR = $20 ; space: corridor
|
||||
CH_BAR = $e3 ; 7 chars: a bar cell 1-7 pixels full
|
||||
|
||||
; ---- the actors are hardware sprites ----
|
||||
SP_RUN = 0 ; player 1, the runner
|
||||
SP_CUR = 1 ; player 2, the corner cursor
|
||||
SP_RUN = 0 ; player 1, the worker
|
||||
SP_CUR = 1 ; player 2, ra's cursor
|
||||
SP_SHOT = 2 ; the optional bullet
|
||||
SP_EN = 3 ; the enemies ride sprites 3-6
|
||||
SP_STING = 7 ; the scorpions' venom sting
|
||||
|
||||
COL_WALL = MGREY ; spinnable wall pieces
|
||||
COL_POST = DGREY ; fixed pivot posts
|
||||
; ---- desert palette ----
|
||||
COL_WALL = ORANGE ; sandstone wall pieces
|
||||
COL_POST = BROWN ; fixed pivot posts
|
||||
COL_EXIT = LGREEN ; the exit portal
|
||||
COL_HILITE = YELLOW ; walls the cursor's spin would move
|
||||
STATCOL = BLUE ; background band behind the status row
|
||||
COL_SCARAB = CYAN ; the scarabs
|
||||
COL_SCORP = LRED ; the scorpions
|
||||
COL_STING = PURPLE ; the venom sting
|
||||
STATCOL = BROWN ; background band behind the status row
|
||||
|
||||
; ---- game timing ----
|
||||
REP_HOLD = 10 ; runner: frames before a held dir repeats
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
; -----------------------------------------------------------
|
||||
; gfx.asm - the graphics layer:
|
||||
; - the ROM font is copied into RAM and a handful of custom
|
||||
; tiles are stamped over it (brick wall, pivot post, the
|
||||
; animated exit portal, the 1/8-step cooldown bar cells)
|
||||
; tiles are stamped over it (sandstone wall, pivot post,
|
||||
; the animated exit portal, the 1/8-step cooldown bar)
|
||||
; - a small sprite engine: every actor lives on the char
|
||||
; grid, its sprite glides toward the cell a few pixels a
|
||||
; frame (the runner bobs, the enemies wave)
|
||||
; frame (the worker bobs, the enemies wave)
|
||||
; - fade to black: the transition between two screens
|
||||
; -----------------------------------------------------------
|
||||
|
||||
@@ -308,7 +308,7 @@ fadetbl: ; each color, one step darker
|
||||
!byte $02, $00, $02, $00, $0b, $05, $06, $0c
|
||||
|
||||
; ---- the custom tiles ----
|
||||
tile_gfx: ; CH_WALL: bricks with dark mortar
|
||||
tile_gfx: ; CH_WALL: sandstone blocks, dark mortar
|
||||
!byte %11111111
|
||||
!byte %11110111
|
||||
!byte %11110111
|
||||
@@ -430,50 +430,61 @@ spr_cur0: ; the corner cursor: four brackets
|
||||
!byte %10000001, 0, 0
|
||||
!byte %11100111, 0, 0
|
||||
!fill 40, 0
|
||||
spr_ena0: ; enemies 0-1: a ghost, skirt waving
|
||||
!byte %00111100, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %11011011, 0, 0
|
||||
!byte %11011011, 0, 0
|
||||
!byte %11111111, 0, 0
|
||||
!byte %11111111, 0, 0
|
||||
!byte %11111111, 0, 0
|
||||
!byte %10110101, 0, 0
|
||||
!fill 40, 0
|
||||
spr_ena1:
|
||||
!byte %00111100, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %11011011, 0, 0
|
||||
!byte %11011011, 0, 0
|
||||
!byte %11111111, 0, 0
|
||||
!byte %11111111, 0, 0
|
||||
!byte %11111111, 0, 0
|
||||
!byte %01101101, 0, 0
|
||||
!fill 40, 0
|
||||
spr_enb0: ; enemies 2-3: a crawler, legs pumping
|
||||
spr_sting0: ; the scorpion's venom sting: a drop
|
||||
!byte %00000000, 0, 0
|
||||
!byte %00011000, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %00011000, 0, 0
|
||||
!byte %00000000, 0, 0
|
||||
!byte %00000000, 0, 0
|
||||
!fill 40, 0
|
||||
spr_ena0: ; even enemies: a scarab, legs out...
|
||||
!byte %00100100, 0, 0
|
||||
!byte %10111101, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %11011011, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %10111101, 0, 0
|
||||
!byte %00000000, 0, 0
|
||||
!byte %00000000, 0, 0
|
||||
!fill 40, 0
|
||||
spr_enb1:
|
||||
!byte %00000000, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %11011011, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %10111101, 0, 0
|
||||
!byte %00100100, 0, 0
|
||||
!fill 40, 0
|
||||
spr_ena1: ; ...and tucked as it scuttles
|
||||
!byte %00100100, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %00000000, 0, 0
|
||||
!byte %00000000, 0, 0
|
||||
!byte %11111111, 0, 0
|
||||
!byte %01011010, 0, 0
|
||||
!byte %01011010, 0, 0
|
||||
!byte %11111111, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %00100100, 0, 0
|
||||
!fill 40, 0
|
||||
spr_enb0: ; odd enemies: a scorpion, claws up,
|
||||
!byte %11000011, 0, 0 ; the tail swinging right...
|
||||
!byte %01100110, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %00011000, 0, 0
|
||||
!byte %00001100, 0, 0
|
||||
!byte %00011110, 0, 0
|
||||
!fill 40, 0
|
||||
spr_enb1: ; ...and left
|
||||
!byte %11000011, 0, 0
|
||||
!byte %01100110, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %01111110, 0, 0
|
||||
!byte %00111100, 0, 0
|
||||
!byte %00011000, 0, 0
|
||||
!byte %00110000, 0, 0
|
||||
!byte %01111000, 0, 0
|
||||
!fill 40, 0
|
||||
|
||||
SPR_RUN = spr_run0 DIV 64
|
||||
SPR_SHOT = spr_shot0 DIV 64
|
||||
SPR_CUR = spr_cur0 DIV 64
|
||||
SPR_STING = spr_sting0 DIV 64
|
||||
SPR_ENA = spr_ena0 DIV 64
|
||||
SPR_ENB = spr_enb0 DIV 64
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
; intro.asm - boot screen ported from rabbitc64: giant TTG
|
||||
; letters built from 8x8 bitmaps with a gold color wash
|
||||
; running down them, TELETYPE GAMES / PRESENTS below;
|
||||
; advances to the menu after a few seconds or on fire
|
||||
; advances to the pyramid title card after a few seconds or
|
||||
; on fire
|
||||
; -----------------------------------------------------------
|
||||
|
||||
INTRO_LROW = 3 ; top cell row of the giant letters
|
||||
@@ -78,11 +79,11 @@ iw_skip:
|
||||
; fire skips, otherwise wait out the timer
|
||||
jsr start_edge
|
||||
beq iw_tick
|
||||
+fadeto menu_init
|
||||
+fadeto pyramid_init
|
||||
iw_tick:
|
||||
dec introt
|
||||
bne iw_done
|
||||
+fadeto menu_init
|
||||
+fadeto pyramid_init
|
||||
iw_done:
|
||||
rts
|
||||
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
; -----------------------------------------------------------
|
||||
; main.asm - LABYRINTWO for the C64
|
||||
; two-player maze duel: player 1 runs the corridors toward
|
||||
; the green exit portal while dodging the roaming colored
|
||||
; enemies; player 2 rides the wall corners with a cursor
|
||||
; and fire spins the four wall pieces around it by 90
|
||||
; degrees, reshaping the maze under the runner's feet
|
||||
; main.asm - BLESSING OF RA for the C64
|
||||
; two-player pyramid escape: player 1 is a worker sealed in
|
||||
; the great pyramid, running the corridors toward the exit
|
||||
; portal while dodging the scarabs and scorpions (whose
|
||||
; venom stings fly down the corridors); player 2 is ra: the
|
||||
; cursor rides the wall corners and fire spins the four
|
||||
; wall pieces around it by 90 degrees, reshaping the maze
|
||||
; under the worker's feet; eight levels, each maze one cell
|
||||
; bigger than the last (4x4 up to 11x11)
|
||||
;
|
||||
; Files:
|
||||
; defs.asm - constants, zero page, macros
|
||||
; intro.asm - TTG boot logo (ported from rabbitc64)
|
||||
; pyramid.asm - title card: the pyramid and the sun of ra
|
||||
; menu.asm - main menu over a dark maze backdrop
|
||||
; options.asm - optional extras: runner gun, spin cooldown
|
||||
; rules.asm - how to play
|
||||
; controls.asm- joystick + keyboard mappings
|
||||
; options.asm - optional extras: worker gun, spin cooldown
|
||||
; story.asm - the legend + who steers what
|
||||
; credits.asm - the crew (content from rabbitc64, new look)
|
||||
; play.asm - maze generation + the game itself
|
||||
; win.asm - escape screen, returns to the menu
|
||||
@@ -21,7 +24,7 @@
|
||||
; sound.asm - single-voice SFX driver
|
||||
; gfx.asm - RAM charset, sprite engine, fades
|
||||
;
|
||||
; Build: acme -f cbm -o labyrintwo.prg main.asm
|
||||
; Build: acme -f cbm -o blessingofra.prg main.asm
|
||||
; -----------------------------------------------------------
|
||||
|
||||
* = $0801
|
||||
@@ -54,11 +57,11 @@ start:
|
||||
!ifdef AUTOPLAY { ; test builds boot straight into one state
|
||||
jsr play_init
|
||||
} else {
|
||||
!ifdef AUTORULES {
|
||||
jsr rules_init
|
||||
!ifdef AUTOSTORY {
|
||||
jsr story_init
|
||||
} else {
|
||||
!ifdef AUTOCONTROLS {
|
||||
jsr controls_init
|
||||
!ifdef AUTOPYRAMID {
|
||||
jsr pyramid_init
|
||||
} else {
|
||||
!ifdef AUTOOPTIONS {
|
||||
jsr options_init
|
||||
@@ -72,7 +75,7 @@ start:
|
||||
!ifdef AUTOLOSE {
|
||||
jsr lose_init
|
||||
} else {
|
||||
jsr intro_init ; TTG logo, then the menu
|
||||
jsr intro_init ; TTG logo, then the pyramid, then the menu
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,10 +148,10 @@ wf_hit:
|
||||
; the states and everything they share
|
||||
; ============================================================
|
||||
!src "intro.asm"
|
||||
!src "pyramid.asm"
|
||||
!src "menu.asm"
|
||||
!src "options.asm"
|
||||
!src "rules.asm"
|
||||
!src "controls.asm"
|
||||
!src "story.asm"
|
||||
!src "credits.asm"
|
||||
!src "play.asm"
|
||||
!src "win.asm"
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
; -----------------------------------------------------------
|
||||
; menu.asm - full-screen menu card: big LABYRINTWO title in
|
||||
; two colors (gold wash on LABYRIN, cool blue shimmer on
|
||||
; TWO), and a five-item menu: play / options / rules /
|
||||
; controls / credits (joystick or w/s up/down + fire, space
|
||||
; or return)
|
||||
; menu.asm - full-screen menu card: big BLESSING / OF RA
|
||||
; title under the rolling gold sun wash, and a four-item
|
||||
; menu: play / options / story / credits (joystick or w/s
|
||||
; up/down + fire, space or return)
|
||||
; -----------------------------------------------------------
|
||||
|
||||
MENU_ITEMS = 5
|
||||
MENU_ITEMS = 4
|
||||
|
||||
menu_init:
|
||||
jsr clear_screen
|
||||
|
||||
; a dark maze weaves behind the whole card
|
||||
lda #DGREY
|
||||
lda #MAZE_CW
|
||||
sta mzcw
|
||||
lda #MAZE_CH
|
||||
sta mzch
|
||||
jsr set_maze
|
||||
lda #BROWN
|
||||
sta latwcol
|
||||
sta latpcol
|
||||
jsr draw_lattice
|
||||
jsr gen_init
|
||||
jsr gen_maze_full
|
||||
|
||||
; a clean panel for the menu itself (rows 9-22, cols 4-35)
|
||||
ldx #9
|
||||
; a clean panel for the menu itself (rows 13-24, cols 4-35)
|
||||
ldx #13
|
||||
mi_panel:
|
||||
stx ptmp
|
||||
jsr row_ptr
|
||||
@@ -35,12 +39,12 @@ mi_pcol:
|
||||
bne mi_pcol
|
||||
ldx ptmp
|
||||
inx
|
||||
cpx #23
|
||||
cpx #25
|
||||
bne mi_panel
|
||||
|
||||
+prbig 2, 0, YELLOW, txt_t1, 7
|
||||
+prbig 2, 28, CYAN, txt_t2, 3
|
||||
+prtext 9, 13, LGREY, txt_ttgname, 14
|
||||
+prbig 1, 4, YELLOW, txt_t1, 8
|
||||
+prbig 7, 10, ORANGE, txt_t2, 5
|
||||
+prtext 13, 13, LGREY, txt_ttgname, 14
|
||||
|
||||
lda #0
|
||||
sta menusel
|
||||
@@ -50,58 +54,7 @@ mi_pcol:
|
||||
rts
|
||||
|
||||
menu_update:
|
||||
; the title rows 2-6: gold wash on LABYRIN (columns 0-26),
|
||||
; cool blue shimmer on TWO (columns 27-38)
|
||||
inc washphase
|
||||
lda #0
|
||||
sta g8row
|
||||
mw_row:
|
||||
lda #2
|
||||
clc
|
||||
adc g8row
|
||||
tax
|
||||
jsr row_ptr
|
||||
lda washphase
|
||||
lsr
|
||||
clc
|
||||
adc g8row
|
||||
and #15
|
||||
tax
|
||||
lda washtbl,x
|
||||
sta rtmp
|
||||
ldy #26
|
||||
mw_col:
|
||||
lda (scrlo),y
|
||||
cmp #$a0 ; only touch the letter blocks
|
||||
bne mw_skip
|
||||
lda rtmp
|
||||
sta (collo),y
|
||||
mw_skip:
|
||||
dey
|
||||
bpl mw_col
|
||||
lda washphase
|
||||
lsr
|
||||
clc
|
||||
adc g8row
|
||||
and #7
|
||||
tax
|
||||
lda cooltbl,x
|
||||
sta rtmp
|
||||
ldy #38
|
||||
mw_col2:
|
||||
lda (scrlo),y
|
||||
cmp #$a0
|
||||
bne mw_skip2
|
||||
lda rtmp
|
||||
sta (collo),y
|
||||
mw_skip2:
|
||||
dey
|
||||
cpy #26
|
||||
bne mw_col2
|
||||
inc g8row
|
||||
lda g8row
|
||||
cmp #5
|
||||
bne mw_row
|
||||
jsr wash_title ; gold sun wash on both title lines
|
||||
|
||||
; joystick up/down steps the cursor (edge detected)
|
||||
jsr read_joy
|
||||
@@ -135,8 +88,8 @@ mu_udrel:
|
||||
mu_udend:
|
||||
|
||||
; footer: both control lines always visible
|
||||
+prtext 21, 8, LGREY, txt_info, txt_infoe-txt_info
|
||||
+prtext 22, 5, LGREY, txt_info2, txt_info2e-txt_info2
|
||||
+prtext 23, 7, LGREY, txt_info, txt_infoe-txt_info
|
||||
+prtext 24, 11, LGREY, txt_info2, txt_info2e-txt_info2
|
||||
|
||||
; the menu items: the picked line is yellow
|
||||
ldx #0
|
||||
@@ -152,11 +105,10 @@ mm_items:
|
||||
|
||||
; blinking '>' cursor in front of the picked line
|
||||
lda #$20
|
||||
sta SCREEN+11*40+15
|
||||
sta SCREEN+13*40+15
|
||||
sta SCREEN+15*40+15
|
||||
sta SCREEN+17*40+15
|
||||
sta SCREEN+19*40+15
|
||||
sta SCREEN+21*40+15
|
||||
lda framectr
|
||||
and #16
|
||||
bne mu_start
|
||||
@@ -186,18 +138,20 @@ mu_start:
|
||||
cmp #1
|
||||
beq mg_options
|
||||
cmp #2
|
||||
beq mg_rules
|
||||
cmp #3
|
||||
beq mg_controls
|
||||
beq mg_story
|
||||
+fadeto credits_init ; every screen change fades to black
|
||||
mg_play:
|
||||
lda #MZMIN ; a fresh run: level 1, clock zeroed
|
||||
sta mzsize
|
||||
lda #0
|
||||
sta tframe
|
||||
sta tsec
|
||||
sta tmin
|
||||
+fadeto play_init
|
||||
mg_options:
|
||||
+fadeto options_init
|
||||
mg_rules:
|
||||
+fadeto rules_init
|
||||
mg_controls:
|
||||
+fadeto controls_init
|
||||
mg_story:
|
||||
+fadeto story_init
|
||||
mu_done:
|
||||
rts
|
||||
|
||||
@@ -223,35 +177,27 @@ dm_store:
|
||||
|
||||
; ---- menu tables ----
|
||||
mitem_lo:
|
||||
!byte <txt_play, <txt_options, <txt_rules
|
||||
!byte <txt_controls, <txt_credits
|
||||
!byte <txt_play, <txt_options, <txt_story, <txt_credits
|
||||
mitem_hi:
|
||||
!byte >txt_play, >txt_options, >txt_rules
|
||||
!byte >txt_controls, >txt_credits
|
||||
mitem_len: !byte 4, 7, 5, 8, 7
|
||||
mitem_row: !byte 11, 13, 15, 17, 19
|
||||
!byte >txt_play, >txt_options, >txt_story, >txt_credits
|
||||
mitem_len: !byte 4, 7, 5, 7
|
||||
mitem_row: !byte 15, 17, 19, 21
|
||||
mcur_lo: ; cursor cells: column 15 of those rows
|
||||
!byte <(SCREEN+11*40+15), <(SCREEN+13*40+15)
|
||||
!byte <(SCREEN+15*40+15), <(SCREEN+17*40+15)
|
||||
!byte <(SCREEN+19*40+15)
|
||||
!byte <(SCREEN+19*40+15), <(SCREEN+21*40+15)
|
||||
mcur_hi:
|
||||
!byte >(SCREEN+11*40+15), >(SCREEN+13*40+15)
|
||||
!byte >(SCREEN+15*40+15), >(SCREEN+17*40+15)
|
||||
!byte >(SCREEN+19*40+15)
|
||||
|
||||
cooltbl: ; blue-cyan-white shimmer for the TWO
|
||||
!byte $06, $0e, $03, $01, $01, $03, $0e, $06
|
||||
!byte >(SCREEN+19*40+15), >(SCREEN+21*40+15)
|
||||
|
||||
; ---- menu texts ----
|
||||
txt_play: !scr "play"
|
||||
txt_options: !scr "options"
|
||||
txt_rules: !scr "rules"
|
||||
txt_credits: !scr "credits"
|
||||
txt_info: !scr "p1: joy2 / wasd - runner"
|
||||
txt_info: !scr "p1: joy2/wasd - the worker"
|
||||
txt_infoe:
|
||||
txt_info2: !scr "p2: joy1 / ijkl - wall spinner"
|
||||
txt_info2: !scr "p2: joy1/ijkl - ra"
|
||||
txt_info2e:
|
||||
|
||||
; ---- menu variables ----
|
||||
menusel: !byte 0 ; picked line: 0-2
|
||||
menusel: !byte 0 ; picked line: 0-3
|
||||
udheld: !byte 0 ; joystick up/down edge detection state
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "labyrintwo",
|
||||
"title": "LabyrinTwo",
|
||||
"name": "blessingofra",
|
||||
"title": "Blessing of Ra",
|
||||
"author": "Teletype Games",
|
||||
"desc": "Two-player maze duel: one player runs for the exit while the other spins the walls of the labyrintwo around their corners. Dodge the enemies, find the diamond.",
|
||||
"desc": "Two-player pyramid escape: a worker sealed in the great pyramid runs for the exit while Ra bends the maze walls around him. Scarabs and scorpions - and their flying venom stings - hunt him through eight levels, from a 4x4 maze up to 11x11.",
|
||||
"site": "https://git.teletype.hu/games/labyrintwo",
|
||||
"license": "MIT",
|
||||
"version": "1.0.0"
|
||||
"version": "2.0.0"
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
; -----------------------------------------------------------
|
||||
; options.asm - optional extras, toggled with fire:
|
||||
; runner gun - player 1 shoots with fire; a hit enemy
|
||||
; worker gun - player 1 shoots with fire; a hit enemy
|
||||
; respawns elsewhere after a pause
|
||||
; spin cooldown - the wall spinner needs a recharge between
|
||||
; two spins, shown on the status row
|
||||
; the settings live here and survive between rounds
|
||||
; spin cooldown - ra needs a recharge between two spins,
|
||||
; shown on the status row
|
||||
; the settings live here and survive between levels
|
||||
; -----------------------------------------------------------
|
||||
|
||||
OPT_ITEMS = 3
|
||||
@@ -173,7 +173,7 @@ ovtx_hi: !byte >txt_off, >txt_on
|
||||
ovcol: !byte LGREY, LGREEN
|
||||
|
||||
; ---- option texts ----
|
||||
txt_ogun: !scr "runner gun"
|
||||
txt_ogun: !scr "worker gun"
|
||||
txt_ocool: !scr "spin cooldown"
|
||||
txt_oback: !scr "back"
|
||||
txt_on: !scr "on "
|
||||
@@ -188,7 +188,7 @@ txt_oh2e:
|
||||
opt_shoot: !byte 1
|
||||
opt_cool: !byte 1
|
||||
} else {
|
||||
opt_shoot: !byte 0 ; 0 = classic game, 1 = the runner shoots
|
||||
opt_shoot: !byte 0 ; 0 = classic game, 1 = the worker shoots
|
||||
opt_cool: !byte 0 ; 1 = spins need a recharge
|
||||
}
|
||||
optsel: !byte 0 ; picked line: 0-2
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
; -----------------------------------------------------------
|
||||
; over.asm - game over screen: big red GAME OVER, fire
|
||||
; restarts with a fresh maze, the m key backs out to the menu
|
||||
; retries the same level with a fresh maze, the m key backs
|
||||
; out to the menu
|
||||
; -----------------------------------------------------------
|
||||
|
||||
lose_init:
|
||||
@@ -11,7 +12,14 @@ lose_init:
|
||||
|
||||
+prbig 3, 2, RED, txt_gameover, 9
|
||||
|
||||
+prtext 11, 10, WHITE, txt_caught, txt_caughte-txt_caught
|
||||
+prtext 11, 8, WHITE, txt_caught, txt_caughte-txt_caught
|
||||
|
||||
lda mzsize ; which level claimed him
|
||||
sec
|
||||
sbc #MZMIN-1
|
||||
ora #$30
|
||||
sta txt_felld
|
||||
+prtext 13, 10, LGREY, txt_fell, txt_felle-txt_fell
|
||||
|
||||
+prtext 21, 13, LGREY, txt_mmenu, txt_mmenue-txt_mmenu
|
||||
|
||||
@@ -51,8 +59,11 @@ lu_done:
|
||||
|
||||
; ---- game over texts ----
|
||||
txt_gameover: !scr "game over"
|
||||
txt_caught: !scr "the enemies got you"
|
||||
txt_caught: !scr "the pyramid claimed you"
|
||||
txt_caughte:
|
||||
txt_fell: !scr "you fell on level "
|
||||
txt_felld: !scr "1"
|
||||
txt_felle:
|
||||
txt_retry: !scr "fire = try again"
|
||||
txt_retrye:
|
||||
txt_mmenu: !scr "m = main menu"
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
; -----------------------------------------------------------
|
||||
; play.asm - the game: a fresh maze carves itself on screen
|
||||
; every round (recursive backtracker, a few steps a frame),
|
||||
; player 1 (joystick 2) runs the corridors toward the exit
|
||||
; portal, player 2 (joystick 1) rides the wall corners and
|
||||
; fire spins the four wall pieces around the cursor by 90
|
||||
; degrees; the roaming enemies end the round on touch
|
||||
; play.asm - the game: eight levels of pyramid maze, each one
|
||||
; cell bigger than the last (4x4 up to 11x11, always square,
|
||||
; centered on screen); a fresh maze carves itself at the
|
||||
; start of every level (recursive backtracker, a few steps a
|
||||
; frame), player 1 (joystick 2) is the trapped worker running
|
||||
; for the exit, player 2 (joystick 1) is ra: the cursor rides
|
||||
; the wall corners and fire spins the four wall pieces around
|
||||
; it by 90 degrees; scarabs roam the corridors on the
|
||||
; worker's life, and the scorpions also spit venom stings
|
||||
; down them
|
||||
;
|
||||
; the walls, posts and the portal are chars (the screen stays
|
||||
; the wall data structure), but every actor - runner, cursor,
|
||||
; bullet, enemies - is a hardware sprite gliding between the
|
||||
; cells; actor collisions are grid coordinate checks
|
||||
; the wall data structure), but every actor - worker, cursor,
|
||||
; bullet, enemies, sting - is a hardware sprite gliding
|
||||
; between the cells; actor collisions are grid coordinate
|
||||
; checks
|
||||
;
|
||||
; optional extras (see options.asm):
|
||||
; opt_shoot - player 1's fire shoots a bullet in the last
|
||||
@@ -19,15 +24,34 @@
|
||||
; a draining 1/8-step bar on the status row
|
||||
;
|
||||
; screen layout: status on row 0 (over the colored raster
|
||||
; band), the 39x23 maze lattice on rows 1-23, hints on row 24
|
||||
; band), the centered lattice on rows 1-23, hints on row 24
|
||||
; -----------------------------------------------------------
|
||||
|
||||
play_init:
|
||||
jsr clear_screen
|
||||
+prtext 0, 0, WHITE, txt_t1, 7
|
||||
+prtext 0, 7, CYAN, txt_t2, 3
|
||||
+prtext 0, 0, WHITE, txt_level, 5
|
||||
lda mzsize ; level number 1-8 next to the label
|
||||
sec
|
||||
sbc #MZMIN-1
|
||||
ora #$30
|
||||
sta SCREEN+6
|
||||
lda #YELLOW
|
||||
sta COLRAM+6
|
||||
+prtext 0, 34, LGREY, txt_goal, txt_goale-txt_goal
|
||||
+prtext 24, 6, 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
|
||||
sta mzcw
|
||||
sta mzch
|
||||
jsr set_maze
|
||||
lda mzsize ; one more enemy each level, capped
|
||||
sec
|
||||
sbc #MZMIN-1
|
||||
cmp #NENEMIES
|
||||
bcc pi_ne
|
||||
lda #NENEMIES
|
||||
pi_ne:
|
||||
sta nenem
|
||||
|
||||
lda #COL_WALL
|
||||
sta latwcol
|
||||
@@ -60,26 +84,31 @@ play_start:
|
||||
ps_exit:
|
||||
jsr rand8
|
||||
and #$0f
|
||||
cmp #MAZE_CH
|
||||
cmp mzch
|
||||
bcs ps_exit
|
||||
asl ; cell row -> screen row
|
||||
clc
|
||||
adc #2
|
||||
asl ; cell row -> screen row (offy + 2*cy + 1)
|
||||
sec
|
||||
adc offy
|
||||
sta exrow
|
||||
tax
|
||||
jsr row_ptr
|
||||
ldy #38
|
||||
ldy excol
|
||||
lda #CH_EXIT
|
||||
sta (scrlo),y
|
||||
lda #COL_EXIT
|
||||
sta (collo),y
|
||||
|
||||
; the runner starts in the top-left cell, facing right
|
||||
lda #1
|
||||
; the worker starts in the top-left cell, facing right
|
||||
lda offx
|
||||
clc
|
||||
adc #1
|
||||
sta px
|
||||
sta fdx
|
||||
lda #2
|
||||
lda offy
|
||||
clc
|
||||
adc #1
|
||||
sta py
|
||||
lda #1
|
||||
sta fdx
|
||||
lda #0
|
||||
sta fdy
|
||||
lda px
|
||||
@@ -90,10 +119,18 @@ ps_exit:
|
||||
ldx #SP_RUN
|
||||
jsr spr_jump
|
||||
|
||||
; the corner cursor starts on the center post
|
||||
lda #18
|
||||
; ra's cursor starts on the center post
|
||||
lda mzcw
|
||||
lsr
|
||||
asl
|
||||
clc
|
||||
adc offx
|
||||
sta kx
|
||||
lda #11
|
||||
lda mzch
|
||||
lsr
|
||||
asl
|
||||
clc
|
||||
adc offy
|
||||
sta ky
|
||||
lda #COL_HILITE
|
||||
jsr mark_slots
|
||||
@@ -107,9 +144,11 @@ ps_exit:
|
||||
|
||||
lda #WHITE
|
||||
sta SPRCOL+SP_RUN
|
||||
sta SPRCOL+SP_CUR
|
||||
lda #YELLOW
|
||||
sta SPRCOL+SP_SHOT
|
||||
lda #COL_HILITE ; ra wears the sun's color
|
||||
sta SPRCOL+SP_CUR
|
||||
lda #COL_STING
|
||||
sta SPRCOL+SP_STING
|
||||
|
||||
jsr spawn_enemies
|
||||
|
||||
@@ -122,11 +161,9 @@ ps_exit:
|
||||
sta s_on
|
||||
sta sx
|
||||
sta sy
|
||||
sta es_on
|
||||
sta cool
|
||||
sta rotflash
|
||||
sta tframe ; the clock starts when the maze is done
|
||||
sta tsec
|
||||
sta tmin
|
||||
lda #1
|
||||
sta cfheld
|
||||
sta rfheld
|
||||
@@ -134,34 +171,101 @@ ps_exit:
|
||||
jmp upd_sprites ; positions, shapes and enables now
|
||||
|
||||
; ============================================================
|
||||
; maze generation - recursive backtracker over the 19x11
|
||||
; cells; the screen itself is the wall data structure
|
||||
; maze geometry - the lattice is sized and placed from the
|
||||
; cell counts in mzcw / mzch (the levels are squares, the
|
||||
; menu backdrop is the full 19x11)
|
||||
; ============================================================
|
||||
|
||||
; fill rows 1-23 of the lattice: brick walls in latwcol, the
|
||||
; pivot posts (even col, odd row) in latpcol
|
||||
; from mzcw/mzch: screen offsets, the exit column, the
|
||||
; visited-index multiply table, ra's post bounds and the
|
||||
; enemies' spawn half
|
||||
set_maze:
|
||||
lda #19 ; offx = (39 - (2*cw+1)) / 2 = 19 - cw
|
||||
sec
|
||||
sbc mzcw
|
||||
sta offx
|
||||
lda #12 ; rows 1-23: offy = 12 - ch
|
||||
sec
|
||||
sbc mzch
|
||||
sta offy
|
||||
lda #0 ; multab[i] = i * mzcw
|
||||
tax
|
||||
sm_mul:
|
||||
sta multab,x
|
||||
clc
|
||||
adc mzcw
|
||||
inx
|
||||
cpx #MZMAX
|
||||
bne sm_mul
|
||||
lda mzcw ; the right border column holds the exit
|
||||
asl
|
||||
clc
|
||||
adc offx
|
||||
sta excol
|
||||
sec ; interior posts: offx+2 .. offx+2*cw-2
|
||||
sbc #2
|
||||
sta kmaxx
|
||||
lda offx
|
||||
clc
|
||||
adc #2
|
||||
sta kminx
|
||||
lda mzch
|
||||
asl
|
||||
clc
|
||||
adc offy
|
||||
sec
|
||||
sbc #2
|
||||
sta kmaxy
|
||||
lda offy
|
||||
clc
|
||||
adc #2
|
||||
sta kminy
|
||||
lda mzcw ; enemies spawn on the right half
|
||||
lsr
|
||||
sta enhalf
|
||||
rts
|
||||
|
||||
; fill the lattice with sandstone in latwcol, the pivot posts
|
||||
; (even local column and row) in latpcol
|
||||
draw_lattice:
|
||||
ldx #1
|
||||
lda offy
|
||||
sta ptmp
|
||||
dl_fill:
|
||||
stx ptmp
|
||||
ldx ptmp
|
||||
jsr row_ptr
|
||||
ldy #38
|
||||
lda mzcw
|
||||
asl
|
||||
sta lcnt
|
||||
inc lcnt ; 2*cw+1 chars per lattice row
|
||||
ldy offx
|
||||
dl_col:
|
||||
lda #CH_WALL
|
||||
sta (scrlo),y
|
||||
lda latwcol
|
||||
sta (collo),y
|
||||
dey
|
||||
bpl dl_col
|
||||
ldx ptmp
|
||||
inx
|
||||
cpx #24
|
||||
bne dl_fill
|
||||
ldx #1 ; post rows 1, 3, ... 23
|
||||
iny
|
||||
dec lcnt
|
||||
bne dl_col
|
||||
inc ptmp
|
||||
lda mzch
|
||||
asl
|
||||
clc
|
||||
adc offy ; the bottom lattice row
|
||||
cmp ptmp
|
||||
bcs dl_fill
|
||||
lda offy ; post rows: offy, offy+2, ...
|
||||
sta ptmp
|
||||
dl_prow:
|
||||
stx ptmp
|
||||
ldx ptmp
|
||||
jsr row_ptr
|
||||
ldy #38 ; post columns 38, 36, ... 0
|
||||
lda mzcw
|
||||
asl
|
||||
clc
|
||||
adc offx
|
||||
tay ; post columns from the right edge down
|
||||
lda mzcw
|
||||
sta lcnt
|
||||
inc lcnt ; cw+1 posts per post row
|
||||
dl_pcol:
|
||||
lda #CH_POST
|
||||
sta (scrlo),y
|
||||
@@ -169,14 +273,23 @@ dl_pcol:
|
||||
sta (collo),y
|
||||
dey
|
||||
dey
|
||||
bpl dl_pcol
|
||||
ldx ptmp
|
||||
inx
|
||||
inx
|
||||
cpx #25
|
||||
bcc dl_prow
|
||||
dec lcnt
|
||||
bne dl_pcol
|
||||
inc ptmp
|
||||
inc ptmp
|
||||
lda mzch
|
||||
asl
|
||||
clc
|
||||
adc offy
|
||||
cmp ptmp
|
||||
bcs dl_prow
|
||||
rts
|
||||
|
||||
; ============================================================
|
||||
; maze generation - recursive backtracker over the cells;
|
||||
; the screen itself is the wall data structure
|
||||
; ============================================================
|
||||
|
||||
; reset the generator: nothing visited, start on cell (0,0)
|
||||
gen_init:
|
||||
ldx #0
|
||||
@@ -206,17 +319,17 @@ gm_scan:
|
||||
clc
|
||||
adc dxtab,x
|
||||
sta gnx
|
||||
cmp #MAZE_CW ; unsigned: -1 wraps to $ff and fails too
|
||||
cmp mzcw ; unsigned: -1 wraps to $ff and fails too
|
||||
bcs gm_next
|
||||
ldx gtd
|
||||
lda gcy
|
||||
clc
|
||||
adc dytab,x
|
||||
sta gny
|
||||
cmp #MAZE_CH
|
||||
cmp mzch
|
||||
bcs gm_next
|
||||
ldx gny
|
||||
lda mul19,x
|
||||
lda multab,x
|
||||
clc
|
||||
adc gnx
|
||||
tax
|
||||
@@ -285,9 +398,9 @@ gen_maze_full: ; the menu backdrop wants it all at once
|
||||
bcc gen_maze_full
|
||||
rts
|
||||
|
||||
gv_mark: ; visited[gcy * 19 + gcx] = 1
|
||||
gv_mark: ; visited[gcy * mzcw + gcx] = 1
|
||||
ldx gcy
|
||||
lda mul19,x
|
||||
lda multab,x
|
||||
clc
|
||||
adc gcx
|
||||
tax
|
||||
@@ -295,17 +408,17 @@ gv_mark: ; visited[gcy * 19 + gcx] = 1
|
||||
sta visited,x
|
||||
rts
|
||||
|
||||
carve_cell: ; open the cell (2*gcx+1, 2*gcy+2)
|
||||
carve_cell: ; open the cell at (offx+2*gcx+1, offy+2*gcy+1)
|
||||
lda gcy
|
||||
asl
|
||||
clc
|
||||
adc #2
|
||||
sec
|
||||
adc offy
|
||||
tax
|
||||
jsr row_ptr
|
||||
lda gcx
|
||||
asl
|
||||
clc
|
||||
adc #1
|
||||
sec
|
||||
adc offx
|
||||
tay
|
||||
lda #CH_FLOOR
|
||||
sta (scrlo),y
|
||||
@@ -317,8 +430,8 @@ carve_wall: ; open the wall slot toward direction gtd
|
||||
ldx gtd
|
||||
lda gcy
|
||||
asl
|
||||
clc
|
||||
adc #2
|
||||
sec
|
||||
adc offy
|
||||
clc
|
||||
adc dytab,x
|
||||
tax
|
||||
@@ -326,8 +439,8 @@ carve_wall: ; open the wall slot toward direction gtd
|
||||
ldx gtd
|
||||
lda gcx
|
||||
asl
|
||||
clc
|
||||
adc #1
|
||||
sec
|
||||
adc offx
|
||||
clc
|
||||
adc dxtab,x
|
||||
tay
|
||||
@@ -339,9 +452,9 @@ carve_wall: ; open the wall slot toward direction gtd
|
||||
|
||||
dxtab: !byte 0, 0, $ff, 1 ; up, down, left, right
|
||||
dytab: !byte $ff, 1, 0, 0
|
||||
mul19: !byte 0, 19, 38, 57, 76, 95, 114, 133, 152, 171, 190
|
||||
|
||||
; ---- enemies: random colors, random right-half cells ----
|
||||
; ---- enemies: even index = scarab, odd = scorpion; random
|
||||
; right-half cells, away from the worker's start ----
|
||||
spawn_enemies:
|
||||
lda #0
|
||||
sta ei
|
||||
@@ -349,7 +462,7 @@ sn_all:
|
||||
jsr spawn_one
|
||||
inc ei
|
||||
lda ei
|
||||
cmp #NENEMIES
|
||||
cmp nenem
|
||||
bne sn_all
|
||||
rts
|
||||
|
||||
@@ -357,22 +470,22 @@ spawn_one: ; place enemy ei on a random free cell
|
||||
sn_rx:
|
||||
jsr rand8
|
||||
and #$0f
|
||||
cmp #MAZE_CH
|
||||
cmp mzcw
|
||||
bcs sn_rx
|
||||
clc
|
||||
adc #MAZE_CW-MAZE_CH ; cell column 8-18: away from the start
|
||||
cmp enhalf ; keep to the right half
|
||||
bcc sn_rx
|
||||
asl
|
||||
clc
|
||||
adc #1
|
||||
sta ttx ; candidate screen column
|
||||
sec
|
||||
adc offx ; cell column -> screen column
|
||||
sta ttx
|
||||
sn_ry:
|
||||
jsr rand8
|
||||
and #$0f
|
||||
cmp #MAZE_CH
|
||||
cmp mzch
|
||||
bcs sn_ry
|
||||
asl
|
||||
clc
|
||||
adc #2
|
||||
sec
|
||||
adc offy
|
||||
sta tty ; candidate screen row
|
||||
ldx tty
|
||||
jsr row_ptr
|
||||
@@ -380,7 +493,7 @@ sn_ry:
|
||||
lda (scrlo),y
|
||||
cmp #CH_FLOOR ; only a carved cell will do...
|
||||
bne sn_rx
|
||||
lda ttx ; ...without the runner on it...
|
||||
lda ttx ; ...without the worker on it...
|
||||
cmp px
|
||||
bne sn_free
|
||||
lda tty
|
||||
@@ -394,11 +507,10 @@ sn_free:
|
||||
sta ex,x
|
||||
lda tty
|
||||
sta ey,x
|
||||
jsr rand8
|
||||
and #7
|
||||
lda ei
|
||||
and #1 ; the type wears its own color
|
||||
tay
|
||||
lda ecoltab,y
|
||||
sta ecol,x
|
||||
lda etypecol,y
|
||||
sta SPRCOL+SP_EN,x
|
||||
jsr rand8
|
||||
and #3
|
||||
@@ -416,14 +528,13 @@ sn_free:
|
||||
tax
|
||||
jmp spr_jump
|
||||
|
||||
ecoltab: ; anything but the white runner / grey walls
|
||||
!byte RED, CYAN, PURPLE, YELLOW, ORANGE, LRED, LBLUE, BLUE
|
||||
etypecol: !byte COL_SCARAB, COL_SCORP
|
||||
|
||||
; ============================================================
|
||||
; one frame of play
|
||||
; ============================================================
|
||||
play_update:
|
||||
inc tframe ; the round clock: 50 frames = one second
|
||||
inc tframe ; the run clock: 50 frames = one second
|
||||
lda tframe
|
||||
cmp #50
|
||||
bne pu_clock
|
||||
@@ -453,6 +564,9 @@ pu_nocool:
|
||||
jsr upd_enemies
|
||||
lda endflag
|
||||
bne pu_end
|
||||
jsr upd_sting
|
||||
lda endflag
|
||||
bne pu_end
|
||||
jsr upd_cursor
|
||||
jsr upd_flash
|
||||
jsr upd_status
|
||||
@@ -467,6 +581,12 @@ pu_end:
|
||||
pu_win:
|
||||
lda #SFX_WIN
|
||||
jsr sfx_play
|
||||
lda mzsize ; the last level won: the blessing is earned
|
||||
cmp #MZMAX
|
||||
bcs pw_final
|
||||
inc mzsize ; otherwise the next maze is one cell bigger
|
||||
+fadeto play_init
|
||||
pw_final:
|
||||
+fadeto win_init
|
||||
|
||||
; ---- player 1: walk the corridors, one cell per step ----
|
||||
@@ -543,6 +663,15 @@ ur_try:
|
||||
bne ur_stop ; a wall or a post: blocked
|
||||
jsr enemy_at ; walking into an enemy still hurts
|
||||
bcs ur_dead
|
||||
lda es_on ; and so does the venom sting
|
||||
beq ur_go
|
||||
lda ttx
|
||||
cmp esx
|
||||
bne ur_go
|
||||
lda tty
|
||||
cmp esy
|
||||
beq ur_dead
|
||||
ur_go:
|
||||
lda ttx
|
||||
sta px
|
||||
lda tty
|
||||
@@ -649,12 +778,12 @@ ea_loop:
|
||||
rts
|
||||
ea_next:
|
||||
inx
|
||||
cpx #NENEMIES
|
||||
cpx nenem
|
||||
bne ea_loop
|
||||
clc
|
||||
rts
|
||||
|
||||
; ---- player 2: the corner cursor + the wall spin ----
|
||||
; ---- player 2: ra's corner cursor + the wall spin ----
|
||||
upd_cursor:
|
||||
jsr read_joy2
|
||||
sta j2bits
|
||||
@@ -689,26 +818,28 @@ uc_move:
|
||||
bcs uc_down
|
||||
lsr
|
||||
bcs uc_left
|
||||
cpx #36 ; right: interior posts end at column 36
|
||||
cpx kmaxx ; right: the interior posts end here
|
||||
bcs uc_fire
|
||||
inx
|
||||
inx
|
||||
jmp uc_go
|
||||
uc_up:
|
||||
cpy #4 ; top interior post row is 3
|
||||
cpy kminy
|
||||
bcc uc_fire
|
||||
beq uc_fire
|
||||
dey
|
||||
dey
|
||||
jmp uc_go
|
||||
uc_down:
|
||||
cpy #21 ; bottom interior post row is 21
|
||||
cpy kmaxy
|
||||
bcs uc_fire
|
||||
iny
|
||||
iny
|
||||
jmp uc_go
|
||||
uc_left:
|
||||
cpx #3 ; left interior post column is 2
|
||||
cpx kminx
|
||||
bcc uc_fire
|
||||
beq uc_fire
|
||||
dex
|
||||
dex
|
||||
uc_go:
|
||||
@@ -849,13 +980,22 @@ so_norun:
|
||||
jsr enemy_at
|
||||
bcs so_yes
|
||||
lda s_on
|
||||
beq so_no
|
||||
beq so_nosht
|
||||
lda sx
|
||||
cmp ttx
|
||||
bne so_no
|
||||
bne so_nosht
|
||||
lda sy
|
||||
cmp tty
|
||||
beq so_yes
|
||||
so_nosht:
|
||||
lda es_on ; the sting blocks a spin too
|
||||
beq so_no
|
||||
lda esx
|
||||
cmp ttx
|
||||
bne so_no
|
||||
lda esy
|
||||
cmp tty
|
||||
beq so_yes
|
||||
so_no:
|
||||
clc
|
||||
rts
|
||||
@@ -927,10 +1067,11 @@ ue_alive:
|
||||
jsr enemy_step
|
||||
lda endflag
|
||||
bne ue_out
|
||||
jsr try_sting
|
||||
ue_next:
|
||||
inc ei
|
||||
lda ei
|
||||
cmp #NENEMIES
|
||||
cmp nenem
|
||||
bne ue_loop
|
||||
ue_out:
|
||||
rts
|
||||
@@ -970,7 +1111,7 @@ etry_dir: ; A = direction; C clear when it moved (or won)
|
||||
clc
|
||||
adc dytab,x
|
||||
sta tty
|
||||
lda px ; onto the runner: the round is over
|
||||
lda px ; onto the worker: the level is over
|
||||
cmp ttx
|
||||
bne en_norun
|
||||
lda py
|
||||
@@ -1020,6 +1161,105 @@ en_move:
|
||||
clc
|
||||
rts
|
||||
|
||||
; ---- a scorpion (odd index) spits a venom sting when it
|
||||
; lines up with the worker; one sting flies at a time ----
|
||||
try_sting:
|
||||
lda ei
|
||||
and #1
|
||||
beq ts_no ; scarabs do not shoot
|
||||
lda es_on
|
||||
bne ts_no
|
||||
jsr rand8 ; menacing, not machine-gun constant
|
||||
and #3
|
||||
bne ts_no
|
||||
ldx ei
|
||||
lda ex,x
|
||||
cmp px
|
||||
beq ts_col
|
||||
lda ey,x
|
||||
cmp py
|
||||
beq ts_row
|
||||
ts_no:
|
||||
rts
|
||||
ts_col: ; same column: the sting flies vertically
|
||||
lda #0
|
||||
sta esdx
|
||||
ldy #1
|
||||
lda py
|
||||
cmp ey,x
|
||||
bcs ts_cgo
|
||||
ldy #$ff
|
||||
ts_cgo:
|
||||
sty esdy
|
||||
jmp ts_fire
|
||||
ts_row: ; same row: horizontally
|
||||
lda #0
|
||||
sta esdy
|
||||
ldy #1
|
||||
lda px
|
||||
cmp ex,x
|
||||
bcs ts_rgo
|
||||
ldy #$ff
|
||||
ts_rgo:
|
||||
sty esdx
|
||||
ts_fire:
|
||||
lda ex,x
|
||||
sta esx
|
||||
sta tgc
|
||||
lda ey,x
|
||||
sta esy
|
||||
sta tgr
|
||||
jsr set_target ; the sprite pops in on the scorpion,
|
||||
ldx #SP_STING ; not gliding over from the last sting
|
||||
jsr spr_jump
|
||||
lda #1
|
||||
sta es_on
|
||||
lda #SFX_SHOT
|
||||
jmp sfx_play
|
||||
|
||||
; ---- the sting flies a char every other frame; a wall
|
||||
; swallows it, the worker dies on it ----
|
||||
upd_sting:
|
||||
lda es_on
|
||||
beq ust_done
|
||||
lda framectr
|
||||
and #1
|
||||
bne ust_done
|
||||
lda esx
|
||||
clc
|
||||
adc esdx
|
||||
sta ttx
|
||||
lda esy
|
||||
clc
|
||||
adc esdy
|
||||
sta tty
|
||||
lda px ; onto the worker: the level is over
|
||||
cmp ttx
|
||||
bne ust_norun
|
||||
lda py
|
||||
cmp tty
|
||||
bne ust_norun
|
||||
lda #2
|
||||
sta endflag
|
||||
rts
|
||||
ust_norun:
|
||||
ldx tty
|
||||
jsr row_ptr
|
||||
ldy ttx
|
||||
lda (scrlo),y
|
||||
cmp #CH_FLOOR
|
||||
beq ust_fly
|
||||
lda #0 ; a wall swallows it
|
||||
sta es_on
|
||||
rts
|
||||
ust_fly:
|
||||
lda ttx
|
||||
sta esx
|
||||
lda tty
|
||||
sta esy
|
||||
ust_done:
|
||||
rts
|
||||
|
||||
; ---- per-frame flashes: the portal spins and blinks, the
|
||||
; freshly spun walls flash white, the cursor shows the
|
||||
; recharge state on its own color ----
|
||||
@@ -1027,7 +1267,7 @@ upd_flash:
|
||||
jsr upd_portal ; cycle the portal glyph
|
||||
ldx exrow
|
||||
jsr row_ptr
|
||||
ldy #38
|
||||
ldy excol
|
||||
lda framectr
|
||||
and #8
|
||||
bne uf_exw
|
||||
@@ -1055,7 +1295,7 @@ uf_norf:
|
||||
lda #RED
|
||||
jmp uf_cset
|
||||
uf_hot:
|
||||
lda #WHITE
|
||||
lda #COL_HILITE
|
||||
uf_cset:
|
||||
sta SPRCOL+SP_CUR
|
||||
rts
|
||||
@@ -1110,7 +1350,7 @@ us_clr:
|
||||
bpl us_clr
|
||||
rts
|
||||
|
||||
; ---- the round clock, live on the status row ----
|
||||
; ---- the run clock, live on the status row ----
|
||||
upd_clock:
|
||||
lda tmin
|
||||
jsr two_digits
|
||||
@@ -1137,7 +1377,7 @@ upd_sprites:
|
||||
lsr
|
||||
lsr
|
||||
sta frame8
|
||||
; the runner glides 2 pixels a frame
|
||||
; the worker glides 2 pixels a frame
|
||||
lda px
|
||||
sta tgc
|
||||
lda py
|
||||
@@ -1165,6 +1405,16 @@ upd_sprites:
|
||||
jsr set_target
|
||||
ldx #SP_SHOT
|
||||
jsr spr_jump
|
||||
; the sting glides 4: a char every other frame, smoothly
|
||||
lda esx
|
||||
sta tgc
|
||||
lda esy
|
||||
sta tgr
|
||||
jsr set_target
|
||||
lda #4
|
||||
sta gspd
|
||||
ldx #SP_STING
|
||||
jsr spr_glide
|
||||
; the enemies glide 1
|
||||
lda #1
|
||||
sta gspd
|
||||
@@ -1183,9 +1433,9 @@ us_en:
|
||||
jsr spr_glide
|
||||
ldx ptmp
|
||||
inx
|
||||
cpx #NENEMIES
|
||||
cpx nenem
|
||||
bne us_en
|
||||
; shapes: the runner bobs, each enemy waves on its own beat
|
||||
; shapes: the worker bobs, each enemy waves on its own beat
|
||||
lda frame8
|
||||
and #1
|
||||
clc
|
||||
@@ -1195,6 +1445,8 @@ us_en:
|
||||
sta SPRPTR+SP_CUR
|
||||
lda #SPR_SHOT
|
||||
sta SPRPTR+SP_SHOT
|
||||
lda #SPR_STING
|
||||
sta SPRPTR+SP_STING
|
||||
ldx #0
|
||||
us_shape:
|
||||
txa
|
||||
@@ -1202,23 +1454,30 @@ us_shape:
|
||||
adc frame8
|
||||
and #1
|
||||
sta rtmp
|
||||
lda #SPR_ENA ; enemies 0-1 are ghosts, 2-3 crawlers
|
||||
cpx #2
|
||||
bcc us_seta
|
||||
txa
|
||||
and #1 ; even index = scarab, odd = scorpion
|
||||
beq us_scar
|
||||
lda #SPR_ENB
|
||||
bne us_seta ; always taken
|
||||
us_scar:
|
||||
lda #SPR_ENA
|
||||
us_seta:
|
||||
clc
|
||||
adc rtmp
|
||||
sta SPRPTR+SP_EN,x
|
||||
inx
|
||||
cpx #NENEMIES
|
||||
cpx nenem
|
||||
bne us_shape
|
||||
; enable: runner + cursor + the bullet and the live enemies
|
||||
; enable: worker + cursor + bullet, sting, live enemies
|
||||
lda #%00000011
|
||||
ldy s_on
|
||||
beq us_nosht
|
||||
ora #%00000100
|
||||
us_nosht:
|
||||
ldy es_on
|
||||
beq us_nostg
|
||||
ora #%10000000
|
||||
us_nostg:
|
||||
sta rtmp
|
||||
ldx #0
|
||||
us_alive:
|
||||
@@ -1229,7 +1488,7 @@ us_alive:
|
||||
sta rtmp
|
||||
us_dead:
|
||||
inx
|
||||
cpx #NENEMIES
|
||||
cpx nenem
|
||||
bne us_alive
|
||||
lda rtmp
|
||||
sta SPR_EN
|
||||
@@ -1238,18 +1497,31 @@ us_dead:
|
||||
ebit: !byte 8, 16, 32, 64
|
||||
|
||||
; ---- play texts ----
|
||||
txt_level: !scr "level"
|
||||
txt_goal: !scr "exit "
|
||||
!byte CH_EXIT
|
||||
txt_goale:
|
||||
txt_hint: !scr "p1: joy2/wasd p2: joy1/ijkl"
|
||||
txt_hint: !scr "worker: joy2/wasd ra: joy1/ijkl"
|
||||
txt_hinte:
|
||||
txt_wait: !scr "wait"
|
||||
txt_ready: !scr "ready"
|
||||
|
||||
; ---- play variables ----
|
||||
px: !byte 0 ; runner position (screen col / row)
|
||||
mzsize: !byte MZMIN ; this level's cells per side (4-11)
|
||||
mzcw: !byte 0 ; lattice cells across / down
|
||||
mzch: !byte 0
|
||||
offx: !byte 0 ; screen offset of the lattice
|
||||
offy: !byte 0
|
||||
excol: !byte 0 ; screen column of the right border wall
|
||||
enhalf: !byte 0 ; enemies spawn from this cell column
|
||||
nenem: !byte 0 ; live enemy slots this level (1-4)
|
||||
kminx: !byte 0 ; ra's interior post bounds
|
||||
kmaxx: !byte 0
|
||||
kminy: !byte 0
|
||||
kmaxy: !byte 0
|
||||
px: !byte 0 ; worker position (screen col / row)
|
||||
py: !byte 0
|
||||
fdx: !byte 0 ; runner facing: the gun aims this way
|
||||
fdx: !byte 0 ; worker facing: the gun aims this way
|
||||
fdy: !byte 0
|
||||
kx: !byte 0 ; corner cursor position (post col / row)
|
||||
ky: !byte 0
|
||||
@@ -1262,16 +1534,22 @@ sx: !byte 0 ; bullet position and heading
|
||||
sy: !byte 0
|
||||
sdx: !byte 0
|
||||
sdy: !byte 0
|
||||
rheld: !byte 0 ; runner direction repeat state
|
||||
es_on: !byte 0 ; venom sting in flight?
|
||||
esx: !byte 0 ; sting position and heading
|
||||
esy: !byte 0
|
||||
esdx: !byte 0
|
||||
esdy: !byte 0
|
||||
rheld: !byte 0 ; worker direction repeat state
|
||||
rtimer: !byte 0
|
||||
rdir: !byte 0
|
||||
rfheld: !byte 0 ; runner fire edge detection state
|
||||
rfheld: !byte 0 ; worker fire edge detection state
|
||||
cheld: !byte 0 ; cursor direction repeat state
|
||||
ctimer: !byte 0
|
||||
cdir: !byte 0
|
||||
cfheld: !byte 0 ; cursor fire edge detection state
|
||||
j2bits: !byte 0
|
||||
ptmp: !byte 0 ; scratch
|
||||
lcnt: !byte 0 ; draw_lattice column counter
|
||||
ttx: !byte 0 ; move target (col / row)
|
||||
tty: !byte 0
|
||||
nch: !byte 0 ; the four slot chars around the cursor
|
||||
@@ -1281,7 +1559,7 @@ wch: !byte 0
|
||||
hlcol: !byte 0 ; mark_slots color parameter
|
||||
latwcol: !byte 0 ; draw_lattice colors: walls, posts
|
||||
latpcol: !byte 0
|
||||
tframe: !byte 0 ; round clock: frame, second, minute
|
||||
tframe: !byte 0 ; run clock: frame, second, minute
|
||||
tsec: !byte 0
|
||||
tmin: !byte 0
|
||||
frame8: !byte 0 ; framectr / 8: the animation beat
|
||||
@@ -1296,10 +1574,10 @@ gtd: !byte 0
|
||||
gnx: !byte 0
|
||||
gny: !byte 0
|
||||
gdlist: !fill 4, 0
|
||||
ex: !fill NENEMIES, 0 ; enemy positions, headings, colors
|
||||
multab: !fill MZMAX, 0 ; row * mzcw for the visited index
|
||||
ex: !fill NENEMIES, 0 ; enemy positions and headings
|
||||
ey: !fill NENEMIES, 0
|
||||
edir: !fill NENEMIES, 0
|
||||
ecol: !fill NENEMIES, 0
|
||||
edead: !fill NENEMIES, 0 ; respawn countdown, 0 = alive
|
||||
|
||||
; ---- maze generator buffers ----
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
; -----------------------------------------------------------
|
||||
; pyramid.asm - the title card between the TTG logo and the
|
||||
; menu: big BLESSING / OF RA under the rolling gold wash, a
|
||||
; sandstone pyramid rising below with the trapped worker
|
||||
; glinting at its peak and the sun of ra pulsing beside it;
|
||||
; advances to the menu after a few seconds or on fire
|
||||
; -----------------------------------------------------------
|
||||
|
||||
PYR_TIME = 250 ; frames before it advances on its own
|
||||
|
||||
pyramid_init:
|
||||
jsr clear_screen
|
||||
|
||||
+prbig 1, 4, YELLOW, txt_t1, 8
|
||||
+prbig 7, 10, ORANGE, txt_t2, 5
|
||||
|
||||
; the pyramid: ten block rows, apex on row 13
|
||||
lda #0
|
||||
sta ptmp
|
||||
py_prow:
|
||||
lda #13
|
||||
clc
|
||||
adc ptmp
|
||||
tax
|
||||
jsr row_ptr
|
||||
lda #19 ; row r spans columns 19-r .. 20+r
|
||||
sec
|
||||
sbc ptmp
|
||||
tay
|
||||
lda ptmp
|
||||
asl
|
||||
clc
|
||||
adc #2 ; 2r+2 blocks on this row
|
||||
sta rtmp2
|
||||
py_pcol:
|
||||
lda #$a0
|
||||
sta (scrlo),y
|
||||
ldx ptmp
|
||||
lda pyrcols,x ; sunlit top, shaded base
|
||||
sta (collo),y
|
||||
iny
|
||||
dec rtmp2
|
||||
bne py_pcol
|
||||
inc ptmp
|
||||
lda ptmp
|
||||
cmp #10
|
||||
bne py_prow
|
||||
|
||||
; the worker glints at the peak
|
||||
lda #$51 ; filled dot
|
||||
sta SCREEN+12*40+19
|
||||
lda #WHITE
|
||||
sta COLRAM+12*40+19
|
||||
|
||||
; the sun of ra beside the pyramid
|
||||
lda #$a0
|
||||
sta SCREEN+14*40+32
|
||||
sta SCREEN+14*40+33
|
||||
sta SCREEN+15*40+31
|
||||
sta SCREEN+15*40+32
|
||||
sta SCREEN+15*40+33
|
||||
sta SCREEN+15*40+34
|
||||
sta SCREEN+16*40+32
|
||||
sta SCREEN+16*40+33
|
||||
|
||||
+prtext 24, 5, LGREY, txt_pray, txt_praye-txt_pray
|
||||
|
||||
lda #PYR_TIME
|
||||
sta pyrt
|
||||
lda #0
|
||||
sta washphase
|
||||
+setupd pyramid_update
|
||||
rts
|
||||
|
||||
pyramid_update:
|
||||
jsr wash_title ; the gold wash rolls down the title
|
||||
|
||||
; the sun pulses
|
||||
lda framectr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
and #3
|
||||
tax
|
||||
lda sunpulse,x
|
||||
sta COLRAM+14*40+32
|
||||
sta COLRAM+14*40+33
|
||||
sta COLRAM+15*40+31
|
||||
sta COLRAM+15*40+32
|
||||
sta COLRAM+15*40+33
|
||||
sta COLRAM+15*40+34
|
||||
sta COLRAM+16*40+32
|
||||
sta COLRAM+16*40+33
|
||||
|
||||
; fire skips, otherwise wait out the timer
|
||||
jsr start_edge
|
||||
beq py_tick
|
||||
+fadeto menu_init
|
||||
py_tick:
|
||||
dec pyrt
|
||||
bne py_done
|
||||
+fadeto menu_init
|
||||
py_done:
|
||||
rts
|
||||
|
||||
; ---- tables and texts ----
|
||||
pyrcols: ; pyramid rows top to bottom
|
||||
!byte YELLOW, YELLOW, ORANGE, ORANGE, ORANGE
|
||||
!byte ORANGE, ORANGE, BROWN, BROWN, BROWN
|
||||
sunpulse: ; the sun of ra breathes
|
||||
!byte YELLOW, YELLOW, WHITE, YELLOW
|
||||
txt_pray: !scr "a worker prays at the peak..."
|
||||
txt_praye:
|
||||
|
||||
; ---- pyramid variables ----
|
||||
pyrt: !byte 0 ; frames left before auto-advancing
|
||||
@@ -1,56 +0,0 @@
|
||||
; -----------------------------------------------------------
|
||||
; rules.asm - how to play, one static card; fire returns
|
||||
; -----------------------------------------------------------
|
||||
|
||||
rules_init:
|
||||
jsr clear_screen
|
||||
|
||||
+prbig 1, 10, WHITE, txt_rules, 5
|
||||
|
||||
+prtext 8, 9, LGREEN, txt_r1, txt_r1e-txt_r1
|
||||
+prtext 9, 8, WHITE, txt_r2, txt_r2e-txt_r2
|
||||
+prtext 10, 7, WHITE, txt_r3, txt_r3e-txt_r3
|
||||
|
||||
+prtext 12, 9, LBLUE, txt_r4, txt_r4e-txt_r4
|
||||
+prtext 13, 6, WHITE, txt_r5, txt_r5e-txt_r5
|
||||
+prtext 14, 6, WHITE, txt_r6, txt_r6e-txt_r6
|
||||
+prtext 15, 7, WHITE, txt_r7, txt_r7e-txt_r7
|
||||
|
||||
+prtext 17, 7, LRED, txt_r8, txt_r8e-txt_r8
|
||||
|
||||
+setupd rules_update
|
||||
rts
|
||||
|
||||
rules_update:
|
||||
; blink the return prompt
|
||||
lda framectr
|
||||
and #32
|
||||
bne ru_hide
|
||||
+prtext 21, 13, YELLOW, txt_return, 13
|
||||
jmp ru_input
|
||||
ru_hide:
|
||||
+prtext 21, 13, YELLOW, txt_blank, 13
|
||||
ru_input:
|
||||
jsr start_edge
|
||||
beq ru_stay
|
||||
+fadeto menu_init
|
||||
ru_stay:
|
||||
rts
|
||||
|
||||
; ---- rules texts ----
|
||||
txt_r1: !scr "player 1 - joystick 2"
|
||||
txt_r1e:
|
||||
txt_r2: !scr "run the maze and escape"
|
||||
txt_r2e:
|
||||
txt_r3: !scr "through the green diamond."
|
||||
txt_r3e:
|
||||
txt_r4: !scr "player 2 - joystick 1"
|
||||
txt_r4e:
|
||||
txt_r5: !scr "ride the corners of the walls;"
|
||||
txt_r5e:
|
||||
txt_r6: !scr "fire spins the four wall pieces"
|
||||
txt_r6e:
|
||||
txt_r7: !scr "around the cursor by 90 degrees."
|
||||
txt_r7e:
|
||||
txt_r8: !scr "avoid the colored enemies!"
|
||||
txt_r8e:
|
||||
@@ -0,0 +1,72 @@
|
||||
; -----------------------------------------------------------
|
||||
; story.asm - the legend of the trapped worker and ra, plus
|
||||
; who steers what (the old rules and controls cards merged
|
||||
; into one); a static card, fire returns to the menu
|
||||
; -----------------------------------------------------------
|
||||
|
||||
story_init:
|
||||
jsr clear_screen
|
||||
|
||||
+prbig 1, 10, WHITE, txt_story, 5
|
||||
|
||||
+prtext 7, 1, WHITE, txt_s1, txt_s1e-txt_s1
|
||||
+prtext 8, 2, WHITE, txt_s2, txt_s2e-txt_s2
|
||||
+prtext 9, 4, WHITE, txt_s3, txt_s3e-txt_s3
|
||||
+prtext 10, 4, YELLOW, txt_s4, txt_s4e-txt_s4
|
||||
+prtext 11, 8, YELLOW, txt_s5, txt_s5e-txt_s5
|
||||
|
||||
+prtext 13, 2, LRED, txt_s6, txt_s6e-txt_s6
|
||||
+prtext 14, 4, LRED, txt_s7, txt_s7e-txt_s7
|
||||
|
||||
+prtext 16, 6, LGREEN, txt_s8, txt_s8e-txt_s8
|
||||
+prtext 17, 5, LGREY, txt_s9, txt_s9e-txt_s9
|
||||
+prtext 18, 10, LBLUE, txt_s10, txt_s10e-txt_s10
|
||||
+prtext 19, 3, LGREY, txt_s11, txt_s11e-txt_s11
|
||||
|
||||
+prtext 21, 6, LGREY, txt_s12, txt_s12e-txt_s12
|
||||
|
||||
+setupd story_update
|
||||
rts
|
||||
|
||||
story_update:
|
||||
; blink the return prompt
|
||||
lda framectr
|
||||
and #32
|
||||
bne st_hide
|
||||
+prtext 23, 13, YELLOW, txt_return, 13
|
||||
jmp st_input
|
||||
st_hide:
|
||||
+prtext 23, 13, YELLOW, txt_blank, 13
|
||||
st_input:
|
||||
jsr start_edge
|
||||
beq st_stay
|
||||
+fadeto menu_init
|
||||
st_stay:
|
||||
rts
|
||||
|
||||
; ---- story texts ----
|
||||
txt_story: !scr "story"
|
||||
txt_s1: !scr "when the great pyramid rose, a worker"
|
||||
txt_s1e:
|
||||
txt_s2: !scr "was sealed in its peak. he prayed to"
|
||||
txt_s2e:
|
||||
txt_s3: !scr "ra until the sun god took pity:"
|
||||
txt_s3e:
|
||||
txt_s4: !scr "now ra bends the pyramid's walls"
|
||||
txt_s4e:
|
||||
txt_s5: !scr "to lead the worker out."
|
||||
txt_s5e:
|
||||
txt_s6: !scr "beware the scarabs and the scorpions"
|
||||
txt_s6e:
|
||||
txt_s7: !scr "- a scorpion's sting flies far!"
|
||||
txt_s7e:
|
||||
txt_s8: !scr "p1 - the worker: joy2 / wasd"
|
||||
txt_s8e:
|
||||
txt_s9: !scr "gun: fire or space, if enabled"
|
||||
txt_s9e:
|
||||
txt_s10: !scr "p2 - ra: joy1 / ijkl"
|
||||
txt_s10e:
|
||||
txt_s11: !scr "fire spins the walls at the cursor"
|
||||
txt_s11e:
|
||||
txt_s12: !scr "menus: fire, space or return"
|
||||
txt_s12e:
|
||||
@@ -1,6 +1,6 @@
|
||||
; -----------------------------------------------------------
|
||||
; win.asm - the escape screen: big ESCAPED with the gold
|
||||
; wash; fire returns to the main menu
|
||||
; win.asm - the escape screen after the last level: big
|
||||
; ESCAPED with the gold wash; fire returns to the main menu
|
||||
; -----------------------------------------------------------
|
||||
|
||||
win_init:
|
||||
@@ -8,8 +8,8 @@ win_init:
|
||||
|
||||
+prbig 3, 6, YELLOW, txt_escaped, 7
|
||||
|
||||
+prtext 11, 15, WHITE, txt_welldone, txt_welldonee-txt_welldone
|
||||
+prtext 13, 10, LGREY, txt_beaten, txt_beatene-txt_beaten
|
||||
+prtext 11, 10, WHITE, txt_welldone, txt_welldonee-txt_welldone
|
||||
+prtext 13, 5, LGREY, txt_beaten, txt_beatene-txt_beaten
|
||||
|
||||
; the round time into the readout: "time: mm:ss"
|
||||
lda tmin
|
||||
@@ -100,9 +100,9 @@ td_ones:
|
||||
|
||||
; ---- win texts ----
|
||||
txt_escaped: !scr "escaped"
|
||||
txt_welldone: !scr "well done!"
|
||||
txt_welldone: !scr "ra smiles upon you!"
|
||||
txt_welldonee:
|
||||
txt_beaten: !scr "you beat labyrintwo"
|
||||
txt_beaten: !scr "you escaped the pyramid of ra"
|
||||
txt_beatene:
|
||||
txt_time: !scr "time: "
|
||||
txt_timev: !scr "00:00"
|
||||
|
||||
Reference in New Issue
Block a user