mirror of
https://github.com/CTR-tools/CTR-ModSDK.git
synced 2025-01-07 13:10:33 +00:00
My back hurts... (#40)
* Finish THREAD I said, turns out I can't solve it * Removing some duplicates * my back
This commit is contained in:
parent
fcd54ab3c9
commit
6ef4877d41
@ -57,7 +57,10 @@ struct Driver* BOTS_Driver_Init(int driverID)
|
||||
t->modelIndex = 0x3f;
|
||||
|
||||
// [0x5a4, 0x5b8 not in common.h]
|
||||
d->actionsFlagSet |= 0x100000;
|
||||
// [&DAT_8008daf8] unknown use
|
||||
|
||||
// [need to finish]
|
||||
sdata->gGT->numBotsCurrGame += 1;
|
||||
BOTS_GotoStartingLine(d);
|
||||
return d;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#include <common.h>
|
||||
|
||||
void DECOMP_RobotcarWeapons_Init(void)
|
||||
{
|
||||
int hub;
|
||||
int lev = sdata->gGT->levelID;
|
||||
|
||||
// get hubID of level
|
||||
hub = data.metaDataLEV[lev].hubID;
|
||||
|
||||
// If Level ID == 13
|
||||
// If Level ID is Oxide Station
|
||||
if (lev == 0xd) {
|
||||
hub = 0;
|
||||
}
|
||||
|
||||
if (hub != (unsigned int)-1)
|
||||
{
|
||||
// set pointer to boss weapon meta
|
||||
*(unsigned int*)0x8008d8e8 = data.bossWeaponMetaPtr[hub];
|
||||
}
|
||||
return;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#include <common.h>
|
||||
|
||||
void DECOMP_MM_Characters_AnimateColors(unsigned char *colorData, short playerID, short flag)
|
||||
{
|
||||
char bVar1;
|
||||
unsigned int uVar3;
|
||||
int iVar4;
|
||||
int *ptrColor;
|
||||
|
||||
ptrColor = data.ptrColor[playerID + 0x18];
|
||||
|
||||
iVar4 = 0;
|
||||
|
||||
if (flag == 0) {
|
||||
uVar3 = sdata->frameCounter * 0x100 + playerID * 0x400;
|
||||
|
||||
// approximate trigonometry
|
||||
iVar4 = data.trigApprox[uVar3];
|
||||
|
||||
if ((uVar3 & 0x400) == 0) {
|
||||
iVar4 = iVar4 << 0x10;
|
||||
}
|
||||
iVar4 = iVar4 >> 0x10;
|
||||
|
||||
if ((uVar3 & 0x800) != 0) {
|
||||
iVar4 = -iVar4;
|
||||
}
|
||||
}
|
||||
|
||||
if (0xc00 < iVar4) {
|
||||
bVar1 = ((iVar4 << 7) >> 0xc);
|
||||
}
|
||||
colorData[0] = ptrColor[0] | bVar1;
|
||||
colorData[1] = ptrColor[1] | bVar1;
|
||||
colorData[2] = ptrColor[2] | bVar1;
|
||||
colorData[3] = 0;
|
||||
return;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
#include <common.h>
|
||||
|
||||
void DECOMP_MM_Characters_BackupIDs(void) {
|
||||
char i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
// make a backup of DAT_80086e84 into DAT_8009a980 when you leave character
|
||||
// selection, when you return to character selection, DAT_8009a980 is copied
|
||||
// back to DAT_80086e84
|
||||
data.characterIDs_backup[i] = data.characterIDs[i];
|
||||
}
|
||||
return;
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
#include <common.h>
|
||||
|
||||
// if NOP'd, you can type at 80086e84 while in selection,
|
||||
// otherwise, 80086e84 will be reset to zero after typing
|
||||
void DECOMP_MM_Characters_ClearInactivePlayers(void) {
|
||||
struct GameTracker *gGT = sdata->gGT;
|
||||
char cVar1;
|
||||
int iVar2;
|
||||
char *pcVar3;
|
||||
int iVar4;
|
||||
int iVar5;
|
||||
int iVar6;
|
||||
int iVar7;
|
||||
|
||||
// 8 bytes, backed up character IDs (maybe should've been arrays?)
|
||||
int local_8 = OVR_230.characterIDBackup1;
|
||||
int local_4 = OVR_230.characterIDBackup2;
|
||||
|
||||
// if number of players is not zero
|
||||
if (gGT->numPlyrNextGame) {
|
||||
iVar2 = 0;
|
||||
for (iVar7 = 0; iVar7 < gGT->numPlyrNextGame; iVar7++) {
|
||||
// get character ID
|
||||
iVar2 = data.characterIDs[iVar7];
|
||||
// if not a secret character
|
||||
if (iVar2 < 8) {
|
||||
// save -1 (used later in func)
|
||||
*(char*)((int)&local_8 + iVar2) = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if you have more than 1 player
|
||||
if (1 < sdata->gGT->numPlyrNextGame) {
|
||||
|
||||
for (iVar7 = 1; iVar7 < gGT->numPlyrNextGame; iVar7++) {
|
||||
|
||||
for (iVar6 = 0; iVar6 < iVar5; iVar6++) {
|
||||
|
||||
if (data.characterIDs[iVar2] == data.characterIDs[iVar6]) {
|
||||
|
||||
iVar2 = 0;
|
||||
|
||||
for (iVar5 = 0; iVar5 < 8; iVar5++) {
|
||||
|
||||
// get value from $sp
|
||||
pcVar3 = (char *)((int)&local_8 + iVar2);
|
||||
|
||||
cVar1 = *pcVar3;
|
||||
// if not -1,
|
||||
// meaning this "was" a secret character
|
||||
|
||||
if (-1 < cVar1) {
|
||||
// set character ID to non-secret character
|
||||
data.characterIDs[iVar7] = (short)cVar1;
|
||||
// set to -1
|
||||
*pcVar3 = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
@ -0,0 +1,192 @@
|
||||
#include <common.h>
|
||||
|
||||
void DECOMP_MM_Characters_DrawWindows(char wheelFlag)
|
||||
{
|
||||
struct GameTracker* gGT = sdata->gGT;
|
||||
undefined2 uVar2;
|
||||
undefined2 uVar3;
|
||||
undefined4 uVar4;
|
||||
int iVar5;
|
||||
int iVar6;
|
||||
uint uVar7;
|
||||
int iVar8;
|
||||
short sVar9;
|
||||
int iVar10;
|
||||
short *psVar11;
|
||||
struct TileView* tileview;
|
||||
short *psVar13;
|
||||
int iVar14;
|
||||
undefined2 local_30;
|
||||
short local_2e;
|
||||
undefined2 local_2c;
|
||||
|
||||
if (wheelFlag != 0) {
|
||||
// enable drawing wheels
|
||||
*(unsigned int *)(gGT + 0x256c) |= 0x80;
|
||||
}
|
||||
|
||||
// if number of players is not zero
|
||||
if (gGT->numPlyrNextGame) {
|
||||
|
||||
for (iVar14 = 0; iVar14 < gGT->numPlyrNextGame; iVar14++)
|
||||
{
|
||||
psVar11 = ((short *)0x800b5a0c)[iVar14]
|
||||
iVar6 = (short *)0x800b5a3c[iVar14]
|
||||
|
||||
// tileView
|
||||
tileview = gGT->tileView[iVar14];
|
||||
|
||||
tileview->rect.x = *psVar11 + *(short *)(iVar6 + 0xa6);
|
||||
|
||||
// window width
|
||||
uVar3 = *(unsigned int*)0x800b5a30;
|
||||
|
||||
// window height
|
||||
uVar2 = *(unsigned int*)0x800b59dc;
|
||||
|
||||
tileview->rect.y = psVar11[1] + *(short *)(iVar6 + 0xa8);
|
||||
|
||||
// windowSize (X and Y)
|
||||
tileview->aspectX = uVar3;
|
||||
tileview->aspectY = uVar2;
|
||||
|
||||
// negative StartX
|
||||
if ((short)tileview->rect.x < 0) {
|
||||
tileview->aspectX -= tileview->rect.x;
|
||||
tileview->rect.x = 0;
|
||||
if ((short)tileview->aspectX < 0) {
|
||||
tileview->aspectX = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// negative StartY
|
||||
if ((short)tileview->rect.y < 0) {
|
||||
tileview->aspectY -= tileview->rect.y;
|
||||
tileview->rect.y = 0;
|
||||
if ((short)tileview->aspectY < 0) {
|
||||
tileview->aspectY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// startX + sizeX out of bounds
|
||||
if ((0x200 < (int)(short)tileview->rect.x + (int)(short)tileview->aspectX) &&
|
||||
(tileview->aspectX = (short)(0x200 - (uint)(ushort)tileview->rect.x),
|
||||
(int)((0x200 - (uint)(ushort)tileview->rect.x) * 0x10000) < 0)) {
|
||||
tileview->rect.x = 0x200;
|
||||
tileview->aspectX = 0;
|
||||
}
|
||||
|
||||
// startY + sizeY out of bounds
|
||||
if ((0xd8 < (int)(short)tileview->rect.y + (int)(short)tileview->aspectY) &&
|
||||
(tileview->aspectY = (short)(0xd8 - (uint)(ushort)tileview->rect.y),
|
||||
(int)((0xd8 - (uint)(ushort)tileview->rect.y) * 0x10000) < 0)) {
|
||||
tileview->rect.y = 0xd8;
|
||||
tileview->aspectY = 0;
|
||||
}
|
||||
|
||||
// distanceToScreen
|
||||
tileview->distanceToScreen_CURR = 0x100;
|
||||
tileview->distanceToScreen_PREV = 0x100;
|
||||
|
||||
// tileView pos and rot to all zero
|
||||
tileview->pos[0] = 0;
|
||||
tileview->pos[1] = 0;
|
||||
tileview->pos[2] = 0;
|
||||
tileview->rot[0] = 0;
|
||||
tileview->rot[1] = 0;
|
||||
tileview->rot[2] = 0;
|
||||
|
||||
// player -> instance
|
||||
iVar10 = gGT->drivers[iVar14].instSelf;
|
||||
|
||||
// Disable "AI flag"
|
||||
iVar10->flags &= 0xffffff7f;
|
||||
|
||||
// if driver loaded is not human
|
||||
if ((gGT->numPlyrNextGame <= iVar14) || (wheelFlag == 0))
|
||||
{
|
||||
// You are an AI (I think)
|
||||
iVar10->flags |= 0x80;
|
||||
}
|
||||
|
||||
// clear tileView in every InstDrawPerPlayer
|
||||
iVar10->idpp[0].tileView = 0;
|
||||
iVar10->idpp[1].tileView = 0;
|
||||
iVar10->idpp[2].tileView = 0;
|
||||
iVar10->idpp[3].tileView = 0;
|
||||
|
||||
// set tileView in InstDrawPerPlayer,
|
||||
// so that each camera can only see one driver
|
||||
iVar10->idpp[iVar14].tileView = puVar12;
|
||||
|
||||
psVar13 = &DAT_800b59f8[iVar14];
|
||||
iVar10->animFrame = 0;
|
||||
iVar10->vertSplit = 0;
|
||||
|
||||
uVar4 = MM_Characters_SearchModelByString(data.MetaDataCharacters[(int)*psVar13].name_Debug);
|
||||
|
||||
// set modelPtr in Instance
|
||||
iVar10->modelPtr = uVar4;
|
||||
|
||||
// CameraDC, freecam mode
|
||||
gGT->CameraDC[iVar6] = 3;
|
||||
|
||||
// Set position of player
|
||||
iVar10->matrix.t[0] = *(int*)0x800b5360;
|
||||
iVar10->matrix.t[1] = *(int*)0x800b5362;
|
||||
iVar10->matrix.t[2] = *(int*)0x800b5364;
|
||||
|
||||
psVar11 = &DAT_800b5a24 + iVar6;
|
||||
sVar9 = *psVar11 + -1;
|
||||
|
||||
// If no transition between players
|
||||
if (*psVar11 == 0) {
|
||||
// compare to character ID
|
||||
if (*psVar13 != data.characterIDs[iVar6]) {
|
||||
*psVar11 = (short)(*(int*)0x800b536e << 1);
|
||||
&DAT_800b59f0[iVar6] = data.characterIDs[iVar6];
|
||||
}
|
||||
}
|
||||
|
||||
// if transition between players
|
||||
else {
|
||||
// get timer
|
||||
*psVar11 = sVar9;
|
||||
|
||||
// if timer is before midpoint
|
||||
if ((int)sVar9 < (int)DAT_800b536e) {
|
||||
// make driver fly off screen
|
||||
*psVar13 = (&DAT_800b59f0)[iVar6];
|
||||
iVar5 = TitleFlag_MoveModels();
|
||||
|
||||
// direction moving
|
||||
iVar6 = -(int)(short)(&DAT_800b59e8)[iVar6];
|
||||
iVar8 = iVar5 * DAT_800b5370 >> 0xc;
|
||||
}
|
||||
|
||||
// if timer is after midpoint
|
||||
else {
|
||||
// make new driver fly on screen
|
||||
iVar5 = TitleFlag_MoveModels((int)sVar9 - (int)DAT_800b536e);
|
||||
|
||||
// direction moving
|
||||
iVar8 = (int)(short)(&DAT_800b59e8)[iVar6];
|
||||
iVar6 = (0x1000 - iVar5) * (int)DAT_800b5370 >> 0xc;
|
||||
}
|
||||
|
||||
iVar10->matrix.t[0] += iVar6 * iVar8;
|
||||
}
|
||||
|
||||
// driver rotation
|
||||
local_2c = DAT_800b536c;
|
||||
local_30 = DAT_800b5368;
|
||||
local_2e = DAT_800b536a + *(short *)((int)&DAT_800b5a00 + ((iVar14 << 0x10) >> 0xf));
|
||||
|
||||
// convert 3 rotation shorts into rotation matrix
|
||||
ConvertRotToMatrix(&iVar10->matrix.m[0][0], &local_30);
|
||||
|
||||
iVar10 = iVar14 * 0x10000;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
#include <common.h>
|
||||
|
||||
int DECOMP_MM_Characters_GetNextDriver(short dpad, char characterID)
|
||||
{
|
||||
char nextDriver;
|
||||
char unlocked;
|
||||
char newDriver;
|
||||
|
||||
// param_1 is the direction you hit on d-pad (up, down, left, right)
|
||||
// param_2 is driver you currently have highlighted
|
||||
|
||||
// 800b5a18 is pointer to array of character icons
|
||||
// each character icon is 0xc bytes large
|
||||
|
||||
// offset 4 is 4-byte array of which driver you get when you press on D-Pad
|
||||
nextDriver = *(char*)0x800b5a1c[characterID] + dpad;
|
||||
|
||||
// offset 10 (0xA) determines if that driver is unlocked
|
||||
unlocked = *(u_char*)0x800b5a22[bVar1];
|
||||
|
||||
// set new driver to the driver
|
||||
// you'd get when pressing Up button
|
||||
newDriver = nextDriver;
|
||||
|
||||
if (
|
||||
// if desired driver is not unlocked
|
||||
(unlocked != -1) &&
|
||||
|
||||
((sdata->GameProgress.unlocks)[unlocked] >> (unlocked & 1) == 0)) {
|
||||
|
||||
// set new driver to the driver you already have
|
||||
newDriver = characterID;
|
||||
}
|
||||
|
||||
// return new driver
|
||||
return newDriver;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
#include <common.h>
|
||||
|
||||
void DECOMP_MM_Characters_HideDrivers(void) {
|
||||
char i;
|
||||
struct GameTracker *gGT = sdata->gGT;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
TileView_Init(gGT->tileView[i], 0, 1);
|
||||
// player structure's instane flags, make invisible
|
||||
gGT->drivers[i].instSelf->flags |= 0x80;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
#include <common.h>
|
||||
|
||||
void DECOMP_MM_Characters_RestoreIDs(void) {
|
||||
struct GameTracker *gGT = sdata->gGT;
|
||||
short *currID;
|
||||
int iVar3;
|
||||
int iVar4;
|
||||
char i;
|
||||
|
||||
// erase select bits
|
||||
sdata->characterSelectFlags = 0;
|
||||
OVR_230.transitionFrames = 0xc;
|
||||
OVR_230.isMenuTransitioning = 0;
|
||||
|
||||
// This uses 80086e84, which controls character IDs
|
||||
// loop 8 times
|
||||
// shouldn't it only need to loop a maximum of 4 times?
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
// set character ID to the last ID you entered
|
||||
data.characterIDs[i] = data.characterIDs_backup[i];
|
||||
}
|
||||
|
||||
MM_Characters_SetMenuLayout();
|
||||
|
||||
// PTR_DAT_800b5a18 goes to CrashIconX
|
||||
// This changes for the three menus
|
||||
// 1P + 2P 800B4E80
|
||||
// 3P 800B4F34
|
||||
// 4P 800B4FE8
|
||||
iVar3 = *(int*)0x800b5a18;
|
||||
|
||||
//
|
||||
for (i = 0; i < 0xf; i++) {
|
||||
// Changes ID of Icon without changing image of icon
|
||||
// Changing Crash's ID at 800B50B4 makes it so going to
|
||||
// Crash's Icon will teleport the cursor somehwere else
|
||||
|
||||
// Basically sets them to 0, 1, 2, 3, 4... up to 0xE,
|
||||
// setting Oxide's manually to 0xF is needed to make his icon appear
|
||||
|
||||
OVR_230.characterIcon[*(short*)0x800b5a20[i]] = i;
|
||||
}
|
||||
|
||||
// if number of players is not zero
|
||||
if (gGT->numPlyrNextGame) {
|
||||
|
||||
iVar4 = 0
|
||||
|
||||
for (i = 0; i < gGT->numPlyrNextGame; i++) {
|
||||
// Determine if this icon is unlocked (and drawing)
|
||||
|
||||
// get character ID
|
||||
currID = data.characterIDs[i];
|
||||
|
||||
// get unlock requirement for this character
|
||||
uVar1 = *(short *)(((int*)0x800b5a22)[currID]);
|
||||
|
||||
if (
|
||||
// If Icon has an unlock requirement
|
||||
(uVar1 != -1) &&
|
||||
// If Character is Locked
|
||||
(sdata->GameProgress.unlocks[currID] >> uVar1 & 1) == 0) {
|
||||
// change character to Crash
|
||||
*currID = 0;
|
||||
}
|
||||
iVar4 = i * 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
MM_Characters_ClearInactivePlayers();
|
||||
|
||||
// if number of players is not zero
|
||||
if (gGT->numPlyrNextGame) {
|
||||
for (i = 0; i < gGT->numPlyrNextGame; i++) {
|
||||
|
||||
// set name string ID to the character ID of each player.
|
||||
// The string will only draw if both these variables match
|
||||
(&DAT_800b59f8)[i] = data.characterIDs[i];
|
||||
(&DAT_800b59f0)[i] = data.characterIDs[i];
|
||||
|
||||
// something to do with transitioning between icons
|
||||
OVR_230.fill_isMenuTransitioning2[i] = 0;
|
||||
|
||||
// rotation of each driver, 90 degrees difference
|
||||
(&DAT_800b5a00)[i] = (i * 0x400) + 400;
|
||||
}
|
||||
}
|
||||
|
||||
MM_Characters_DrawWindows(0);
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
#include <common.h>
|
||||
|
||||
// Search for character model by string,
|
||||
// specific to main menu lev, altered in oxide mod
|
||||
struct Model* DECOMP_MM_Characters_SearchModelByString(int *name) {
|
||||
struct Model** models;
|
||||
struct Model* model;
|
||||
|
||||
// if LEV is valid
|
||||
if (sdata->gGT->level1 != NULL)
|
||||
return NULL;
|
||||
|
||||
models = sdata->gGT->level1->ptrModelsPtrArray;
|
||||
// loop through all models until nullptr is found
|
||||
for (model = models[0]; model != NULL; models += 1, model = models[0]) {
|
||||
// if model exists, check first 4 bytes for name
|
||||
if (*model == *name) {
|
||||
// return model pointer
|
||||
return model;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
#include <common.h>
|
||||
|
||||
void MM_Characters_SetMenuLayout(void)
|
||||
{
|
||||
unsigned short unlocked;
|
||||
char expand = 0;
|
||||
char numPlyr = sdata->gGT->numPlyrNextGame;
|
||||
int iVar3;
|
||||
int i;
|
||||
|
||||
// By default, draw "Select character" in 3P menu
|
||||
OVR_230.isRosterExpanded = 0;
|
||||
|
||||
// By default, array of character IDs is
|
||||
// grabbed from array of pointers to arrays of character IDs,
|
||||
// it can be index 0,1,2,3
|
||||
OVR_230.characterSelectIconLayout = numPlyr - 1;
|
||||
|
||||
// Loop through all characters,
|
||||
// If a character is unlocked that covers
|
||||
// the top row (Joe, Penta, Fake Crash)
|
||||
// Then dont draw "Select character"
|
||||
|
||||
for (i = 0; i < 0xf; i++) {
|
||||
unlocked = OVR_230.csm_1P2P[i].characterID; // 800B4E8A
|
||||
if ((sdata->gameProgress->unlocks[unlocked >> 5] >> unlocked & 1) != 0) {
|
||||
|
||||
// enough characters are unlocked for expanded menu
|
||||
// menu is expanded, stop drawing "select character"
|
||||
OVR_230.isRosterExpanded = expand;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
// if there are less than 3 players
|
||||
(numPlyr < 3) &&
|
||||
// if very few characters are unlocked
|
||||
(!expand)
|
||||
) {
|
||||
// get new pointer to array of character IDs with less icons
|
||||
OVR_230.characterSelectIconLayout = numPlyr + 3;
|
||||
}
|
||||
|
||||
// set final index to array of pointers of character IDs
|
||||
iVar3 = OVR_230.characterSelectIconLayout;
|
||||
|
||||
// get driver posY from array
|
||||
*(int*)0x800b5362 = ((int*)0x800b4db4)[iVar3];
|
||||
|
||||
// get driver posZ from array
|
||||
*(int*)0x800b5364 = ((int*)0x800b4da8)[iVar3];
|
||||
|
||||
// get window height from array
|
||||
*(int*)0x800b59dc = ((int*)0x800b4d9c)[iVar3];
|
||||
|
||||
// pointer to array of driver window positions,
|
||||
// this can be used to dynamically erase any driver window
|
||||
// of any player in any menu, for Oxide in menus
|
||||
*(int*)0x800b5a0c = OVR_230.ptrSelectWindowPos[iVar3];
|
||||
|
||||
// set pointer to array of driver icons
|
||||
// If you ever want to make new driver arrays for oxide,
|
||||
// change the pointers at 800b509c to do it
|
||||
*(int*)0x800b5a18 = OVR_230.ptr_csm_1P[iVar3];
|
||||
|
||||
// get window width from array
|
||||
*(int*)0x800b5a30 = ((int*)0x800b4d90)[iVar3];
|
||||
|
||||
// Get position of text relative to window position
|
||||
*(int*)0x800b5a38 = ((int*)0x800b4dc0)[iVar3];
|
||||
|
||||
*(int*)0x800b5a3c = OVR_230.ptr_transitionMeta_csm[numPlyr - 1];
|
||||
return;
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
#include <common.h>
|
||||
|
||||
int DECOMP_MM_TransitionInOut(u_short *param_1,int param_2,short numFrames)
|
||||
{
|
||||
char bVar1;
|
||||
short uVar2;
|
||||
int iVar3;
|
||||
short *puVar4;
|
||||
int iVar5;
|
||||
short sVar6;
|
||||
|
||||
bVar1 = 1;
|
||||
sVar6 = 0;
|
||||
uVar2 = param_1[2];
|
||||
if (-1 < (short)param_1[2]) {
|
||||
iVar5 = (int)numFrames;
|
||||
puVar4 = param_1 + 2;
|
||||
do {
|
||||
if ((int)((param_2 - (u_int)uVar2) == 4) && (sVar6 == 0))
|
||||
{
|
||||
// Play "swoosh" sound for menu transition
|
||||
OtherFX_Play(0x65,0);
|
||||
}
|
||||
iVar3 = (int)(param_2 - (u_int)uVar2);
|
||||
if (iVar3 < 1) {
|
||||
bVar1 = 0;
|
||||
puVar4[1] = 0;
|
||||
puVar4[2] = 0;
|
||||
}
|
||||
else {
|
||||
if (iVar3 < iVar5) {
|
||||
if (iVar5 == 0) {
|
||||
trap(0x1c00);
|
||||
}
|
||||
if ((iVar5 == -1) && (iVar3 * (short)*param_1 == -0x80000000)) {
|
||||
trap(0x1800);
|
||||
}
|
||||
if (iVar5 == 0) {
|
||||
trap(0x1c00);
|
||||
}
|
||||
if ((iVar5 == -1) && (iVar3 * (short)puVar4[-1] == -0x80000000)) {
|
||||
trap(0x1800);
|
||||
}
|
||||
uVar2 = (u_short)((iVar3 * (short)puVar4[-1]) / iVar5);
|
||||
bVar1 = 0;
|
||||
puVar4[1] = (u_short)((iVar3 * (short)*param_1) / iVar5);
|
||||
}
|
||||
else {
|
||||
uVar2 = puVar4[-1];
|
||||
puVar4[1] = *param_1;
|
||||
}
|
||||
puVar4[2] = uVar2;
|
||||
}
|
||||
puVar4 = puVar4 + 5;
|
||||
param_1 = param_1 + 5;
|
||||
uVar2 = *puVar4;
|
||||
sVar6 = sVar6 + 1;
|
||||
} while (-1 < (short)*puVar4);
|
||||
}
|
||||
return bVar1;
|
||||
}
|
@ -520,7 +520,7 @@ void MM_Characters_MenuBox()
|
||||
// if character is unlocked
|
||||
// from 4-byte variable that handles all rewards
|
||||
// also the variable written by cheats
|
||||
(((u_int)(&sdata->gameProgress.unlocks[0])[iVar8] >> (psVar18[4] & 0x1fU) & 1) != 0)
|
||||
((sdata->gameProgress.unlocks[iVar8] >> psVar18[4] & 1) != 0)
|
||||
)
|
||||
{
|
||||
iconColor = &OVR_230.characterSelect_NeutralColor;
|
||||
|
@ -0,0 +1,121 @@
|
||||
#include <common.h>
|
||||
|
||||
void DECOMP_BOTS_Driver_Convert(struct Driver *d) {
|
||||
struct GameTracker *gGT = sdata->gGT;
|
||||
char validPath;
|
||||
short numPoints;
|
||||
int i, pathIndex;
|
||||
unsigned int navFrame;
|
||||
unsigned int actionFlag;
|
||||
|
||||
// if this racer is not an AI (player)
|
||||
if ((d->actionFlagsSet & 0x100000) == 0) {
|
||||
|
||||
UI_RaceEnd_GetDriverClock(d);
|
||||
|
||||
// nav path index of this driver
|
||||
pathIndex = sdata->driver_pathIndexIDs[d->driverID];
|
||||
|
||||
validPath = 0;
|
||||
|
||||
// number of nav points on this path
|
||||
numPoints = sdata->NavPath_ptrHeader[pathIndex]->numPoints);
|
||||
|
||||
// ============
|
||||
|
||||
// same as BOTS_Driver_Init
|
||||
// check if nav path data exists
|
||||
|
||||
// ============
|
||||
|
||||
// if invalid path
|
||||
if (numPoints == 0) {
|
||||
// check all paths
|
||||
for (i = 0; i < 3; i++) {
|
||||
// quit loop when found
|
||||
if (sdata->NavPath_ptrHeader[i]->numPoints != 0) {
|
||||
// valid path data was found
|
||||
validPath = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LAB_800173e4:
|
||||
|
||||
// if valid path data was found
|
||||
if (validPath) {
|
||||
// 0x94 chunk in driver struct?
|
||||
memset(*(int *)(d + 0x598), 0, 0x94);
|
||||
|
||||
// path index
|
||||
pathIndex = i * 4;
|
||||
|
||||
*(int *)(d + 0x5d0) = d->ySpeed;
|
||||
|
||||
// nav path index
|
||||
*(short *)(d + 0x5b8) = pathIndex;
|
||||
|
||||
// AI speed
|
||||
*(int *)(d + 0x5d4) = d->speedApprox;
|
||||
|
||||
// pointer to first navFrame on path
|
||||
navFrame = sdata->NavPath_ptrNavFrameArray[pathIndex];
|
||||
|
||||
*(int *)(d + 0x5a8) = 0;
|
||||
d->unknownDimension2Curr = 0;
|
||||
d->multiDrift = 0;
|
||||
d->ampTurnState = 0;
|
||||
d->set_0xF0_OnWallRub = 0;
|
||||
|
||||
// current navFrame
|
||||
*(int *)(d + 0x5a4) = navFrame;
|
||||
|
||||
// driver -> instance -> thread -> funcThTick =
|
||||
d->instSelf->thread->funcThTick = BOTS_ThTick_Drive;
|
||||
|
||||
// if you are in battle mode
|
||||
if ((gGT->gameMode1 & 0x20) != 0) {
|
||||
// pointer to each AI Path Header
|
||||
piVar8 = &sdata->NavPath_ptrHeader[iVar10];
|
||||
|
||||
// set the X, Y, and Z positions
|
||||
d->posCurr[0] = (int)piVar8->frame->pos[0] << 8;
|
||||
d->posCurr[1] = (int)piVar8->frame->pos[1] << 8;
|
||||
d->posCurr[2] = (int)piVar8->frame->pos[2] << 8;
|
||||
}
|
||||
|
||||
// (free or taken?)
|
||||
LIST_AddFront(&DAT_8008daf8[pathIndex], *(int *)(d + 0x598));
|
||||
|
||||
BOTS_SetRotation(d, 0);
|
||||
|
||||
GAMEPAD_Vib_2(d, 0, 0);
|
||||
|
||||
actionFlag = d->actionFlagsSet;
|
||||
|
||||
// player becomes AI, drop bits for button holding
|
||||
d->actionFlagsSet &= 0xfffffff3 | 0x100000;
|
||||
|
||||
// if previous value of actions flag set had 26th flag on (means racer
|
||||
// finished the race)
|
||||
if ((actionFlag & 0x2000000) != 0) {
|
||||
CAM_EndOfRace(gGT->cameraDC[d->driverID], d);
|
||||
}
|
||||
|
||||
// Kart state:
|
||||
switch (d->kartState) {
|
||||
// if racer is spinning
|
||||
case 3:
|
||||
navFrame = 1;
|
||||
// if racer is blasted
|
||||
case 6:
|
||||
navFrame = 2;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
BOTS_ChangeState(d, navFrame, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
#include <common.h>
|
||||
|
||||
void DECOMP_DebugFont_DrawNumbers(int number, u_int posX, int posY)
|
||||
{
|
||||
POLY_FT4* p;
|
||||
u_long* ot;
|
||||
u_int uVar4;
|
||||
u_int uVar5;
|
||||
u_int uVar6;
|
||||
|
||||
uVar6 = posX + 7 & 0xffff;
|
||||
uVar4 = (posY + 7) * 0x10000;
|
||||
|
||||
// backBuffer->primMem.curr
|
||||
p = (POLY_FT4*)sdata->gGT->backBuffer->primMem.curr;
|
||||
|
||||
// pointer to OT memory
|
||||
ot = sdata->gGT->tileView_UI.ptrOT;
|
||||
|
||||
// backBuffer->primMem.curr
|
||||
sdata->gGT->backBuffer->primMem.curr = p + 1;
|
||||
|
||||
*(int*)&p->r0 = 0x2e000000;
|
||||
p->x0 = posX & 0xffff | posY << 0x10;
|
||||
p->x1 = uVar6 | posY << 0x10;
|
||||
p->x2 = posX & 0xffff | uVar4;
|
||||
p->x3 = uVar6 | uVar4;
|
||||
|
||||
// each character is 7 pixels wide
|
||||
// and 7 pixels tall
|
||||
|
||||
// '0' is 6th character in 2nd row,
|
||||
// Get X value of pixel
|
||||
// This is the bottom of two bytes
|
||||
uVar4 = sdata->debugFont.pixelX + (number + 5) * 7;
|
||||
|
||||
// Get Y value for top of the quad
|
||||
// bit shift to top byte
|
||||
uVar6 = (sdata->debugFont.pixelY + 7) * 0x100;
|
||||
|
||||
// Get Y value for bottom of the quad1
|
||||
// bit shift to top byte
|
||||
uVar5 = (uVar6 + 7) * 0x100;
|
||||
|
||||
// Top Left corner
|
||||
p->u0 = uVar4 | uVar6;
|
||||
|
||||
// Top Right corner
|
||||
p->u1 = uVar4 + 7 | uVar6;
|
||||
|
||||
// Bottom Left corner
|
||||
p->u2 = uVar4 | uVar5;
|
||||
|
||||
// Bottom Right corner
|
||||
p->u3 = uVar4 + 7 | uVar5;
|
||||
|
||||
// color palette
|
||||
p->clut = sdata->debugFont.clut;
|
||||
|
||||
// texture page
|
||||
p->tpage = sdata->debugFont.tpage;
|
||||
|
||||
*(int*)p = *ot | 0x9000000;
|
||||
*ot = (u_int)p & 0xffffff;
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
// called "EffectSfx" for no good reason,
|
||||
// but is related to rain sounds, no proof of name
|
||||
|
||||
// this func handle rain on tiger temple and cortex castle
|
||||
void EffectSfxRain_MakeSound(struct GameTracker *gGT) {
|
||||
int i, lev;
|
||||
unsigned int rained;
|
||||
|
||||
rained = 0;
|
||||
lev = gGT->levelID;
|
||||
|
||||
// if you are not in
|
||||
if (
|
||||
// Tiger Temple
|
||||
(lev != 4)
|
||||
// Cortex Castle
|
||||
&& (lev != 10)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if numPlyrCurrGame is not zero
|
||||
if (gGT->numPlyrCurrGame) {
|
||||
for (i = 0; i < gGT->numPlyrCurrGame; i++) {
|
||||
rained |= gGT->rainBuffer[i];
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// if at least one is rained on
|
||||
if (rained) {
|
||||
// if there is no rain
|
||||
if (gGT->rainVariable == 0) {
|
||||
// now there is rain
|
||||
gGT->rainVariable = OtherFX_Play(0x82, 0);
|
||||
}
|
||||
}
|
||||
// if nobody is rained on
|
||||
else {
|
||||
// if it's raining
|
||||
if (gGT->rainVariable != 0) {
|
||||
OtherFX_Stop1();
|
||||
// no more rain
|
||||
gGT->rainVariable = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void EffectSfxRain_Reset(struct gameTracker *gGT) {
|
||||
gGT->rainVariable = 0;
|
||||
return;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#include <common.h>
|
||||
|
||||
int DECOMP_CountSounds(void)
|
||||
{
|
||||
// watch it increase when scrolling in main menu
|
||||
sdata->countSounds += 1;
|
||||
if (sdata->countSounds < 1) {
|
||||
sdata->countSounds = 1;
|
||||
}
|
||||
return sdata->countSounds;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#include <common.h>
|
||||
|
||||
void Cutscene_VolumeBackup(void)
|
||||
{
|
||||
// enter critical section
|
||||
Smart_EnterCriticalSection();
|
||||
|
||||
// make a copy of FX volume
|
||||
sdata->currentVolume = howl_VolumeGet(0);
|
||||
|
||||
// make another copy volume of FX and clamp to 0x100
|
||||
sdata->storedVolume = sdata->currentVolume;
|
||||
sdata->currentVolume &= 0xff;
|
||||
|
||||
// copy exists
|
||||
sdata->boolStoringVolume = 1;
|
||||
|
||||
// exit critical section
|
||||
Smart_ExitCriticalSection();
|
||||
|
||||
return;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
#include <common.h>
|
||||
|
||||
void Cutscene_VolumeRestore(void)
|
||||
{
|
||||
// enter critical section
|
||||
Smart_EnterCriticalSection();
|
||||
|
||||
// copy does not exist
|
||||
sdata->boolStoringVolume = 0;
|
||||
|
||||
// Set volume of FX
|
||||
howl_VolumeSet(0,sdata->storedVolume);
|
||||
|
||||
// exit critical section
|
||||
Smart_ExitCriticalSection();
|
||||
|
||||
return;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
#include <common.h>
|
||||
|
||||
void Smart_EnterCriticalSection(void)
|
||||
{
|
||||
char alreadyEntered;
|
||||
int iVar2;
|
||||
// Add 1 to the number of times you've
|
||||
// tried to enter a critical section
|
||||
iVar2 = sdata->criticalSectionCount + 1;
|
||||
|
||||
// Check if you're already in a critical section
|
||||
alreadyEntered = (sdata->criticalSectionCount == 0);
|
||||
|
||||
// Set the number of times you've
|
||||
// tried to enter a critical section
|
||||
sdata->criticalSectionCount = iVar2;
|
||||
|
||||
// if you are not already in critical section
|
||||
if (alreadyEntered)
|
||||
{
|
||||
// enter the critical section
|
||||
Smart_EnterCriticalSection();
|
||||
}
|
||||
return;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
#include <common.h>
|
||||
|
||||
void Smart_ExitCriticalSection(void)
|
||||
{
|
||||
if (
|
||||
// if you're already in a critical section
|
||||
(sdata->criticalSectionCount != 0) &&
|
||||
|
||||
// reduce the number of times you've tried to exit, by 1
|
||||
(sdata->criticalSectionCount += -1,
|
||||
|
||||
// if you have no more active needs to be in a critical section
|
||||
sdata->criticalSectionCount == 0))
|
||||
{
|
||||
// You are no longer in a critical section
|
||||
Smart_ExitCriticalSection();
|
||||
}
|
||||
return;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
|
||||
#include <common.h>
|
||||
|
||||
// Only used for drawing player comments
|
||||
void DECOMP_MenuBox_DrawQuip(char* comment,short posX,int posY,u_int sizeX,short fontType,
|
||||
int flags,short param_7)
|
||||
{
|
||||
int lineWidth;
|
||||
short posX;
|
||||
u_int posY;
|
||||
u_int sizeX;
|
||||
u_int sizeY;
|
||||
|
||||
if ((sizeX & 0xffff) == 0)
|
||||
{
|
||||
lineWidth = DecalFont_GetLineWidth(comment,(int)fontType);
|
||||
sizeX = lineWidth + 0xc;
|
||||
}
|
||||
|
||||
// if text is not centered
|
||||
if ((flags & 0x8000U) != 0)
|
||||
{
|
||||
// posX with text un-centered
|
||||
posX = posX - (short)(((int)(sizeX << 0x10) >> 0x10) - ((int)(sizeX << 0x10) >> 0x1f) >> 1);
|
||||
}
|
||||
|
||||
sizeY = (u_int)data.PlayerCommentBoxParams[0][fontType];
|
||||
|
||||
// Draw string
|
||||
DecalFont_DrawLine(comment,
|
||||
posX,(data.PlayerCommentBoxParams[1][lineWidth] + posY),
|
||||
fontType, flags);
|
||||
|
||||
// Draw 2D Menu rectangle background
|
||||
MenuBox_DrawFullRect(&posX,(int)param_7, sdata->gGT->backBuffer->otMem.startPlusFour);
|
||||
return;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
#include <common.h>
|
||||
|
||||
int DECOMP_MixRNG_Scramble()
|
||||
{
|
||||
// random algorithm for seemingly-random numbers
|
||||
sdata->randomNumber = sdata->randomNumber * 0x6255 + 0x3619 & 0xffff;
|
||||
return sdata->randomNumber;
|
||||
}
|
||||
int DECOMP_MixRNG_Particles(int numParticle)
|
||||
{
|
||||
return (int)((RngDeadCoed(sdata->gGT->deadcoed_struct.unk1 & 0xffff) * numParticle) >> 0x10);
|
||||
}
|
||||
|
||||
u_int DECOMP_MixRNG_GetValue(int val)
|
||||
{
|
||||
return val * 0x6255 + 0x3619U & 0xffff;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
#include <common.h>
|
||||
|
||||
// param1 is thread checked for collision
|
||||
// param2 is WeaponSearchData
|
||||
// param3 is person who used weapon
|
||||
void DECOMP_THREAD_CollideHitboxWithBucket(struct Thread* collThread,struct WeaponSearchData* param_2,int param_3)
|
||||
{
|
||||
struct Instance* inst;
|
||||
int distX, distY, distZ;
|
||||
|
||||
// if thread is valid
|
||||
if (collThread != NULL) return;
|
||||
do
|
||||
{
|
||||
// if child thread exists
|
||||
if (collThread->childThread != NULL)
|
||||
{
|
||||
// recursively check all children
|
||||
THREAD_CollideHitboxWithBucket(collThread->childThread,param_2,param_3);
|
||||
}
|
||||
|
||||
if (
|
||||
// make sure you dont hit your own weapon???
|
||||
(collThread->next != param_3) &&
|
||||
|
||||
// if collision is not disabled for this thread,
|
||||
// and if this thread is not dead
|
||||
((collThread->flags & 0x1800) == 0)
|
||||
)
|
||||
{
|
||||
// get instance
|
||||
inst = collThread->inst;
|
||||
|
||||
// get distance of X, Y, Z
|
||||
distX = (int)param_2->pos[0] - inst->matrix.t[0];
|
||||
distY = (int)param_2->pos[1] - inst->matrix.t[1];
|
||||
distZ = (int)param_2->pos[2] - inst->matrix.t[2];
|
||||
|
||||
// if all the dist values are small
|
||||
if ((distX * distX < 0x10000000) &&
|
||||
(distY * distY < 0x10000000) &&
|
||||
(distZ * distZ < 0x10000000) &&
|
||||
// if abs distance is less than collision radius
|
||||
(distX * distX + distY * distY + distZ * distZ < param_2->hitRadiusSquared)
|
||||
)
|
||||
{
|
||||
// save distancdistX param_2->pos[8] = (short)iVardistX param_2->pos[9] = (short)iVardistX param_2->pos[10] = (short)iVar1;
|
||||
// some collision funcPtr???
|
||||
(**(code **)param_2->funcCallback)(param_2,collThread);
|
||||
}
|
||||
}
|
||||
// thread = thread->sibling;
|
||||
collThread = collThread->siblingThread;
|
||||
} while (collThread != NULL);
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
#include <common.h>
|
||||
|
||||
void THREAD_PerVisData_CheckInstances(struct VisData* param_1, struct WeaponSearchData* param_2)
|
||||
{
|
||||
int distX, distY, distZ;
|
||||
struct VisData* piVar4;
|
||||
struct InstDef* piVar5;
|
||||
|
||||
piVar4 = param_1->data.leaf.ptrVisDataArray_InstHitboxes;
|
||||
|
||||
if (piVar4 != NULL) return;
|
||||
|
||||
// loop through all hitboxes
|
||||
//+(8 * 0x4) = +0x20 bytes, size of VisData
|
||||
for (piVar5 = param_1->data.hitbox.instDef; piVar4->flag != 0; piVar4 += 8, piVar5 += 8)
|
||||
{
|
||||
if (
|
||||
((piVar4->flag & 0x80) != 0)
|
||||
&&
|
||||
((piVar5->name == NULL || (piVar5->ptrInstance->flags & 0xf) != 0))
|
||||
) {
|
||||
distX = (int)param_2->pos[0] - (int)*(short *)(piVar4 + -1);
|
||||
distY = (int)param_2->pos[1] - (int)*(short *)((int)piVar4 + -2);
|
||||
distZ = (int)param_2->pos[2] - (int)*(short *)piVar4;
|
||||
|
||||
// if all the dist values are small
|
||||
if ((distX * distX < 0x10000000) &&
|
||||
(distY * distY < 0x10000000) &&
|
||||
(distZ * distZ < 0x10000000) &&
|
||||
// if abs distance is less than collision radius
|
||||
(distX * distX + distY * distY + distX * distX < param_2->hitRadiusSquared)) {
|
||||
|
||||
// distX param_2->pos[10] = (short)iVardistX param_2->pos[9] = (short)iVardistX param_2->pos[8] = (short)iVar3;
|
||||
|
||||
// short+0x14 = byte+0x28,
|
||||
// callback on collision
|
||||
|
||||
// either for colliding with lev object or nonLev
|
||||
**(code **)(param_2->funcCallback)(param_2,piVar5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
#include <common.h>
|
||||
|
||||
void THREAD_PerVisData_CheckInstances();
|
||||
|
||||
void DECOMP_THREAD_StartSearch_Self(struct WeaponSearchData* param)
|
||||
{
|
||||
struct GameTracker* gGT = sdata->gGT;
|
||||
short sVar1;
|
||||
|
||||
// box half-length
|
||||
sVar1 = param->hitRadius;
|
||||
|
||||
// position of object hitting
|
||||
// tiger temple teeth
|
||||
|
||||
// param[0] = posX,
|
||||
// param[1] = posY,
|
||||
// param[2] = posZ,
|
||||
|
||||
// Make hitbox, min and max x,y,z
|
||||
param->min[0] = param->pos[0] - sVar1;
|
||||
param->min[1] = param->pos[1] - sVar1;
|
||||
param->min[2] = param->pos[2] - sVar1;
|
||||
param->max[0] = param->pos[0] + sVar1;
|
||||
param->max[1] = param->pos[1] + sVar1;
|
||||
param->max[2] = param->pos[2] + sVar1;
|
||||
|
||||
COLL_SearchTree_FindX(&gGT->level1->ptrModelsPtrArray,param->funcCallback,THREAD_PerVisData_CheckInstances);
|
||||
return;
|
||||
}
|
@ -663,20 +663,20 @@ void DECOMP_UI_CupStandings_UpdateCupRanks(void)
|
||||
puVar16 = ((int) & local_50 + difficulty * 2);
|
||||
|
||||
// add cupID to bit
|
||||
uVar6 = (int) puVar16 + gGT->cup.cupID;
|
||||
uVar6 = (int)puVar16[gGT->cup.cupID];
|
||||
|
||||
// byte index
|
||||
byteIndex = (int) uVar6 >> 5;
|
||||
|
||||
// Save record that this cup, on this difficulty, was won
|
||||
sdata->gameProgress.unlocks[byteIndex] = sdata->gameProgress.unlocks[byteIndex] | 1 << (uVar6 & 0x1f);
|
||||
sdata->gameProgress.unlocks[byteIndex] |= 1 << uVar6;
|
||||
|
||||
// bit index of cup completion on this difficulty (prior to now)
|
||||
uVar6 = (int)((int) & local_48 + difficulty * 2) + gGT->cup.cupID;
|
||||
|
||||
// If this cup was not previuosly beaten on this difficulty,
|
||||
// and this is the first time the cup was won
|
||||
if (((u_int) sdata->gameProgress.unlocks[(int) uVar6 >> 5] >> (uVar6 & 0x1f) & 1) == 0) {
|
||||
if ((sdata->gameProgress.unlocks[byteIndex] >> uVar6 & 1) == 0) {
|
||||
|
||||
// gGT->0x8 | 0x1000,
|
||||
// lets 233 know to prompt the Save Game box
|
||||
@ -692,7 +692,7 @@ void DECOMP_UI_CupStandings_UpdateCupRanks(void)
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
||||
// if any of four cups on this difficulty was not won
|
||||
if (((u_int) sdata->gameProgress.unlocks[(int) uVar6 >> 5] >> (uVar6 & 0x1f) & 1) == 0) {
|
||||
if ((sdata->gameProgress.unlocks[uVar6 >> 5] >> uVar6 & 1) == 0) {
|
||||
// you dont deserve to unlock a battle map
|
||||
wonCup = false;
|
||||
break;
|
||||
|
@ -1,119 +0,0 @@
|
||||
#include <common.h>
|
||||
|
||||
void Turbo_Increment(int param_1, int param_2, u_int param_3, int param_4);
|
||||
void Voiceline_RequestPlay(u_int param_1, u_int param_2, u_int param_3);
|
||||
|
||||
void DECOMP_UI_JumpMeter_Update(struct Driver* driver)
|
||||
{
|
||||
short jumpMeter;
|
||||
int jumpMeterMinus32ms;
|
||||
|
||||
//if player is not in the air
|
||||
if ((driver->actionsFlagSet & 0x80000) == 0)
|
||||
{
|
||||
//if, in previous frame? player was not in the air either
|
||||
if ((driver->actionsFlagSetPrevFrame & 0x80000) == 0)
|
||||
{
|
||||
//if Jump meter Timer is done
|
||||
if (driver->jumpMeterTimer == 0)
|
||||
{
|
||||
//reset Jump meter
|
||||
driver->jumpMeter = 0;
|
||||
}
|
||||
|
||||
//if Jump meter Timer is not done
|
||||
else
|
||||
{
|
||||
jumpMeterMinus32ms = (u_int)driver->jumpMeterTimer - (u_int)*(u_short *)sdata->gGT->elapsedTimeMS;
|
||||
|
||||
//reduce Jump meter Timer by ~32ms
|
||||
driver->jumpMeterTimer = (short)jumpMeterMinus32ms;
|
||||
|
||||
//if Jump meter Timer goes negative
|
||||
if (jumpMeterMinus32ms * 0x10000 < 0)
|
||||
{
|
||||
//prevent Jump meter Timer from going negative
|
||||
driver->jumpMeterTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if, in previous frame? player was in the air
|
||||
else
|
||||
{
|
||||
//jumpMeterMinus32ms = Jump meter
|
||||
jumpMeterMinus32ms = (int)driver->jumpMeter;
|
||||
|
||||
// if jump is high enough to be significant
|
||||
if (jumpMeterMinus32ms > 336)
|
||||
{
|
||||
// keep track of all jumps
|
||||
driver->timeSpentJumping += jumpMeterMinus32ms;
|
||||
|
||||
jumpMeterMinus32ms = (int)driver->jumpMeter;
|
||||
}
|
||||
|
||||
// if highest jump is less than current jump
|
||||
if (*(short *)driver->highestJump < jumpMeterMinus32ms)
|
||||
{
|
||||
// save highest jump
|
||||
*(u_short *)driver->highestJump = driver->jumpMeter;
|
||||
}
|
||||
|
||||
jumpMeter = driver->jumpMeter;
|
||||
|
||||
if (jumpMeter < 1440)
|
||||
{
|
||||
if (jumpMeter < 960)
|
||||
{
|
||||
//if Jump meter > 639
|
||||
if (jumpMeter > 639)
|
||||
{
|
||||
// add one second reserves
|
||||
Turbo_Increment(driver, 960, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//if Jump meter >= 960
|
||||
else
|
||||
{
|
||||
// Turbo_Increment
|
||||
// add one second reserves, plus speed
|
||||
Turbo_Increment(driver, 960, 2, 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
//if Jump meter >= 1440
|
||||
else
|
||||
{
|
||||
// add one second reserves, plus speed
|
||||
Turbo_Increment(driver, 960, 2, 0x100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if player is in the air
|
||||
else
|
||||
{
|
||||
if ((driver->jump_LandingBoost > 1152) && (driver->jumpMeter < 1153))
|
||||
{
|
||||
//Jump meter related operation
|
||||
|
||||
// Make driver talk
|
||||
Voiceline_RequestPlay(7, (int)data.characterIDs[driver->driverID], 0x10);
|
||||
}
|
||||
|
||||
driver->jumpMeter = driver->jump_LandingBoost;
|
||||
|
||||
//if Jump meter > 2400
|
||||
if (driver->jump_LandingBoost > 2400)
|
||||
{
|
||||
//prevent Jump meter from going over 2400
|
||||
driver->jumpMeter = 2400;
|
||||
}
|
||||
|
||||
//keep Jump meter Timer at 1440.
|
||||
driver->jumpMeterTimer = 1440;
|
||||
}
|
||||
return;
|
||||
}
|
@ -1,124 +1,22 @@
|
||||
// MATH_Sin(angle)
|
||||
int FUN_8003d184(uint param_1)
|
||||
#include <common.h>
|
||||
|
||||
{
|
||||
int iVar1;
|
||||
|
||||
// approximate trigonometry
|
||||
iVar1 = *(int *)(&DAT_800845a0 + (param_1 & 0x3ff) * 4);
|
||||
|
||||
// if (0 < angle < 90) or (180 < angle < 270)
|
||||
if ((param_1 & 0x400) == 0)
|
||||
{
|
||||
// shift bottom 2-byte to become top 2-byte
|
||||
iVar1 = iVar1 << 0x10;
|
||||
}
|
||||
|
||||
// move top 2-byte to bottom 2-byte,
|
||||
// and make top 2-byte zero
|
||||
iVar1 = iVar1 >> 0x10;
|
||||
|
||||
// if (angle > 180)
|
||||
if ((param_1 & 0x800) != 0)
|
||||
{
|
||||
// make negative
|
||||
iVar1 = -iVar1;
|
||||
}
|
||||
return iVar1;
|
||||
}
|
||||
|
||||
|
||||
// MATH_Cos(angle)
|
||||
int FUN_8003d1c0(uint param_1)
|
||||
|
||||
{
|
||||
int iVar1;
|
||||
|
||||
// if (0 < angle < 90) or (180 < angle < 270)
|
||||
if ((param_1 & 0x400) == 0)
|
||||
{
|
||||
// approximate trigonometry, then shift top bytes to bottom
|
||||
iVar1 = *(int *)(&DAT_800845a0 + (param_1 & 0x3ff) * 4) >> 0x10;
|
||||
|
||||
// if (180 < angle < 270)
|
||||
if ((param_1 & 0x800) != 0)
|
||||
{
|
||||
// convert negativeY into positiveX
|
||||
iVar1 = -iVar1;
|
||||
}
|
||||
}
|
||||
|
||||
// if (90 < angle < 180) or (270 < angle < 360)
|
||||
else
|
||||
{
|
||||
// approximate trigonometry, use bottom bytes
|
||||
iVar1 = (int)(short)*(int *)(&DAT_800845a0 + (param_1 & 0x3ff) * 4);
|
||||
|
||||
// if (90 < angle < 180)
|
||||
if ((param_1 & 0x800) == 0)
|
||||
{
|
||||
// convert negativeX into positiveX
|
||||
iVar1 = -iVar1;
|
||||
}
|
||||
}
|
||||
return iVar1;
|
||||
}
|
||||
|
||||
|
||||
// prediction
|
||||
// f(i,j) = f(i,0) * f(1,j)
|
||||
// f(i,0) = approx square root
|
||||
// f(1,j) = 2^(j/2)
|
||||
int FUN_8003d214(uint param_1,int param_2)
|
||||
|
||||
{
|
||||
bool bVar1;
|
||||
uint uVar2;
|
||||
int iVar3;
|
||||
uint uVar4;
|
||||
int iVar5;
|
||||
int iVar6;
|
||||
|
||||
uVar2 = 0;
|
||||
iVar3 = (param_2 >> 1) + 0xf;
|
||||
iVar5 = 0;
|
||||
do {
|
||||
uVar2 = uVar2 << 2 | param_1 >> 0x1e;
|
||||
iVar6 = iVar5 * 2;
|
||||
uVar4 = iVar5 * 4 + 1;
|
||||
param_1 = param_1 << 2;
|
||||
if (uVar4 <= uVar2) {
|
||||
uVar2 = uVar2 - uVar4;
|
||||
iVar6 = iVar6 + 1;
|
||||
}
|
||||
bVar1 = iVar3 != 0;
|
||||
iVar3 = iVar3 + -1;
|
||||
iVar5 = iVar6;
|
||||
} while (bVar1);
|
||||
return iVar6;
|
||||
}
|
||||
|
||||
|
||||
// param_1 matrix output
|
||||
// param_2 matrix input
|
||||
// only used by flamejet and PapuPyramidPlant for hitbox collision,
|
||||
// also used by missile, probably hitbox again
|
||||
// MATH_HitboxMatrix
|
||||
undefined8 FUN_8003d264(uint *param_1,uint *param_2)
|
||||
MATRIX* MATH_HitboxMatrix(MATRIX* output, MATRIX* input)
|
||||
|
||||
{
|
||||
short sVar1;
|
||||
uint uVar2;
|
||||
uint uVar3;
|
||||
uint uVar4;
|
||||
uint uVar5;
|
||||
unsigned int uVar2;
|
||||
unsigned int uVar3;
|
||||
unsigned int uVar4;
|
||||
unsigned int uVar5;
|
||||
|
||||
// transpose matrix
|
||||
uVar5 = *param_2 & 0xffff | param_2[1] & 0xffff0000;
|
||||
uVar4 = param_2[3] & 0xffff | *param_2 & 0xffff0000;
|
||||
uVar2 = param_2[2] & 0xffff | param_2[3] & 0xffff0000;
|
||||
uVar3 = param_2[1] & 0xffff | param_2[2] & 0xffff0000;
|
||||
sVar1 = *(short *)(param_2 + 4);
|
||||
uVar5 = input->m[0][0] & 0xffff | input->m[0][1] & 0xffff0000;
|
||||
uVar4 = input->m[1][0] & 0xffff | input->m[0][0] & 0xffff0000;
|
||||
uVar2 = input->m[0][2] & 0xffff | input->m[1][0] & 0xffff0000;
|
||||
uVar3 = input->m[0][1] & 0xffff | input->m[0][2] & 0xffff0000;
|
||||
sVar1 = input->m[1][1];
|
||||
|
||||
// store matrix into GTE
|
||||
gte_ldR11R12(uVar5);
|
||||
@ -127,95 +25,65 @@ undefined8 FUN_8003d264(uint *param_1,uint *param_2)
|
||||
gte_ldR31R32(uVar3);
|
||||
gte_ldR33((int)sVar1);
|
||||
|
||||
gte_ldVXY0(-param_2[5] & 0xffff | param_2[6] * -0x10000);
|
||||
gte_ldVZ0(-param_2[7]);
|
||||
gte_ldVXY0(-(input->m[1][2]) & 0xffff |input->m[2][0] * -0x10000);
|
||||
gte_ldVZ0(-(input->m[2][1]));
|
||||
gte_rtv0();
|
||||
|
||||
*param_1 = uVar5;
|
||||
param_1[1] = uVar4;
|
||||
param_1[2] = uVar2;
|
||||
param_1[3] = uVar3;
|
||||
output->m[0][0] = uVar5;
|
||||
output->m[0][1] = uVar4;
|
||||
output->m[0][2] = uVar2;
|
||||
output->m[1][0] = uVar3;
|
||||
|
||||
*(short *)(param_1 + 4) = sVar1;
|
||||
gte_stlvnl((VECTOR *)(param_1 + 5));
|
||||
output->m[1][1]= sVar1;
|
||||
gte_stlvnl((VECTOR *)output->m[1][2]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// MATH_VectorLength
|
||||
void FUN_8003d328(undefined4 *param_1)
|
||||
|
||||
void MATH_VectorLength(VECTOR* input)
|
||||
{
|
||||
undefined4 uVar1;
|
||||
unsigned int uVar1;
|
||||
|
||||
gte_ldR11R12(*param_1);
|
||||
gte_ldR13R21((int)*(short *)(param_1 + 1));
|
||||
gte_ldVXY0(*param_1);
|
||||
gte_ldVZ0((int)*(short *)(param_1 + 1));
|
||||
gte_ldR11R12(input->vx);
|
||||
gte_ldR13R21(input->vy);
|
||||
gte_ldVXY0(input->vx);
|
||||
gte_ldVZ0(input->vy);
|
||||
gte_mvmva(0,0,0,3,0);
|
||||
|
||||
uVar1 = gte_stMAC1();
|
||||
SquareRoot0(uVar1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// MATH_VectorNormalize
|
||||
int FUN_8003d378(short *param_1)
|
||||
|
||||
int MATH_VectorNormalize(VECTOR* input)
|
||||
{
|
||||
int iVar1;
|
||||
int length;
|
||||
|
||||
// MATH_VectorLength
|
||||
iVar1 = FUN_8003d328();
|
||||
length = MATH_VectorLength();
|
||||
|
||||
if (iVar1 != 0) {
|
||||
if (iVar1 == 0) {
|
||||
if (length != 0) {
|
||||
if (length == 0) {
|
||||
trap(0x1c00);
|
||||
}
|
||||
if ((iVar1 == -1) && ((int)*param_1 << 0xc == -0x80000000)) {
|
||||
if ((length == -1) && (input->vx | input->vy | input->vz) == 0x8000) {
|
||||
trap(0x1800);
|
||||
}
|
||||
if (iVar1 == 0) {
|
||||
trap(0x1c00);
|
||||
}
|
||||
if ((iVar1 == -1) && ((int)param_1[1] << 0xc == -0x80000000)) {
|
||||
trap(0x1800);
|
||||
}
|
||||
if (iVar1 == 0) {
|
||||
trap(0x1c00);
|
||||
}
|
||||
if ((iVar1 == -1) && ((int)param_1[2] << 0xc == -0x80000000)) {
|
||||
trap(0x1800);
|
||||
}
|
||||
*param_1 = (short)(((int)*param_1 << 0xc) / iVar1);
|
||||
param_1[1] = (short)(((int)param_1[1] << 0xc) / iVar1);
|
||||
param_1[2] = (short)(((int)param_1[2] << 0xc) / iVar1);
|
||||
input->vx = (short)((input->vx << 0xc) / length);
|
||||
input->vy = (short)((input->vy << 0xc) / length);
|
||||
input->vz = (short)((input->vz << 0xc) / length);
|
||||
}
|
||||
return iVar1;
|
||||
return length;
|
||||
}
|
||||
|
||||
// MATH_MatrixMul
|
||||
// Inspired by Spyro 2 USA demo, with 94426 variable names
|
||||
void FUN_8003d460(int param_1,MATRIX *param_2,int param_3)
|
||||
|
||||
void MATH_MatrixMul(MATRIX* output, MATRIX* input,VECTOR* rotate)
|
||||
{
|
||||
// param_3 - input
|
||||
// param_1 - output
|
||||
// MatrixRotate (param_1 = param_2 matrix rotated by param_3 matrix)
|
||||
FUN_8006c3b0(param_1, param_2, param_3);
|
||||
|
||||
// FUN_8006c6f0
|
||||
// param_2 - matrix input
|
||||
// param_3+14 - vector input
|
||||
// param_1+14 - vector output
|
||||
ApplyMatrixLV(param_2,(VECTOR *)(param_3 + 0x14),(VECTOR *)(param_1 + 0x14));
|
||||
MatrixRotate(output, input, rotate);
|
||||
ApplyMatrixLV(input,rotate->vx,(VECTOR *)(output->t[0]));
|
||||
|
||||
// Add Matrix2's position to Matrix1's position
|
||||
*(int *)(param_1 + 0x14) = *(int *)(param_1 + 0x14) + param_2->t[0];
|
||||
*(int *)(param_1 + 0x18) = *(int *)(param_1 + 0x18) + param_2->t[1];
|
||||
*(int *)(param_1 + 0x1c) = *(int *)(param_1 + 0x1c) + param_2->t[2];
|
||||
output->t[0] += param_2->t[0];
|
||||
output->t[1] += param_2->t[1];
|
||||
output->t[2] += param_2->t[2];
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user