diff --git a/decompile/General/LOAD/LOAD_A33_LangFile.c b/decompile/General/LOAD/LOAD_A33_LangFile.c index 9246e1e09..be60d5c88 100644 --- a/decompile/General/LOAD/LOAD_A33_LangFile.c +++ b/decompile/General/LOAD/LOAD_A33_LangFile.c @@ -19,7 +19,7 @@ void DECOMP_LOAD_LangFile(int bigfilePtr, int lang) char **strArray; #if BUILD == EurRetail - // This is (probably) to turn the screen black for a bit until lng is loaded. + // This is to turn the screen black for a bit (optional) DECOMP_CTR_ErrorScreen(0, 0, 0); VSync(0); #endif @@ -51,6 +51,7 @@ void DECOMP_LOAD_LangFile(int bigfilePtr, int lang) (unsigned int)lngFile; } #if BUILD == EurRetail + // set voicelines to new lang DECOMP_CDSYS_SetXAToLang(lang); #endif } \ No newline at end of file diff --git a/decompile/General/MAIN/MainMain.c b/decompile/General/MAIN/MainMain.c index 25f8f3711..213141d3e 100644 --- a/decompile/General/MAIN/MainMain.c +++ b/decompile/General/MAIN/MainMain.c @@ -120,6 +120,12 @@ u_int DECOMP_main() // Main Gameplay Update // Makes up all normal interaction with the game case 3: + #ifdef USE_LANG + if ((gGT->gameMode2 & LNG_CHANGE) != 0) { + LOAD_LangFile(sdata->ptrBigfileCdPos_2, gGT->langIndex); + gGT->gameMode2 &= ~(LNG_CHANGE); + } + #endif // if loading, or gameplay interrupted if (sdata->Loading.stage != -1) { diff --git a/decompile/General/Vehicle/VehAfterColl_GetTerrain.c b/decompile/General/Vehicle/VehAfterColl_GetTerrain.c index 25c3eeaaa..633671b2e 100644 --- a/decompile/General/Vehicle/VehAfterColl_GetTerrain.c +++ b/decompile/General/Vehicle/VehAfterColl_GetTerrain.c @@ -4,8 +4,9 @@ struct Terrain* DECOMP_VehAfterColl_GetTerrain(u_char terrainType) { struct Terrain* ter = &data.MetaDataTerrain[0]; - if (terrainType < 0x15) + // if terrain is valid + if (terrainType < 21) return &ter[terrainType]; - + return ter; } diff --git a/decompile/General/Vehicle/VehBirth_TireSprites.c b/decompile/General/Vehicle/VehBirth_TireSprites.c index 7677e8014..29e5a38a8 100644 --- a/decompile/General/Vehicle/VehBirth_TireSprites.c +++ b/decompile/General/Vehicle/VehBirth_TireSprites.c @@ -41,7 +41,7 @@ void DECOMP_VehBirth_TireSprites(struct Thread *t) d->numFramesSpentSteering = 10000; #ifndef REBUILD_PS1 - d->terrainMeta1 = VehAfterColl_GetTerrain(10); + d->terrainMeta1 = VehAfterColl_GetTerrain(TERRAIN_NONE); #endif d->BattleHUD.numLives = gGT->battleLifeLimit; diff --git a/decompile/WorkInProgress/src/231/231_028_RB_Warpball_NewPathNode.c b/decompile/WorkInProgress/src/231/231_028_RB_Warpball_NewPathNode.c new file mode 100644 index 000000000..f679b1283 --- /dev/null +++ b/decompile/WorkInProgress/src/231/231_028_RB_Warpball_NewPathNode.c @@ -0,0 +1,60 @@ +#include + +struct CheckpointNode* DECOMP_RB_Warpball_NewPathNode(struct CheckpointNode *cn, struct Driver *d) +{ + u_char currPoint; + u_int currIndex; + u_char boolPointExists = false; + + struct GameTracker *gGT = sdata->gGT; + + // if no driver is chased + if (d == NULL) + { + RETURN_NEXT_INDEX: + return &gGT->level1->ptr_restart_points[cn->nextIndex_forward]; + } + + // pathPoint -> left index + currIndex = cn->nextIndex_left; + + // if driver is not near that point + if (d->unknown_lap_related[0] != currIndex) + { + // if left point is valid + if (cn->nextIndex_left != 0xff) + { + struct CheckpointNode *currNode = cn; + for (int i = 0; i < 3; i++) + { + // path index + if (currNode->nextIndex_left == -1) + { + currPoint = currNode->nextIndex_forward; + } + + // path index + else + { + currPoint = currNode->nextIndex_left; + } + + // path node + currNode = gGT->level1->ptr_restart_points[currPoint]; + + // compare path index + if (d->unknown_lap_related[0] == currNode->nextIndex_forward) + { + boolPointExists = true; + break; + } + } + } + if (!boolPointExists) + goto RETURN_NEXT_INDEX; + currIndex = cn->nextIndex_left; + } + + // new path node + return &gGT->level1->ptr_restart_points[currIndex]; +} \ No newline at end of file diff --git a/decompile/WorkInProgress/src/231/231_030_RB_Warpball_GetDriverTarget.c b/decompile/WorkInProgress/src/231/231_030_RB_Warpball_GetDriverTarget.c new file mode 100644 index 000000000..4e6e8eaa8 --- /dev/null +++ b/decompile/WorkInProgress/src/231/231_030_RB_Warpball_GetDriverTarget.c @@ -0,0 +1,119 @@ +#include + +struct Driver* RB_Warpball_GetDriverTarget(struct TrackerWeapon *tw, struct Instance *inst) +{ + u_int distToFinish; + int currDistance; + int index; + int iVar4; + + struct Driver* currDriver = NULL; + struct Driver* hitDriver = NULL; + + // if 10 wumpa fruit were not used + if ((tw->flags & 1) == 0) + { + for (index = 0; index < 8; index++) + { + // check next driver until you get the driver + // farthest in the lead, that has not finished race + currDriver = sdata->gGT->drivers[index]; + + // if driver is valid + if (((currDriver != NULL) && + + // if driver is not the same as driver that fired warpball + (currDriver != tw->driverParent)) && + + // if the race is not over for this driver + ((currDriver->actionsFlagSet & 0x2000000) == 0)) + { + return currDriver; + } + } + } + + // if 10 wumpa fruit were used + else + { + // start of lev->path + struct CheckpointNode* cn = &sdata->gGT->level1->ptr_restart_points[0]; + + // node1 + struct CheckpointNode* node1 = &cn[tw->ptrNodeCurr->nextIndex_forward]; + + // node2 + struct CheckpointNode* node2 = &cn[node1->nextIndex_forward]; + + u_int distToFinish = cn->distToFinish * 8; + + short vec1[4]; + // direction from node1 to node2 + vec1[0] = node1->pos[0] - node2->pos[0]; + vec1[1] = node1->pos[1] - node2->pos[1]; + vec1[2] = node1->pos[2] - node2->pos[2]; + + MATH_VectorNormalize(&vec1[0]); + + short vec2[4]; + // direction from orb to node1 + vec2[0] = inst->matrix.t[0] - node1.pos[0]; + vec2[1] = inst->matrix.t[1] - node1.pos[1]; + vec2[2] = inst->matrix.t[2] - node1.pos[2]; + + // replace R11R12 and R13R21 + gte_ldsvrtrow0(&vec1[0]); + + gte_ldv0(&vec2[0]); + + gte_mvmva(0,0,0,3,0); + + // replace stMAC1 + gte_stlvnl0(&iVar4); + + u_int maxDistance = 0x7fffffff; + + iVar4 = node1->distanceToFinish * 8 + (iVar4 >> 0xc) + 0x200; + + #if 0 + if (uVar1 == 0) + { + trap(0x1c00); + } + if ((distToFinish == -1) && (iVar4 == -0x80000000)) + { + trap(0x1800); + } + #endif + + for (index = 0; index < 8; index++) + { + // pointer to structure of each player + currDriver = sdata->gGT->drivers[index]; + + // if driver is valid + if (((currDriver != NULL) && + ((tw->driversHit & 1 << (index & 0x1fU)) == 0)) && + (( + // If the race is not over for this player + (currDriver->actionsFlagSet & 0x2000000) == 0 && + + // If you are not being mask-grabbed + (currDriver->kartState != KS_MASK_GRABBED)))) + { + currDistance = iVar4 % distToFinish - currDriver->distanceToFinish_curr; + + if (currDistance < 0) + { + currDistance += distToFinish; + } + if (currDistance < maxDistance) + { + maxDistance = currDistance; + hitDriver = currDriver; + } + } + } + } + return hitDriver; +} diff --git a/decompile/WorkInProgress/src/231/231_031_RB_Warpball_SetTargetDriver.c b/decompile/WorkInProgress/src/231/231_031_RB_Warpball_SetTargetDriver.c new file mode 100644 index 000000000..b8c0fb6e2 --- /dev/null +++ b/decompile/WorkInProgress/src/231/231_031_RB_Warpball_SetTargetDriver.c @@ -0,0 +1,79 @@ +#include + +void RB_Warpball_SetTargetDriver(struct TrackerWeapon *tw) +{ + int distance; + int i, j; + int local_20; + int local_1c; + + struct GameTracker *gGT = sdata->gGT; + + // driver being chased + struct Driver *target = tw->driverTarget; + + // if driver is valid + if (target == NULL) + return; + + distance = target->distanceToFinish_curr; + + // path node + struct CheckpointNode *firstNode = &gGT->level->ptr_restart_points[0]; + struct CheckpointNode *currNode = &first[target->unknown_lap_related]; + + // distance is less than path node distance + while ((distance <= (thisNode->distToFinish << 3) && + + // path node is not first node + (currNode != firstNode))) + { + currNode = RB_Warpball_NewPathNode(currNode, tw->driverTarget); + } + + target = NULL; + local_1c = 0; + thisNode = tw->ptrNodeCurr; + + if ((tw->flags & 4) == 0) + { + for (i = 0; i < 2; i++) + { + distance = *(int *)((int)&local_20 + (distance >> 0xe)); + if (distance != 0) + { + thisNode = 0; + for (j = 0; j < 3; j++) + { + if (distance == currNode) + { + tw->flags = tw->flags & 0xfff7 | 4; + break; + } + if (*(byte *)(distance + 0xb) != 0xff) + { + // path node + local_1c = *(int *)(*(int *)(gGT + 0x160) + 0x14c) + + (uint) * (byte *)(distance + 0xb) * 0xc; + } + + // path node + distance = *(int *)(*(int *)(gGT + 0x160) + 0x14c) + (uint) * (byte *)(distance + 10) * 0xc; + } + } + } + } + + // path node + thisNode = tw->ptrNodeCurr; + + for (i = 0; i < 3; i++) + { + if (thisNode == currNode) + { + tw->flags = tw->flags & ~(8) | 4; + return; + } + target = RB_Warpball_NewPathNode(target, tw->driverTarget); + } +} \ No newline at end of file diff --git a/decompile/WorkInProgress/src/RefreshCard/RefreshCard_BoolGhostForLEV.c b/decompile/WorkInProgress/src/RefreshCard/RefreshCard_BoolGhostForLEV.c new file mode 100644 index 000000000..7a01f91d7 --- /dev/null +++ b/decompile/WorkInProgress/src/RefreshCard/RefreshCard_BoolGhostForLEV.c @@ -0,0 +1,18 @@ +int RefreshCard_BoolGhostForLEV(u_short trackID) +{ + short numGhost = 0; + + // if ghost profiles are present + if (sdata->numGhostProfilesSaved){ + // loop through ghost profiles + for (char i = 0; i < sdata->numGhostProfilesSaved - 1; i++) + { + // Check trackID of each profile + if (sdata->ghostProfile_memcard[i].trackID == trackID) + { + numGhost++; + } + } + } + return numGhost; +} \ No newline at end of file diff --git a/decompile/WorkInProgress/src/RefreshCard/RefreshCard_GetResult.c b/decompile/WorkInProgress/src/RefreshCard/RefreshCard_GetResult.c new file mode 100644 index 000000000..24906c222 --- /dev/null +++ b/decompile/WorkInProgress/src/RefreshCard/RefreshCard_GetResult.c @@ -0,0 +1,23 @@ +#include + +u_int RefreshCard_GetResult(short searchResult) +{ + // MC_RESULT_FINISHED + if ((searchResult == 8) && + ((sdata->memcardUnk1 & 6) != 0)) + { + return true; + } + + u_int boolFound = false; + + if (((sdata->memcardUnk1 & 6) == 0) && + // if frame3 == frame4 + (sdata->frame3_memcardAction == sdata->frame4_memcardAction) && + (sdata->frame3_memcardSlot == sdata->frame4_memcardSlot)) + { + // is desired_memcardResult == WhatYouLookFor? + boolFound = (sdata->desired_memcardResult == searchResult); + } + return boolFound; +} \ No newline at end of file diff --git a/decompile/WorkInProgress/src/RefreshCard/RefreshCard_GhostEncodeByte.c b/decompile/WorkInProgress/src/RefreshCard/RefreshCard_GhostEncodeByte.c new file mode 100644 index 000000000..3ca5ff12a --- /dev/null +++ b/decompile/WorkInProgress/src/RefreshCard/RefreshCard_GhostEncodeByte.c @@ -0,0 +1,44 @@ +#include + +u_int RefreshCard_GhostEncodeByte(int currByte) +{ + // only called from RefreshCard_GhostEncodeProfile + + u_int uVar1; + short sVar2; + + sVar2 = (short)currByte; + if (sVar2 < 10) + { + return currByte + 0x30U & 0xff; + } + if (sVar2 < 0x24) + { + return currByte + 0x37U & 0xff; + } + if (sVar2 < 0x3e) + { + uVar1 = currByte + 0x3dU & 0xff; + } + else + { + uVar1 = 0x2d; + if (sVar2 != 0x3e) + { + return 0x5f; + } + } + return uVar1; +} + +int RefreshCard_GhostDecodeByte(char currByte) +{ + // only called from RefreshCard_GhostDecodeProfile + + if (currByte == 0x2d) return 0x3e; + if (currByte == 0x5f) return 0x3f; + if (currByte < 0x3a) return (short)(currByte - 0x30); + if (0x5a < currByte) return (short)(currByte - 0x3d); + + return (short)(currByte - 0x37); +} \ No newline at end of file diff --git a/decompile/WorkInProgress/src/RefreshCard/RefreshCard_NextMemcardAction.c b/decompile/WorkInProgress/src/RefreshCard/RefreshCard_NextMemcardAction.c new file mode 100644 index 000000000..06bd0ee0c --- /dev/null +++ b/decompile/WorkInProgress/src/RefreshCard/RefreshCard_NextMemcardAction.c @@ -0,0 +1,24 @@ +#include + +void RefreshCard_NextMemcardAction(u_short memcardSlot, u_short memcardAction, u_char* filename, u_char* memcardIcon, struct GhostHeader* ghost, u_short filesize) +{ + sdata->memcardUnk1 &= ~(0x8); + + sdata->frame2_memcardAction = memcardAction; + sdata->frame2_memcardSlot = memcardSlot; + + sdata->frame4_memcardAction = memcardAction; + sdata->frame4_memcardSlot = memcardSlot; + + // Save filename (BASCUS...) + sdata->ghostProfile_fileName = filename; + + // Save icon (crash/ghost/psyqhand) + sdata->ghostProfile_fileIconHeader = memcardIcon; + + // pointer to ghostHeader (not memcard) + sdata->ghostProfile_ptrGhostHeader = ghost; + + // size (3E00) + sdata->ghostProfile_size3E00 = filesize; +} \ No newline at end of file diff --git a/include/namespace_Level.h b/include/namespace_Level.h index a16793848..d659a63fc 100644 --- a/include/namespace_Level.h +++ b/include/namespace_Level.h @@ -69,7 +69,27 @@ enum LevelID enum TerrainType { - TERRAIN_MUD = 14, + TERRAIN_ASPHALT, + TERRAIN_DIRT, + TERRAIN_GRASS, + TERRAIN_WOOD, + TERRAIN_WATER, + TERRAIN_STONE, + TERRAIN_ICE, + TERRAIN_TRACK, + TERRAIN_ICY_ROAD, + TERRAIN_SNOW, + TERRAIN_NONE, + TERRAIN_HARDPACK, + TERRAIN_METAL, + TERRAIN_FASTWATER, + TERRAIN_MUD, + TERRAIN_SIDESLIP, + TERRAIN_RIVERASPHALT, + TERRAIN_STEAMASPHALT, + TERRAIN_OCEANASPHALT, + TERRAIN_SLOWGRASS, + TERRAIN_SLOWDIRT }; // transparent parameter of getTPage() diff --git a/include/namespace_Main.h b/include/namespace_Main.h index 806b55ccf..88c689f54 100644 --- a/include/namespace_Main.h +++ b/include/namespace_Main.h @@ -68,8 +68,8 @@ enum GameMode2 INC_RELIC = 0x1000000, INC_KEY = 0x2000000, INC_TROPHY = 0x4000000, - CHEAT_TURBOCOUNT= 0x8000000 - // & 0x10000000 - LNG_CHANGE (EurRetail Only) + CHEAT_TURBOCOUNT= 0x8000000, + LNG_CHANGE = 0x10000000 // (EurRetail Only) }; // real ND name