1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-03-23 07:35:00 +00:00

Buffer screen updates for better visual appearance

This commit is contained in:
David Schmenk 2023-04-11 16:28:08 -07:00
parent 37f906d5a6
commit e47ca69101
2 changed files with 140 additions and 48 deletions

View File

@ -24,6 +24,12 @@ byte = " Artwork by Seth Sternberger\n"
byte = ""
word titlestr = @initstr
//
// Animated tile sequence
//
byte animseq = 0
//
// Octant beam parameters
//
@ -120,7 +126,8 @@ const mapsize = maprows*mapcols
const WALL_TILE = '#'
const FLOOR_TILE = '.'
const TORCH_TILE = '*'
const TORCH1_TILE = '*'
const TORCH2_TILE = 'X'
const PIT_TILE = ' '
const DOOR_TILE = '+'
const LOCKED_TILE = '%'
@ -146,6 +153,12 @@ const ycentr = 12
const scrnwidth = 40
const scrnheight = 22
//
// Screen buffer
//
byte[scrnheight * scrnwidth] screenbuffer
//
// Buffer to void checks in octant caster
//
@ -155,14 +168,20 @@ 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[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
//
@ -234,17 +253,19 @@ end
//
export def lighttorches#0
word imap, tmap
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 = (ymap << rowshift) + xmap
if ^(map + imap) & MAP_TILE == TORCH_TILE
imap = rowmap + xmap
if ^imap & MAP_TILE == TORCH1_TILE // or ^imap & MAP_TILE == TORCH2_TILE
for yt = ymap - 1 to ymap + 1
imap = map + (yt << rowshift)
for xt = xmap - 1 to xmap + 1
tmap = (yt << rowshift) + xt
^(map + tmap) = ^(map + tmap) | LIT_TILE
tmap = imap + xt
^tmap = ^tmap | LIT_TILE
next
next
fin
@ -255,6 +276,30 @@ export def lighttorches#0
next
end
//
// Animate tiles in map
//
export def animate(tile)
if animseq
when tile & MAP_TILE
is TORCH1_TILE
tile = TORCH2_TILE
break
is TORCH2_TILE
tile = TORCH1_TILE
break
is WATER1_TILE
tile = WATER2_TILE
break
is WATER2_TILE
tile = WATER1_TILE
break
wend
fin
return tile & INV_TILE
end
//
// Draw the map. Return 0 if any light visible, 1 if in complete darkness
//
@ -273,7 +318,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
//
// Clear screen
//
conio:home()
memset(@screenbuffer, $A0A0, scrnheight * scrnwidth)
//
// Draw background map if in light
//
@ -349,7 +394,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
//
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr-ybeam[l], xcentr+xbeam[l]] = tile & INV_TILE
screen.[ycentr-ybeam[l], xcentr+xbeam[l]] = animate(tile)
fin
else
vispix[l] = 0
@ -382,7 +427,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
//
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr-ybeam[l], xcentr+xbeam[l]] = tile & INV_TILE
screen.[ycentr-ybeam[l], xcentr+xbeam[l]] = animate(tile)
darkness = 0
fin
else
@ -402,7 +447,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
// Update distance
//
occluded = 1
dist = dist + 1
dist++
fin
next
break
@ -423,7 +468,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr-xbeam[l], xcentr+ybeam[l]] = tile & INV_TILE
screen.[ycentr-xbeam[l], xcentr+ybeam[l]] = animate(tile)
fin
else
vispix[l] = 0
@ -441,7 +486,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr-xbeam[l], xcentr+ybeam[l]] = tile & INV_TILE
screen.[ycentr-xbeam[l], xcentr+ybeam[l]] = animate(tile)
darkness = 0
fin
else
@ -452,7 +497,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
break
fin
occluded = 1
dist = dist + 1
dist++
fin
next
break
@ -473,7 +518,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr+xbeam[l], xcentr+ybeam[l]] = tile & INV_TILE
screen.[ycentr+xbeam[l], xcentr+ybeam[l]] = animate(tile)
fin
else
vispix[l] = 0
@ -491,7 +536,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr+xbeam[l], xcentr+ybeam[l]] = tile & INV_TILE
screen.[ycentr+xbeam[l], xcentr+ybeam[l]] = animate(tile)
darkness = 0
fin
else
@ -502,7 +547,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
break
fin
occluded = 1
dist = dist + 1
dist++
fin
next
break
@ -523,7 +568,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr+ybeam[l], xcentr+xbeam[l]] = tile & INV_TILE
screen.[ycentr+ybeam[l], xcentr+xbeam[l]] = animate(tile)
fin
else
vispix[l] = 0
@ -541,7 +586,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr+ybeam[l], xcentr+xbeam[l]] = tile & INV_TILE
screen.[ycentr+ybeam[l], xcentr+xbeam[l]] = animate(tile)
darkness = 0
fin
else
@ -552,7 +597,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
break
fin
occluded = 1
dist = dist + 1
dist++
fin
next
break
@ -573,7 +618,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr+ybeam[l], xcentr-xbeam[l]] = tile & INV_TILE
screen.[ycentr+ybeam[l], xcentr-xbeam[l]] = animate(tile)
fin
else
vispix[l] = 0
@ -591,7 +636,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr+ybeam[l], xcentr-xbeam[l]] = tile & INV_TILE
screen.[ycentr+ybeam[l], xcentr-xbeam[l]] = animate(tile)
darkness = 0
fin
else
@ -602,7 +647,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
break
fin
occluded = 1
dist = dist + 1
dist++
fin
next
break
@ -623,7 +668,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr+xbeam[l], xcentr-ybeam[l]] = tile & INV_TILE
screen.[ycentr+xbeam[l], xcentr-ybeam[l]] = animate(tile)
fin
else
vispix[l] = 0
@ -641,7 +686,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr+xbeam[l], xcentr-ybeam[l]] = tile & INV_TILE
screen.[ycentr+xbeam[l], xcentr-ybeam[l]] = animate(tile)
darkness = 0
fin
else
@ -652,7 +697,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
break
fin
occluded = 1
dist = dist + 1
dist++
fin
next
break
@ -673,7 +718,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr-xbeam[l], xcentr-ybeam[l]] = tile & INV_TILE
screen.[ycentr-xbeam[l], xcentr-ybeam[l]] = animate(tile)
fin
else
vispix[l] = 0
@ -691,7 +736,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr-xbeam[l], xcentr-ybeam[l]] = tile & INV_TILE
screen.[ycentr-xbeam[l], xcentr-ybeam[l]] = animate(tile)
darkness = 0
fin
else
@ -702,7 +747,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
break
fin
occluded = 1
dist = dist + 1
dist++
fin
next
break
@ -723,7 +768,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
^(viewmap + imap) = tile | VIEWED_TILE
if tile <> PIT_TILE
screen.[ycentr-ybeam[l], xcentr-xbeam[l]] = tile & INV_TILE
screen.[ycentr-ybeam[l], xcentr-xbeam[l]] = animate(tile)
fin
else
vispix[l] = 0
@ -741,7 +786,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
fin
if tile & LIT_TILE
^(viewmap + imap) = tile | VIEWED_TILE
screen.[ycentr-ybeam[l], xcentr-xbeam[l]] = tile & INV_TILE
screen.[ycentr-ybeam[l], xcentr-xbeam[l]] = animate(tile)
darkness = 0
fin
else
@ -752,12 +797,13 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
break
fin
occluded = 1
dist = dist + 1
dist++
fin
next
break
wend
next
animseq = animseq ^ 1 // Update animation sequence
return darkness
end
@ -771,6 +817,22 @@ export def drawvisentity(xofst, yofst, tile)#0
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
//
@ -780,5 +842,7 @@ while ^titlestr
puts(titlestr)
titlestr = titlestr + ^titlestr + 1
loop
for titlestr = 0 to scrnheight - 1
screen[titlestr] = @screenbuffer + titlestr * scrnwidth
next
done

View File

@ -12,7 +12,8 @@ import roguemap
const FLOOR_TILE = '.'
const WALL_TILE = '#'
const TORCH_TILE = '*'
const TORCH1_TILE = '*'
const TORCH2_TILE = 'X'
const PIT_TILE = ' '
const DOOR_TILE = '+'
const LOCKED_TILE = '%'
@ -33,7 +34,8 @@ import roguemap
predef loadmap(level), getmaptile(xmap, ymap), setmaptile(xmap, ymap, tile)#0
predef updtmaptile(xmap, ymap, tile)#0, lighttorches#0
predef drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist)
predef drawvisentity(xofst, yofst, tile)#0
predef drawvisentity(xofst, yofst, tile)#0, drawplayer(tile)#0
predef updatescreen#0
end
import roguecombat
@ -198,6 +200,7 @@ end
//
def status#0
memset($07D0, $A0A0, 40)
conio:gotoxy(0, statusline)
puts(@helthstr)
puti(player.health)
@ -248,7 +251,8 @@ def moveplayer(dir)#0
break
fin
is FLOOR_TILE
is TORCH_TILE
is TORCH1_TILE
is TORCH2_TILE
is KEY_TILE
is RAFT_TILE
is GOLD_TILE
@ -423,7 +427,8 @@ def moveentities(playerisvis)#0
fin
when getmaptile(xmove, ymove) & MAP_TILE
is FLOOR_TILE
is TORCH_TILE
is TORCH1_TILE
is TORCH2_TILE
is KEY_TILE
is GOLD_TILE
is FOOD_TILE
@ -449,10 +454,37 @@ def moveentities(playerisvis)#0
loop
end
//
// Draw entire map view
//
def drawview#0
totaldarkness = drawmap(player.xpos, player.ypos, player.fov, player.angle, player.lamp, maxview)
if not totaldarkness
drawentities
drawplayer(vplayer[player.angle])
fin
updatescreen
end
//
// Read player input and do something
//
def waitkey
word delay
delay = 200
while not conio:keypressed()
delay--
if delay == 0
drawview
delay = 200
fin
loop
return toupper(conio:getkey())
end
def play
byte xt, yt
@ -460,7 +492,7 @@ def play
return FALSE
fin
conio:gotoxy(xcentr, ycentr)
when toupper(conio:getkey())
when waitkey
is 'I'
if totaldarkness
player.angle = conio:rnd() & 7
@ -547,7 +579,8 @@ def play
updtmaptile(player.xpos, player.ypos, FLOOR_TILE)
gotit
break
is TORCH_TILE
is TORCH1_TILE
is TORCH2_TILE
if player.oil < 1000
player:oil = player:oil + TORCH_OIL
if player:oil > 1000
@ -633,12 +666,7 @@ while loadmap(level)
lighttorches
repeat
moveentities(player.lamp or getmaptile(player.xpos, player.ypos) & LIT_TILE))
totaldarkness = drawmap(player.xpos, player.ypos, player.fov, player.angle, player.lamp, maxview)
if not totaldarkness
drawentities
conio:gotoxy(xcentr, ycentr)
putc(vplayer[player.angle])
fin
drawview
status
until not play
heaprelease(free_entities)