C64_Superchase/superchase.bas

808 lines
27 KiB
QBasic
Raw Normal View History

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