// // Map module // include "inc/cmdsys.plh" import rogueio const O_READ = 1 const O_WRITE = 2 const O_READ_WRITE = 3 predef puti, toupper word rnd, getkb, home, gotoxy, tone, open, read, close, newline end const FALSE = 0 const TRUE = 1 // // 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 // // Buffer to void checks in octant caster // byte[scrnwidth] linebuffer word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer word[] screen 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 word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer // // 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 = open(@catacomb, O_READ) if mapref newline(mapref, $7F, $0D) for row = 1 to maprows - 2 l = read(mapref, map + (row << 6) + 1, mapcols) ^(map + (row << 6) + l) = WALL_TILE next 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) 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) 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 word imap, tmap byte xmap, ymap, xt, yt for ymap = 1 to maprows - 2 for xmap = 1 to mapcols - 2 imap = (ymap << rowshift) + xmap if ^(map + imap) & MAP_TILE == TORCH_TILE for yt = ymap - 1 to ymap + 1 for xt = xmap - 1 to xmap + 1 tmap = (yt << rowshift) + xt ^(map + tmap) = ^(map + tmap) | LIT_TILE next next fin next if not (ymap & 7) putc('.') fin next 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 o, l, dist, tile, adjtile, occluded, darkness word ymap, xmap, imap byte yscr, xscr if viewdist > beamdepth viewdist = beamdepth fin if lightdist > viewdist lightdist = viewdist fin // // Clear screen // home() // // Draw background map if in light // darkness = 1 imap = (yorg << rowshift) + xorg if ^(map + imap) & LIT_TILE or lightdist // // 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]] = tile & INV_TILE fin else vispix[l] = 0 fin next // // Run through visible octant beam points // for l = l 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]] = tile & INV_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 = dist + 1 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]] = tile & INV_TILE fin else vispix[l] = 0 fin next for l = l 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]] = tile & INV_TILE darkness = 0 fin else vispix[l] = 0 fin if l == dbeam[dist] if occluded break fin occluded = 1 dist = dist + 1 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]] = tile & INV_TILE fin else vispix[l] = 0 fin next for l = l 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]] = tile & INV_TILE darkness = 0 fin else vispix[l] = 0 fin if l == dbeam[dist] if occluded break fin occluded = 1 dist = dist + 1 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]] = tile & INV_TILE fin else vispix[l] = 0 fin next for l = l 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]] = tile & INV_TILE darkness = 0 fin else vispix[l] = 0 fin if l == dbeam[dist] if occluded break fin occluded = 1 dist = dist + 1 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]] = tile & INV_TILE fin else vispix[l] = 0 fin next for l = l 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]] = tile & INV_TILE darkness = 0 fin else vispix[l] = 0 fin if l == dbeam[dist] if occluded break fin occluded = 1 dist = dist + 1 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]] = tile & INV_TILE fin else vispix[l] = 0 fin next for l = l 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]] = tile & INV_TILE darkness = 0 fin else vispix[l] = 0 fin if l == dbeam[dist] if occluded break fin occluded = 1 dist = dist + 1 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]] = tile & INV_TILE fin else vispix[l] = 0 fin next for l = l 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]] = tile & INV_TILE darkness = 0 fin else vispix[l] = 0 fin if l == dbeam[dist] if occluded break fin occluded = 1 dist = dist + 1 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]] = tile & INV_TILE fin else vispix[l] = 0 fin next for l = l 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]] = tile & INV_TILE darkness = 0 fin else vispix[l] = 0 fin if l == dbeam[dist] if occluded break fin occluded = 1 dist = dist + 1 fin next break wend next return darkness end // // Draw other entities // export def drawvisentity(xofst, yofst, tile) if screen.[ycentr+yofst, xcentr+xofst] < $80 screen.[ycentr+yofst, xcentr+xofst] = tile fin end done