'*********************************************************************** '** SUPERCHASE ** '** REMIX! ** '** ** '** 3 different versions of the same game into one program! ** '** ** '** - Original VIC-20 version by Anthony Godshall - October 1982 ** '** - Atari version by someone @ Compute! Gazette ** '** - TI-99 4/A version by Cheryl Regena ** '** ** '** Written in XC-BASIC 3.0.8 by @JJFlash@mastodon.social - Sep 2022 ** '** XC-BASIC created by Csaba Fekete! - https://xc-basic.net/ ** '** ** '** WORK IN PROGRESS!! ** '*********************************************************************** '--------------INITIAL-SETUP-------------------------------------------- Dim scrAddrCache(25) as WORD @loc_scrAddrCache ' 0 -> 24 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 poke 53280, 0 : poke 53281, 0 memcpy @LOC_charset_addr, $3800, 1024 poke $D018, 31 'final character location: $3800 poke 657, 128 'disable upper-lower case change Dim wStack(128) as WORD @LOC_charset_addr 'recycling the charset data already copied to the final location! '----------------------------------------------------------------------- '-------------CONSTANTS------------------------------------------------- Const TRUE = 255 Const FALSE = 0 Const INIT = 255 Const GO_ON = 0 Const SPACE = 88 Const MARKED_SPACE = 89 Const WALL = 96 Const EX_WALL = 98 Const DOOR_CLOSED = 97 Const DOOR_CLOSED_REVERSED = 101 Const DOOR_OPEN = 99 Const DOOR_OPEN_REVERSED = 103 Const PLAYER = 64 Const PLAYER_LEFT = 66 Const MONSTER = 68 Const MONSTER_ALT = 69 Const TRAIL = 80 Const TREASURES = 112 Const TREASURE_GOLD = 116 Const EAST = 0 Const NORTH = 1 Const WEST = 2 Const SOUTH = 3 Const MASK_WALKABLE = 16 '0001 0000 Const MASK_ALL = 48 '0011 0000 Const MASK_SUBGROUP = 8 '0000 1000 Const MASK_ALL_SUBGROUP = 56 '0011 1000 Const MASK_TILE = 7 '0000 0111 Const GROUP_CREATURES = 0 '0000 0000 Const GROUP_WALKABLE = 16 '0001 0000 '~ Const GROUP_WALLS = 32 '0010 0000 Const GROUP_TREASURE = 48 '0011 0000 Const SUBGROUP_TREASURE = 56 '0011 1000 Const VIC_COLOR_OFFSET = $D400 '----------------------------------------------------------------------- '--------------GAME-STATE-&-GLOBAL-STUFF-------------------------------- Dim bPeekedTileContent as BYTE Dim bFrameCounter as BYTE Dim bAnimFrameCounter as BYTE Dim iDirections(4) as INT @loc_iDirections loc_iDirections: DATA as INT 1, -40, -1, 40 'east, north, west, south Dim bPlayer_Col as BYTE Dim bPlayer_Row as BYTE Dim bPlayer_FacingCharacter as BYTE Dim bMonsterIsOn as BYTE Dim bMonster_Col as BYTE Dim bMonster_Row as BYTE Dim bMonster_Direction as BYTE Dim bMonster_Lag as BYTE Dim bMonster_PreviousTile as BYTE Dim bMonster_SpeedUpMode as BYTE Dim bMonster_DelayFrame as BYTE Dim bMonster_Distance_TurnONSpeedUp as BYTE Dim bMonster_Distance_TurnOFFSpeedUp as BYTE Dim bTreasuresToActivateMonster as BYTE Dim bManhattanDistance as BYTE Dim wDoorAddress as WORD Dim wGoldColorAddress as WORD Dim bSkillLevel as BYTE : bSkillLevel = 1 Dim wScore as WORD Dim wLastExitScore as WORD : wLastExitScore = 0 Dim bTreasures_Quantity as BYTE Dim bTreasuresCollected as BYTE Dim bTreasuresToOpenDoor as BYTE Dim bGoldNotCollected as BYTE Dim bPlayerExited as BYTE Dim bPlayerCaught as BYTE declare sub generateMaze () STATIC declare sub placeDoor() STATIC declare sub playerMovement() STATIC declare sub initMonster() STATIC declare sub handleMonster() STATIC declare sub monsterMovement() STATIC declare sub drawInfoBox() STATIC declare sub shakeScreen() STATIC declare sub mazeShiftAway() STATIC declare sub openDoorAnimation() STATIC declare sub goldFlashAnimation(bInitAnim as BYTE) STATIC declare sub titleScreen() STATIC '----------------------------------------------------------------------- '------------------HELPER FUNCTIONS------------------------------------- function myRandom as BYTE (bMax as BYTE, bMask as BYTE) STATIC do myRandom = RNDB() AND bMask loop while myRandom > bMax end function function myByteABS as BYTE (bNumber as BYTE) STATIC if (bNumber AND 128) = 128 then bNumber = (NOT bNumber) + 1 return bNumber end function '------------------TITLE SCREEN----------------------------------------- sys $E544 FAST ' clear screen call titleScreen() '------------------LEVEL-START------------------------------------------ '~ Dim lRandomSeed as LONG : lRandomSeed = clong(248) ' <<<<<<<<<<<<<<<------------- RANDOM!!! sys $E544 FAST ' clear screen textat 32, 0, "super", 1 'white textat 33, 1, "chase!", 1 'white textat 32, 7, "skill", 5 'green textat 33, 8, "level", 5 'green textat 32, 13, "score", 3 'cyan textat 32, 18, "speed", 7 'yellow Randomize (TI() * (clong(peek( $D012)) + clong(1))) redraw: For N as BYTE = 0 to 24 memset scrAddrCache(N), 31, WALL memset VIC_COLOR_OFFSET + scrAddrCache(N), 31, 6 'blue Next N '~ lRandomSeed = lRandomSeed + clong(1) '~ textat 33, 23, str$(lRandomSeed), 14 'light blue '~ Randomize (lRandomSeed) For N as BYTE = 1 to 10 : bPeekedTileContent = RNDB() : Next N ' bPeekedTileContent used here as a dummy variable! call generateMaze() '~ textat 33, 24, str$(bTreasures_Quantity), 7 'yellow call placeDoor() bFrameCounter = 0 bPlayer_Col = 1 bPlayer_Row = 1 bPlayer_FacingCharacter = PLAYER call initMonster() wScore = wLastExitScore bTreasuresCollected = 0 bPlayerExited = FALSE bPlayerCaught = FALSE textat 33, 10, str$(bSkillLevel), 1 'white memset 1657, 5, 32 'erase previous printed score textat 33, 15, str$(wScore), 10 'light red textat 33, 20, "1 ", 2 'red bTreasuresToOpenDoor = shr(bTreasures_Quantity, 1) if bSkillLevel < bTreasuresToOpenDoor then bTreasuresToOpenDoor = bTreasuresToOpenDoor + bSkillLevel else bTreasuresToOpenDoor = bTreasures_Quantity end if '~ textat 36, 24, str$(bTreasuresToOpenDoor), 12 'gray '-------------------------MAIN LOOP!------------------------------------ do on bFrameCounter goto actorMovement, endFrame, animation, endFrame actorMovement: '-------PLAYER MOVEMENT----------------- call playerMovement() if (bPlayerCaught OR bPlayerExited) then exit do '~ textat 33, 22, str$(bTreasuresCollected) + " ", 15 ' light gray '-------MONSTER MOVEMENT----------------- if bMonsterIsOn then call handleMonster() if bPlayerCaught then exit do else if bTreasuresCollected = bTreasuresToActivateMonster then bMonsterIsOn = TRUE end if if NOT bGoldNotCollected then call goldFlashAnimation(GO_ON) goto endFrame '------------------------------------------------------------------- animation: if bGoldNotCollected then poke wGoldColorAddress, peek(wGoldColorAddress) XOR 6 'alternates white, yellow, white, yellow, ... else call goldFlashAnimation(GO_ON) end if charat bPlayer_Col, bPlayer_Row, bPlayer_FacingCharacter XOR 1, 13 'light green if bMonsterIsOn then if bMonster_SpeedUpMode then call handleMonster() else charat bMonster_Col, bMonster_Row, MONSTER_ALT, 2 'red end if end if if bTreasuresCollected = bTreasuresToOpenDoor then call openDoorAnimation() '------------------------------------------------------------------- endFrame: '~ if (peek ( $DC00) AND 16) = 0 then goto redraw wait $d011, 128, 128 : wait $d011, 128 : wait $d011, 128, 128 : wait $d011, 128 bFrameCounter = (bFrameCounter + 1) AND 3 loop if bPlayerCaught then call shakeScreen() call drawInfoBox() textat 8, 12, "a tasty morsel", 8 'orange textat 12, 13, "indeed!", 8 'orange wScore = wLastExitScore else call drawInfoBox() textat 8, 12, "congratulations!", 7 'yellow textat 6, 13, "onto the next level!", 7 'yellow wLastExitScore = wScore if bSkillLevel < 255 then bSkillLevel = bSkillLevel + 1 end if wait $DC00, 16, 16 'wait for fire to be pressed if bPlayerExited then call mazeShiftAway() goto redraw '------------GAME-SUBROUTINES------------------------------------------- sub generateMaze () STATIC Dim bRow as BYTE Dim bCol as BYTE Dim bRowEnd as BYTE Dim bColEnd as BYTE memset 1065, 5, EX_WALL poke 1105, EX_WALL poke 1145, EX_WALL poke 1185, EX_WALL poke 1225, EX_WALL For N as BYTE = 1 to 65 bCol = shl(myRandom(13, 15), 1) + 1 bRow = shl(myRandom(11, 15), 1) + 1 bColEnd = bCol + 6 : if bColEnd > 29 then bColEnd = 29 memset scrAddrCache(bRow) + bCol, bColEnd - bCol + 1, EX_WALL Next N For N as BYTE = 1 to 60 bCol = shl(myRandom(14, 15), 1) + 1 bRow = shl(myRandom(10, 15), 1) + 1 bRowEnd = bRow + 4 : if bRowEnd > 23 then bRowEnd = 23 For K AS BYTE = bRow to bRowEnd poke scrAddrCache(K) + bCol, EX_WALL Next K Next N Dim wCalcScreenAddress as WORD Dim bStackPointer as BYTE Dim wFilledCells as WORD Dim wPatchScrAddress as WORD bStackPointer = 1 : wFilledCells = 0 wStack(0) = 1065 'player starting position: Row 1, Column 1 wPatchScrAddress = 1226 'row 5, column 2 Const PATCHSCRADDRESS_END = 1253 'row 5, column 29 Dim bTreasures_Color(5) as BYTE @loc_bbTreasures_Color loc_bbTreasures_Color: DATA AS BYTE 12, 9, 10, 8, 7 'gray, brown, light red, orange, yellow Dim bTreasures_Sequence(51) as BYTE @loc_bTreasures_Sequence '26 treasure 0, 15 treasure 1, 12 treasure 2, 7 treasure 3, 1 treasure 4 (gold!) loc_bTreasures_Sequence: '0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 '1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 '2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 '3, 3, 3, 3, 3, 3, 3 ' 4 DATA AS BYTE 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 4 DATA AS BYTE 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 0, 1, 0, 1, 0 Dim bTreasures_Index as BYTE : bTreasures_Index = 0 Dim bTileType as BYTE Dim bTileColor as BYTE bTreasures_Quantity = 0 bGoldNotCollected = FALSE 'in the event the Gold treasure doesn't show up... do bStackPointer = bStackPointer - 1 wCalcScreenAddress = wStack(bStackPointer) do while peek(wCalcScreenAddress) = EX_WALL wCalcScreenAddress = wCalcScreenAddress - cword(1) loop wCalcScreenAddress = wCalcScreenAddress + cword(1) do while peek(wCalcScreenAddress) = EX_WALL bTileType = SPACE if wFilledCells > 5 then If myRandom(5, 7) = 5 then bTileType = TREASURES + bTreasures_Sequence(bTreasures_Index) bTileColor = bTreasures_Color(bTileType AND 7) if bTreasures_Index < 50 then bTreasures_Index = bTreasures_Index + 1 bTreasures_Quantity = bTreasures_Quantity + 1 end if end if if bTileType = TREASURE_GOLD then wGoldColorAddress = VIC_COLOR_OFFSET + wCalcScreenAddress : bGoldNotCollected = TRUE poke wCalcScreenAddress, bTileType : poke VIC_COLOR_OFFSET + wCalcScreenAddress, bTileColor wFilledCells = wFilledCells + 1 wCalcScreenAddress = wCalcScreenAddress - cword(40) 'one row UP if peek(wCalcScreenAddress) = EX_WALL then wStack(bStackPointer) = wCalcScreenAddress bStackPointer = bStackPointer + 1 end if wCalcScreenAddress = wCalcScreenAddress + cword(80) 'back to the original row + one row DOWN if peek(wCalcScreenAddress) = EX_WALL then wStack(bStackPointer) = wCalcScreenAddress bStackPointer = bStackPointer + 1 end if wCalcScreenAddress = wCalcScreenAddress - cword(39) 'one row UP + one column RIGHT loop if bStackPointer = 0 then if wFilledCells < 280 then do until peek(wPatchScrAddress) = WALL wPatchScrAddress = wPatchScrAddress + 1 if wPatchScrAddress > PATCHSCRADDRESS_END then exit sub loop poke wPatchScrAddress, EX_WALL wStack(bStackPointer) = wPatchScrAddress bStackPointer = 1 else exit sub end if end if loop end sub sub placeDoor() STATIC wDoorAddress = $0586 'Col 30, Row 9 do For bRowIncrement AS BYTE = 0 to 22 'row 9 -> 23 + 1 -> 8 if ((peek(wDoorAddress - cword(1)) AND MASK_WALKABLE) = GROUP_WALKABLE) then poke wDoorAddress, DOOR_CLOSED poke VIC_COLOR_OFFSET + wDoorAddress, 14 'light blue exit sub else if bRowIncrement = 14 then wDoorAddress = wDoorAddress - 880 'up 22 rows else wDoorAddress = wDoorAddress + cword(40) 'next row end if end if Next bRowIncrement 'back to row 9? Try the previous column... wDoorAddress = wDoorAddress - cword(1) loop end sub sub playerMovement() STATIC Dim wScoreTable(5) as WORD @loc_wScoreTable loc_wScoreTable: DATA AS WORD 10, 20, 30, 50, 500 Dim bJoystick2 as BYTE bJoystick2 = peek ( $DC00) XOR 127 if (bJoystick2 AND 1) then bJoystick2 = NORTH else if (bJoystick2 AND 2) then bJoystick2 = SOUTH else if (bJoystick2 AND 4) then bJoystick2 = WEST bPlayer_FacingCharacter = PLAYER_LEFT else if (bJoystick2 AND 8) then bJoystick2 = EAST bPlayer_FacingCharacter = PLAYER else exit sub end if end if end if end if bPeekedTileContent = peek(scrAddrCache(bPlayer_Row) + bPlayer_Col + iDirections(bJoystick2)) if (bPeekedTileContent AND MASK_ALL) = GROUP_CREATURES then 'Player bumped into Monster! charat bPlayer_Col, bPlayer_Row, SPACE, 11 'dark grey bPlayerCaught = TRUE : exit sub end if if ((bPeekedTileContent AND MASK_WALKABLE) = GROUP_WALKABLE) OR (bPeekedTileContent = DOOR_OPEN) then charat bPlayer_Col, bPlayer_Row, TRAIL, 11 'dark grey if (bJoystick2 AND 1) then 'odd number, vertical direction bPlayer_Row = bPlayer_Row + cbyte(SGN(iDirections(bJoystick2))) else 'even number, horizontal direction bPlayer_Col = bPlayer_Col + cbyte(iDirections(bJoystick2)) end if charat bPlayer_Col, bPlayer_Row, bPlayer_FacingCharacter, 13 'light green if (bPeekedTileContent AND MASK_ALL) = GROUP_TREASURE Then '~ poke 53280, (bPeekedTileContent AND MASK_TILE) + 1 '~ wait $d011, 128, 128 : wait $d011, 128 : wait $d011, 128, 128 : wait $d011, 128 '~ poke 53280, 0 bTreasuresCollected = bTreasuresCollected + 1 if (bPeekedTileContent AND 247) = TREASURE_GOLD then call goldFlashAnimation(INIT) 'both non-marked and marked! wScore = wScore + wScoreTable ( (bPeekedTileContent AND MASK_TILE) ) textat 33, 15, str$(wScore), 10 'light red else if bPeekedTileContent = DOOR_OPEN then bPlayerExited = TRUE end if end if end sub sub initMonster() STATIC bMonsterIsOn = FALSE if bSkillLevel < 8 then bTreasuresToActivateMonster = 8 - bSkillLevel else bTreasuresToActivateMonster = 1 end if bMonster_Col = 1 bMonster_Row = 1 bMonster_Direction = EAST bMonster_Lag = 10 bMonster_PreviousTile = SPACE bMonster_SpeedUpMode = FALSE if bSkillLevel < 14 then bMonster_Distance_TurnONSpeedUp = 20 - bSkillLevel bMonster_Distance_TurnOFFSpeedUp = 12 - shr(bSkillLevel, 1) else bMonster_Distance_TurnONSpeedUp = 7 bMonster_Distance_TurnOFFSpeedUp = 5 end if bMonster_DelayFrame = 9 '= Lag - 1 '~ textat 33, 3, " " '~ textat 33, 4, " " '~ textat 33, 21, " " end sub sub handleMonster() STATIC Dim bMoveFrame as BYTE bManhattanDistance = myByteABS(bPlayer_Row - bMonster_Row) + myByteABS(bPlayer_Col - bMonster_Col) '~ textat 33, 21, str$(bManhattanDistance) + " ", 11 'dark gray if bManhattanDistance > bMonster_Distance_TurnONSpeedUp then bMonster_SpeedUpMode = TRUE else if bManhattanDistance < bMonster_Distance_TurnOFFSpeedUp then if bMonster_SpeedUpMode then if bMonster_Lag > 1 then bMonster_Lag = bMonster_Lag - 1 textat 33, 20, str$(11 - bMonster_Lag), 2 'red end if bMonster_SpeedUpMode = FALSE end if end if end if if bMonster_SpeedUpMode then call monsterMovement() : exit sub if bMonster_DelayFrame = 0 then call monsterMovement() if bMoveFrame > 0 then bMoveFrame = bMoveFrame - 1 if bMoveFrame = 0 then bMonster_DelayFrame = bMonster_Lag - 1 else bMonster_DelayFrame = bMonster_DelayFrame - 1 if bMonster_DelayFrame = 0 then bMoveFrame = bSkillLevel end if '~ textat 33, 3, str$(bMonster_DelayFrame), 10 'light red '~ textat 33, 4, str$(bMoveFrame) + " ", 13 'light green end sub sub monsterMovement() STATIC Const MINUS_ONE = 255 Dim wPeekingLocation as WORD Dim bMonster_PreviousColour as BYTE Dim bTravelingDirection as BYTE Dim bThisTileDistance as BYTE Dim bClosestDistance as BYTE Dim bThisTileRow as BYTE Dim bThisTileCol as BYTE Dim bClosestTileDirection as BYTE Dim bPeekedDirection as BYTE Dim bWalkableDirections(4) as BYTE '0...3 Dim bWalkableDirections_Count as BYTE Dim bTrailDirections(4) as BYTE '0...3 Dim bTrailDirections_Count as BYTE '------------------------------------------------ wPeekingLocation = scrAddrCache(bMonster_Row) + bMonster_Col bTravelingDirection = bMonster_Direction bWalkableDirections_Count = MINUS_ONE bTrailDirections_Count = MINUS_ONE bClosestDistance = 255 bMonster_Direction = (bMonster_Direction - 1) AND 3 'starting from the Monster's right (going clockwise) For bPeekedDirection = 1 to 4 bPeekedTileContent = peek(wPeekingLocation + iDirections(bMonster_Direction)) if (bPeekedTileContent AND MASK_ALL) = GROUP_CREATURES then bPlayerCaught = TRUE : exit for 'Gotcha, Player!! if (bPeekedTileContent AND MASK_WALKABLE) = GROUP_WALKABLE then '~ if (bPeekedTileContent AND MASK_ALL_SUBGROUP) = GROUP_TRAIL then if bPeekedTileContent = TRAIL then bWalkableDirections_Count = bWalkableDirections_Count + 1 '~ bWalkableDirections(bWalkableDirections_Count) = bMonster_Direction bTrailDirections_Count = bTrailDirections_Count + 1 bTrailDirections(bTrailDirections_Count) = bMonster_Direction else if ((bPeekedTileContent AND MASK_ALL_SUBGROUP) <> SUBGROUP_TREASURE) AND (bPeekedTileContent <> MARKED_SPACE) and bPeekedDirection < 4 then 'ignoring the opposite direction travelled! bWalkableDirections_Count = bWalkableDirections_Count + 1 bWalkableDirections(bWalkableDirections_Count) = bMonster_Direction 'ALSO, find the closest tile to the player... bThisTileRow = bMonster_Row : bThisTileCol = bMonster_Col if (bMonster_Direction AND 1) then 'odd number, vertical direction bThisTileRow = bMonster_Row + cbyte(SGN(iDirections(bMonster_Direction))) else 'even number, horizontal direction bThisTileCol = bMonster_Col + cbyte(iDirections(bMonster_Direction)) end if bThisTileDistance = myByteABS(bPlayer_Row - bThisTileRow) + myByteABS(bPlayer_Col - bThisTileCol) if bThisTileDistance < bClosestDistance then bClosestDistance = bThisTileDistance bClosestTileDirection = bMonster_Direction end if end if end if end if bMonster_Direction = (bMonster_Direction + 1) AND 3 'now going counter-clockwise next bPeekedDirection if bPlayerCaught = FALSE then if bTrailDirections_Count <> MINUS_ONE then bMonster_Direction = bTrailDirections(myRandom(bTrailDirections_Count, 3)) else if bWalkableDirections_Count = MINUS_ONE then bMonster_Direction = (bTravelingDirection + 2) AND 3 'opposite direction else bWalkableDirections_Count = bWalkableDirections_Count + 1 bWalkableDirections(bWalkableDirections_Count) = bClosestTileDirection bMonster_Direction = bWalkableDirections(myRandom(bWalkableDirections_Count, 3)) end if end if end if '------------------------DRAW------------------------------------------- '~ for bMonsterDebug as BYTE = 0 to 3 '~ textat 33, 2 + bMonsterDebug, " " '~ next bMonsterDebug '~ if bWalkableDirections_Count <> MINUS_ONE then '~ for bMonsterDebug as BYTE = 0 to bWalkableDirections_Count '~ if bWalkableDirections(bMonsterDebug) = bMonster_Direction then '~ textat 33, 2 + bMonsterDebug, str$(bWalkableDirections(bMonsterDebug)), 1 'white '~ else '~ textat 33, 2 + bMonsterDebug, str$(bWalkableDirections(bMonsterDebug)), 11 'gray '~ end if '~ next bMonsterDebug '~ end if if (bMonster_PreviousTile AND MASK_ALL) = GROUP_TREASURE then if bWalkableDirections_Count = MINUS_ONE then bMonster_PreviousTile = bMonster_PreviousTile OR MASK_SUBGROUP end if else if bWalkableDirections_Count = MINUS_ONE then bMonster_PreviousTile = MARKED_SPACE else bMonster_PreviousTile = SPACE end if end if if (bMonster_PreviousColour AND 15) = 0 then bMonster_PreviousColour = 14 charat bMonster_Col, bMonster_Row, bMonster_PreviousTile, bMonster_PreviousColour bMonster_PreviousTile = peek(wPeekingLocation + iDirections(bMonster_Direction)) bMonster_PreviousColour = peek(VIC_COLOR_OFFSET + wPeekingLocation + iDirections(bMonster_Direction)) if (bMonster_Direction AND 1) = 1 then 'odd number, vertical direction bMonster_Row = bMonster_Row + cbyte(SGN(iDirections(bMonster_Direction))) else 'even number, horizontal direction bMonster_Col = bMonster_Col + cbyte(iDirections(bMonster_Direction)) end if charat bMonster_Col, bMonster_Row, MONSTER, 2 'red if bWalkableDirections_Count = MINUS_ONE then bMonster_Direction = bTravelingDirection end sub sub drawInfoBox() STATIC '~ textat 4, 11, "{168}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{171}{173}", 6 'blu '~ textat 4, 12, "{169} {174}", 6 'blu '~ textat 4, 13, "{169} {174}", 6 'blu '~ textat 4, 14, "{170}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{172}{175}", 6 'blu poke 1468, 104 'col 4, row 11 memset 1469, 21, 107 'col 5-25, row 11 poke 1490, 109 'col 26, row 11 poke 1508, 105 'col 4, row 12 memset 1509, 21, 32 'col 5-25, row 12 poke 1530, 110 'col 26, row 12 poke 1548, 105 'col 4, row 13 memset 1549, 21, 32 'col 5-25, row 13 poke 1570, 110 'col 26, row 13 poke 1588, 106 'col 4, row 13 memset 1589, 21, 108 'col 5-25, row 13 poke 1610, 111 'col 26, row 13 memset VIC_COLOR_OFFSET + 1468, 23, 6 'blu memset VIC_COLOR_OFFSET + 1508, 23, 6 'blu memset VIC_COLOR_OFFSET + 1548, 23, 6 'blu memset VIC_COLOR_OFFSET + 1588, 23, 6 'blu end sub sub shakeScreen() STATIC Dim bVariance as BYTE : bVariance = 7 bAnimFrameCounter = 0 do poke $D011, %10011000 OR ((3 + myRandom(bVariance, 7)) AND 7) poke $D016, %00001000 OR myRandom(bVariance, 7) wait $d011, 128, 128 : wait $d011, 128 bAnimFrameCounter = (bAnimFrameCounter + 1) AND 3 if bAnimFrameCounter = 0 then bVariance = bVariance - 1 loop until bVariance = 255 end sub sub mazeShiftAway() STATIC dim wLineAddress as WORD : dim wColorLineAddress as WORD wait $d011, 128, 128 : wait $d011, 128 for nShiftColumn as BYTE = 0 to 30 for nShiftLine as BYTE = 0 to 24 wLineAddress = scrAddrCache(nShiftLine) wColorLineAddress = VIC_COLOR_OFFSET + wLineAddress memcpy wLineAddress + 1, wLineAddress, 31 memcpy wColorLineAddress + 1, wColorLineAddress, 31 next nShiftLine wait $d011, 128, 128 : wait $d011, 128 next nShiftColumn end sub sub openDoorAnimation() STATIC For bAnimFrameCounter = 1 to 5 poke wDoorAddress, DOOR_CLOSED_REVERSED poke VIC_COLOR_OFFSET + wDoorAddress, 13 'light green wait $d011, 128, 128 : wait $d011, 128 : wait $d011, 128, 128 : wait $d011, 128 poke wDoorAddress, DOOR_CLOSED poke VIC_COLOR_OFFSET + wDoorAddress, 14 'light blue wait $d011, 128, 128 : wait $d011, 128 : wait $d011, 128, 128 : wait $d011, 128 Next bAnimFrameCounter For bAnimFrameCounter = 1 to 5 poke wDoorAddress, DOOR_OPEN_REVERSED poke VIC_COLOR_OFFSET + wDoorAddress, 7 'yellow wait $d011, 128, 128 : wait $d011, 128 : wait $d011, 128, 128 : wait $d011, 128 poke wDoorAddress, DOOR_OPEN poke VIC_COLOR_OFFSET + wDoorAddress, 14 'light blue wait $d011, 128, 128 : wait $d011, 128 : wait $d011, 128, 128 : wait $d011, 128 Next bAnimFrameCounter bTreasuresToOpenDoor = 0 end sub sub goldFlashAnimation (bInitAnim as BYTE) STATIC Dim bFlashTimer as BYTE if bInitAnim then bGoldNotCollected = FALSE bFlashTimer = 8 else if bFlashTimer = 0 then exit sub end if bFlashTimer = bFlashTimer - 1 if (bFlashTimer AND 1) then poke 53281, 8 'orange else poke 53281, 0 'black end if end sub sub titleScreen() STATIC Const PLAYER_LOCATION = 1354 Const MONSTER_LOCATION = 1434 Dim bJoystick2 as BYTE 'treasure frame for title memset 1036, 16, TREASURE_GOLD memset 1236, 16, TREASURE_GOLD memset 55308, 216, 7 'yellow poke 1076, TREASURE_GOLD poke 1116, TREASURE_GOLD poke 1156, TREASURE_GOLD poke 1196, TREASURE_GOLD poke 1091, TREASURE_GOLD poke 1131, TREASURE_GOLD poke 1171, TREASURE_GOLD poke 1211, TREASURE_GOLD textat 15, 2, "superchase", 1 'white textat 17, 3, "remix!", 1 'white textat 13, 8, "treasure hunter", 3 'cyan textat 13, 10, "monster of dungeons!", 7 'yellow textat 12, 15, "choose skill level", 5 'green charat 18, 17, 60, 10 'left arrow, light red charat 22, 17, 62, 10 'right arrow, light red poke PLAYER_LOCATION, PLAYER : poke 55626, 13 'light green poke MONSTER_LOCATION, MONSTER : poke 55706, 2 'red do charat 20, 17, 48 + bSkillLevel, 1 'white poke 55994, 10 'color for left arrow, light red poke 55998, 10 'color for right arrow, light red bJoystick2 = peek( $DC00) XOR 127 if (bJoystick2 AND 4) then 'color for left arrow, left poke 55994, 1 'white if bSkillLevel > 1 then bSkillLevel = bSkillLevel - 1 else if (bJoystick2 AND 8) then 'right poke 55998, 1 'color for right arrow, white if bSkillLevel < 9 then bSkillLevel = bSkillLevel + 1 else if (bJoystick2 AND 16) then 'fire exit do end if end if end if poke PLAYER_LOCATION, peek(PLAYER_LOCATION) XOR 1 poke MONSTER_LOCATION, peek(MONSTER_LOCATION) XOR 1 wait $D011, 128, 128 : wait $D011, 128 : wait $D011, 128, 128 : wait $D011, 128 wait $D011, 128, 128 : wait $D011, 128 : wait $D011, 128, 128 : wait $D011, 128 wait $D011, 128, 128 : wait $D011, 128 : wait $D011, 128, 128 : wait $D011, 128 loop end sub '----------------------------------------------------------------------- LOC_charset_addr: incbin "charset_superchase.chr"