1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-06-02 10:41:35 +00:00
PLASMA/src/samplesrc/rogue.map.pla
2023-04-11 20:22:44 -07:00

854 lines
22 KiB
Plaintext

//
// Map module
//
include "inc/cmdsys.plh"
include "inc/conio.plh"
include "inc/fileio.plh"
//
// Title page
//
byte[] initstr
byte = " ( )\n"
byte = " )\\ ) ( /( (\n"
byte = "(()/( )\\()) )\\ ) ( (\n"
byte = " /(_))((_)\\ (()/( )\\ )\\\n"
byte = "(_)) ((_) /(_))_ _ ((_)((_)\n"
byte = "| _ \\ / _ \\(_)) __|| | | || __|\n"
byte = "| / | (_) | | (_ || |_| || _|\n"
byte = "|_|_\\ \\___/ \\___| \\___/ |___|\n"
byte = "\n"
byte = " By Resman\n"
byte = " Artwork by Seth Sternberger\n"
byte = ""
word titlestr = @initstr
//
// Animated tile sequence
//
byte animseq = 0
//
// Octant beam parameters
//
const beamdepth = 23
byte dbeam = 0,2,4,8,12,17,22,28,37,44,53,63,72,83,96,109,123,137,151,166,183,202,220,239
const beampts = 240
byte[] xbeam
byte = 0
byte = 1,0
byte = 1,0
byte = 2,2,1,0
byte = 3,2,1,0
byte = 4,3,2,1,0
byte = 4,3,2,1,0
byte = 5,4,3,2,1,0
byte = 6,5,5,4,3,3,2,1,0
byte = 6,5,4,3,2,1,0
byte = 7,7,6,5,4,3,2,1,0
byte = 8,7,6,6,5,4,3,2,1,0
byte = 8,7,6,5,4,3,2,1,0
byte = 9,9,8,7,6,5,4,3,2,1,0
byte = 10,9,8,8,7,6,5,4,4,3,2,1,0
byte = 11,10,10,9,8,7,6,5,4,3,2,1,0
byte = 11,10,9,9,8,7,7,6,5,4,3,2,1,0
byte = 12,12,11,10,9,8,7,6,5,4,3,2,1,0
byte = 13,12,11,10,9,8,7,6,5,4,3,2,1,0
byte = 13,12,11,11,10,9,8,7,6,5,4,3,2,1,0
byte = 14,14,13,12,11,10,10,9,8,7,6,5,4,3,2,1,0
byte = 15,14,13,13,12,12,11,10,9,8,8,7,6,5,4,3,2,1,0
byte = 16,15,14,13,12,11,10,9,8,7,6,5,5,4,3,2,1,0
byte = 16,15,15,14,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
byte[] ybeam
byte = 0
byte = 1,1
byte = 2,2
byte = 2,3,3,3
byte = 3,4,4,4
byte = 4,4,5,5,5
byte = 5,5,6,6,6
byte = 5,6,6,7,7,7
byte = 6,6,7,7,7,8,8,8,8
byte = 7,8,8,9,9,9,9
byte = 7,8,8,9,9,10,10,10,10
byte = 8,9,9,10,10,10,11,11,11,11
byte = 9,10,11,11,11,12,12,12,12
byte = 9,10,10,11,12,12,12,13,13,13,13
byte = 10,11,11,12,12,13,13,13,14,14,14,14,14
byte = 11,11,12,12,13,13,14,14,15,15,15,15,15
byte = 12,13,13,14,14,14,15,15,15,16,16,16,16,16
byte = 12,13,13,14,15,15,16,16,16,17,17,17,17,17
byte = 13,14,14,15,16,16,17,17,17,18,18,18,18,18
byte = 14,15,15,16,16,17,17,18,18,18,19,19,19,19,19
byte = 14,15,15,16,17,17,18,18,18,19,19,19,20,20,20,20,20
byte = 15,16,16,17,17,18,18,19,19,19,20,20,20,20,21,21,21,21,21
byte = 16,16,17,18,19,19,20,20,21,21,21,21,22,22,22,22,22,22
byte = 17,17,18,18,19,19,20,20,21,21,22,22,22,23,23,23,23,23,23
byte[] vbeam
byte = 0
byte = 0,0
byte = 2,2
byte = 1,3,4,4
byte = 5,7,7,8
byte = 9,6,11,11,12
byte = 14,10,16,16,17
byte = 13,19,15,21,21,22
byte = 23,18,24,25,20,26,26,27,28
byte = 30,32,33,35,35,36,37
byte = 29,38,31,40,34,42,42,43,44
byte = 45,47,39,48,49,41,51,51,52,53
byte = 46,56,58,59,50,60,61,62,63
byte = 54,64,55,57,67,68,60,69,70,71,72
byte = 73,75,65,76,66,78,79,69,80,80,81,82,83
byte = 84,74,85,86,88,77,90,91,93,93,94,95,96
byte = 98,100,87,101,102,89,103,104,92,105,106,107,108,109
byte = 97,110,99,112,114,115,117,118,105,119,120,121,122,123
byte = 124,126,111,113,129,116,131,132,119,133,134,135,136,137
byte = 125,140,127,141,128,143,130,145,146,133,147,148,149,150,151
byte = 138,152,139,154,156,142,157,158,144,160,161,147,162,163,164,165,166
byte = 167,169,153,170,155,171,172,174,175,159,176,177,178,178,179,180,181,182,183
byte = 184,168,186,188,190,173,192,193,195,196,197,197,214,198,199,200,201,202
byte = 204,185,205,187,206,189,208,191,210,194,212,213,214,215,216,217,218,219,220
byte[beampts] vispix = 1
const rowshift = 6
const maprows = 64
const mapcols = 64
const mapsize = maprows*mapcols
const WALL_TILE = '#'
const FLOOR_TILE = '.'
const TORCH_TILE = '*'
const PIT_TILE = ' '
const DOOR_TILE = '+'
const LOCKED_TILE = '%'
const WATER1_TILE = '>'
const WATER2_TILE = '<'
const KEY_TILE = ','
const RAFT_TILE = '@'
const GOLD_TILE = '$'
const FOOD_TILE = '&'
const ENTER_TILE = '-'
const EXIT_TILE = '='
const OPAQUE_TILE = $01
const VIEWED_TILE = $80
const LIT_TILE = $80
const INV_TILE = $3F
const MAP_TILE = $7F
byte catacomb = "LEVEL0"
word map, viewmap
const xcentr = 20
const ycentr = 12
const scrnwidth = 40
const scrnheight = 22
//
// Screen buffer
//
byte[scrnheight * scrnwidth] screenbuffer
//
// Buffer to void checks in octant caster
//
byte[scrnwidth] linebuffer
word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer
word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer
word[scrnheight] screen
word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer
word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer
//
// Visisble screen row addresses
//
word[] viscreen
word = $400, $480, $500, $580, $600, $680, $700, $780
word = $428, $4A8, $528, $5A8, $628, $6A8, $728, $7A8
word = $450, $4D0, $550, $5D0, $650, $6D0, $750, @linebuffer // $7D0
//
// Load map - levels 0 to 9
//
export def loadmap(level)
byte mapref, row, l
//
// Init the view map
//
if not viewmap
viewmap = heapalloc(mapsize)
fin
memset(viewmap, $A0A0, mapsize)
//
// Load catacomb map from file
//
if not map
map = heapalloc(mapsize)
fin
memset(map, $2323, mapsize) // Solid walls
//
// Set level map and read it
//
catacomb[catacomb] = '0' + level
mapref = fileio:open(@catacomb)
if mapref
fileio:newline(mapref, $7F, $0D)
for row = 1 to maprows - 2
l = fileio:read(mapref, map + (row << 6) + 1, mapcols)
^(map + (row << 6) + l) = WALL_TILE
next
fileio:close(mapref)
return TRUE
fin
return FALSE
end
//
// Tile access to map
//
export def getmaptile(xmap, ymap)
return ^(map + (ymap << rowshift) + xmap)
end
export def setmaptile(xmap, ymap, tile)#0
word imap
imap = (ymap << rowshift) + xmap
^(map + imap) = tile
if ^(viewmap + imap) <> $A0
^(viewmap + imap) = tile | VIEWED_TILE
fin
end
export def updtmaptile(xmap, ymap, tile)#0
word imap
imap = (ymap << rowshift) + xmap
^(map + imap) = (^(map + imap) & LIT_TILE) | tile
if ^(viewmap + imap) <> $A0
^(viewmap + imap) = tile | VIEWED_TILE
fin
end
//
// Light torches in map
//
export def lighttorches#0
word imap, tmap, rowmap
byte xmap, ymap, xt, yt
for ymap = 1 to maprows - 2
rowmap = map + (ymap << rowshift)
for xmap = 1 to mapcols - 2
imap = rowmap + xmap
if ^imap & MAP_TILE == TORCH_TILE
for yt = ymap - 1 to ymap + 1
imap = map + (yt << rowshift)
for xt = xmap - 1 to xmap + 1
tmap = imap + xt
^tmap = ^tmap | LIT_TILE
next
next
fin
next
if not (ymap & 7)
putc('.')
fin
next
end
//
// Animate tiles in map
//
export def animate(tile)
if animseq
when tile & MAP_TILE
is TORCH_TILE
tile = 'X'
break
is WATER1_TILE
tile = '('
break
is WATER2_TILE
tile = ')'
break
wend
else
when tile & MAP_TILE
is WATER1_TILE
tile = ')'
break
is WATER2_TILE
tile = '('
break
wend
fin
return tile & INV_TILE
end
//
// Draw the map. Return 0 if any light visible, 1 if in complete darkness
//
export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
byte l, dist, tile, adjtile, occluded, darkness
word ymap, xmap, imap, o
byte yscr, xscr
if viewdist > beamdepth
viewdist = beamdepth
fin
if lightdist > viewdist
lightdist = viewdist
fin
//
// Clear screen
//
memset(@screenbuffer, $A0A0, scrnheight * scrnwidth)
//
// Draw background map if in light
//
darkness = 1
imap = (yorg << rowshift) + xorg
if lightdist or ^(map + imap) & LIT_TILE
//
// Update current spot in viewmap
//
^(viewmap + imap) = ^(map + imap) | VIEWED_TILE
//
// Draw the viewmap
//
xmap = xorg - xcentr
if xmap < 0
l = mapcols
xscr = -xmap
xmap = 0
else
l = mapcols - xmap
xscr = 0
fin
if xscr + l > scrnwidth
l = scrnwidth - xscr
fin
for yscr = 0 to scrnheight
ymap = yscr - ycentr + yorg
if ymap >= 0 and ymap < maprows
memcpy(screen[yscr] + xscr, viewmap + (ymap << rowshift) + xmap, l)
fin
next
darkness = 0
fin
//
// Draw visible octants
//
for o = viewdir - viewfield - 1 to viewdir + viewfield
dist = lightdist + 1
occluded = 1
when o & 7
is 0
//
// Run through lit octant beam points
//
for l = 1 to dbeam[lightdist]
//
// Check parent visiblity
//
if vispix[vbeam[l]]
imap = ((yorg - ybeam[l]) << rowshift) + xorg + xbeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
//
// The view stops here
//
vispix[l] = 0
else
//
// This tile is transparent
//
vispix[l] = 1
//
// Check adjacent tile for opaqueness - improves wall display
//
adjtile = ^(map + imap + 1) & INV_TILE
if adjtile & OPAQUE_TILE
^(viewmap + imap + 1) = adjtile | VIEWED_TILE
screen.[ycentr-ybeam[l], xcentr+xbeam[l]+1] = adjtile
fin
fin
//
// Update view
//
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr-ybeam[l], xcentr+xbeam[l]] = animate(tile)
fin
else
vispix[l] = 0
fin
next
//
// Run through visible octant beam points
//
for l = dbeam[lightdist]+1 to dbeam[viewdist]
//
// Check parent visiblity
//
if vispix[vbeam[l]]
imap = ((yorg - ybeam[l]) << rowshift) + xorg + xbeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
//
// The view stops here
//
vispix[l] = 0
else
//
// This tile is transparent
//
vispix[l] = 1
occluded = 0
fin
//
// If the tile is in light, update view
//
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr-ybeam[l], xcentr+xbeam[l]] = animate(tile)
darkness = 0
fin
else
vispix[l] = 0
fin
//
// Advance beam distance
//
if l == dbeam[dist]
if occluded
//
// Beam fully occluded
//
break
fin
//
// Update distance
//
occluded = 1
dist++
fin
next
break
is 1
for l = 1 to dbeam[lightdist]
if vispix[vbeam[l]]
imap = ((yorg - xbeam[l]) << rowshift) + xorg + ybeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
adjtile = ^(map + imap - mapcols) & INV_TILE
if adjtile & OPAQUE_TILE
^(viewmap + imap - mapcols) = adjtile | VIEWED_TILE
screen.[ycentr-xbeam[l]-1, xcentr+ybeam[l]] = adjtile
fin
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr-xbeam[l], xcentr+ybeam[l]] = animate(tile)
fin
else
vispix[l] = 0
fin
next
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg - xbeam[l]) << rowshift) + xorg + ybeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
occluded = 0
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr-xbeam[l], xcentr+ybeam[l]] = animate(tile)
darkness = 0
fin
else
vispix[l] = 0
fin
if l == dbeam[dist]
if occluded
break
fin
occluded = 1
dist++
fin
next
break
is 2
for l = 1 to dbeam[lightdist]
if vispix[vbeam[l]]
imap = ((yorg + xbeam[l]) << rowshift) + xorg + ybeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
adjtile = ^(map + imap + mapcols) & INV_TILE
if adjtile & OPAQUE_TILE
^(viewmap + imap + mapcols) = adjtile | VIEWED_TILE
screen.[ycentr+xbeam[l]+1, xcentr+ybeam[l]] = adjtile
fin
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr+xbeam[l], xcentr+ybeam[l]] = animate(tile)
fin
else
vispix[l] = 0
fin
next
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg + xbeam[l]) << rowshift) + xorg + ybeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
occluded = 0
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr+xbeam[l], xcentr+ybeam[l]] = animate(tile)
darkness = 0
fin
else
vispix[l] = 0
fin
if l == dbeam[dist]
if occluded
break
fin
occluded = 1
dist++
fin
next
break
is 3
for l = 1 to dbeam[lightdist]
if vispix[vbeam[l]]
imap = ((yorg + ybeam[l]) << rowshift) + xorg + xbeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
adjtile = ^(map + imap + 1) & INV_TILE
if adjtile & OPAQUE_TILE
^(viewmap + imap + 1) = adjtile | VIEWED_TILE
screen.[ycentr+ybeam[l], xcentr+xbeam[l]+1] = adjtile
fin
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr+ybeam[l], xcentr+xbeam[l]] = animate(tile)
fin
else
vispix[l] = 0
fin
next
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg + ybeam[l]) << rowshift) + xorg + xbeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
occluded = 0
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr+ybeam[l], xcentr+xbeam[l]] = animate(tile)
darkness = 0
fin
else
vispix[l] = 0
fin
if l == dbeam[dist]
if occluded
break
fin
occluded = 1
dist++
fin
next
break
is 4
for l = 1 to dbeam[lightdist]
if vispix[vbeam[l]]
imap = ((yorg + ybeam[l]) << rowshift) + xorg - xbeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
adjtile = ^(map + imap - 1) & INV_TILE
if adjtile & OPAQUE_TILE
^(viewmap + imap - 1) = adjtile | VIEWED_TILE
screen.[ycentr+ybeam[l], xcentr-xbeam[l]-1] = adjtile
fin
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr+ybeam[l], xcentr-xbeam[l]] = animate(tile)
fin
else
vispix[l] = 0
fin
next
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg + ybeam[l]) << rowshift) + xorg - xbeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
occluded = 0
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr+ybeam[l], xcentr-xbeam[l]] = animate(tile)
darkness = 0
fin
else
vispix[l] = 0
fin
if l == dbeam[dist]
if occluded
break
fin
occluded = 1
dist++
fin
next
break
is 5
for l = 1 to dbeam[lightdist]
if vispix[vbeam[l]]
imap = ((yorg + xbeam[l]) << rowshift) + xorg - ybeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
adjtile = ^(map + imap + mapcols) & INV_TILE
if adjtile & OPAQUE_TILE
^(viewmap + imap + mapcols) = adjtile | VIEWED_TILE
screen.[ycentr+xbeam[l]+1, xcentr-ybeam[l]] = adjtile
fin
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr+xbeam[l], xcentr-ybeam[l]] = animate(tile)
fin
else
vispix[l] = 0
fin
next
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg + xbeam[l]) << rowshift) + xorg - ybeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
occluded = 0
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr+xbeam[l], xcentr-ybeam[l]] = animate(tile)
darkness = 0
fin
else
vispix[l] = 0
fin
if l == dbeam[dist]
if occluded
break
fin
occluded = 1
dist++
fin
next
break
is 6
for l = 1 to dbeam[lightdist]
if vispix[vbeam[l]]
imap = ((yorg - xbeam[l]) << rowshift) + xorg - ybeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
adjtile = ^(map + imap - mapcols) & INV_TILE
if adjtile & OPAQUE_TILE
^(viewmap + imap - mapcols) = adjtile | VIEWED_TILE
screen.[ycentr-xbeam[l]-1, xcentr-ybeam[l]] = adjtile
fin
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr-xbeam[l], xcentr-ybeam[l]] = animate(tile)
fin
else
vispix[l] = 0
fin
next
for l = dbeam[lightdist]+1 to dbeam[viewdist]
if vispix[vbeam[l]]
imap = ((yorg - xbeam[l]) << rowshift) + xorg - ybeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
occluded = 0
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr-xbeam[l], xcentr-ybeam[l]] = animate(tile)
darkness = 0
fin
else
vispix[l] = 0
fin
if l == dbeam[dist]
if occluded
break
fin
occluded = 1
dist++
fin
next
break
is 7
for l = 1 to dbeam[lightdist]
if vispix[vbeam[l]]
imap = ((yorg - ybeam[l]) << rowshift) + xorg - xbeam[l]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
adjtile = ^(map + imap - 1) & INV_TILE
if adjtile & OPAQUE_TILE
^(viewmap + imap - 1) = adjtile | VIEWED_TILE
screen.[ycentr-ybeam[l], xcentr-xbeam[l]-1] = adjtile
fin
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr-ybeam[l], xcentr-xbeam[l]] = animate(tile)
fin
else
vispix[l] = 0
fin
next
for l = dbeam[lightdist]+1 to dbeam[viewdist]
imap = ((yorg - ybeam[l]) << rowshift) + xorg - xbeam[l]
if vispix[vbeam[l]]
tile = ^(map + imap)
if tile & OPAQUE_TILE
vispix[l] = 0
else
vispix[l] = 1
occluded = 0
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr-ybeam[l], xcentr-xbeam[l]] = animate(tile)
darkness = 0
fin
else
vispix[l] = 0
fin
if l == dbeam[dist]
if occluded
break
fin
occluded = 1
dist++
fin
next
break
wend
next
animseq = animseq ^ 1 // Update animation sequence
return darkness
end
//
// Draw other entities
//
export def drawvisentity(xofst, yofst, tile)#0
if screen.[ycentr+yofst, xcentr+xofst] < $80
screen.[ycentr+yofst, xcentr+xofst] = tile
fin
end
export def drawplayer(tile)#0
screen.[ycentr, xcentr] = tile | $80
end
//
// Update visible screen with screen buffer
//
export def updatescreen#0
byte row
for row = 0 to scrnheight - 2
memcpy(viscreen[row], screen[row], 40)
next
end
//
// Print title page
//
conio:home()
while ^titlestr
puts(titlestr)
titlestr = titlestr + ^titlestr + 1
loop
for titlestr = 0 to scrnheight - 1
screen[titlestr] = @screenbuffer + titlestr * scrnwidth
next
done