C64_Chaze_In_The_Maze-xcBASIC3/digitaltag3.xcbbas

384 lines
15 KiB
Plaintext

poke 53280, 0: poke 53281, 0
dim mapname as string * 16
print "{WHITE}{CLR}";
input "map name? "; mapname;
memset $d800, 1000, 8
load mapname, 8
'-----------------CONSTANTS--------------------------
const RASTER_LINE = $d011
const WALL = 35 ' "#"
const PLAYER_CHAR = 42 ' "*"
const COMPUTER_CHAR = 0 ' "@"
const EMPTY_CHAR = 32 ' " "
const PLAYERSTART_X = 1 : const PLAYERSTART_Y = 1
const COMPUTERSTART_X = 38 : const COMPUTERSTART_Y = 23
const MAXDIR = 3
CONST JOY2 = $dc00
'----------------------------------------------------
'---------------INITIALIZATION-----------------------
Dim tPlayer_x as BYTE : Dim tPlayer_y as BYTE : Dim tPlayer_x_Old as BYTE : Dim tPlayer_y_Old as BYTE
tPlayer_x = PLAYERSTART_X : tPlayer_y = PLAYERSTART_Y : tPlayer_x_Old = PLAYERSTART_X : tPlayer_y_Old = PLAYERSTART_Y
Dim tComputer_x as BYTE : Dim tComputer_y as BYTE : Dim tComputer_x_Old as BYTE : Dim tComputer_y_Old as BYTE
tComputer_x = COMPUTERSTART_X : tComputer_y = COMPUTERSTART_Y : tComputer_x_Old = COMPUTERSTART_X : tComputer_y_Old = COMPUTERSTART_Y
Dim tFuturePoint_x as BYTE fast : Dim tFuturePoint_y as BYTE fast : Dim tFuturePoint_Direction as BYTE fast
tFuturePoint_x = 0: tFuturePoint_y = 0 : tFuturePoint_Direction = 0
Dim bMoveNow as BYTE : bMoveNow = 0
Dim tVecComputerPlayer_Xdiff as INT : Dim tVecComputerPlayer_Ydiff as INT : Dim tVecComputerPlayer_XdiffABS as INT : Dim tVecComputerPlayer_YdiffABS as INT
tVecComputerPlayer_Xdiff = 0 : tVecComputerPlayer_Ydiff = 0 : tVecComputerPlayer_XdiffABS = 0 : tVecComputerPlayer_YdiffABS = 0
Dim tVecSimulToPlayer_Xdiff as INT : Dim tVecSimulToPlayer_Ydiff as INT
tVecSimulToPlayer_Xdiff = 0 : tVecSimulToPlayer_Ydiff = 0
Dim tVectorDir_X as BYTE : Dim tVectorDir_Y as BYTE
tVectorDir_X = 0 : tVectorDir_Y = 0
Dim tWallVectorDir_X as BYTE : Dim tWallVectorDir_Y as BYTE
tWallVectorDir_X = 0 : tWallVectorDir_Y = 0
Dim tWallPosition_Y as BYTE : Dim tWallPosition_X as BYTE
tWallPosition_Y = 0 : tWallPosition_X = 0
Dim nBresenhamDiff as INT : nBresenhamDiff = 0
Dim bLineMoreVertical as BYTE : bLineMoreVertical = 0
Dim nDirectionScalar as BYTE
nDirectionScalar = 0
Dim bWllFllwMode as BYTE : bWllFllwMode = 0
Dim bStrictExitMode as BYTE : bStrictExitMode = 0
dim nSimulatorNumber as BYTE fast : nSimulatorNumber = 0
dim aSimulators_Y(2) as BYTE: dim aSimulators_X(2) as BYTE: dim aSimulators_WalkDir(2) as BYTE: dim aSimulators_StartWalkDir(2) as BYTE
Dim scrAddrCache(25) as WORD @loc_scrAddrCache
loc_scrAddrCache:
DATA AS WORD 1024, 1064, 1104, 1144, 1184, 1224, 1264, 1304, 1344, 1384
DATA AS WORD 1424, 1464, 1504, 1544, 1584, 1624, 1664, 1704, 1744, 1784
DATA AS WORD 1824, 1864, 1904, 1944, 1984
Dim bresenCache(25) as WORD @loc_bresenCache
loc_bresenCache:
DATA AS WORD 49152, 49192, 49232, 49272, 49312, 49352, 49392, 49432, 49472, 49512
DATA AS WORD 49552, 49592, 49632, 49672, 49712, 49752, 49792, 49832, 49872, 49912
DATA AS WORD 49952, 49992, 50032, 50072, 50112
dim JoyValue as BYTE
'----------------------------------------------------
'------------------FUNCTIONS-------------------------
function screen_peek as BYTE(screen_x as BYTE, screen_y as BYTE) STATIC
return peek(scrAddrCache(screen_y) + screen_x)
end function
sub plotLine(x0 as INT, y0 as INT, x1 as INT, y1 as INT) STATIC
Dim dx as INT : dx = abs(x1 - x0)
Dim sx as INT : sx = -1 : if x0 < x1 then sx = 1 ' sx = x0 < x1 ? 1 : -1
Dim dy as INT : dy = cint(0) - abs(y1 - y0)
Dim sy as INT : sy = -1 : if y0 < y1 then sy = 1 ' sy = y0 < y1 ? 1 : -1
Dim brError as INT : brError = dx + dy
Dim e2 as INT
plotLine_whiletrue:
poke bresenCache(y0) + x0, 1 'plot(x0, y0)
if x0 = x1 AND y0 = y1 then exit sub
e2 = shl(brError, 1) '2 * brError
if e2 >= dy then
if x0 = x1 then exit sub
brError = brError + dy
x0 = x0 + sx
end if
if e2 <= dx then
if y0 = y1 then exit sub
brError = brError + dx
y0 = y0 + sy
end if
goto plotLine_whiletrue
end sub
'----------------------------------------------------
'---------------MAIN LOOP----------------------------
' *** DRAW ***
mainLoop:
if tPlayer_x <> tPlayer_x_Old or tPlayer_y <> tPlayer_y_Old then
charat tPlayer_x_Old, tPlayer_y_Old, EMPTY_CHAR
tPlayer_x_Old = tPlayer_x : tPlayer_y_Old = tPlayer_y
end if
if tComputer_x <> tComputer_x_Old or tComputer_y <> tComputer_y_Old then
charat tComputer_x_Old, tComputer_y_Old, EMPTY_CHAR
tComputer_x_Old = tComputer_x : tComputer_y_Old = tComputer_y
end if
charat tPlayer_x, tPlayer_y, PLAYER_CHAR, 1 ' 1 = white
charat tComputer_x, tComputer_y, COMPUTER_CHAR, 13 ' 13 = cyan
'Pauses for 2 frames
wait RASTER_LINE, 128 : wait RASTER_LINE, 128, 128 : wait RASTER_LINE, 128 : wait RASTER_LINE, 128, 128
' *** PLAYER MOVEMENT ***
tFuturePoint_x = tPlayer_x : tFuturePoint_y = tPlayer_y
JoyValue = peek(JOY2)
if (JoyValue AND 1) XOR 1 then tFuturePoint_y = tFuturePoint_y - 1 'UP
if (JoyValue AND 2) XOR 2 then tFuturePoint_y = tFuturePoint_y + 1 'DOWN
if (JoyValue AND 4) XOR 4 then tFuturePoint_x = tFuturePoint_x - 1 'LEFT
if (JoyValue AND 8) XOR 8 then tFuturePoint_x = tFuturePoint_x + 1 'RIGHT
if screen_peek(tPlayer_x, tFuturePoint_y) <> WALL Then tPlayer_y = tFuturePoint_y
if screen_peek(tFuturePoint_x, tPlayer_y) <> WALL Then tPlayer_x = tFuturePoint_x
' *** COMPUTER MOVEMENT ***
on bMoveNow goto skipMovement, doMovement
doMovement:
on bWllFllwMode goto WallFollowFalse, WallFollowTrue
WallFollowFalse:
tVecComputerPlayer_Xdiff = cint(tPlayer_x) - tComputer_x
tVecComputerPlayer_XdiffABS = abs(tVecComputerPlayer_Xdiff)
tVecComputerPlayer_Ydiff = cint(tPlayer_y) - tComputer_y
tVecComputerPlayer_YdiffABS = abs(tVecComputerPlayer_Ydiff)
if tVecComputerPlayer_YdiffABS >= tVecComputerPlayer_XdiffABS Then bLineMoreVertical = 1 Else bLineMoreVertical = 0
tVectorDir_X = cbyte(sgn(tVecComputerPlayer_Xdiff))
tVectorDir_Y = cbyte(sgn(tVecComputerPlayer_Ydiff))
on bLineMoreVertical goto BresenhamHorizontal, BresenhamVertical
BresenhamVertical:
nBresenhamDiff = shl(tVecComputerPlayer_XdiffABS, 1) - tVecComputerPlayer_YdiffABS
goto BresenhamEnd
BresenhamHorizontal:
nBresenhamDiff = shl(tVecComputerPlayer_YdiffABS, 1) - tVecComputerPlayer_XdiffABS
BresenhamEnd:
if nBresenhamDiff <= 0 then
on bLineMoreVertical goto LineMoreVerticalFalse, LineMoreVerticalTrue
LineMoreVerticalFalse:
tVectorDir_Y = 0
goto LineMoreVerticalEnd
LineMoreVerticalTrue:
tVectorDir_X = 0
LineMoreVerticalEnd:
end if
tFuturePoint_y = tComputer_y + tVectorDir_Y
if screen_peek(tComputer_x, tFuturePoint_y) = WALL then
tWallVectorDir_Y = tVectorDir_Y
else
tWallVectorDir_Y = 0
end if
tFuturePoint_x = tComputer_x + tVectorDir_X
if screen_peek(tFuturePoint_x, tComputer_y) = WALL then
tWallVectorDir_X = tVectorDir_X
else
tWallVectorDir_X = 0
end if
if tWallVectorDir_Y <> 0 and tWallVectorDir_X <> 0 then
on bLineMoreVertical goto WallVectorHorizontal, WallVectorVertical
WallVectorHorizontal:
tWallVectorDir_Y = 0
goto WallVectorEnd
WallVectorVertical:
tWallVectorDir_X = 0
WallVectorEnd:
end if
if tWallVectorDir_X <> 0 or tWallVectorDir_Y <> 0 then
'-------------------------- WALL HANDLING -------------------------
on tWallVectorDir_Y + 1 goto wallNorth, noYwall, wallSouth ' -1, 0, 1
wallNorth:
nDirectionScalar = 0 'north
goto DirectionScalarFound
wallSouth:
nDirectionScalar = 2 'south
goto DirectionScalarFound
noYwall:
on tWallVectorDir_X + 1 goto wallWest, DirectionScalarFound, wallEast ' -1, 0, 1
wallWest:
nDirectionScalar = 3 'west
goto DirectionScalarFound
wallEast:
nDirectionScalar = 1 'east
DirectionScalarFound:
tWallPosition_Y = tComputer_y + tWallVectorDir_Y
tWallPosition_X = tComputer_x + tWallVectorDir_X
memset 49152, 1000, 0
call plotLine(tWallPosition_X, tWallPosition_Y, tPlayer_x, tPlayer_y)
'Simulator INIT
aSimulators_Y(0) = tComputer_y
aSimulators_X(0) = tComputer_x
aSimulators_WalkDir(0) = (nDirectionScalar + 1) AND MAXDIR
aSimulators_StartWalkDir(0) = aSimulators_WalkDir(0)
aSimulators_Y(1) = tComputer_y
aSimulators_X(1) = tComputer_x
aSimulators_WalkDir(1) = (nDirectionScalar - 1) AND MAXDIR
aSimulators_StartWalkDir(1) = aSimulators_WalkDir(1)
'Simulator LAUNCH
nSimulatorNumber = 0
SimulatorLoopStart:
tFuturePoint_Direction = aSimulators_WalkDir(nSimulatorNumber)
CheckWallStartLoop:
tFuturePoint_y = aSimulators_Y(nSimulatorNumber)
tFuturePoint_x = aSimulators_X(nSimulatorNumber)
on tFuturePoint_Direction goto SimulDirNorth, SimulDirEast, SimulDirSouth, SimulDirWest
SimulDirNorth:
tFuturePoint_y = tFuturePoint_y - 1
goto SimulDirExit
SimulDirEast:
tFuturePoint_x = tFuturePoint_x + 1
goto SimulDirExit
SimulDirSouth:
tFuturePoint_y = tFuturePoint_y + 1
goto SimulDirExit
SimulDirWest:
tFuturePoint_x = tFuturePoint_x - 1
SimulDirExit:
if peek(scrAddrCache(tFuturePoint_y) + tFuturePoint_x) <> WALL Then Goto CheckWallExitLoop
on nSimulatorNumber goto WalkDirIncrease, WalkDirDecrease
WalkDirIncrease:
tFuturePoint_Direction = (tFuturePoint_Direction + 1) AND MAXDIR
goto WalkDirEndOnGoTo
WalkDirDecrease:
tFuturePoint_Direction = (tFuturePoint_Direction - 1) AND MAXDIR
WalkDirEndOnGoTo:
goto CheckWallStartLoop
CheckWallExitLoop:
aSimulators_Y(nSimulatorNumber) = tFuturePoint_y
aSimulators_X(nSimulatorNumber) = tFuturePoint_x
if peek(bresenCache(tFuturePoint_y) + tFuturePoint_x) = 1 then goto SimulatorLoopExit
on nSimulatorNumber goto WalkDirDecrAgainstWall, WalkDirIncrAgainstWall
WalkDirDecrAgainstWall:
tFuturePoint_Direction = (tFuturePoint_Direction - 1) AND MAXDIR
goto WalkDirAgainstWallEnd
WalkDirIncrAgainstWall:
tFuturePoint_Direction = (tFuturePoint_Direction + 1) AND MAXDIR
WalkDirAgainstWallEnd:
aSimulators_WalkDir(nSimulatorNumber) = tFuturePoint_Direction
nSimulatorNumber = nSimulatorNumber XOR 1 'Alternates 1, 0, 1, 0, ...
goto SimulatorLoopStart
SimulatorLoopExit:
bWllFllwMode = 1
bStrictExitMode = 1
nDirectionScalar = aSimulators_StartWalkDir(nSimulatorNumber) ' ReUse!
else 'if tWallVectorDir_X <> 0 or tWallVectorDir_Y <> 0 then
if screen_peek(tFuturePoint_x, tFuturePoint_y) = WALL then
on bLineMoreVertical goto DiagonalHorizontal, DiagonalVertical
DiagonalHorizontal:
tFuturePoint_y = tComputer_y
goto DiagonalEnd
DiagonalVertical:
tFuturePoint_x = tComputer_x
DiagonalEnd:
end if
tComputer_y = tFuturePoint_y
tComputer_x = tFuturePoint_x
goto skipMovement
end if 'if tWallVectorDir_X <> 0 or tWallVectorDir_Y <> 0 then
WallFollowTrue:
WllFllwCheckWallStartLoop:
tFuturePoint_y = tComputer_y
tFuturePoint_x = tComputer_x
on nDirectionScalar goto ComputerNorth, ComputerEast, ComputerSouth, ComputerWest
ComputerNorth:
tFuturePoint_y = tFuturePoint_y - 1
goto ComputerDirEnd
ComputerEast:
tFuturePoint_x = tFuturePoint_x + 1
goto ComputerDirEnd
ComputerSouth:
tFuturePoint_y = tFuturePoint_y + 1
goto ComputerDirEnd
ComputerWest:
tFuturePoint_x = tFuturePoint_x - 1
ComputerDirEnd:
if screen_peek(tFuturePoint_x, tFuturePoint_y) <> WALL Then Goto WllFllwCheckWallExitLoop
on nSimulatorNumber goto ComputerIncrease, ComputerDecrease
ComputerIncrease:
nDirectionScalar = (nDirectionScalar + 1) AND MAXDIR
goto ComputerDirEndOnGoTo
ComputerDecrease:
nDirectionScalar = (nDirectionScalar - 1) AND MAXDIR
ComputerDirEndOnGoTo:
goto WllFllwCheckWallStartLoop
WllFllwCheckWallExitLoop:
tComputer_y = tFuturePoint_y
tComputer_x = tFuturePoint_x
on bStrictExitMode goto skipStrictExit, checkStrictExit
checkStrictExit:
if tWallVectorDir_Y <> 0 and tComputer_y = tWallPosition_Y then
bStrictExitMode = 0
else
if tWallVectorDir_X <> 0 and tComputer_x = tWallPosition_X then
bStrictExitMode = 0
end if
end if
skipStrictExit:
tVecSimulToPlayer_Ydiff = abs(cint(tPlayer_y) - aSimulators_Y(nSimulatorNumber))
tVecSimulToPlayer_Xdiff = abs(cint(tPlayer_x) - aSimulators_X(nSimulatorNumber))
tVecComputerPlayer_Ydiff = abs(cint(tPlayer_y) - tComputer_y)
tVecComputerPlayer_Xdiff = abs(cint(tPlayer_x) - tComputer_x)
'DEBUG: let me see where the simulator is, 19 = "S"
'charat aSimulators_X(nSimulatorNumber), aSimulators_Y(nSimulatorNumber), 19
on bStrictExitMode goto StrictExitModeOff, StrictExitModeOn
StrictExitModeOff:
'DEBUG: let me see the wall Computer bumped into, in yellow
'charat tWallPosition_X, tWallPosition_Y, WALL, 7
if tVecComputerPlayer_Ydiff + tVecComputerPlayer_Xdiff <= tVecSimulToPlayer_Ydiff + tVecSimulToPlayer_Xdiff Then
bWllFllwMode = 0 ' *** EXITING FROM WALL FOLLOWING MODE! ***
'DEBUG: turn off simulator and wall
'charat aSimulators_X(nSimulatorNumber), aSimulators_Y(nSimulatorNumber), 32
'charat tWallPosition_X, tWallPosition_Y, WALL, 8
goto skipMovement
end if
goto StrictExitModeEnd
StrictExitModeOn:
'DEBUG: let me see the wall Computer bumped into, in white
'charat tWallPosition_X, tWallPosition_Y, WALL, 1
if tVecComputerPlayer_Ydiff <= tVecSimulToPlayer_Ydiff then
if tVecComputerPlayer_Xdiff <= tVecSimulToPlayer_Xdiff then
bWllFllwMode = 0 ' *** EXITING FROM WALL FOLLOWING MODE! ***
'DEBUG: turn off simulator and wall
'charat aSimulators_X(nSimulatorNumber), aSimulators_Y(nSimulatorNumber), 32
'charat tWallPosition_X, tWallPosition_Y, WALL, 8
goto skipMovement
end if
end if
StrictExitModeEnd:
on nSimulatorNumber goto ComputerDecrAgainstWall, ComputerIncrAgainstWall
ComputerDecrAgainstWall:
nDirectionScalar = (nDirectionScalar - 1) AND MAXDIR
goto ComputerAgainstWallEnd
ComputerIncrAgainstWall:
nDirectionScalar = (nDirectionScalar + 1) AND MAXDIR
ComputerAgainstWallEnd:
skipMovement:
bMoveNow = bMoveNow XOR 1 'Alternating 0, 1, 0, 1, 0, 1, ...
goto mainLoop
'----------------------------------------------------