Improve end of race UI, improve speedometer UI, bug fixes

This commit is contained in:
mateusfavarin 2024-07-03 00:32:15 -03:00
parent 03e5f2674a
commit fbd06efec1
9 changed files with 211 additions and 138 deletions

View File

@ -7,6 +7,30 @@
#include "OnlineCTR/thread.c"
#include "OnlineCTR/endOfRaceUI.c"
void AssignMeterGrade(struct Driver * driver, int meterLeft)
{
const int gradeTreshold[] = {SECONDS(1) * FP(0.50), SECONDS(1) * FP(0.65),
SECONDS(1) * FP(0.80), SECONDS(1) * FP(0.90),
SECONDS(1) * FP(0.95)};
const int gradeColors[] = {TROPY_LIGHT_BLUE, TINY_GREEN, PAPU_YELLOW, ROO_ORANGE, ORANGE_RED};
driver->meterGradeTimer = SECONDS(0.5);
driver->meterGrade[1] = '\0';
char grades[] = "FDCBA";
for (int i = 0; i < len(gradeTreshold); i++)
{
if (meterLeft > SECONDS(1) - FP_INT(gradeTreshold[i]))
{
driver->meterGrade[0] = grades[i];
driver->gradeColor = gradeColors[i];
return;
}
}
driver->meterGrade[0] = 'S';
driver->gradeColor = COCO_MAGENTA;
}
void StatsUpgrade()
{
/*

View File

@ -74,7 +74,7 @@ void DrawBoostBar(short posX, short posY, struct Driver* driver)
#ifdef USE_ONLINE
char s_barsCompleted[15];
sprintf(s_barsCompleted, "%d", numBarsFilled);
sprintf(s_barsCompleted, "%d", numFullBarsFilled);
DECOMP_DecalFont_DrawLine(s_barsCompleted, topX - 2, topY - 3, FONT_SMALL, PENTA_WHITE | JUSTIFY_RIGHT);
ColorCode colorCode;

View File

@ -57,11 +57,16 @@ void EndOfRace_Icons()
{
char s_time[15];
TotalTime tt;
const int spacing = 150;
const int iconHeight = 25;
const short xStart = 0;
Point pos = MakePoint(xStart, 20);
const int playersPerRow = 4;
const int rectSpace = 5;
const int iconSpacing = 126;
const int iconHeight = 28;
const int xStart = 0;
const int yStart = 20;
const int scale = FP(1);
int playersFinished = 0;
int rectHeightMultiplier = 1;
Point pos = MakePoint(xStart, yStart);
UpdateBestTimes();
for (int i = 0; i < octr->NumDrivers; i++)
{
@ -74,7 +79,14 @@ void EndOfRace_Icons()
DECOMP_DecalFont_DrawLineStrlen(&racePos, 1, pos.x + 27, pos.y, FONT_SMALL, RED);
DECOMP_DecalFont_DrawLineStrlen(octr->nameBuffer[index], NAME_LEN, pos.x + 38, pos.y + 1, FONT_SMALL, index == 0 ? BLUE : ORANGE);
ElapsedTimeToTotalTime(&tt, octr->raceStats[i].finalTime);
sprintf(s_time, "%d:%02d:%02d.%03d", tt.hours, tt.minutes, tt.seconds, tt.miliseconds);
if (tt.hours > 0)
{
sprintf(s_time, "%d:%02d:%02d", tt.hours, tt.minutes, tt.seconds);
}
else
{
sprintf(s_time, "%d:%02d.%03d", tt.minutes, tt.seconds, tt.miliseconds);
}
DECOMP_DecalFont_DrawLine(s_time, pos.x + 38, pos.y + 8 + 1, FONT_SMALL, index == bestCourseIndex ? TINY_GREEN : WHITE);
ElapsedTimeToTotalTime(&tt, octr->raceStats[i].bestLap);
tt.minutes = min(tt.minutes, 9);
@ -82,11 +94,15 @@ void EndOfRace_Icons()
DECOMP_DecalFont_DrawLine(s_time, pos.x + 38, pos.y + 16 + 1, FONT_SMALL, index == bestLapIndex ? TINY_GREEN : WHITE);
DECOMP_UI_DrawDriverIcon(icon, pos, sdata->gGT->pushBuffer_UI.ptrOT, 1, scale, MakeColor(0x80, 0x80, 0x80));
pos.x += 126;
if (i == 3)
pos.x += iconSpacing;
playersFinished++;
if (playersFinished == playersPerRow)
{
pos.x = xStart;
pos.y += iconHeight;
}
else if (playersFinished > playersPerRow) { rectHeightMultiplier = 2; }
}
const RECT bgRect = {.x = 0, .y = yStart - rectSpace, .w = 512, .h = rectSpace * 2 + iconHeight * rectHeightMultiplier - 3};
DECOMP_RECTMENU_DrawInnerRect(&bgRect, 0, sdata->gGT->backBuffer->otMem.startPlusFour);
}

View File

@ -153,6 +153,9 @@ typedef struct CheckpointTracker
extern CheckpointTracker checkpointTracker[MAX_NUM_PLAYERS];
void EndOfRace_Camera();
void EndOfRace_Icons();
#ifdef WINDOWS_INCLUDE
#include <time.h>

View File

@ -185,8 +185,6 @@ bool HasRaceEnded()
RECT windowText = {0x118, 0x40, 0xD8, 0};
void EndOfRace_Camera();
void EndOfRace_Icons();
void OnlineEndOfRace()
{
struct Driver * driver = sdata->gGT->drivers[0];
@ -194,13 +192,16 @@ void OnlineEndOfRace()
(octr->CurrState < GAME_START_RACE)) { return; }
octr->CurrState = GAME_END_RACE;
static unsigned frameCounter = 0;
EndOfRace_Camera();
EndOfRace_Icons();
int color = frameCounter & 1 ? RED : WHITE;
if (HasRaceEnded())
{
DecalFont_DrawLine("Restart in 6 seconds", 256, 108, FONT_BIG, JUSTIFY_CENTER | RED);
DecalFont_DrawLine("Restart in 6 seconds", 256, 108, FONT_BIG, JUSTIFY_CENTER | color);
}
frameCounter++;
}
void Online_OtherFX_RecycleNew(

View File

@ -44,12 +44,12 @@ void DECOMP_MainInit_JitPoolsNew(struct GameTracker *gGT)
uVar9 = 0x1000;
}
else
else
{
// Main Menu, bare minimum
uVar9 = 0x400;
if (gGT->levelID == ADVENTURE_CHARACTER_SELECT)
if (gGT->levelID == ADVENTURE_CHARACTER_SELECT)
{
uVar9 = 0x800;
}
@ -84,7 +84,7 @@ void DECOMP_MainInit_JitPoolsNew(struct GameTracker *gGT)
// ThreadPool
DECOMP_JitPool_Init(
&gGT->JitPools.thread, numThread,
&gGT->JitPools.thread, numThread,
sizeof(struct Thread), /*"ThreadPool"*/0);
@ -94,11 +94,11 @@ void DECOMP_MainInit_JitPoolsNew(struct GameTracker *gGT)
sdata->mempack[0].firstFreeByte = 0x8000F000;
#endif
// normally maxed at 32
int numMedium = uVar7 >> 7;
if(numMedium > 20) numMedium = 20;
// MediumStackPool
// OG game was 0x80+8,
// now changed to 0x60+8 (optimized Warppad)
@ -115,11 +115,11 @@ void DECOMP_MainInit_JitPoolsNew(struct GameTracker *gGT)
// normally maxed at 128
int numInstance = uVar9 >> 5;
// InstancePool
DECOMP_JitPool_Init(
&gGT->JitPools.instance, numInstance,
sizeof(struct Instance) + (sizeof(struct InstDrawPerPlayer) * numPlyr),
sizeof(struct Instance) + (sizeof(struct InstDrawPerPlayer) * numPlyr),
/*"InstancePool"*/0);
@ -148,30 +148,30 @@ void DECOMP_MainInit_JitPoolsNew(struct GameTracker *gGT)
// OG game used 0x670 for driver, should be 0x640,
// maybe intended to mix RainPool into Driver struct?
DECOMP_JitPool_Init(&gGT->JitPools.largeStack,numDriver, 0x640, /*"LargeStackPool"*/0);
DECOMP_JitPool_Init(&gGT->JitPools.largeStack,numDriver, sizeof(struct Driver), /*"LargeStackPool"*/0);
DECOMP_JitPool_Init(&gGT->JitPools.rain, numDriver, 0x28, /*"RainPool"*/0);
// Must be 64 in adventure arena,
// normally maxed at 128
int numParticle = uVar7 >> 5;
if(numParticle > 120) numParticle = 120;
#ifdef USE_ONLINE
// fix mystery caves with 8 players,
// cause all drivers use P1 exhaust
numParticle = 120*10;
#endif
DECOMP_JitPool_Init(&gGT->JitPools.particle, numParticle,0x7c, /*"ParticlePool"*/0);
DECOMP_JitPool_Init(&gGT->JitPools.oscillator,numParticle,0x18, /*"OscillatorPool"*/0);
#ifdef REBUILD_PS1
// original CTR code, still used for
// REBUILD_PS1 and REBUILD_PC cause those
// original CTR code, still used for
// REBUILD_PS1 and REBUILD_PC cause those
// builds dont have OG game's bloatful RDATA
gGT->ptrRenderBucketInstance = DECOMP_MEMPACK_AllocMem(uVar9/*,"RENDER_BUCKET_INSTANCE"*/);
#else
@ -206,11 +206,11 @@ void DECOMP_MainInit_JitPoolsNew(struct GameTracker *gGT)
}
for (int i = 0; i < numPlyr; i++)
{
data.PtrClipBuffer[i] =
DECOMP_MEMPACK_AllocMem(
{
data.PtrClipBuffer[i] =
DECOMP_MEMPACK_AllocMem(
DECOMP_MainDB_GetClipSize(gGT->levelID, numPlyr) << 2
/*,"Clip Buffer"*/);
}
}
}

View File

@ -3,13 +3,13 @@
void DECOMP_UI_DrawSlideMeter(short posX, short posY, struct Driver* driver)
{
const struct GameTracker * gGT = sdata->gGT;
int barWidth = WIDE_34(49);
#ifdef USE_ONLINE
const int xOffset = 2;
const int barWidth = 39;
int barHeight = 10;
posX += xOffset;
barWidth += xOffset;
#else
const int barWidth = WIDE_34(49);
int barHeight = gGT->numPlyrCurrGame > 2 ? 3 : 7;
#endif
@ -29,6 +29,18 @@ void DECOMP_UI_DrawSlideMeter(short posX, short posY, struct Driver* driver)
box.h = barHeight;
DECOMP_CTR_Box_DrawWireBox(&box, MakeColor(0, 0, 0), gGT->pushBuffer_UI.ptrOT);
#ifdef USE_ONLINE
/*
F > 50% | 50% < D < 65% | 65% < C < 80%
80% < B < 90% | 90% < A < 95% | 95% < A+
*/
if (driver->driverID == 0 && driver->meterGradeTimer > 0)
{
driver->meterGradeTimer -= gGT->elapsedTimeMS;
DECOMP_DecalFont_DrawLine(driver->meterGrade, topX, topY - 8, FONT_SMALL, driver->gradeColor);
}
#endif
const PrimCode primCode = { .poly = { .quad = 1, .renderCode = RenderCode_Polygon } };
ColorCode colorCode = MakeColorCode(0xFF, 0, 0, primCode); // red color, ready to boost

View File

@ -1,5 +1,9 @@
#include <common.h>
#ifdef USE_ONLINE
void AssignMeterGrade(struct Driver * driver, int meterLeft);
#endif
void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver* driver)
{
char cVar1;
@ -21,11 +25,11 @@ void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver*
int elapsedTimeDouble;
short iVar12_C;
short iVar12_D;
int absVal_NumFrameDrift;
int absVal_DistortCurr;
int absVal_DistortVel;
gGT = sdata->gGT;
iVar12_A = ((driver->axisRotationX - driver->angle) + 0x800U & 0xfff) - 0x800;
@ -33,19 +37,19 @@ void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver*
{
// 30fps
#ifndef USE_60FPS
// decrease by 1/8
// val = val * 7/8
iVar13 = iVar12_A >> 3;
// 60fps
#else
// how to split division by 8,
// into two separate frames, which is
// into two separate frames, which is
// exponentional at 30fps, but a hybrid
// linear/exponential at 60fps
if(gGT->timer&1)
{
// 1/16, half of 1/8
@ -56,37 +60,37 @@ void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver*
// undo last frame's change,
// undo 1/16 change, with 16/15
iVar13 = (iVar12_A * 16) / 15;
// now take 1/8 of that
iVar13 = iVar13 >> 3;
}
#endif
if (iVar13 == 0)
{
iVar13 = 1;
}
elapsedTimeDouble = gGT->elapsedTimeMS * 2;
if (iVar13 > elapsedTimeDouble)
iVar13 = elapsedTimeDouble;
if (iVar13 < -elapsedTimeDouble)
iVar13 = -elapsedTimeDouble;
// change player rotation
driver->angle += iVar13;
driver->axisRotationX -= iVar13;
driver->axisRotationX &= 0xfff;
driver->axisRotationX &= 0xfff;
}
// positive cam spin rate
iVar13 = (int)driver->const_Drifting_CameraSpinRate;
if (driver->multDrift < 0)
if (driver->multDrift < 0)
{
// negative cam spin rate
iVar13 = -iVar13;
@ -97,73 +101,73 @@ void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver*
// turning rate
iVar12_D = driver->rotationSpinRate;
// drift direction
iVar15 = (int)driver->multDrift;
bVar3 = false;
iVar9 = (int)driver->simpTurnState;
iVar13 = iVar9 * 0x100;
// if drifting to the right
if (iVar15 < 0)
if (iVar15 < 0)
{
// if steering to the right
if (iVar13 < 1)
if (iVar13 < 1)
{
iVar13 = iVar9 * -0x100;
// const_SteerVel_DriftStandard
iVar9 = -(int)driver->const_SteerVel_DriftStandard;
}
// if steering to the left
else
else
{
// const_SteerVel_DriftSwitchWay
iVar9 = -(int)driver->const_SteerVel_DriftSwitchWay;
}
}
// if drifting to the left
else
else
{
// if steering to the right
if (iVar13 < 0)
if (iVar13 < 0)
{
iVar13 = iVar9 * -0x100;
// const_SteerVel_DriftSwitchWay
cVar1 = driver->const_SteerVel_DriftSwitchWay;
}
// if steering to the left
else
else
{
// const_SteerVel_DriftStandard
cVar1 = driver->const_SteerVel_DriftStandard;
}
iVar9 = (int)cVar1;
}
// Map "simpTurnState" from [0, const_TurnRate] to [0, driftDirection]
iVar13 = DECOMP_VehCalc_MapToRange(iVar13, 0, ((u_int)driver->const_TurnRate + ((int)driver->turnConst << 1) / 5) * 0x100, 0, iVar9 << 8);
if
(
(iVar13 < 0) ||
(iVar13 < 0) ||
(
(
// compare two turning rates
bVar2 = iVar13 < iVar12_D,
iVar13 == 0 && (iVar12_D < 0)
)
)
)
)
{
bVar3 = true;
iVar13 = -iVar13;
@ -184,15 +188,15 @@ void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver*
iVar12_D += ((int)driver->unk464 * gGT->elapsedTimeMS) >> 5;
bVar2 = iVar13 < iVar12_D;
}
if (bVar2)
{
iVar12_D = iVar13;
}
// if not holding a drift direction,
// if not holding a drift direction,
// interpolate to "neutral" drift
if ((iVar13 == 0) || (iVar15 == 0))
if ((iVar13 == 0) || (iVar15 == 0))
{
LAB_80063244:
@ -204,9 +208,9 @@ LAB_80063244:
driver->KartStates.Drifting.numFramesDrifting =
DECOMP_VehCalc_InterpBySpeed((int)driver->KartStates.Drifting.numFramesDrifting, 1, 0);
}
// if holding a drift
else
else
{
// if drifting right
if(iVar15 < 1)
@ -214,22 +218,22 @@ LAB_80063244:
#ifdef USE_60FPS
if(gGT->timer & 1)
#endif
driver->KartStates.Drifting.numFramesDrifting--;
if(driver->KartStates.Drifting.numFramesDrifting > 0)
driver->KartStates.Drifting.numFramesDrifting = 0;
}
// if drifting left
else
{
#ifdef USE_60FPS
if(gGT->timer & 1)
#endif
driver->KartStates.Drifting.numFramesDrifting++;
if(driver->KartStates.Drifting.numFramesDrifting < 0)
driver->KartStates.Drifting.numFramesDrifting = 0;
}
@ -269,25 +273,25 @@ LAB_800632cc:
// Map value from [oldMin, oldMax] to [newMin, newMax]
// inverting newMin and newMax will give an inverse range mapping
iVar12_D = DECOMP_VehCalc_MapToRange(iVar12_D, 0, (int)driver->unk460 + ((int)driver->turnConst << 2) / 5, 0, (int)driver->unk474);
iVar15 = iVar9;
if (iVar9 < 0)
if (iVar9 < 0)
iVar15 = -iVar9;
// iVar13 and iVar9 have different signs
iVar8 = (int)driver->unk472;
iVar11 = driver->const_SteerVel_DriftSwitchWay;
// if both numbers have same sign,
// either both < 0, or both >= 0
if((iVar13 ^ iVar9) >= 0)
{
iVar8 = (int)driver->unk470;
iVar11 = (int)driver->const_SteerVel_DriftStandard;
iVar11 = (int)driver->const_SteerVel_DriftStandard;
}
if (iVar13 < 0)
if (iVar13 < 0)
{
iVar12_D = -iVar12_D;
iVar8 = -iVar8;
@ -296,9 +300,9 @@ LAB_800632cc:
// Map value from [oldMin, oldMax] to [newMin, newMax]
// inverting newMin and newMax will give an inverse range mapping
iVar15 = DECOMP_VehCalc_MapToRange(iVar15, 0, iVar11 << 8, 0, iVar8);
iVar12_D = (iVar12_D + iVar15) - driver->turnAngleCurr;
// Same trick as above ">>3"
// which has more comments there
#ifndef USE_60FPS
@ -312,9 +316,9 @@ LAB_800632cc:
{
iVar15 = (iVar12_D * 16) / 15;
iVar15 = iVar15 >> 3;
}
}
#endif
sVar5 = (short)iVar15;
if (iVar12_D != 0)
{
@ -325,41 +329,41 @@ LAB_800632cc:
driver->turnAngleCurr += sVar5;
}
absVal_NumFrameDrift =
absVal_NumFrameDrift =
driver->KartStates.Drifting.numFramesDrifting;
if (absVal_NumFrameDrift < 0)
absVal_NumFrameDrift = -absVal_NumFrameDrift;
// get half of spin-out constant,
// this determines when to start making tire sound effects,
// get half of spin-out constant,
// this determines when to start making tire sound effects,
// after the turbo meter finishes filling past it's max capacity
// if you drift beyond the limit of the turbo meter
if ((driver->const_Drifting_FramesTillSpinout >> 1) < absVal_NumFrameDrift)
{
// Play the SFX of near-spinout
absVal_DistortCurr = driver->unk3D4[0];
if (absVal_DistortCurr < 0)
absVal_DistortCurr = -absVal_DistortCurr;
// if low distortion
if (absVal_DistortCurr < 10)
{
// count up for 8 frames
driver->unk3D4[2] = FPS_DOUBLE(8);
// distortion, rate of change
driver->unk3D4[1] = FPS_HALF(0x14);
if (iVar13 < 0)
{
driver->unk3D4[1] = -driver->unk3D4[1];
}
}
}
// if not near-spinout
else
{
@ -367,11 +371,11 @@ LAB_800632cc:
// go back down
driver->unk3D4[2] = 0;
}
absVal_DistortCurr = driver->unk3D4[0];
if (absVal_DistortCurr < 0)
absVal_DistortCurr = -absVal_DistortCurr;
// if distortion is too high
if (0x32 < absVal_DistortCurr)
{
@ -379,16 +383,16 @@ LAB_800632cc:
// go back down
driver->unk3D4[2] = 0;
}
// frame countdown over
if (driver->unk3D4[2] == 0)
{
// nearing spinout sfx
driver->unk3D4[1] = FPS_HALF(10);
if (0 < driver->unk3D4[0])
driver->unk3D4[1] = -driver->unk3D4[1];
absVal_DistortVel = driver->unk3D4[1];
if (absVal_DistortVel < 0)
absVal_DistortVel = -absVal_DistortVel;
@ -397,43 +401,43 @@ LAB_800632cc:
sVar5 = DECOMP_VehCalc_InterpBySpeed(
driver->unk3D4[0], absVal_DistortVel, 0);
}
// frames counting down
else
{
driver->unk3D4[2]--;
// move up each frame
sVar5 = driver->unk3D4[0] + driver->unk3D4[1];
}
// near-spinout distortion SFX
driver->unk3D4[0] = sVar5;
driver->ampTurnState = (short)(iVar9 + iVar13);
driver->angle += (short)((driver->ampTurnState * gGT->elapsedTimeMS) >> 0xd);
driver->angle &= 0xfff;
if (driver->KartStates.Drifting.driftBoostTimeMS != 0)
{
if (driver->KartStates.Drifting.driftBoostTimeMS != 0)
{
// decrease by elpased time
driver->KartStates.Drifting.driftBoostTimeMS -= (u_int)gGT->elapsedTimeMS;
if (driver->KartStates.Drifting.driftBoostTimeMS < 0)
driver->KartStates.Drifting.driftBoostTimeMS = 0;
sVar5 = (short)((int)((u_int)driver->unk47A * gGT->elapsedTimeMS) >> 5);
if (driver->turnAngleCurr < 0)
{
sVar5 = -sVar5;
}
driver->axisRotationX += sVar5;
driver->axisRotationX &= 0xfff;
}
driver->rotCurr.y = driver->unk3D4[0] + driver->angle + driver->turnAngleCurr;
// increment this by milliseconds
@ -441,7 +445,7 @@ LAB_800632cc:
if (driver->KartStates.Drifting.driftTotalTimeMS > (int)((u_int)driver->unk462 << 5))
driver->KartStates.Drifting.driftTotalTimeMS = (u_short)driver->unk462 << 5;
// Located in Drifting_FuncPtrs.c
void PhysTerrainSlope(struct Driver* driver);
PhysTerrainSlope(driver);
@ -450,12 +454,12 @@ LAB_800632cc:
void PhysLerpRot(struct Driver* driver, int iVar13)
{
int uVar14;
// abs value: spinDistRemain
int iVar12_C = driver->rotCurr.w - iVar13;
if (iVar12_C < 0)
iVar12_C = -iVar12_C;
// Same trick as above ">>3"
// which has more comments there
#ifndef USE_60FPS
@ -469,33 +473,33 @@ void PhysLerpRot(struct Driver* driver, int iVar13)
{
uVar14 = (iVar12_C * 16) / 15;
uVar14 = uVar14 >> 3;
}
}
#endif
if (uVar14 == 0)
{
uVar14 = 1;
}
// max spin this frame
int uVar10 = (u_int)driver->unk46a;
if ((int)uVar14 < (int)(u_int)driver->unk46a)
{
uVar10 = uVar14;
}
// Interpolate rotation by speed
driver->rotPrev.w =
DECOMP_VehCalc_InterpBySpeed(
(int)driver->rotPrev.w,
8,
(int)driver->rotPrev.w,
8,
uVar10);
// Interpolate rotation by speed
driver->rotCurr.w =
DECOMP_VehCalc_InterpBySpeed(
(int)driver->rotCurr.w,
(int)(driver->rotPrev.w * sdata->gGT->elapsedTimeMS) >> 5,
(int)driver->rotCurr.w,
(int)(driver->rotPrev.w * sdata->gGT->elapsedTimeMS) >> 5,
iVar13);
}
@ -535,7 +539,7 @@ void DECOMP_VehPhysProc_PowerSlide_Update(struct Thread *t, struct Driver *d)
if (d->KartStates.Drifting.numBoostsAttempted < 3)
{
// set turbo meter to empty
meterLeft = d->const_turboMaxRoom << 5;
meterLeft = d->const_turboMaxRoom * ELAPSED_MS;
}
}
@ -558,7 +562,7 @@ void DECOMP_VehPhysProc_PowerSlide_Update(struct Thread *t, struct Driver *d)
#ifdef USE_ONLINE
if(d->driverID == 0)
#endif
// Make a sound
DECOMP_OtherFX_Play_Echo(0xf, 1, d->actionsFlagSet & 0x10000);
@ -581,11 +585,14 @@ void DECOMP_VehPhysProc_PowerSlide_Update(struct Thread *t, struct Driver *d)
{
// const_turboLowRoomWarning
// get length where turbo turns from green to red
highMeter = d->const_turboLowRoomWarning << 5;
highMeter = d->const_turboLowRoomWarning * ELAPSED_MS;
// If distance remaining to be filled in turbo bar, is less than,
// the distance remaining from the red/green "turning point" to the end,
#ifdef USE_ONLINE
AssignMeterGrade(d, meterLeft);
#endif
// If meter is in the red
if (meterLeft < highMeter)
{
@ -593,7 +600,7 @@ void DECOMP_VehPhysProc_PowerSlide_Update(struct Thread *t, struct Driver *d)
// the more room remaining to fill, the less boost you get
// old minMax: [zero -> const_turboLowRoomWarning]
// new minMax: [const_turboFullBarReserveGain, -> zero]
incrementReserves = DECOMP_VehCalc_MapToRange(meterLeft, 0, highMeter, d->const_turboFullBarReserveGain << 5, 0);
incrementReserves = DECOMP_VehCalc_MapToRange(meterLeft, 0, highMeter, d->const_turboFullBarReserveGain * ELAPSED_MS, 0);
DECOMP_VehFire_Increment(
@ -619,7 +626,7 @@ void DECOMP_VehPhysProc_PowerSlide_Update(struct Thread *t, struct Driver *d)
}
// drift boost meter = constant
d->KartStates.Drifting.driftBoostTimeMS = d->unk479 << 5;
d->KartStates.Drifting.driftBoostTimeMS = d->unk479 * ELAPSED_MS;
}
// If meter is in the green

View File

@ -321,6 +321,12 @@ struct Turbo
short fireVisibilityCooldown;
};
struct JitPoolHeader
{
struct JitPool * next;
struct JitPool * prev;
};
// for Players, AIs and Ghosts
struct Driver
{
@ -1550,10 +1556,14 @@ struct Driver
#ifdef USE_ONLINE
int uncappedReserves; // 0x638
int bestLapTime; // 0x63A
int currLapTime;
int bestLapTime; // 0x63C
int currLapTime; // 0x640
char meterGrade[2]; // 0x644
short meterGradeTimer; // 0x646
int gradeColor; // 0x648
#endif
struct JitPoolHeader jitPoolHeader;
// 0x638
// end of ghost struct (as determined by memset)