This commit is contained in:
Niko 2024-04-18 08:46:10 -07:00
parent c0793b4261
commit 46814d1fd7
13 changed files with 359 additions and 333 deletions

View File

@ -1,7 +1,325 @@
#include <common.h>
void DECOMP_RB_ShieldDark_ThTick_Grow(struct Thread* t)
void DECOMP_RB_ShieldDark_ThTick_Grow(struct Thread *th)
{
u_short shieldFlags;
short sVar4;
int i;
int rotY;
struct TrackerWeapon* tw;
struct PushBuffer* pb;
struct GameTracker* gGT = sdata->gGT;
struct Instance* shieldInst = th->inst;
struct Shield* shield = th->object;
struct Instance* colorInst = shield->instColor;
struct Instance* highlightInst = shield->instHighlight;
struct Thread* playerTh = th->parentThread;
struct Driver* player = playerTh->object;
struct Instance* driverInst = playerTh->inst;
// if highlight cooldown is gone
if (shield->highlightTimer == 0)
{
shield->highlightRot[1] += FPS_HALF(0x100);
// highlight is now visible
highlightInst->flags &= ~(0x80);
rotY = shield->highlightRot[1];
int iVar8 = rotY;
if (rotY < 0)
iVar8 = rotY + 0xfff;
// if highlight is finished
if ((rotY + (iVar8 >> 12) * -0x1000) == 0x400)
{
// cooldown is 30 frames (one second)
shield->highlightTimer = FPS_DOUBLE(30);
shield->highlightRot[1] = 0xc00;
// make highlight invisible
highlightInst->flags |= 0x80;
}
}
// if highlight cooldown is not done
else
{
// decrease counter, make invisible when this is zero
shield->highlightTimer--;
// make invisible
highlightInst->flags |= 0x80;
// if timer runs out (last frame)
if (shield->highlightTimer == 0)
{
// make visible
highlightInst->flags &= ~(0x80);
}
}
struct InstDrawPerPlayer* idpp = INST_GETIDPP(shieldInst);
struct InstDrawPerPlayer* colorIdpp = INST_GETIDPP(colorInst);
struct InstDrawPerPlayer* highlightIdpp = INST_GETIDPP(highlightInst);
// If the driver that used this weapon is visible
if (player->invisibleTimer == 0)
{
for (i = 0; i < gGT->numPlyrCurrGame; i++)
{
pb = &gGT->pushBuffer[i];
idpp[i].pushBuffer = pb;
colorIdpp[i].pushBuffer = pb;
highlightIdpp[i].pushBuffer = pb;
}
}
// if driver is not invisible
else
{
for (i = 0; i < gGT->numPlyrCurrGame; i++)
{
if (i == player->driverID)
continue;
pb = &gGT->pushBuffer[i];
idpp[i].pushBuffer = 0;
colorIdpp[i].pushBuffer = 0;
highlightIdpp[i].pushBuffer = 0;
}
}
short pos[3];
pos[0] = 0;
pos[1] = 0;
pos[2] = 0;
// Copy matrix
// To: shield instance, highlight instance, etc
// From: thread (shield) -> parentthread (player) -> object (driver) -> instance
LHMatrix_Parent(shieldInst, driverInst, &pos[0]);
LHMatrix_Parent(colorInst, driverInst, &pos[0]);
LHMatrix_Parent(highlightInst,driverInst, &pos[0]);
// set rotation variables
*(int *)&shieldInst->matrix.m[0][0] = 0x1000;
*(int *)&shieldInst->matrix.m[0][2] = 0;
*(int *)&shieldInst->matrix.m[1][1] = 0x1000;
*(int *)&shieldInst->matrix.m[2][0] = 0;
shieldInst->matrix.m[2][2] = 0x1000;
// set rotation variables
*(int *)&colorInst->matrix.m[0][0] = 0x1000;
*(int *)&colorInst->matrix.m[0][2] = 0;
*(int *)&colorInst->matrix.m[1][1] = 0x1000;
*(int *)&colorInst->matrix.m[2][0] = 0;
colorInst->matrix.m[2][2] = 0x1000;
// convert 3 rotation shorts into rotation matrix
ConvertRotToMatrix(&highlightInst->matrix, &shield->highlightRot[0]);
short scaleXZ;
short scaleY;
// if animation is not done
if (shield->animFrame < 8)
{
scaleXZ = ((int *)0x800b2cf4)[shield->animFrame*2+0];
scaleY = ((int *)0x800b2cf4)[shield->animFrame*2+1];
// set scale
shieldInst->scale[0] = WIDE_34(scaleXZ);
shieldInst->scale[1] = scaleY;
shieldInst->scale[2] = scaleXZ;
// set scale
colorInst->scale[0] = WIDE_34(scaleXZ);
colorInst->scale[1] = scaleY;
colorInst->scale[2] = scaleXZ;
#ifdef USE_60FPS
if(sdata->gGT->timer & 1)
#endif
// next frame
shield->animFrame++;
}
// if animation is done
else
{
short timerIndex =
(
(gGT->timer >> FPS_RIGHTSHIFT(0))
% 6
);
scaleXZ = ((short *)0x800b2d40)[timerIndex*2+0];
scaleY = ((short *)0x800b2d40)[timerIndex*2+1];
// set scale
shieldInst->scale[0] = WIDE_34(scaleXZ);
shieldInst->scale[1] = scaleY;
shieldInst->scale[2] = scaleXZ;
// set scale
colorInst->scale[0] = WIDE_34(scaleXZ);
colorInst->scale[1] = scaleY;
colorInst->scale[2] = scaleXZ;
// set scale
highlightInst->scale[0] = scaleXZ;
highlightInst->scale[1] = scaleY;
highlightInst->scale[2] = WIDE_34(scaleXZ);
}
// if this is not a blue shield,
// meaning it must fade eventually
if ((shield->flags & 4) == 0)
{
// duration
short duration = shield->duration;
// if out of time
if (duration == 0)
{
// erase bubble instance from driver
player->instBubbleHold = NULL;
goto LAB_800b0d6c;
}
// subtract 32ms by hand
duration -= FPS_HALF(32);
shield->duration = duration;
// 2.0 seconds
if (duration < 1920)
{
sVar4 = (short)(((60 - (duration >> 5)) * 3072) / 60) + 0x400;
// transparency
shieldInst->alphaScale = sVar4;
colorInst->alphaScale = sVar4;
highlightInst->alphaScale = sVar4;
}
}
shieldFlags = shield->flags;
if (
((shieldFlags & 1) != 0) ||
((shieldFlags & 8) != 0) ||
// if race ended for this driver
((player->actionsFlagSet & 0x2000000) != 0) ||
// if driver is being mask grabbed
(player->kartState == KS_MASK_GRABBED)
)
{
if ((shieldFlags & 8) != 0)
{
pb = &gGT->pushBuffer[player->driverID];
pb->fadeFromBlack_currentValue = 0x1fff;
pb->fadeFromBlack_desiredResult = 0x1000;
pb->fade_step = -(0x88);
}
shield->animFrame = 0;
player->instBubbleHold = NULL;
// execute, then assign per-frame funcPtr to thread
void RB_ShieldDark_ThTick_Pop();
ThTick_SetAndExec(th, RB_ShieldDark_ThTick_Pop);
return;
}
if ((shieldFlags & 2) == 0)
return;
player->instBubbleHold = NULL;
player->numTimesMissileLaunched++;
DECOMP_GAMEPAD_ShockFreq(player, 8, 0);
DECOMP_GAMEPAD_ShockForce1(player, 8, 0x7f);
// green shield
u_char model = 0x5e;
if ((shieldFlags & 4) != 0)
{
// blue shield
model = 0x56;
}
void RB_MovingExplosive_ThTick();
// create a thread, get an instance
struct Instance *bombInst =
DECOMP_INSTANCE_BirthWithThread(
model, 0, MEDIUM, OTHER,
RB_MovingExplosive_ThTick,
sizeof(struct TrackerWeapon),
playerTh);
struct Thread* bombTh = bombInst->thread;
bombTh->funcThDestroy = DECOMP_PROC_DestroyInstance;
// if driver is not an AI (human)
if ((player->actionsFlagSet & 0x100000) == 0)
{
// make driver talk
Voiceline_RequestPlay(13, data.characterIDs[player->driverID], 0x10);
}
// copy position and rotation from one instance to another
*(int*)&bombInst->matrix.m[0][0] = *(int*)&shieldInst->matrix.m[0][0];
*(int*)&bombInst->matrix.m[0][2] = *(int*)&shieldInst->matrix.m[0][2];
*(int*)&bombInst->matrix.m[1][1] = *(int*)&shieldInst->matrix.m[1][1];
*(int*)&bombInst->matrix.m[2][0] = *(int*)&shieldInst->matrix.m[2][0];
bombInst->matrix.m[2][2] = shieldInst->matrix.m[2][2];
// set scale (x, y, z) and transparency
for (i = 0; i < 4; i++)
bombInst->scale[i] = 0x400;
// get object from thread
tw = bombTh->object;
tw->flags = 0;
tw->driverTarget = 0;
tw->timeAlive = 0;
tw->audioPtr = 0;
tw->unk22 = 0;
tw->driverParent = player;
tw->instParent = driverInst;
tw->dir[1] = 0;
tw->dir[0] = (driverInst->matrix.m[0][2] * 3) >> FPS_RIGHTSHIFT(7);
tw->dir[2] = (driverInst->matrix.m[2][2] * 3) >> FPS_RIGHTSHIFT(7);
tw->rotY = player->angle;
tw->frameCount_DontHurtParent = FPS_DOUBLE(10);
LAB_800b0d6c:
// green shield fade away sound
PlaySound3D(0x58, player);
// shield and highlight
DECOMP_INSTANCE_Death(colorInst);
DECOMP_INSTANCE_Death(highlightInst);
// This thread is now dead
th->flags |= 0x800;
}

View File

@ -181,9 +181,9 @@ void DECOMP_VehPickupItem_ShootNow(struct Driver* d, int weaponID, int flags)
Voiceline_RequestPlay(talk, data.characterIDs[d->driverID], 0x10);
}
tw->vel[1] = 0;
tw->rotY = d->rotCurr.y;
tw->vel[1] = 0;
tw->vel[0] = (weaponInst->matrix.m[0][2] * 3) >> FPS_RIGHTSHIFT(7);
tw->vel[2] = (weaponInst->matrix.m[2][2] * 3) >> FPS_RIGHTSHIFT(7);

View File

@ -1,315 +0,0 @@
#include <common.h>
void RB_ShieldDark_ThTick(struct Thread *th)
{
u_short shieldFlags;
short sVar4;
int i;
int iVar8;
int rotY;
struct ShieldBomb* bomb;
struct PushBuffer* pb;
short pos[3];
struct GameTracker *gGT = sdata->gGT;
struct Instance *shieldInst = th->inst;
struct Shield *shield = th->object;
struct Instance *colorInst = colorInst;
struct Instance *highlightInst = highlightInst;
struct Driver *player = th->parentThread->object;
// if highlight cooldown is gone
if (shield->highlightTimer == 0)
{
shield->highlightRot[1] += 0x100;
// highlight is now visible
highlightInst->flags &= ~(0x80);
rotY = shield->highlightRot[1];
iVar8 = rotY;
if (rotY < 0)
{
iVar8 = rotY + 0xfff;
}
// if highlight is finished
if ((rotY + (iVar8 >> 12) * -0x1000) == 0x400)
{
// cooldown is 30 frames (one second)
shield->highlightTimer = FPS_DOUBLE(30);
shield->highlightRot[1] = 0xc00;
// make highlight invisible
highlightInst->flags |= 0x80;
}
}
// if highlight cooldown is not done
else
{
// decrease counter, make invisible when this is zero
shield->highlightTimer--;
// make invisible
highlightInst->flags |= 0x80;
// if timer runs out (last frame)
if (shield->highlightTimer == 0)
{
// make visible
highlightInst->flags &= ~(0x80);
}
}
// If the driver that used this weapon is visible
if (player->invisibleTimer == 0)
{
// if numPlyrCurrGame is not zero
if (gGT->numPlyrCurrGame != 0)
{
struct InstDrawPerPlayer idpp * = INST_GETIDPP(shieldInst);
struct InstDrawPerPlayer colorIdpp * = INST_GETIDPP(colorInst);
struct InstDrawPerPlayer highlightIdpp * = INST_GETIDPP(highlightInst);
for (i = 0; i < gGT->numPlyrCurrGame; i++)
{
pb = gGT->pushBuffer[i];
idpp[i].pushBuffer = pb;
colorIdpp[i].pushBuffer = pb;
highlightIdpp[i].pushBuffer = pb;
}
}
}
else
{
// if numPlyrCurrGame is not zero
if (gGT->numPlyrCurrGame != 0)
{
struct InstDrawPerPlayer idpp * = INST_GETIDPP(shieldInst);
struct InstDrawPerPlayer colorIdpp * = INST_GETIDPP(colorInst);
struct InstDrawPerPlayer highlightIdpp * = INST_GETIDPP(highlightInst);
for (i = 0; i < gGT->numPlyrCurrGame; i++)
{
if (i == player->driverID)
continue;
pb = gGT->pushBuffer[i];
idpp[i].pushBuffer = pb;
colorIdpp[i].pushBuffer = pb;
highlightIdpp[i].pushBuffer = pb;
}
}
}
// Copy matrix
// To: shield instance, highlight instance, etc
// From: thread (shield) -> parentthread (player) -> object (driver) -> instance
LHMatrix_Parent(shieldInst, player->instSelf, &pos);
LHMatrix_Parent(colorInst, player->instSelf, &pos);
LHMatrix_Parent(highlightInst, player->instSelf, &pos);
// set rotation variables
*(int *)&shieldInst->matrix.m[0][0] = 0x1000;
*(int *)&shieldInst->matrix.m[0][2] = 0;
*(int *)&shieldInst->matrix.m[1][1] = 0x1000;
*(int *)&shieldInst->matrix.m[2][0] = 0;
shieldInst->matrix.m[2][2] = 0x1000;
// set rotation variables
*(int *)&colorInst->matrix.m[0][0] = 0x1000;
*(int *)&colorInst->matrix.m[0][2] = 0;
*(int *)&colorInst->matrix.m[1][1] = 0x1000;
*(int *)&colorInst->matrix.m[2][0] = 0;
colorInst->matrix.m[2][2] = 0x1000;
// convert 3 rotation shorts into rotation matrix
ConvertRotToMatrix(&highlightInst->matrix, &shield->highlightRot[0]);
short scaleXZ;
short scaleY;
// if animation is not done
if (shield->animFrame < 8)
{
scaleXZ = ((int *)0x800b2cf4)[shield->animFrame];
scaleY = ((int *)0x800b2cf6)[shield->animFrame];
// set scale
shieldInst->scale[0] = scaleXZ;
shieldInst->scale[1] = scaleY;
shieldInst->scale[2] = scaleXZ;
// set scale
colorInst->scale[0] = scaleXZ;
colorInst->scale[1] = scaleY;
colorInst->scale[2] = scaleXZ;
shield->animFrame++;
}
// if animation is done
else
{
short timerIndex = (gGT->timer % 6);
scaleXZ = ((short *)0x800b2d40)[timerIndex];
scaleY = ((short *)0x800b2d42)[timerIndex];
// set scale
shieldInst->scale[0] = scaleXZ;
shieldInst->scale[1] = scaleY;
shieldInst->scale[2] = scaleXZ;
// set scale
colorInst->scale[0] = scaleXZ;
colorInst->scale[1] = scaleY;
colorInst->scale[2] = scaleXZ;
// set scale
highlightInst->scale[0] = scaleXZ;
highlightInst->scale[1] = scaleY;
highlightInst->scale[2] = scaleXZ;
}
// if this is not a blue shield,
// meaning it must fade eventually
if ((shield->flags & 4) == 0)
{
// duration
short duration = shield->duration;
// if out of time
if (duration == 0)
{
// erase bubble instance from driver
player->instBubbleHold = NULL;
goto LAB_800b0d6c;
}
// subtract 32ms by hand, instead of using in-game timer?
duration -= FPS_DOUBLE(32);
shield->duration = duration;
// last full second?
if (duration < FPS_DOUBLE(1920))
{
sVar4 = (short)(((60 - (iVar8 >> 5)) * 3072) / 60) + 0x400;
// transparency
shieldInst->alphaScale = sVar4;
colorInst->alphaScale = sVar4;
highlightInst->alphaScale = sVar4;
}
}
shieldFlags = shield->flags;
if (((((shieldFlags & 1) != 0) || ((shieldFlags & 8) != 0)) ||
// if race ended for this driver
((player->actionsFlagSet & 0x2000000) != 0))
// if driver is being mask grabbed
|| (player->kartState == KS_MASK_GRABBED))
{
if ((shield->flags & 8) != 0)
{
pb = gGT->pushBuffer[player->driverID];
pb->fadeFromBlack_currentValue = 0x1fff;
pb->fadeFromBlack_desiredResult = 0x1000;
pb->fade_step = -(0x88);
}
shield->animFrame = 0;
player->instBubbleHold = NULL;
// RB_ShieldDark_Pop is from being mask-grabbed,
// or from colliding with another player
// execute, then assign per-frame funcPtr to thread
ThTick_SetAndExec(th, RB_ShieldDark_Pop);
return;
}
if ((shieldFlags & 2) == 0)
return;
player->instBubbleHold = NULL;
player->numTimesMissileLaunched++;
GAMEPAD_ShockFreq(player, 8, 0);
GAMEPAD_ShockForce1(player, 8, 0x7f);
// green shield
u_char model = 0x5e;
if ((shieldFlags & 4) != 0)
{
// blue shield
model = 0x56;
}
// create a thread, get an instance
struct Instance *bombInst =
INSTANCE_BirthWithThread(
model,
s_shieldbomb_800aba04,
MEDIUM, OTHER,
RB_MovingExplosive_ThTick,
0x58,
player->instSelf->thread);
// if driver is not an AI (human)
if ((player->actionsFlagSet & 0x100000) == 0)
{
// make driver talk
VoiceLine_RequestPlay(13, data.charactersIDs[player->driverID], 0x10);
}
// copy instance matrices
for (i = 0; i < 8; i++)
((int *)bombInst->matrix.m[0][0])[i] = ((int *)shieldInst->matrix.m[0][0])[i];
// set funcThDestroy to remove instance from instance pool
bombInst->thread->funcThDestroy = PROC_DestroyInstance;
// set scale (x, y, z) and transparency
for (i = 0; i < 4; i++)
((short *)&bombInst->scale[0])[i] = 0x400;
// get object from thread
bomb = bombInst->thread->object;
// frame timer to zero
bomenu->timer = 0;
bomenu->unk = 0;
bomenu->driverWhoShot = player;
bomenu->driverInst = player->instSelf;
*(short *)((int)bomb + 0x10) = (short)(player->instSelf->matrix.m[0][2] * 3 >> 7);
*(short *)((int)bomb + 0x12) = 0;
*(short *)((int)bomb + 0x14) = (short)(player->instSelf->matrix.m[2][2] * 3 >> 7);
*(short *)((int)bomb + 0x1e) = player->angle;
*(short *)((int)bomb + 0x20) = 10;
*(short *)((int)bomb + 0x22) = 0;
*(short *)((int)bomb + 0x24) = 0;
bomb[0x12] = 0;
LAB_800b0d6c:
// green shield fade away sound
PlaySound3D(0x58, player);
// INSTANCE_Death
// shield and highlight
INSTANCE_Death(colorInst);
INSTANCE_Death(highlightInst);
// This thread is now dead
th->flags |= 0x800;
}

View File

@ -1,5 +1,5 @@
// 500+43+33+27+38+14+18+35+19+12+6+1+8+9+1+1+1+2+2+3+3+2+4+2+3+16+3+47-12 = 841 rewritten so far
// 500 for every 'common' and ','
// 503+43+33+27+38+14+18+35+19+12+6+1+8+9+1+1+1+2+2+3+3+2+4+2+3+16+3+47-12 = 844 rewritten so far
// 503 for every 'common' and ','
// additions for every file that has multiple functions,
// 43 for HOWL block
// 33 for LOAD block
@ -89,8 +89,12 @@ common, 231, RB_TNT_ThTick_ThrowOnHead, 0x0, General/231/231_020_RB_TNT_ThTick_T
// skip 3 functions
common, 231, RB_Hazard_InterpolateValue, 0x0, General/231/231_023_RB_Hazard_InterpolateValue.c
// skip 10 functions (warpball)
common, 231, RB_ShieldDark_ThTick_Pop, 0x0, General/231/231_037_RB_ShieldDark_ThTick_Pop.c
// rb_38_shieldgrow
//ommon, 231, RB_MaskWeapon_FadeAway, 0x0, General/231/231_035_RB_MaskWeapon_FadeAway.c
//ommon, 231, RB_MaskWeapon_ThTick, 0x0, General/231/231_036_RB_MaskWeapon_ThTick.c
//ommon, 231, RB_ShieldDark_ThTick_Pop, 0x0, General/231/231_037_RB_ShieldDark_ThTick_Pop.c
//ommon, 231, RB_ShieldDark_ThTick_Grow, 0x0, General/231/231_038_RB_ShieldDark_ThTick_Grow.c
common, 231, RB_Player_ToggleInvisible, 0x0, General/231/231_039_RB_Player_ToggleInvisible.c
common, 231, RB_Player_ToggleFlicker, 0x0, General/231/231_040_RB_Player_ToggleFlicker.c
common, 231, RB_RainCloud_FadeAway, 0x0, General/231/231_041_RB_RainCloud_FadeAway.c

View File

@ -4566,11 +4566,15 @@ void FUN_800b0454(int param_1)
return;
}
if ((uVar1 & 2) == 0) {
return;
}
*(undefined4 *)(iVar8 + 0x14) = 0;
*(char *)(iVar8 + 0x55c) = *(char *)(iVar8 + 0x55c) + '\x01';
// vibration
FUN_80026440(iVar8,8,0);
FUN_800264c0(iVar8,8,0x7f);
@ -4622,24 +4626,49 @@ void FUN_800b0454(int param_1)
// a 4th scale value???
*(undefined2 *)(iVar10 + 0x22) = 0x400;
// get object from thread
// get TrackerWeapon object from thread
puVar11 = *(undefined4 **)(*(int *)(iVar10 + 0x6c) + 0x30);
// frame timer to zero
// tw->flags
*(undefined2 *)((int)puVar11 + 0x16) = 0;
// tw->driverParent
puVar11[1] = iVar8;
// tw->driverTarget
*puVar11 = 0;
// tw->timeAlive
puVar11[0x12] = 0;
// tw->audioPtr
puVar11[9] = 0;
// angle
uVar2 = *(undefined2 *)(iVar8 + 0x39a);
// tw->dir[1]
*(undefined2 *)((int)puVar11 + 0x12) = 0;
// tw->rotY
*(undefined2 *)((int)puVar11 + 0x1e) = uVar2;
// tw->dir[0] = driver->instSelf->matrix.m[0][2]
*(short *)(puVar11 + 4) = (short)((int)*(short *)(*(int *)(iVar8 + 0x1c) + 0x34) * 3 >> 7);
// tw->dir[2] = driver->instSelf->matrix.m[2][2]
sVar4 = *(short *)(*(int *)(iVar8 + 0x1c) + 0x40);
// tw->frameCount_DontHurtParent
*(undefined2 *)(puVar11 + 8) = 10;
// tw->unk22
*(undefined2 *)((int)puVar11 + 0x22) = 0;
// tw->dir[2]
*(short *)(puVar11 + 5) = (short)((int)sVar4 * 3 >> 7);
// tw->instParent
puVar11[2] = *(undefined4 *)(iVar8 + 0x1c);
LAB_800b0d6c:

View File

@ -1,4 +1,3 @@
#include <common.h>
void DECOMP_CAM_ClearScreen(struct GameTracker* gGT);
void DECOMP_CAM_Init(struct CameraDC* cDC, int cameraID, struct Driver* d, struct PushBuffer* pb);

View File

@ -164,7 +164,6 @@ struct RainCloud
// size - 0x8
};
// when the shield is worn
struct Shield
{
// 0x0
@ -193,13 +192,6 @@ struct Shield
// 0x18
};
// when the shield is thrown
struct ShieldBomb
{
// 0x58 bytes
int unk;
};
struct MineWeapon;
struct WeaponSlot231

View File

@ -1,4 +1,3 @@
#include <common.h>
struct MaskHint
{