384 lines
15 KiB
Plaintext
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
|
||
|
'----------------------------------------------------
|
||
|
|