diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/slot_machine.c | 778 | ||||
-rw-r--r-- | src/vs_seeker.c | 2 |
2 files changed, 779 insertions, 1 deletions
diff --git a/src/slot_machine.c b/src/slot_machine.c new file mode 100644 index 000000000..41271b425 --- /dev/null +++ b/src/slot_machine.c @@ -0,0 +1,778 @@ +#include "global.h" +#include "palette.h" +#include "task.h" +#include "main.h" +#include "malloc.h" +#include "sound.h" +#include "coins.h" +#include "quest_log.h" +#include "overworld.h" +#include "slot_machine.h" +#include "menu.h" +#include "random.h" +#include "constants/songs.h" + +struct SlotMachineState +{ + MainCallback savedCallback; + u16 machineidx; + u16 field_06; + u16 field_08; + u16 slotRewardClass; + u8 filler_0C[2]; + u16 bet; + u8 field_10; + u8 field_11; + bool32 field_14[3]; + s16 field_20[3]; + s16 field_26[3]; + s16 field_2C[3]; + s16 field_32[3]; + u32 field_38; + u8 filler_3C[0x14]; + u16 payout; +}; + +EWRAM_DATA struct SlotMachineState * sSlotMachineState = NULL; + +void sub_813F84C(struct SlotMachineState * ptr); +void sub_813F898(void); +void sub_813F92C(void); +void sub_813F94C(void); +void MainTask_SlotsGameLoop(u8 taskId); +void MainTask_NoCoinsGameOver(u8 taskId); +void MainTask_ShowHelp(u8 taskId); +void MainTask_ConfirmExitGame(u8 taskId); +void MainTask_DarnNoPayout(u8 taskId); +void MainTask_WinHandlePayout(u8 taskId); +void MainTask_ExitSlots(u8 taskId); +static void SetMainTask(TaskFunc taskFunc); +void sub_8140060(u8 taskId); +void sub_8140148(void); +void sub_814016C(u16 whichReel, u16 whichReel2); +bool32 sub_81401A0(u16); +void sub_81401F0(u16 whichReel); +void sub_81403BC(u16 whichReel); +void sub_81404B8(u16 whichReel); +bool32 sub_814054C(s32, s32, s32, s32, s32); +bool32 sub_81406E8(s32, s32, s32); +bool32 sub_81408F4(s32, s32); +void sub_81409B4(void); +void sub_8140A70(void); +u16 sub_8140A80(void); +void sub_8140D7C(s16 *, s16 *); +bool32 sub_814104C(void); +void sub_8141094(void); +void sub_8141148(u16 a0, u8 a1); +bool32 sub_8141180(u8 a0); +void sub_8141C30(u8, u8); + +extern const u8 gUnknown_8464890[][2]; +extern const u8 gUnknown_8464926[][21]; + +void PlaySlotMachine(u16 machineIdx, MainCallback savedCallback) +{ + ResetTasks(); + sSlotMachineState = Alloc(sizeof(*sSlotMachineState)); + if (sSlotMachineState == NULL) + SetMainCallback2(savedCallback); + else + { + if (machineIdx > 5) + machineIdx = 0; + sSlotMachineState->machineidx = machineIdx; + sSlotMachineState->savedCallback = savedCallback; + sub_813F84C(sSlotMachineState); + SetMainCallback2(sub_813F898); + } +} + +void sub_813F84C(struct SlotMachineState * ptr) +{ + s32 i; + + ptr->field_06 = 0; + ptr->bet = 0; + ptr->payout = 0; + // for whatever reason, the loop does not use the ptr param + for (i = 0; i < 3; i++) + { + sSlotMachineState->field_14[i] = FALSE; + sSlotMachineState->field_20[i] = 0; + sSlotMachineState->field_26[i] = 0; + sSlotMachineState->field_2C[i] = 21; + } +} + +void sub_813F898(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + + switch (gMain.state) + { + case 0: + if (sub_814104C()) + { + SetMainCallback2(sSlotMachineState->savedCallback); + sub_813F92C(); + } + else + { + sub_8141148(0, 0); + gMain.state++; + } + break; + case 1: + if (!sub_8141180(0)) + { + sSlotMachineState->field_10 = CreateTask(MainTask_SlotsGameLoop, 0); + sSlotMachineState->field_11 = CreateTask(sub_8140060, 1); + SetMainCallback2(sub_813F94C); + } + break; + } +} + +void sub_813F92C(void) +{ + sub_8141094(); + if (sSlotMachineState != NULL) + { + Free(sSlotMachineState); + sSlotMachineState = NULL; + } +} + +void sub_813F94C(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +void MainTask_SlotsGameLoop(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + if (GetCoins() == 0) + { + SetMainTask(MainTask_NoCoinsGameOver); + } + else if (JOY_NEW(DPAD_DOWN)) + { + sSlotMachineState->bet++; + TakeCoins(1); + PlaySE(SE_T_KAMI2); + sub_8141148(8, 0); + sub_8141148(2, 1); + data[0] = 1; + } + else if (JOY_NEW(R_BUTTON)) + { + s32 toAdd = 3 - sSlotMachineState->bet; + if (GetCoins() >= toAdd) + { + sSlotMachineState->bet = 3; + TakeCoins(toAdd); + } + else + { + sSlotMachineState->bet += GetCoins(); + SetCoins(0); + } + PlaySE(SE_T_KAMI2); + sub_8141148(8, 0); + sub_8141148(2, 1); + data[0] = 1; + } + else if (JOY_NEW(A_BUTTON) && sSlotMachineState->bet != 0) + { + data[0] = 2; + } + else if (JOY_NEW(B_BUTTON)) + { + SetMainTask(MainTask_ConfirmExitGame); + } + else if (JOY_NEW(DPAD_RIGHT)) + { + SetMainTask(MainTask_ShowHelp); + } + break; + case 1: + if (!sub_8141180(0) && !sub_8141180(1)) + { + if (sSlotMachineState->bet == 3 || GetCoins() == 0) + data[0] = 2; + else + data[0] = 0; + } + break; + case 2: + sub_811539C(); + sub_81409B4(); + sub_8140148(); + sSlotMachineState->field_06 = 0; + sub_8141148(3, 0); + data[0] = 3; + break; + case 3: + if (!sub_8141180(0)) + { + if (JOY_NEW(A_BUTTON)) + { + PlaySE(SE_JYUNI); + sub_814016C(sSlotMachineState->field_06, sSlotMachineState->field_06); + sub_8141C30(sSlotMachineState->field_06, 0); + data[0] = 4; + } + } + break; + case 4: + if (sub_81401A0(sSlotMachineState->field_06) == 0 && !sub_8141180(0)) + { + sSlotMachineState->field_06++; + if (sSlotMachineState->field_06 >= 3) + { + sSlotMachineState->slotRewardClass = sub_8140A80(); + sSlotMachineState->bet = 0; + sSlotMachineState->field_06 = 0; + if (sSlotMachineState->slotRewardClass == 0) + SetMainTask(MainTask_DarnNoPayout); + else + { + if (sSlotMachineState->slotRewardClass == 6) + IncrementGameStat(GAME_STAT_SLOT_JACKPOTS); + sub_8140A70(); + SetMainTask(MainTask_WinHandlePayout); + } + } + else + data[0] = 3; + } + break; + } +} + +void MainTask_NoCoinsGameOver(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + sub_8141148(9, 0); + data[0]++; + break; + case 1: + if (!sub_8141180(0)) + data[0]++; + break; + case 2: + if (JOY_NEW(A_BUTTON | B_BUTTON | DPAD_ANY)) + SetMainTask(MainTask_ExitSlots); + break; + } +} + +void MainTask_ShowHelp(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + sub_8141148(14, 0); + data[0]++; + break; + case 1: + if (!sub_8141180(0)) + data[0]++; + break; + case 2: + if (JOY_NEW(DPAD_LEFT)) + { + sub_8141148(15, 0); + data[0]++; + } + break; + case 3: + if (!sub_8141180(0)) + SetMainTask(MainTask_SlotsGameLoop); + break; + } +} + +void MainTask_ConfirmExitGame(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + sub_8141148(10, 0); + data[0]++; + break; + case 1: + if (!sub_8141180(0)) + data[0]++; + break; + case 2: + switch (Menu_ProcessInputNoWrapClearOnChoose()) + { + case 0: + GiveCoins(sSlotMachineState->bet); + sub_8141148(8, 0); + data[0] = 3; + break; + case 1: + case -1: + sub_8141148(11, 0); + data[0] = 4; + break; + } + break; + case 3: + if (!sub_8141180(0)) + SetMainTask(MainTask_ExitSlots); + break; + case 4: + if (!sub_8141180(0)) + SetMainTask(MainTask_SlotsGameLoop); + break; + } +} + +void MainTask_DarnNoPayout(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + sub_8141148(6, 0); + data[1] = 0; + data[0]++; + break; + case 1: + data[1]++; + if (data[1] > 60) + { + sub_8141148(7, 0); + sub_8141148(2, 1); + sub_8141148(13, 2); + data[0]++; + } + break; + case 2: + if (!sub_8141180(0) && !sub_8141180(1) && !sub_8141180(2)) + SetMainTask(MainTask_SlotsGameLoop); + break; + } +} + +void MainTask_WinHandlePayout(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + if (sSlotMachineState->slotRewardClass == 5 || sSlotMachineState->slotRewardClass == 6) + PlayFanfare(MUS_ME_B_BIG); + else + PlayFanfare(MUS_ME_B_SMALL); + sub_8141148(8, 0); + sub_8141148(4, 1); + data[1] = 8; + data[0]++; + break; + case 1: + data[1]++; + if (data[1] > 120) + { + data[1] = 8; + if (JOY_HELD(A_BUTTON)) + data[1] = 2; + data[0]++; + } + break; + case 2: + if (!sub_8141180(0)) + { + if (IsFanfareTaskInactive() && JOY_NEW(START_BUTTON)) + { + GiveCoins(sSlotMachineState->payout); + sSlotMachineState->payout = 0; + } + else + { + data[1]--; + if (data[1] == 0) + { + if (IsFanfareTaskInactive()) + PlaySE(SE_PIN); + if (sSlotMachineState->payout != 0) + { + GiveCoins(1); + sSlotMachineState->payout--; + } + data[1] = 8; + if (JOY_HELD(A_BUTTON)) + data[1] = 2; + } + } + sub_8141148(8, 0); + if (sSlotMachineState->payout == 0) + data[0]++; + } + break; + case 3: + if (IsFanfareTaskInactive() && !sub_8141180(0)) + { + sub_8141148(5, 0); + data[0]++; + } + break; + case 4: + if (!sub_8141180(0)) + { + sub_8141148(2, 0); + sub_8141148(13, 1); + data[0]++; + } + break; + case 5: + if (!sub_8141180(0) && !sub_8141180(1)) + SetMainTask(MainTask_SlotsGameLoop); + break; + } +} + +void MainTask_ExitSlots(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + sub_8141148(1, 0); + data[0]++; + break; + case 1: + if (!sub_8141180(0)) + { + SetMainCallback2(sSlotMachineState->savedCallback); + sub_813F92C(); + } + break; + } +} + +static void SetMainTask(TaskFunc taskFunc) +{ + gTasks[sSlotMachineState->field_10].func = taskFunc; + gTasks[sSlotMachineState->field_10].data[0] = 0; +} + +void sub_8140060(u8 taskId) +{ + // taskId is never used + + s32 i; + + for (i = 0; i < 3; i++) + { + if (sSlotMachineState->field_14[i] || sSlotMachineState->field_26[i] != 0) + { + if (sSlotMachineState->field_26[i] != 0 || sSlotMachineState->field_20[i] != sSlotMachineState->field_2C[i]) + { + sSlotMachineState->field_26[i]++; + if (sSlotMachineState->field_26[i] > 2) + { + sSlotMachineState->field_26[i] = 0; + sSlotMachineState->field_20[i]--; + if (sSlotMachineState->field_20[i] < 0) + sSlotMachineState->field_20[i] = 20; + } + if (sSlotMachineState->field_20[i] != sSlotMachineState->field_2C[i]) + continue; + } + sSlotMachineState->field_2C[i] = 21; + sSlotMachineState->field_14[i] = FALSE; + } + } + sub_8140D7C(sSlotMachineState->field_20, sSlotMachineState->field_26); +} + +void sub_8140148(void) +{ + s32 i; + + for (i = 0; i < 3; i++) + { + sSlotMachineState->field_14[i] = TRUE; + } +} + +void sub_814016C(u16 whichReel, u16 whichReel2) +{ + switch (whichReel2) + { + case 0: + sub_81401F0(whichReel); + break; + case 1: + sub_81403BC(whichReel); + break; + case 2: + sub_81404B8(whichReel); + break; + } +} + +bool32 sub_81401A0(u16 whichReel) +{ + return sSlotMachineState->field_14[whichReel]; +} + +s16 sub_81401B4(u16 whichReel) +{ + s16 position = sSlotMachineState->field_20[whichReel]; + if (sSlotMachineState->field_26[whichReel] != 0) + { + position--; + if (position < 0) + position = 20; + } + return position; +} + +void sub_81401F0(u16 whichReel) +{ + s32 i, j; + s16 r2; + u8 sp0[5]; + s16 sp0C = sub_81401B4(whichReel); + s32 r8 = 0; + + if (sSlotMachineState->field_08 == 0 && whichReel == 0) + { + for (i = 0; i < 5; i++) + { + for (j = 0, r2 = sp0C - i + 1; j < 3; j++, r2++) + { + if (r2 >= 21) + r2 = 0; + if (sub_81408F4(1, gUnknown_8464926[whichReel][r2])) + break; + } + if (j == 3) + { + sp0[r8] = i; + r8++; + } + } + } + else if (sSlotMachineState->field_08 != 1 || whichReel == 0) + { + for (i = 0, r2 = sp0C + 1; i < 3; i++, r2++) + { + if (r2 >= 21) + r2 = 0; + if (sub_81408F4(sSlotMachineState->field_08, gUnknown_8464926[whichReel][r2])) + { + sp0[0] = 0; + r8 = 1; + break; + } + } + for (i = 0, r2 = sp0C; i < 4; i++, r2--) + { + if (r2 < 0) + r2 = 20; + if (sub_81408F4(sSlotMachineState->field_08, gUnknown_8464926[whichReel][r2])) + { + sp0[r8] = i + 1; + r8++; + } + } + } + if (r8 == 0) + { + r2 = Random() % 5; + } + else + { + r2 = sp0[Random() % r8]; + } + r2 = sp0C - r2; + if (r2 < 0) + r2 += 21; + sSlotMachineState->field_32[0] = whichReel; + sSlotMachineState->field_2C[whichReel] = r2; +} + +void sub_81403BC(u16 whichReel) +{ + s16 r2, r4, r7, sp10; + s32 i; + s32 r6; + u8 sp4[5]; + + r7 = sSlotMachineState->field_32[0]; + r4 = sSlotMachineState->field_20[r7] + 1; + if (r4 >= 21) + r4 = 0; + sp10 = sub_81401B4(whichReel); + r2 = sp10 + 1; + if (r2 >= 21) + r2 = 0; + r6 = 0; + for (i = 0; i < 5; i++) + { + if (sub_814054C(r7, r4, whichReel, r2, sSlotMachineState->field_08)) + { + sp4[r6] = i; + r6++; + } + r2--; + if (r2 < 0) + r2 = 20; + } + if (r6 == 0) + { + sSlotMachineState->field_38 = 0; + if (sSlotMachineState->field_08 == 5 || sSlotMachineState->field_08 == 6) + r2 = 4; + else + r2 = 0; + } + else + { + sSlotMachineState->field_38 = 1; + r2 = sp4[0]; + } + r2 = sp10 - r2; + if (r2 < 0) + r2 += 21; + sSlotMachineState->field_32[1] = whichReel; + sSlotMachineState->field_2C[whichReel] = r2; +} + +void sub_81404B8(u16 whichReel) +{ + s32 i; + s32 r6; + s32 r9; + s32 r4; + s32 r2; + u8 sp0[5]; + + r9 = sub_81401B4(whichReel); + r4 = r9; + r6 = 0; + for (i = 0; i < 5; i++) + { + if (sub_81406E8(whichReel, r4, sSlotMachineState->field_08)) + { + sp0[r6] = i; + r6++; + } + r4--; + if (r4 < 0) + r4 = 20; + } + if (r6 == 0) + { + if (sSlotMachineState->field_08 == 5 || sSlotMachineState->field_08 == 6) + r2 = 4; + else + r2 = 0; + } + else + r2 = sp0[0]; + r2 = r9 - r2; + if (r2 < 0) + r2 += 21; + sSlotMachineState->field_2C[whichReel] = r2; +} + +bool32 sub_814054C(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4) +{ + s32 i; + s32 r5; + u8 sp0[9] = {}; + + for (i = 0; i < 9; i++) + sp0[i] = 7; + + for (i = 0; i < 3; i++) + { + sp0[3 * a0 + i] = gUnknown_8464926[a0][a1]; + sp0[3 * a2 + i] = gUnknown_8464926[a2][a3]; + a1++; + if (a1 >= 21) + a1 = 0; + a3++; + if (a3 >= 21) + a3 = 0; + } + + switch (a4) + { + case 0: + for (i = 0; i < 3; i++) + { + if (sub_81408F4(1, sp0[i])) + return FALSE; + } + for (i = 0; i < 15; i++) + { + if (sp0[gUnknown_8464890[i][0]] == sp0[gUnknown_8464890[i][1]]) + return TRUE; + } + return FALSE; + case 1: + if (a0 == 0 || a2 == 0) + { + if (a0 == 1 || a2 == 1) + { + for (i = 0; i < 15; i += 3) + { + if (sp0[gUnknown_8464890[i][0]] == sp0[gUnknown_8464890[i][1]]) + return FALSE; + } + } + for (i = 0; i < 3; i++) + { + if (sub_81408F4(a4, sp0[i])) + return TRUE; + } + return FALSE; + } + else + return TRUE; + case 2: + if (a0 == 2 || a2 == 2) + { + for (i = 0; i < 9; i++) + { + if (sub_81408F4(a4, sp0[i])) + return TRUE; + } + return FALSE; // wrong level + } + } + for (i = 0; i < 15; i++) + { + if (sp0[gUnknown_8464890[i][0]] == sp0[gUnknown_8464890[i][1]] && sub_81408F4(a4, sp0[gUnknown_8464890[i][0]])) + return TRUE; + } + return FALSE; +} diff --git a/src/vs_seeker.c b/src/vs_seeker.c index bd5b9c7ea..6c6daf803 100644 --- a/src/vs_seeker.c +++ b/src/vs_seeker.c @@ -1,5 +1,5 @@ #include "global.h" -#include "songs.h" +#include "constants/songs.h" #include "sound.h" #include "task.h" #include "malloc.h" |