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 '----------------------------------------------------