; NAME: Thwomp Toll v1.1 (Airsola™)
; GAMES: MP3_USA
; EXECUTION: Direct
; PARAM: Space|DeclineDestination
; PARAM: Space|DeclineInReverse
; PARAM: +Number|StartingToll

ADDIU SP SP -72
SW RA 64(SP)
SW S0 60(SP)
SW S1 56(SP)
SW S2 52(SP)
SW S3 48(SP)
SW S4 44(SP)
SW S6 40(SP)
SW S7 36(SP)

; S1 = Player Status Flag Address
; S3 = Toll Address
; S2 = Toll Address value
; S4 = Current Player's Index
; S6 = Base Toll
; S7 = Current Player's Coin Amount
; DeclineDestination = Where the player would go if they say no/don't
;                      have enough coins
; DeclineInReverse = Where the player would go if they say no/don't
;                    have enough coins, but they are going in reverse
; StartingToll = What the Thwomp Toll will start at

LI A0 -1
LI A1 -1
JAL SetBoardPlayerAnimation
LI A2 2

JAL GetCurrentPlayerIndex ; At V0
NOP
MOVE S4 V0

LUI S3 hi(0x800CD0A4)
ADDIU S3 S3 lo(0x800CD0A4) ; Load Address of Board-Specific RAM
LHU S2 0(S3) ; Load the RAM Value into S1

LUI A0 hi(coin_string_loc)
ADDIU A0 A0 lo(coin_string_loc)
LUI A1 hi(percent_d)
ADDIU A1 A1 lo(percent_d)
MOVE A2 S2 ; Move Thwomp Toll Total Value into A2
JAL sprintf
NOP

BNE S2 R0 Check
NOP

LI S2 StartingToll ; Set Starting Toll if address reads 0

;FAILSAFE CHECK======================================================
Check:
MOVE A0 S4
JAL PlayerHasCoins ; Checks if Player has the minimum coin amount
MOVE A1 S2

BEQ V0 R0 NotEnoughCoins
NOP
;FAILSAFE CHECK======================================================
MOVE S6 S2 ; Copy Base Toll to S6

JAL PlaySound
LI A0 0x1AE ; Thwomp's cry

LUI T1 hi(p1_coins)
ADDIU T1 T1 lo(p1_coins) ; Load Player 1's Coins
LI T0 0x38 ; Distance between each player's coins address
MULT S4 T0 ;  Multiply Current Player Index by S3
MFLO T0 ; Move the result to S3

ADDU T1 T1 T0 ; Add result to get current Player's coins address
LHU T0 0(T1) ; Load address value into S2
MOVE S7 T0 ; Move Value into S7

START:
LUI A0 hi(coin_string_loc)
ADDIU A0 A0 lo(coin_string_loc)
LUI A1 hi(percent_d)
ADDIU A1 A1 lo(percent_d)
MOVE A2 S2 ; Move Thwomp Toll Total Value into A2
JAL sprintf
NOP

SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 8 ; Character image (Thwomp)
LUI A1 hi(Thwomp_Prompt)
ADDIU A1 A1 lo(Thwomp_Prompt)
LUI A2 hi(coin_string_loc)
ADDIU A2 A2 lo(coin_string_loc) ; Pass ThwompToll as String
LI A3 0
JAL 0x800EC8EC ; ShowMessage
NOP

; If A0 is a pointer to AI data, AI logic is ran to pick for CPUs.
; If A0 is 0 or 1, the 0th or 1st option is chosen by CPUs.
; If A0 is 2, then the value of A1 is the CPUs option index choice.
LUI A0 hi(ai_random_choice)
ADDIU A0 A0 lo(ai_random_choice)
JAL GetBasicPromptSelection
LI A1 0
MOVE S0 V0 ; S0 now has the chosen option index

; Obligatory message box closing/cleanup calls.
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP

; Change the outcome based on the choice.
LI A0 0
BEQ S0 A0 yes
NOP
LI A0 1
BEQ S0 A0 no
NOP
LI A0 2
BEQ S0 A0 viewmap
NOP


yes:
SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 8 ; Character image (Thwomp)
LUI A1 hi(ThwompToll_Message)
ADDIU A1 A1 lo(ThwompToll_Message)
LUI A2 hi(coin_string_loc)
ADDIU A2 A2 lo(coin_string_loc) ; Pass ThwompToll as String
LI A3 0
JAL 0x800EC92C  ; ShowMessage2
NOP

JAL PlayerIsCPU ; Returns 1 if the current player is a CPU
MOVE A0 S4

BNE V0 R0 exitloop
NOP

LoopReturn:
MOVE A0 S4
JAL DetectCStickInput ; V0 = 1 if Stick is Up, -1 if Down, ELSE 0
NOP

BEQ V0 R0 Loop
NOP

LI T0 1
BEQ V0 T0 CheckMax
NOP
J CheckMin
NOP

CheckMax:
BNE S2 S7 ContinueNormal
NOP
MOVE S2 S6
J ContinueRefresh
NOP

CheckMin:
BNE S2 S6 ContinueNormal
NOP
MOVE S2 S7
J ContinueRefresh
NOP

ContinueNormal:
ADDU S2 S2 V0

ContinueRefresh:
LUI A0 hi(coin_string_loc)
ADDIU A0 A0 lo(coin_string_loc)
LUI A1 hi(percent_d)
ADDIU A1 A1 lo(percent_d)
MOVE A2 S2 ; Move Thwomp Toll Total Value into A2
JAL sprintf
NOP

JAL PlaySound
LI A0 582 ; Coin Sound

JAL SleepProcess
LI A0 2 ; Sleep for 2 frames so choosing amount is easier

Loop:
MOVE A0 S4
JAL DetectABInput ; V0 = 1 if A press, 2 if B press, ELSE 0
NOP

LI T0 1
BEQ V0 T0 exitloop
NOP
BEQ V0 R0 ContinueInLoop
NOP

JAL PlaySound
LI A0 4 ; Back Sound Index

JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP
MOVE S2 S6
J START
NOP

ContinueInLoop:
LI A0 2
LUI A1 hi(coin_string_loc)
ADDIU A1 A1 lo(coin_string_loc)
JAL 0x8005B6BC
MOVE A2 R0

LI A0 2
LUI A1 hi(ThwompToll_Message)
ADDIU A1 A1 lo(ThwompToll_Message)
LI A2 -1
JAL 0x8005B43C
LI A3 -1

JAL SleepVProcess
NOP

J LoopReturn
NOP



exitloop:
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP

JAL PlaySound
LI A0 583 ; Cash Register Sound

JAL SleepProcess
LI A0 10 ; Sleep 10 frames

MOVE A0 S4
JAL AdjustPlayerCoinsGradual
SUBU A1 R0 S2

MOVE A0 S4
JAL ShowPlayerCoinChange
SUBU A1 R0 S2

JAL SleepProcess
LI A0 30 ; Sleep 30 frames

JAL PlaySound
LI A0 0x1AE ; Thwomp's cry

SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 8 ; Character image (Thwomp)
LUI A1 hi(ThwompYes_Message)
ADDIU A1 A1 lo(ThwompYes_Message)
LI A2 0
JAL 0x800EC8EC ; ShowMessage
LI A3 0

JAL 0x800EC9DC
NOP
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP

ADDIU S2 S2 1 ; Add 1 to the toll count
SH S2 0(S3) ; Update the minimum amount of Coins for the Toll

J exit
NOP


no:
JAL PlaySound
LI A0 0x1AE ; Thwomp's cry

SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 8 ; Character image (Thwomp)
LUI A1 hi(ThwompNo_Message)
ADDIU A1 A1 lo(ThwompNo_Message)
LI A2 0
JAL 0x800EC8EC ; ShowMessage
LI A3 0

JAL 0x800EC9DC
NOP
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP

StatusFlag:
LUI S1 hi(p1_status_flags)
ADDIU S1 S1 lo(p1_status_flags) ; Load Player 1's Status Flag
LI T0 0x38 ; This is the distance between each player's Flag
MULT S4 T0 ;  Multiply Current Player Index by S3
MFLO T0 ; Move the result to S3

ADDU S1 S1 T0 ; Add result to get Current Player Status Flag Address

LBU A1 0(S1) ; Load address value into A1
LI A0 7
JAL GetPlayerBit ; V0 = 1 if Reversed
NOP

BNE V0 R0 PlayerInReverse ; If it's not 0, they're in Reverse
NOP

MOVE A0 S4 ; Assigns Current Player Index to A0
LI A1 DeclineDestination_chain_index ; Assigns Chain Index to A1
LI A2 DeclineDestination_chain_space_index ;Assigns Space Index to A2
JAL SetNextChainAndSpace
NOP

J exit
NOP

PlayerInReverse:
MOVE A0 S4 ; Assigns Current Player Index to A0
LI A1 DeclineInReverse_chain_index ; Assigns Chain Index to A1
LI A2 DeclineInReverse_chain_space_index ; Assigns Space Index to A2
JAL SetNextChainAndSpace
NOP

LBU T0 0(S1)
ADDIU T0 T0 1
SB T0 0(S1)

J exit
NOP

viewmap:
JAL ViewBoardMap
NOP
J START
NOP


NotEnoughCoins:
JAL PlaySound
LI A0 0x1AE ; Thwomp's cry

SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 8 ; Character image (Thwomp)
LUI A1 hi(ThwompNotEnoughCoins_Message)
ADDIU A1 A1 lo(ThwompNotEnoughCoins_Message)
LUI A2 hi(coin_string_loc)
ADDIU A2 A2 lo(coin_string_loc)
JAL 0x800EC8EC ; ShowMessage
LI A3 0

JAL 0x800EC9DC
NOP
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP

J StatusFlag
NOP


exit:
LW RA 64(SP)
LW S0 60(SP)
LW S1 56(SP)
LW S2 52(SP)
LW S3 48(SP)
LW S4 44(SP)
LW S6 40(SP)
LW S7 36(SP)
JR RA
ADDIU SP SP 72

; Gets player A0's bit value
; A0 = bit to shift to (7)
; A1 = player flag address value
GetPlayerBit:
ADDIU SP SP -8
SW RA 0(SP)

LI T0 1
SLLV T0 T0 A0 ; shift bit mask into position

AND T2 A1 T0

BEQ T2 R0 ret_zero
NOP

ret_one:
LI V0 1
J getplayerbit_exit
NOP

ret_zero:
LI V0 0

getplayerbit_exit:
LW RA 0(SP)
JR RA
ADDIU SP SP 8


; A0 Current Player index
DetectCStickInput:
ADDIU SP SP -20
SW RA 16(SP)
SW S5 12(SP)

LUI T1 hi(p1_controller)
ADDIU T1 T1 lo(p1_controller) ; Load P1's Controller
LI T0 0x38 ; This is the distance between each player's Controller
MULT A0 T0 ;  Multiply Current Player Index by S3
MFLO T0 ; Move the result to S3

ADDU T1 T1 T0 ; Add result to get Current Player's Controller Addr
LBU T0 0(T1) ; Load address value into A1

LUI T1 hi(0x800CC3F7)
ADDIU T1 T1 lo(0x800CC3F7) ; Load P1's Y Axis
LI A2 0x8 ; This is the distance between each player's Controller
MULT A2 T0 ;  Multiply Controller value by 8
MFLO T0 ; Move the result to S3

ADDU T1 T1 T0 ; Add result to get Current Player's Y Axis
LBU T0 0(T1) ; Load address value into A1

SLTI S5 T0 0x1E ; S5 = 1 if less than 1E
NOP
BNE S5 R0 return_zero 
NOP
SLTI S5 T0 0x7C ; Set if Stick is tilted up
NOP
BNE S5 R0 return_one
NOP
SLTI S5 T0 0xE2
NOP
BNE S5 R0 return_neg_one
NOP

return_zero:
LI V0 0
J DetectCStickInputexit
NOP

return_one:
LI V0 1
J DetectCStickInputexit
NOP

return_neg_one:
LI V0 -1
J DetectCStickInputexit
NOP

DetectCStickInputexit:
LW RA 16(SP)
LW S5 12(SP)
JR RA
ADDIU SP SP 20

; A0 Current Player's Control Stick Y axis
DetectABInput:
ADDIU SP SP -20
SW RA 16(SP)

LUI T1 hi(p1_controller)
ADDIU T1 T1 lo(p1_controller) ; Load P1's Controller
LI T0 0x38 ; This is the distance between each player's Controller
MULT A0 T0 ;  Multiply Current Player Index by S3
MFLO T0 ; Move the result to S3

ADDU T1 T1 T0 ; Add result to get Current Player's Controller Addr
LBU T0 0(T1) ; Load address value into A1

LUI T1 hi(0x800CCF7C)
ADDIU T1 T1 lo(0x800CCF7C) ; Load P1's Button Press Address
LI A2 0x2 ; This is the distance between each player's Button Address
MULT A2 T0 ;  Multiply Controller value by 2
MFLO T0 ; Move the result to S3

ADDU T1 T1 T0 ; Add result to get Current Player's Y Axis
LBU T0 0(T1) ; Load address value into A1

LI T1 0x80
BEQ T0 T1 APress
NOP
LI T1 0x40
BEQ T0 T1 BPress
NOP

NoPress:
LI V0 0
J DetectABInputexit
NOP

APress:
LI V0 1
J DetectABInputexit
NOP

BPress:
LI V0 2
J DetectABInputexit
NOP

DetectABInputexit:
LW RA 16(SP)
JR RA
ADDIU SP SP 20



.align 4
percent_d:
.asciiz "%d" ; 0x25640000

coin_string_loc:
.fill 8

.align 16
ai_random_choice:
.word 0x00000000, 0x00000000, 0x064C9932

.align 16
ThwompNotEnoughCoins_Message:
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "Not enough coins"
.byte 0xC3 ; Question Mark (?)
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "No passing for you then"
.byte 0xC2 ; Exclamation Mark (!)
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "Next time bring "
.byte 0x05 ; Green Font
.byte 0x11 ; String 1
.ascii " coins"
.byte 0x08 ; White Font
.byte 0xC2 ; Exclamation Mark (!)
.byte 0xFF,0 ; FF=Pause

.align 16
Thwomp_Prompt:
.byte 0x0B ; Start the message
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "If you pay at least "
.byte 0x05 ; Green Font
.byte 0x11 ; String #1 (ThwompToll)
.ascii " coins"
.byte 0x08 ; White Font
.byte 0x82 ; Comma (,)
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "I"
.byte 0x5C ; Apostrophe (')
.ascii "ll let you pass through"
.byte 0xC2 ; Exclamation Mark (!)
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Picture + Option Indent
.byte 0x0C ; Start option
.ascii "Pay"
.byte 0x0D ; End option
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Picture + Option Indent
.byte 0x0C ; Start option
.ascii "Don"
.byte 0x5C ; Apostrophe (')
.ascii "t pay"
.byte 0x0D ; End option
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Picture + Option Indent
.byte 0x0C ; Start option
.ascii "View Map"
.byte 0x0D ; End option
.byte 0 ; End Prompt

.align 16
ThwompYes_Message:
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "OK"
.byte 0x85 ; Period (.)
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "Go on"
.byte 0xC2 ; Exclamation Mark (!)
.byte 0xFF,0 ; FF=Pause

.align 16
ThwompNo_Message:
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "No passing for you then"
.byte 0xC2 ; Exclamation Mark (!)
.byte 0xFF,0 ; FF=Pause

.align 16
ThwompToll_Message:
.byte 0x0B ; Start the message
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "Choose the amount of"
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "coins you"
.byte 0x5C ; Apostrophe (')
.ascii "ll pay"
.byte 0x85 ; Period (.)
.byte 0x0A ; New Line (Writes Below)
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A ; Picture + Option Indent
.ascii "Pay"
.byte 0x10,0x10 ; Space 2x (  )
.byte 0x29 ; Coin icon
.byte 0x20 ; ???
.byte 0x3E ; x (multiply)
.byte 0x20 ; ???
.byte 0x05 ; Green Font
.byte 0x0F ; ???
.byte 0x11 ; String #1 (Price)
.byte 0x19 ; ???
.byte 0x0A ; New Line (Writes Below)
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A;Picture + Option Indent
.byte 0x28 ; Control Stick Icon
.byte 0x85,0x85,0x85 ; Period (...)
.ascii "Choose"
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A;Picture + Option Indent
.byte 0x21 ; (A) Button Icon
.byte 0x85,0x85,0x85 ; Period (...)
.ascii "Confirm"
.byte 0x0A ; New Line (Writes Below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A;Picture + Option Indent
.byte 0x22 ; (B) Button Icon
.byte 0x85,0x85,0x85 ; Period (...)
.ascii "Quit"
.byte 0
.byte 0