scroll left and right work in stdef and hidef adds octo test roms adds schip fonts to memory
1214 lines
23 KiB
Plaintext
1214 lines
23 KiB
Plaintext
###########################################
|
|
#
|
|
# Cave Explorer
|
|
#
|
|
# Discover the secrets of a mysterious
|
|
# tunnel system. A fairly elaborate
|
|
# Chip8 adventure game. Best played at
|
|
# about 20 cycles/frame.
|
|
#
|
|
# On the overworld, press ASWD to move.
|
|
# In platformer levels, A/D move,
|
|
# E picks up/sets down blocks,
|
|
# Q resets the level.
|
|
#
|
|
###########################################
|
|
|
|
: font
|
|
0x20 0x20 0x20 0x00 0x20 0xF0 0x10 0x70 0x00 0x40 0xE0 0x90 0xE0 0x90 0x90 0x90
|
|
0xE0 0x90 0xE0 0x90 0xE0 0x80 0x80 0xD0 0xB0 0xB0 0x90 0x90 0x90 0x90 0x60 0x60
|
|
0x90 0x90 0x90 0x60 0x90 0xD0 0xB0 0x90 0x90 0x90 0x50 0x20 0x40 0x00 0x00 0x00
|
|
0x00 0x00 0x60 0x90 0xF0 0x90 0x90 0xF0 0x90 0x90 0xF0 0x80 0xE0 0x80 0x80 0x80
|
|
0x80 0xF0 0x80 0xE0 0x80 0xF0 0x40 0x40 0x40 0xF0 0x20 0x40 0x80 0xF0 0x20 0x20
|
|
0x20 0xC0 0x60 0x90 0x80 0x90 0x60 0x90 0x90 0xB0 0x70 0x80 0xB0 0x90 0x70 0x80
|
|
0x60 0x10 0xE0 0x90 0xA0 0xC0 0xA0 0x90 0x90 0xB0 0xB0 0xD0 0xF0 0x40 0x40 0x40
|
|
0x40 0x90 0x90 0x70 0x10 0xE0
|
|
|
|
: special-complete
|
|
: title1
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0xE0 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x08 0x18 0x00 0x00 0x00 0x00 0x00 0x00 0x10 0x04 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x20 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x20 0x02 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x28 0x21 0x00 0x00 0x00 0x00 0x00 0x00 0x40 0x01 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x40 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x40 0x01 0x00 0x00 0x00 0x00 0x0F 0xC0
|
|
0x4F 0x81 0x00 0x00 0x00 0x00 0x10 0x30 0x46 0x01 0x00 0x00 0x00 0x00 0x20 0x08
|
|
0x20 0x02 0x00 0x00 0x00 0x00 0x30 0xE8 0x20 0x02 0x00 0x00 0x00 0x00 0x4F 0x04
|
|
0x10 0x0C 0x00 0x00 0x00 0x00 0x50 0x84 0x1F 0xF6 0x00 0x00 0x00 0x00 0x40 0x04
|
|
0x77 0x09 0x00 0x00 0x00 0x00 0x4F 0x84 0x97 0x90 0xC0 0x00 0x00 0x00 0x50 0x4C
|
|
0x0E 0xE0 0x20 0x00 0x00 0x00 0x20 0x1E 0x0C 0x00 0x10 0x00 0x00 0x00 0x7F 0xFF
|
|
|
|
: block-reg-buffer
|
|
: phrase1
|
|
0x0A 0x41 0x32 0x0C 0x71 0x2D 0x3A 0x1F 0x0A 0x2D 0x2D 0x2D 0x5E 0x52 0x35 0x1F
|
|
0x1F 0x3D 0x05
|
|
|
|
: phrase2
|
|
0x2D 0x2D 0x2D 0x2D 0x2D 0x2D 0x2D 0x2D 0x2D 0x24 0x1F 0x00
|
|
|
|
: phrase3
|
|
0x35 0x1F 0x67 0x2D 0x32 0x10 0x1F 0x1A 0x6C 0x2D 0x2D 0x2D 0x2D
|
|
|
|
: level-buffer
|
|
: title2
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x70 0x00 0x00
|
|
0x00 0x3E 0x00 0x70 0x3C 0x8C 0x7F 0x00 0x01 0xC1 0x81 0x88 0x42 0x84 0x80 0xE0
|
|
0x02 0x00 0x42 0x04 0x42 0x84 0x80 0x10 0x04 0x00 0x44 0x02 0x21 0x04 0x80 0x10
|
|
0x08 0x00 0x44 0x01 0x21 0x05 0x00 0x10 0x10 0x03 0x88 0x01 0x10 0x05 0x07 0x10
|
|
0x14 0x07 0x08 0x00 0x90 0x45 0x0F 0xD0 0x10 0x0C 0x08 0x60 0x90 0x09 0x06 0x70
|
|
0x20 0x18 0x08 0x70 0x90 0x09 0x01 0xA0 0x20 0x18 0x10 0xB0 0x54 0x19 0x00 0x80
|
|
0x28 0x10 0x10 0x90 0x4C 0x1A 0x07 0x00 0x20 0x10 0xD0 0xF0 0xA8 0x32 0x46 0x60
|
|
0x20 0x0F 0x58 0x00 0x28 0xB2 0x03 0x90 0x29 0x20 0xD1 0x00 0x24 0x33 0x00 0x10
|
|
0x30 0x09 0xD4 0x72 0x17 0x73 0x40 0x10 0x14 0x43 0x98 0xF8 0xB6 0x63 0x02 0x10
|
|
0x1A 0xA7 0x1B 0x9A 0x33 0x61 0xD0 0x30 0x0D 0x1E 0x1F 0x8D 0x63 0xC1 0xFA 0xD0
|
|
0x0F 0xFC 0x0D 0x07 0xE1 0x81 0xFF 0x70 0x04 0x60 0x00 0x02 0xC0 0x00 0x8C 0x20
|
|
0x00 0x00 0x00 0x00 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0xFB 0x37 0x98 0x73 0xCF 0xBC 0x00 0x00 0xFB 0xF7 0xD8 0xFB 0xEF 0xBE 0x00
|
|
0x00 0xC1 0xE6 0xD8 0xDB 0x6C 0x36 0x00 0x00 0xF0 0xC7 0xD8 0xDB 0xEF 0x3E 0x00
|
|
0x00 0xC1 0xE7 0x98 0xDB 0xCC 0x3C 0x00 0x00 0xFB 0xF6 0x1E 0xFB 0x6F 0xB6 0x00
|
|
0x00 0xFB 0x36 0x1E 0x73 0x6F 0xB6 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
|
|
: bus
|
|
0x00 0x04 0x00 0x3D 0x97 0xFF 0xFF 0xFF 0xFF 0xFD 0xFF 0x9D 0x4B 0xFF 0x8B 0x47
|
|
0x20 0x04 0x00 0x5D 0xCB 0xFF 0xD8 0x4F 0x26 0x04 0x00 0x1D 0x05 0xFF 0xDB 0x5F
|
|
0x21 0x04 0x00 0x1D 0x85 0xFF 0xDB 0x47 0x20 0x84 0x7C 0x1C 0x05 0xFF 0xFF 0xFF
|
|
0x20 0x84 0xDA 0x5D 0xC5 0xFF 0x8B 0x47 0x20 0x94 0xBC 0xDD 0xE5 0xFF 0x99 0x5B
|
|
0x20 0xB4 0xE6 0x1D 0xE6 0x1F 0xBA 0x5B 0x20 0x94 0xC2 0xDD 0xCF 0xE7 0x8B 0x47
|
|
0x20 0x85 0x7D 0xDC 0x3F 0xF9 0xFF 0xFF 0x2F 0xF5 0x83 0x9F 0xFF 0xFE 0xFF 0xFF
|
|
0x20 0x05 0xFF 0x1F 0xFF 0xFF 0x7F 0xFF 0xFF 0xFC 0xFE 0x1F 0xFF 0xF3 0xBF 0x07
|
|
0xFF 0xFC 0xFE 0x1F 0xFF 0xED 0xDE 0xFB 0xA2 0x2D 0xF8 0x0C 0x07 0xDD 0xED 0xFD
|
|
0x2A 0xA8 0x07 0xF7 0xF9 0xD9 0xE3 0x7E 0xAA 0xAB 0xFF 0xEC 0x1E 0xD6 0xF3 0xFE
|
|
0xA2 0x25 0xF8 0x00 0x06 0xE7 0x1B 0xFE 0xFF 0xFA 0x07 0xF8 0x03 0x77 0xC0 0x7E
|
|
0x00 0x0B 0xBF 0xFE 0x03 0x7B 0xF8 0xFC 0xFF 0xFB 0x9F 0xFF 0x81 0x7C 0xED 0xF8
|
|
0x00 0x0B 0xBF 0xFF 0x81 0x7F 0x0E 0x00 0xFF 0xFB 0xAF 0xF0 0x61 0x7F 0xEE 0x60
|
|
0xFF 0xFB 0xBA 0x3F 0xF9 0x7F 0xDC 0x98 0xFF 0xFD 0xBD 0xFF 0xFE 0x3F 0xDC 0xF8
|
|
0xFF 0xFD 0xBC 0xFF 0xFF 0xCF 0xDC 0xFC 0x00 0x01 0xBD 0x7F 0xFF 0xF1 0xBC 0xFC
|
|
0xFF 0xFD 0xBD 0xBF 0x00 0x0E 0x3C 0xDC 0x00 0x01 0x1D 0xC8 0xFF 0xFF 0x8F 0xDE
|
|
0x00 0x00 0x1D 0xF3 0xFF 0xFF 0xF3 0xBE 0x00 0x00 0x04 0xFB 0xFF 0xFF 0xFC 0x7C
|
|
|
|
: mouth 0xF8
|
|
|
|
: rumbletext # "YOU HEAR A RUMBLE IN THE DISTANCE"
|
|
0x71 0x1F 0x1A 0x2D 0x35 0x41 0x32 0x0A 0x2D 0x2D 0x2D 0x2D 0x32 0x2D 0x0A 0x1A
|
|
0x17 0x10 0x3D 0x41 0x2D 0x45 0x24 0x2D 0x6C 0x35 0x41 0x2D 0x0C 0x45 0x5E 0x6C
|
|
0x32 0x24 0x52 0x41
|
|
|
|
: uselesstext # "JUST A BUNCHOF GOLD? HOWUSELESS!"
|
|
0x4D 0x1A 0x5E 0x6C 0x2D 0x32 0x2D 0x10 0x1A 0x24 0x52 0x35 0x1F 0x3A 0x2D 0x5A
|
|
0x1F 0x3D 0x0C 0x05 0x2D 0x35 0x1F 0x67 0x1A 0x5E 0x41 0x3D 0x41 0x5E 0x5E 0x00
|
|
|
|
: exittext # "CLIMBING OUTYOU EMERGE TO DAZZLING SUNLIGHT"
|
|
0x52 0x3D 0x45 0x17 0x10 0x45 0x24 0x5A 0x2D 0x1F 0x1A 0x6C 0x71 0x1F 0x1A 0x2D
|
|
0x41 0x17 0x41 0x0A 0x5A 0x41 0x2D 0x2D 0x6C 0x1F 0x2D 0x0C 0x32 0x49 0x49 0x3D
|
|
0x45 0x24 0x5A 0x2D 0x5E 0x1A 0x24 0x3D 0x45 0x5A 0x35 0x6C
|
|
|
|
: pyramidtext # "A VISION OF A PYRAMID? ASECRET WALL?"
|
|
0x32 0x2D 0x27 0x45 0x5E 0x45 0x1F 0x24 0x2D 0x1F 0x3A 0x2D 0x32 0x2D 0x12 0x71
|
|
0x0A 0x32 0x17 0x45 0x0C 0x05 0x2D 0x32 0x5E 0x41 0x52 0x0A 0x41 0x6C 0x2D 0x67
|
|
0x32 0x3D 0x3D 0x05
|
|
|
|
: skulltext # "SOMEONE LEFTTHEIR SKULL HERE? GROSS!"
|
|
0x5E 0x1F 0x17 0x41 0x1F 0x24 0x41 0x2D 0x3D 0x41 0x3A 0x6C 0x6C 0x35 0x41 0x45
|
|
0x0A 0x2D 0x5E 0x63 0x1A 0x3D 0x3D 0x2D 0x35 0x41 0x0A 0x41 0x05 0x2D 0x5A 0x0A
|
|
0x1F 0x5E 0x5E 0x00
|
|
|
|
: puzzlestext # "YOU MUST RETURN TO WHERE THIS ALL BEGAN"
|
|
0x71 0x1F 0x1A 0x2D 0x17 0x1A 0x5E 0x6C 0x2D 0x2D 0x2D 0x2D 0x0A 0x41 0x6C 0x1A
|
|
0x0A 0x24 0x2D 0x6C 0x1F 0x2D 0x2D 0x2D 0x67 0x35 0x41 0x0A 0x41 0x2D 0x6C 0x35
|
|
0x45 0x5E 0x2D 0x2D 0x32 0x3D 0x3D 0x2D 0x10 0x41 0x5A 0x32 0x24
|
|
|
|
: deadendtext # "A DEAD END? NUTS!"
|
|
0x32 0x2D 0x0C 0x41 0x32 0x0C 0x2D 0x41 0x24 0x0C 0x05 0x2D 0x24 0x1A 0x6C 0x5E
|
|
0x00
|
|
|
|
: mazetext # "SNWEW"
|
|
0x5E 0x24 0x67 0x41 0x67
|
|
|
|
: draw-bitmap
|
|
clear
|
|
v0 := 0 # x
|
|
v1 := 0 # y
|
|
v2 := 0 # byte
|
|
v3 := 1 # constant
|
|
loop
|
|
sprite v0 v1 1
|
|
i += v3
|
|
v2 += 1
|
|
v0 += 8
|
|
if v0 == 64 then v1 += 1
|
|
if v0 == 64 then v0 := 0
|
|
if v1 != 32 then
|
|
again
|
|
;
|
|
|
|
: draw-text
|
|
v1 := 2 # x
|
|
v2 := 1 # y
|
|
v3 := 0 # byte
|
|
# v4 contains length
|
|
loop
|
|
: text-addr i := 0 # self-modify to alter
|
|
i += v3
|
|
load v0
|
|
i := font
|
|
i += v0
|
|
sprite v1 v2 5
|
|
v1 += 5
|
|
if v1 == 62 then v2 += 6
|
|
if v1 == 62 then v1 := 2
|
|
v3 += 1
|
|
if v3 != v4 then
|
|
again
|
|
;
|
|
|
|
: wait
|
|
v0 := 128
|
|
delay := v0
|
|
loop
|
|
v0 := delay
|
|
if v0 != 0 then
|
|
again
|
|
;
|
|
|
|
: swapmouth
|
|
i := mouth
|
|
v0 := 4
|
|
v1 := 22
|
|
sprite v0 v1 1
|
|
v0 := 52
|
|
v1 := 29
|
|
sprite v0 v1 1
|
|
;
|
|
|
|
: draw-phrase-1
|
|
:unpack 0xA phrase1
|
|
i := text-addr
|
|
save v1
|
|
v4 := 19
|
|
draw-text
|
|
;
|
|
|
|
: draw-phrase-2
|
|
:unpack 0xA phrase2
|
|
i := text-addr
|
|
save v1
|
|
v4 := 12
|
|
draw-text
|
|
;
|
|
|
|
: draw-phrase-3
|
|
:unpack 0xA phrase3
|
|
i := text-addr
|
|
save v1
|
|
v4 := 13
|
|
draw-text
|
|
;
|
|
|
|
###########################################
|
|
#
|
|
# Block pushing puzzle
|
|
#
|
|
###########################################
|
|
|
|
: solid 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
: empty 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
|
: floor 0x00 0xFE 0x55 0x22 0x88 0x00 0x00 0x00
|
|
: roof 0x00 0x00 0x00 0x11 0x91 0x8B 0x8F 0xDF
|
|
: exit 0xC3 0xBD 0xBD 0xBD 0xB9 0xB9 0xBD 0xBD
|
|
: block 0x81 0x7E 0x5A 0x7E 0x7E 0x5A 0x7E 0x81
|
|
|
|
: left 0xE7 0xE7 0xC3 0x81 0x82 0x42 0xDB 0x93
|
|
: right 0xE7 0xE7 0xC3 0x81 0x41 0x42 0xDB 0xC9
|
|
|
|
:const SOLID 0
|
|
:const EMPTY 1
|
|
:const FLOOR 2
|
|
:const ROOF 3
|
|
:const EXIT 4
|
|
:const BLOCK 5
|
|
:const PLAYER_L 6
|
|
:const PLAYER_R 7
|
|
|
|
:alias levelno ve
|
|
:alias playerx vd
|
|
:alias playery vc
|
|
:alias input vb
|
|
:alias direction va
|
|
:alias win v9
|
|
|
|
# v0-v8 reserved for temporary use.
|
|
# v0-v7 are used together for fast buffer copies.
|
|
|
|
# player facing
|
|
:const FACING_LEFT 0
|
|
:const FACING_RIGHT 1
|
|
|
|
# input keys:
|
|
:const MOVE_LT 7
|
|
:const MOVE_RT 9
|
|
:const RESET 4
|
|
:const ACTION 6
|
|
|
|
###########################################
|
|
#
|
|
# Level data
|
|
#
|
|
###########################################
|
|
|
|
: level-0
|
|
4 1 1 3 1 1 3 0
|
|
2 1 1 1 1 1 1 3
|
|
0 2 1 1 1 1 1 1
|
|
0 0 2 2 2 2 1 6
|
|
: level-1
|
|
4 1 3 1 3 1 1 1
|
|
2 1 1 1 1 1 1 5
|
|
0 1 1 6 1 1 2 2
|
|
0 1 2 2 1 5 0 0
|
|
: level-2
|
|
3 1 1 1 1 1 1 4
|
|
1 1 1 2 2 2 2 2
|
|
5 1 1 1 1 1 1 1
|
|
2 5 1 1 6 1 1 5
|
|
: level-3
|
|
1 1 1 1 3 1 1 3
|
|
4 1 6 1 1 1 1 5
|
|
2 1 2 1 1 1 2 2
|
|
0 1 0 5 1 1 0 0
|
|
: level-4
|
|
5 1 3 0 3 1 1 4
|
|
1 1 1 3 1 1 1 2
|
|
1 1 1 1 1 1 1 0
|
|
2 2 1 6 1 5 2 0
|
|
: level-5
|
|
4 1 1 1 1 1 1 1
|
|
2 1 1 6 1 5 1 5
|
|
0 1 1 2 1 1 1 1
|
|
0 1 1 0 1 5 1 5
|
|
: level-6
|
|
0 3 1 5 1 1 1 4
|
|
3 1 1 1 1 1 1 2
|
|
1 1 1 5 2 1 1 0
|
|
5 5 1 6 0 1 1 0
|
|
: level-7
|
|
3 3 1 4 1 5 3 3
|
|
5 5 1 1 1 1 5 5
|
|
1 1 1 1 1 1 1 1
|
|
2 1 1 6 1 1 1 5
|
|
|
|
###########################################
|
|
#
|
|
# Level utilities
|
|
#
|
|
###########################################
|
|
|
|
: level-table
|
|
i := level-0 return
|
|
i := level-1 return
|
|
i := level-2 return
|
|
i := level-3 return
|
|
i := level-4 return
|
|
i := level-5 return
|
|
i := level-6 return
|
|
i := level-7 return
|
|
|
|
: get-level
|
|
v0 <<= levelno
|
|
v0 <<= v0
|
|
jump0 level-table
|
|
|
|
: copy-level
|
|
v8 := 0
|
|
loop
|
|
get-level
|
|
i += v8
|
|
load v7
|
|
|
|
i := level-buffer
|
|
i += v8
|
|
save v7
|
|
|
|
v8 += 8
|
|
if v8 != 32 then
|
|
again
|
|
;
|
|
|
|
: get-tile
|
|
# takes tile index in v0
|
|
v0 <<= v0
|
|
v0 <<= v0
|
|
v0 <<= v0
|
|
i := solid
|
|
i += v0
|
|
;
|
|
|
|
: spawn-player
|
|
direction := FACING_LEFT
|
|
win := 0
|
|
playerx := v1
|
|
playerx >>= playerx
|
|
playerx >>= playerx
|
|
playerx >>= playerx
|
|
playery := v2
|
|
playery >>= playery
|
|
playery >>= playery
|
|
playery >>= playery
|
|
;
|
|
|
|
: init-level
|
|
copy-level
|
|
clear
|
|
v1 := 0 # sprite x
|
|
v2 := 0 # sprite y
|
|
v3 := 0 # tile index
|
|
loop
|
|
i := level-buffer
|
|
i += v3
|
|
load v0
|
|
if v0 == PLAYER_L then spawn-player
|
|
get-tile
|
|
sprite v1 v2 8
|
|
v3 += 1
|
|
v1 += 8
|
|
if v1 == 64 then v2 += 8
|
|
if v1 == 64 then v1 := 0
|
|
if v2 != 32 then
|
|
again
|
|
;
|
|
|
|
: index-at
|
|
# takes x/y in v1/v2
|
|
# returns type in v0
|
|
v0 <<= v2
|
|
v0 <<= v0
|
|
v0 <<= v0
|
|
v0 += v1
|
|
i := level-buffer
|
|
i += v0
|
|
;
|
|
|
|
: draw-at
|
|
# takes x/y in v1/v2
|
|
# trashes v0-v2
|
|
index-at
|
|
load v0
|
|
get-tile
|
|
v1 <<= v1
|
|
v1 <<= v1
|
|
v1 <<= v1
|
|
v2 <<= v2
|
|
v2 <<= v2
|
|
v2 <<= v2
|
|
sprite v1 v2 8
|
|
;
|
|
|
|
: copy-loc
|
|
v1 := v3
|
|
v2 := v4
|
|
;
|
|
|
|
: set-at
|
|
# takes x/y in v3/v4, value in v5
|
|
copy-loc
|
|
draw-at
|
|
copy-loc
|
|
index-at
|
|
v0 := v5
|
|
save v0
|
|
copy-loc
|
|
draw-at
|
|
;
|
|
|
|
###########################################
|
|
#
|
|
# Block pusher player helpers
|
|
#
|
|
###########################################
|
|
|
|
:alias canpass v7
|
|
:alias deltadir v6
|
|
|
|
: player-loc
|
|
v1 := playerx
|
|
v2 := playery
|
|
;
|
|
|
|
: player-copy
|
|
v3 := playerx
|
|
v4 := playery
|
|
;
|
|
|
|
: player-ahead
|
|
player-loc
|
|
v1 += deltadir
|
|
;
|
|
|
|
: player-above
|
|
player-loc
|
|
v2 += -1
|
|
;
|
|
|
|
: player-below
|
|
player-loc
|
|
v2 += 1
|
|
;
|
|
|
|
: draw-player
|
|
player-loc
|
|
draw-at
|
|
;
|
|
|
|
: player-above-type
|
|
player-above
|
|
index-at
|
|
load v0
|
|
;
|
|
|
|
: carrying?
|
|
# returns result in v0
|
|
v0 := 0
|
|
if playery == 0 then return
|
|
player-above-type
|
|
if v0 != BLOCK then v0 := 0
|
|
if v0 == BLOCK then v0 := 1
|
|
;
|
|
|
|
###########################################
|
|
#
|
|
# Block pusher movement
|
|
#
|
|
###########################################
|
|
|
|
: passable?
|
|
# takes x/y in v1/v2
|
|
# returns flag in canpass
|
|
canpass := 0
|
|
if v1 > 7 then return
|
|
if v2 > 3 then return
|
|
index-at
|
|
load v0
|
|
if v0 == EMPTY then canpass := 1
|
|
if v0 == EXIT then canpass := 1
|
|
;
|
|
|
|
: fall-scan
|
|
player-copy
|
|
v3 += deltadir
|
|
loop
|
|
copy-loc
|
|
v2 += 1
|
|
passable?
|
|
while canpass == 1
|
|
v4 += 1
|
|
again
|
|
;
|
|
|
|
: move-player
|
|
# if we're stepping onto
|
|
# an exit, we win.
|
|
copy-loc
|
|
index-at
|
|
load v0
|
|
if v0 == EXIT then win := 1
|
|
|
|
# takes x/y in v3/v4
|
|
draw-player
|
|
player-loc
|
|
index-at
|
|
v0 := EMPTY
|
|
save v0
|
|
draw-player
|
|
|
|
playerx := v3
|
|
playery := v4
|
|
|
|
v5 := PLAYER_L
|
|
v5 += direction
|
|
set-at
|
|
;
|
|
|
|
: hide-block
|
|
v5 := EMPTY
|
|
|
|
: set-block
|
|
player-copy
|
|
v4 += -1
|
|
set-at
|
|
;
|
|
|
|
: show-block
|
|
v5 := BLOCK
|
|
jump set-block
|
|
|
|
: climb-move
|
|
player-copy
|
|
v3 += deltadir
|
|
v4 += -1
|
|
move-player
|
|
;
|
|
|
|
: climb-carry
|
|
# can't climb if blocked above-side
|
|
player-above
|
|
v1 += deltadir
|
|
passable?
|
|
if canpass != 1 then return
|
|
|
|
# can't climb if blocked above-above-side
|
|
player-above
|
|
v1 += deltadir
|
|
v2 += -1
|
|
passable?
|
|
if canpass != 1 then return
|
|
|
|
hide-block
|
|
climb-move
|
|
show-block
|
|
;
|
|
|
|
: climb
|
|
# can't climb if blocked above:
|
|
player-above
|
|
passable?
|
|
if canpass != 1 then return
|
|
|
|
# can't climb if blocked above-side
|
|
player-above
|
|
v1 += deltadir
|
|
passable?
|
|
if canpass != 1 then return
|
|
|
|
climb-move
|
|
;
|
|
|
|
: carry
|
|
# make sure we don't need to climb:
|
|
player-loc
|
|
v1 += deltadir
|
|
passable?
|
|
if canpass != 1 then jump climb-carry
|
|
|
|
# make sure there's horizontal space for the block
|
|
player-loc
|
|
v1 += deltadir
|
|
v2 += -1
|
|
passable?
|
|
if canpass != 1 then return
|
|
|
|
hide-block
|
|
|
|
# scan down and 'fall':
|
|
fall-scan
|
|
move-player
|
|
|
|
show-block
|
|
;
|
|
|
|
: walk
|
|
# make sure we aren't carrying a block:
|
|
carrying?
|
|
if v0 != 0 then jump carry
|
|
|
|
# make sure we don't need to climb:
|
|
player-loc
|
|
v1 += deltadir
|
|
passable?
|
|
if canpass != 1 then jump climb
|
|
|
|
# scan down and 'fall':
|
|
fall-scan
|
|
move-player
|
|
;
|
|
|
|
: walk-left
|
|
deltadir := -1
|
|
if direction == FACING_LEFT then jump walk
|
|
|
|
# face left
|
|
player-copy
|
|
v5 := PLAYER_L
|
|
set-at
|
|
direction := FACING_LEFT
|
|
;
|
|
|
|
: walk-right
|
|
deltadir := 1
|
|
if direction == FACING_RIGHT then jump walk
|
|
|
|
# face right
|
|
player-copy
|
|
v5 := PLAYER_R
|
|
set-at
|
|
direction := FACING_RIGHT
|
|
;
|
|
|
|
: drop
|
|
# there must be at least one empty space
|
|
player-ahead
|
|
passable?
|
|
if canpass != 1 then return
|
|
|
|
# erase block
|
|
player-copy
|
|
v4 += -1
|
|
v5 := EMPTY
|
|
set-at
|
|
|
|
# scan for drop position
|
|
fall-scan
|
|
|
|
# draw repositioned block
|
|
v5 := BLOCK
|
|
set-at
|
|
;
|
|
|
|
: action
|
|
deltadir := 1
|
|
if direction == FACING_LEFT then deltadir := -1
|
|
carrying?
|
|
if v0 != 0 then jump drop
|
|
|
|
# we can only pick up block tiles
|
|
player-ahead
|
|
index-at
|
|
load v0
|
|
if v0 != BLOCK then return
|
|
|
|
# the space above us must be empty
|
|
player-above-type
|
|
if v0 != EMPTY then return
|
|
|
|
# erase block
|
|
player-copy
|
|
v3 += deltadir
|
|
v5 := EMPTY
|
|
set-at
|
|
|
|
# draw repositioned block
|
|
player-copy
|
|
v4 += -1
|
|
v5 := BLOCK
|
|
set-at
|
|
;
|
|
|
|
###########################################
|
|
#
|
|
# Block pusher main routine
|
|
#
|
|
###########################################
|
|
|
|
: puzzle-finished-count 0
|
|
|
|
: block-puzzle
|
|
i := block-reg-buffer
|
|
save vd
|
|
|
|
init-level
|
|
loop
|
|
input := key
|
|
if input == RESET then init-level
|
|
if input == MOVE_LT then walk-left
|
|
if input == MOVE_RT then walk-right
|
|
if input == ACTION then action
|
|
if win == 0 then
|
|
again
|
|
|
|
v0 := 32
|
|
buzzer := v0
|
|
clear
|
|
|
|
i := puzzle-finished-count
|
|
load v0
|
|
v0 += 1
|
|
i := puzzle-finished-count
|
|
save v0
|
|
|
|
i := block-reg-buffer
|
|
load vd
|
|
;
|
|
|
|
###########################################
|
|
#
|
|
# Overworld
|
|
#
|
|
###########################################
|
|
|
|
: rocks1 0x00 0x40 0x00 0x00
|
|
: rocks2 0x00 0x20 0x40 0x00
|
|
: rocks3 0x00 0x40 0x20 0x00
|
|
: rocks4 0x00 0x00 0x00 0x00
|
|
|
|
: path 0x60 0xF0 0xF0 0x60
|
|
: man 0x00 0x60 0x60 0x00
|
|
: target 0x70 0x40 0xF0 0x50
|
|
|
|
: bits 1 2 4 8 16 32 64 128
|
|
|
|
:alias boardno vd
|
|
:alias manx vc
|
|
:alias many vb
|
|
:alias specialx va
|
|
:alias specialy v9
|
|
:alias oldx v8
|
|
:alias oldy v7
|
|
:alias specialflag v6
|
|
|
|
###########################################
|
|
#
|
|
# Board data
|
|
#
|
|
###########################################
|
|
|
|
: special-pos
|
|
3 6 # board 0
|
|
7 4 # board 1
|
|
14 6 # board 2
|
|
7 4 # board 3
|
|
3 3 # board 4
|
|
12 4 # board 5
|
|
7 5 # board 6
|
|
7 4 # board 7
|
|
7 6 # board 8
|
|
9 4 # board 9
|
|
10 4 # board A
|
|
11 3 # board B
|
|
5 3 # board C
|
|
5 3 # board D
|
|
5 3 # board E
|
|
5 3 # board F
|
|
|
|
# board in each direction
|
|
# 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
: board-n
|
|
0x0 0x2 0x1 0x5 0xA 0x6 0x7 0x7 0x8 0x9 0x3 0xC 0xC 0xC 0xC 0xE
|
|
: board-e
|
|
0x3 0x4 0x2 0x1 0x9 0x8 0x6 0x7 0xA 0x9 0xA 0xB 0xD 0xE 0xF 0xD
|
|
: board-s
|
|
0x0 0x2 0x1 0xA 0xD 0x3 0x5 0x6 0x8 0x9 0x4 0xB 0xB 0xB 0xB 0xB
|
|
: board-w
|
|
0x0 0x3 0x2 0x0 0x1 0x5 0x6 0x7 0x5 0x4 0x8 0xB 0xD 0xD 0x3 0xF
|
|
|
|
# pixel data
|
|
: board0
|
|
0x28 0xEB 0x0A 0x7A 0x02 0xEF 0x28 0x2A
|
|
0x6A 0x4A 0x5A 0x42 0x7A 0x0A 0x6E 0x28
|
|
: board1
|
|
0x08 0x08 0x4A 0x08 0xFF 0x40 0x5E 0x52
|
|
0x42 0x7E 0x40 0xCF 0x08 0x4A 0x08 0x08
|
|
: board2
|
|
0x00 0x70 0x50 0x50 0xD7 0x54 0x54 0x54
|
|
0x54 0x54 0x54 0xD5 0x14 0x14 0x7C 0x00
|
|
: board3
|
|
0x28 0x28 0x28 0xEB 0x0A 0x6A 0x0A 0x3A
|
|
0x22 0x3A 0x2A 0x2E 0x20 0x38 0x08 0x28
|
|
: board4
|
|
0x08 0x08 0x1C 0x7F 0x5C 0xC9 0x08 0x1C
|
|
: gate1 0x60 0x1C 0x08 0x08 0x1C : gate2 0x60 0x1C 0x08
|
|
: board5
|
|
0x10 0x00 0x03 0xF3 0x10 0x10 0x10 0xDF
|
|
0xD0 0x16 0x16 0x10 0x10 0x10 0x10 0x10
|
|
: board6
|
|
0x00 0x02 0x4A 0x66 0x70 0x78 0x7C 0xFF
|
|
0x7C 0x78 0x70 0x66 0x4A 0x02 0x00 0x00
|
|
: board7
|
|
0x00 0x76 0x52 0x5A 0x04 0x00 0x39 0xFB
|
|
0x39 0x00 0x04 0x5A 0x52 0x76 0x00 0x00
|
|
: board8
|
|
0x10 0x7E 0x08 0x7E 0x10 0x7E 0x08 0x7E
|
|
0x10 0x7E 0x08 0x7E 0x10 0x7E 0x10 0x10
|
|
: board9
|
|
0x08 0x08 0xD8 0x52 0xD0 0x10 0x38 0x2B
|
|
0x3A 0x12 0x02 0xC2 0x4E 0x78 0x10 0x18
|
|
: boardA
|
|
0x10 0x54 0x10 0xFF 0x04 0x7C 0x40 0x7C
|
|
0x04 0x1C 0x10 0x00 0x28 0x6C 0x74 0x38
|
|
: boardB
|
|
0x00 0xF2 0xEA 0x02 0x02 0xC3 0x0A 0xFA
|
|
0x02 0xFA 0xA2 0x8A 0x22 0xF2 0x9A 0x38
|
|
: boardC
|
|
0x08 0x08 0x08 0x3E 0x22 0xFB 0x22 0x3E
|
|
0x08 0x08 0x08 0x08 0x08 0x08 0x08 0x08
|
|
: boardD
|
|
0x08 0x08 0x08 0x3E 0x22 0xFB 0x22 0x3E
|
|
0x08 0x08 0x08 0x08 0x08 0x08 0x0A 0x08
|
|
: boardE
|
|
0x08 0x08 0x08 0x3E 0x22 0xFB 0x22 0x3E
|
|
0x08 0x08 0x08 0x08 0x0A 0x08 0x0A 0x08
|
|
: boardF
|
|
0x08 0x08 0x08 0x3E 0x22 0xFB 0x22 0x3E
|
|
0x08 0x08 0x0A 0x08 0x0A 0x08 0x0A 0x08
|
|
|
|
###########################################
|
|
#
|
|
# Overworld game logic
|
|
#
|
|
###########################################
|
|
|
|
: secret-wall
|
|
if boardno != 6 then return
|
|
if v4 != 7 then return
|
|
v5 := 0b11111100
|
|
;
|
|
|
|
: draw-board
|
|
clear
|
|
v1 := 0 # x tile
|
|
v4 := 0 # data offset
|
|
v3 <<= boardno # data base
|
|
v3 <<= v3
|
|
v3 <<= v3
|
|
v3 <<= v3
|
|
loop
|
|
i := board0
|
|
i += v3
|
|
i += v4
|
|
load v0
|
|
v5 := v0 # column
|
|
v2 := 0 # y tile
|
|
secret-wall
|
|
|
|
loop
|
|
i := rocks1
|
|
v0 := random 0b1100
|
|
i += v0
|
|
v5 >>= v5
|
|
if vf != 0 then i := path
|
|
sprite v1 v2 4
|
|
v2 += 4
|
|
if v2 != 32 then
|
|
again
|
|
|
|
v1 += 4
|
|
v4 += 1
|
|
if v4 != 16 then
|
|
again
|
|
|
|
specialx := -1
|
|
specialy := -1
|
|
i := special-complete
|
|
i += boardno
|
|
load v0
|
|
if v0 != 0 then return
|
|
|
|
v0 <<= boardno
|
|
i := special-pos
|
|
i += v0
|
|
load v1
|
|
specialx := v0
|
|
specialy := v1
|
|
|
|
v0 <<= v0
|
|
v0 <<= v0
|
|
v1 <<= v1
|
|
v1 <<= v1
|
|
i := path
|
|
sprite v0 v1 4
|
|
i := target
|
|
sprite v0 v1 4
|
|
;
|
|
|
|
: draw-man
|
|
v0 <<= manx
|
|
v0 <<= v0
|
|
v1 <<= many
|
|
v1 <<= v1
|
|
i := man
|
|
sprite v0 v1 4
|
|
;
|
|
|
|
: copy-pos
|
|
oldx := manx
|
|
oldy := many
|
|
;
|
|
|
|
: try-special
|
|
if manx != specialx then return
|
|
if many != specialy then return
|
|
specialflag := 1
|
|
;
|
|
|
|
: try-move
|
|
# fetch column data
|
|
i := board0
|
|
v0 <<= boardno
|
|
v0 <<= v0
|
|
v0 <<= v0
|
|
v0 <<= v0
|
|
i += v0
|
|
|
|
v3 := 15
|
|
v2 := manx
|
|
v2 &= v3
|
|
i += v2
|
|
load v0
|
|
v1 := v0
|
|
|
|
# fetch row mask
|
|
i := bits
|
|
v3 := 7
|
|
v2 := many
|
|
v2 &= v3
|
|
i += v2
|
|
load v0
|
|
|
|
v0 &= v1
|
|
vf := 1
|
|
if v0 != 0 then try-special
|
|
if v0 != 0 then return
|
|
|
|
# roll back
|
|
manx := oldx
|
|
many := oldy
|
|
vf := 0
|
|
;
|
|
|
|
: change-board
|
|
i += boardno
|
|
load v0
|
|
if v0 == boardno then return
|
|
boardno := v0
|
|
draw-board
|
|
;
|
|
|
|
: overworld-walk-w
|
|
manx += -1
|
|
try-move
|
|
if vf == 0 then return
|
|
if manx != -1 then return
|
|
i := board-w
|
|
manx := 15
|
|
jump change-board
|
|
|
|
: overworld-walk-e
|
|
manx += 1
|
|
try-move
|
|
if vf == 0 then return
|
|
if manx != 16 then return
|
|
manx := 0
|
|
i := board-e
|
|
jump change-board
|
|
|
|
: overworld-walk-n
|
|
many += -1
|
|
try-move
|
|
if vf == 0 then return
|
|
if many != -1 then return
|
|
many := 7
|
|
i := board-n
|
|
jump change-board
|
|
|
|
: overworld-walk-s
|
|
many += 1
|
|
try-move
|
|
if vf == 0 then return
|
|
if many != 8 then return
|
|
many := 0
|
|
i := board-s
|
|
jump change-board
|
|
|
|
: overworld-walk
|
|
if v2 == 7 then jump overworld-walk-w
|
|
if v2 == 9 then jump overworld-walk-e
|
|
if v2 == 5 then jump overworld-walk-n
|
|
if v2 == 8 then jump overworld-walk-s
|
|
;
|
|
|
|
###########################################
|
|
#
|
|
# Special scripted events
|
|
#
|
|
###########################################
|
|
|
|
: rumble
|
|
v0 := 0b00001100
|
|
save v0
|
|
|
|
clear
|
|
:unpack 0xA rumbletext
|
|
i := text-addr
|
|
save v1
|
|
v4 := 36
|
|
draw-text
|
|
v0 := key
|
|
;
|
|
|
|
: open-gate-1
|
|
i := gate1
|
|
rumble
|
|
;
|
|
|
|
: open-gate-2
|
|
i := gate2
|
|
rumble
|
|
;
|
|
|
|
: useless-gold
|
|
clear
|
|
:unpack 0xA uselesstext
|
|
i := text-addr
|
|
save v1
|
|
v4 := 32
|
|
draw-text
|
|
v0 := key
|
|
;
|
|
|
|
: pyramid-hint
|
|
clear
|
|
:unpack 0xA pyramidtext
|
|
i := text-addr
|
|
save v1
|
|
v4 := 36
|
|
draw-text
|
|
v0 := key
|
|
;
|
|
|
|
: gross-skull
|
|
clear
|
|
:unpack 0xA skulltext
|
|
i := text-addr
|
|
save v1
|
|
v4 := 36
|
|
draw-text
|
|
v0 := key
|
|
;
|
|
|
|
: dead-end
|
|
clear
|
|
:unpack 0xA deadendtext
|
|
i := text-addr
|
|
save v1
|
|
v4 := 17
|
|
draw-text
|
|
v0 := key
|
|
;
|
|
|
|
: maze-hint
|
|
clear
|
|
:unpack 0xA mazetext
|
|
i := text-addr
|
|
save v1
|
|
v4 := 5
|
|
draw-text
|
|
v0 := key
|
|
;
|
|
|
|
: nop ;
|
|
|
|
: puzzle-0 ve := 0 block-puzzle ;
|
|
: puzzle-1 ve := 1 block-puzzle ;
|
|
: puzzle-2 ve := 2 block-puzzle ;
|
|
: puzzle-3 ve := 3 block-puzzle ;
|
|
: puzzle-4 ve := 4 block-puzzle ;
|
|
: puzzle-5 ve := 5 block-puzzle ;
|
|
: puzzle-6 ve := 6 block-puzzle ;
|
|
|
|
: puzzle-7
|
|
ve := 7
|
|
block-puzzle
|
|
|
|
clear
|
|
:unpack 0xA exittext
|
|
i := text-addr
|
|
save v1
|
|
v4 := 44
|
|
draw-text
|
|
v0 := key
|
|
|
|
i := bus
|
|
draw-bitmap
|
|
loop again
|
|
|
|
: special-things
|
|
jump puzzle-7 # 0
|
|
jump useless-gold # 1
|
|
jump puzzle-1 # 2
|
|
jump puzzle-0 # 3
|
|
jump open-gate-2 # 4
|
|
jump gross-skull # 5
|
|
jump puzzle-2 # 6
|
|
jump open-gate-1 # 7
|
|
jump puzzle-3 # 8
|
|
jump puzzle-6 # 9
|
|
jump dead-end # A
|
|
return # B
|
|
jump pyramid-hint # C
|
|
jump puzzle-4 # D
|
|
jump maze-hint # E
|
|
jump puzzle-5 # F
|
|
|
|
: check-puzzles
|
|
i := puzzle-finished-count
|
|
load v0
|
|
if v0 != 7 then return
|
|
v0 += 1
|
|
i := puzzle-finished-count
|
|
save v0
|
|
|
|
clear
|
|
:unpack 0xA puzzlestext
|
|
i := text-addr
|
|
save v1
|
|
v4 := 45
|
|
draw-text
|
|
v0 := key
|
|
|
|
i := board-e
|
|
v0 := 0
|
|
save v0
|
|
;
|
|
|
|
###########################################
|
|
#
|
|
# Overworld main routine
|
|
#
|
|
###########################################
|
|
|
|
: do-special
|
|
i := special-complete
|
|
i += boardno
|
|
v0 := 1
|
|
save v0
|
|
|
|
v0 <<= boardno
|
|
jump0 special-things
|
|
|
|
: main
|
|
# intro sequence
|
|
i := title1
|
|
draw-bitmap
|
|
draw-phrase-1
|
|
wait
|
|
draw-phrase-1
|
|
swapmouth
|
|
draw-phrase-2
|
|
wait
|
|
draw-phrase-2
|
|
swapmouth
|
|
draw-phrase-3
|
|
wait
|
|
draw-phrase-3
|
|
i := title2
|
|
draw-bitmap
|
|
v0 := key
|
|
|
|
# main routine
|
|
manx := 10
|
|
many := 4
|
|
draw-board
|
|
loop
|
|
draw-man
|
|
v2 := key
|
|
draw-man
|
|
copy-pos
|
|
specialflag := 0
|
|
overworld-walk
|
|
if specialflag != 0 then do-special
|
|
check-puzzles
|
|
if specialflag != 0 then draw-board
|
|
again
|