; NAME: Item Minigame Randomizer (MP2)
; GAMES: MP2_USA
; EXECUTION: Direct
; PARAM: Number|Selector

; This event is designed to fix or randomize the Item Minigame that
; will be played. For randomization, set the parameter "Selector" to
; zero. To fix the Item Minigame to a specific one, set "Selector" to
; a value from 1-6 accordingly:
; 1. Western Land
; 2. Pirate Land
; 3. Horror Land
; 4. Space Land
; 5. Mystery Land
; 6. Bowser Land

; When randomizing the Item Minigame, refer to the Chances Array
; below to set the percent chance of each Item Minigame appearing.

; Credit goes to Rain for originally porting the GetRand function!

ADDIU SP SP -40
SW RA 36(SP)
SW S0 32(SP)
SW S1 28(SP)

;===Get Item Minigame Arrays===
LUI S0 0x800C ; 0x800C0000
ORI S0 S0 0xCCFC ; 0x800CCCFC, Item Minigame Pointer
LUI S1 hi(MinigamesArray)
ADDIU S1 S1 lo(MinigamesArray) ; Load MinigamesArray into S1

;===Check Selector===
LI T0 Selector
BNEZ T0 SelectMinigame ; If T0 = 1-6, select the minigame
NOP
; else, randomize the minigame

;===Randomize Minigame===
JAL GetRand
LI A0 99 ; Get random byte (0-99) at V0

LUI T0 hi(ChancesArray)
ADDIU T0 T0 lo(ChancesArray) ; Load ChancesArray into T0
RandomizeLoop:
LBU T1 0(T0) ; Load item minigame chance into T1
SLT T2 V0 T1 ; If V0 < T1, T2 = 1
BNEZL T2 SetMinigame ; If T2 = 1, set minigame
LBU S1 0(S1) ; Load item minigame index into S1
; else, check the next item minigame chance

ADDIU T0 T0 1 ; Add 1 to check next item minigame chance
J RandomizeLoop
ADDIU S1 S1 1 ; Add 1 to get next item minigame index

;===Select Minigame===
SelectMinigame:
ADDIU T0 T0 -1 ; Subtract 1 to get MinigamesArray offset
ADDU S1 S1 T0 ; Add to get selected item minigame
LBU S1 0(S1) ; Load selected item minigame index into S1

;===Set Minigame===
SetMinigame:
SB S1 0(S0) ; Store item minigame index into item minigame pointer

LW RA 36(SP)
LW S0 32(SP)
LW S1 28(SP)
JR RA
ADDIU SP SP 40

;===Chances Array===
.align 16
ChancesArray:
.byte 16 ; Western Land minigame (0-15) 16%
.byte 32 ; Pirate Land minigame (16-31) 16%
.byte 48 ; Horror Land minigame (32-47) 16%
.byte 64 ; Space Land minigame (48-63) 16%
.byte 80 ; Mystery Land minigame (64-79) 16%
.byte 100 ; Bowser Land minigame (80-99) 20%

; To set the % chances, each byte holds the % chance of the adjacent
; Item Minigame plus the total of all bytes before it (e.g. byte 32
; for Pirate Land = 16% chance for Pirate Land plus the 16% chance
; for Western Land before it). The final byte will always be 100 (the
; sum of all chances will add up to 100%).

;===Minigames Array===
.align 16
MinigamesArray:
.byte 0x05 ; Western Land minigame index
.byte 0x02 ; Pirate Land minigame index
.byte 0x03 ; Horror Land minigame index
.byte 0x04 ; Space Land minigame index
.byte 0x06 ; Mystery Land minigame index
.byte 0x01 ; Bowser Land minigame index

; Do not change these values; they are the in-game indexes for each
; of the Item Minigames. Ensure that the order of Item Minigame
; chances above matches the order of the Item Minigames here.

;===Mini Func to Get Random Byte===
.align 4
GetRand:

; A0 = max byte

ADDIU sp, sp, -0x18
SW ra, 0x0010 (sp)
BLTZL a0, label1_func0
SUBU a0, r0, a0
label1_func0:
BEQZ a0, End1
DADDU v0, r0, r0
ADDIU v0, r0, 0x0001
BNEL a0, v0, label2_func0
ADDIU v0, r0, 0x0064
JAL Function1
ADDIU a0, r0, 0x03E8
SLTI v0, v0, 0x01F5
J End1
XORI v0, v0, 0x0001
label2_func0:
BEQ a0, v0, label3_func0
NOP
JAL Function1
NOP
J End1
NOP
label3_func0:
JAL Function1
ADDIU a0, r0, 0x03F1
LUI v1, 0x6666
ORI v1, v1, 0x6667
MULT v0, v1
SRA v0, v0, 31
MFHI a1
SRA v1, a1, 2
SUBU v0, v1, v0
End1:
LW ra, 0x0010 (sp)
JR RA
ADDIU sp, sp, 0x18
//
Function1:
ADDIU sp, sp, -0x20
SW s0, 0x0010 (sp)
ADDIU s0, r0, 0xFFFF
SW s1, 0x0014 (sp)
ADDIU s1, a0, 0x0001
BNEZ s1, label1_func1
DIVU s0, s1
BREAK 0x01C00
label1_func1:
MFLO s0
BNEZ s0, label2_func1
SW ra, 0x0018 (sp)
ADDIU s0, r0, 0x0001
label2_func1:
JAL Function2
NOP
BNEZ s0, label3_func1
DIVU v0, s0
BREAK 0x01C00
label3_func1:
MFLO v1
SLTU v0, v1, s1
BEQZ v0, label2_func1
DADDU v0, v1, r0
LW ra, 0x0018 (sp)
LW s1, 0x0014 (sp)
LW s0, 0x0010 (sp)
JR RA
ADDIU sp, sp, 0x20
//
Function2:
LUI v0, 0x800D
LW v0, 0x99B4 (v0)
LUI v1, 0x41C6
ORI v1, v1, 0x4E6D
MULT v0, v1
MFLO v0
ADDIU v0, v0, 0x3039
LUI v1, 0x800D
JR RA
SW v0, 0x99B4 (v1)