Last active
November 22, 2020 16:03
-
-
Save jamesu/e145349377ad6b6c31c217a94b95b6b0 to your computer and use it in GitHub Desktop.
marble.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Reverse Engineered MarbleBlast Marble class attempt | |
TODO: pretty much everything | |
*/ | |
class MarbleData : public ShapeBaseData | |
{ | |
private: | |
typedef ShapeBaseData Parent; | |
enum Sounds | |
{ | |
RollHard, | |
Slip, | |
Bounce1, | |
Bounce2, | |
Bounce3, | |
Bounce4, | |
Jump, | |
NumSounds | |
}; | |
AudioProfile* mSounds[NumSounds];// @ 0x314 | |
// NOTE: could be this is actually Point3F and first velocity component is locked | |
F32 mMaxRollVelocity; // @ 0x330 | |
F32 mMinBounceSoundSpeed_334; // @ 0x334 | |
F32 mMaxBounceSoundSpeed_338; // @ 0x338 | |
F32 mAngularAcceleration; // @ 0x33c | |
F32 mBrakingAcceleration; // @ 0x340 | |
F32 mStaticFriction; // @ 0x344 | |
F32 mKineticFriction; // @ 0x348 | |
F32 mBounceKineticFriction; // @0x34c | |
F32 mGravity; // @ 0x350 | |
F32 mMaxDotSlide; // @ 0x354 | |
F32 mBounceRestitution; // @ 0x358 | |
F32 mAirAcceleration // @ 0x35c | |
F32 mEnergyRechargeRate; // @ 0x360 | |
F32 mJumpImpulse; // @ 0x364 | |
F32 mCameraDistance; // @ 0x368 | |
U32 unk3; | |
F32 mMaxForceRadius; // @ 0x370 | |
F32 mMinBounceVel; // @ 0x374 | |
F32 mMinTrailSpeed; // @ 0x37c | |
F32 mMinBounceSpeed; // @ 0x378 | |
ParticleEmitterData* mBounceEmitter; // @ 0x380 | |
ParticleEmitterData* mTrailEmitter; // @ 0x384 | |
ParticleEmitterData* mPowerUpEmitter[6]; // @ 0x388 | |
F32 mPowerUpTime[6]; // @ 0x3a0 | |
public: | |
DECLARE_CONOBJECT(MarbleData); | |
}; | |
class Marble : public ShapeBase | |
{ | |
private: | |
U32 mOtherMaskBits_028; // @ 0x28 | |
// NETOBJECT | |
U32 mMaskBits_040; // @0x40 | |
// SCENEOBJECT | |
MatrixF mObjToWorld_9c; // 9c...dc (last is d8) | |
MatrixF mWorldToObj_dc; // dc...11c (last is 114) | |
Point3F mObjScale_11c; // @0x11c | |
Box3F mObjBox_128; // @0x128 | |
Box3F mWorldBox_140; // @0x140 | |
SphereF mWorldSphere_158; // @0x158 | |
MatrixF mRenderObjToWorld_168; // @0x168 | |
MatrixF mRenderWorldToObj_1a4; // @0x1a4 | |
Box3F mRenderWorldBox_1e4; // @0x1e4 | |
SphereF mRenderWorldSphere_1fc; // @ 0x1fc | |
U32 mBinMinX_218; | |
U32 mBinMaxX_21c; | |
U32 mBinMinY_220; | |
U32 mBinMaxY_224; | |
// mSceneObjectValue_128 | |
// mSceneObjectValue_12c | |
// mSceneObjectValue_130 | |
// mSceneObjectValue_134 | |
// mSceneObjectValue_138 | |
// mSceneObjectValue_13c | |
U32 mMysteryShapeBaseValue_c60; | |
bool mMysteryShapeBaseFlag_6b8; | |
// START: 0x78c | |
typedef ShapeBase Parent; | |
enum MaskBits { | |
PositionMask = Parent::NextFreeMask, | |
NextFreeMask = Parent::NextFreeMask << 1 | |
}; | |
struct MaterialCollision { | |
// TODO | |
}; | |
struct Contact { | |
// TODO | |
}; | |
U32 unk1_78c; // @ 0x78c | |
U32 unk2_790; // @ 0x790 +4 | |
U32 unk3_794; // @ 0x794 +8 | |
U32 unk123_7cc; | |
U32 unk123_7d0; | |
F32 unk123_7d4; | |
Point3D mMysteryPoint_7b4; // @ 0x9b4 | |
MatrixF mMat_a8; // @ 0xa8...0xe8 | |
void* mysteryObject_1b4; // @ 0x1b4 | |
void* mSceneManager_230; // @ 0x230 | |
// Marble stuff | |
void* mMem_794; // @ 0x794 | |
// mMovePath? | |
F32 unkf1; // @ 0x914 | |
Point2D unkPoint_918; // @ 0x918, 0x91c, 0x920, 0x924 | |
F32 unkf6_928; // @ 0x928 | |
F32 unkf7_92c; // @ 0x92c (3.390625) | |
Point4D unkPoint_930; // @ 0x930, 0x938, 0x940 | |
F32 unkf10; // @ 0x938 | |
F32 unkf11; // @ 0x940 | |
F32 unkf12; // @ 0x944 | |
Point4D unkPoint_948; // @ 0x948, 0x950, 0x958 | |
F32 unkf19_960; // @ 0x960 | |
F32 unkf20_964; // @ 0x964 | |
Move lastMove_968; // incl padding (0x40 bytes) | |
MarbleData * mDataBlock_9a8; // @ 0x9A8 | |
U32 mPositionKey_9ac; // @ 0x9ac | |
bool mImpulseFlag_9b0; // @ 0x9b0 | |
// [padding] | |
U32 mBounceVariable_9b4; // @ 0x9b4 | |
U32 mPowerUpId_9b8; // @ 0x9b8 | |
U32 mPowerUpCounter_9bc; // @ 0x9bc | |
S32 mPowerUpNum_9c0; // @ 0x9c0 | |
MarbleMode mMarbleMode_9c4; // @ 0x9c4 | |
U32 mRollSound_9c8; // @ 0x9c8 | |
U32 mSlipSound_9cc; // @ 0x9cc | |
//F32 mCollisionRadius_9d0; // @ 0x9d0 | |
F32 mCollisionRadius_9d0; // @ 0x9d0 | |
Point3D mOtherPoint_9d4; // @ 0x9d4 ... 0x9ec | |
Point3D mVelocity_9ec; // @ 0x9ec | |
U32 padding[5]; | |
U32 foo_a00; // @ 0xa00 | |
Point3D mSimPosition_a04; // @ 0xa04 | |
Point3D mRotVelocity_a1c; // @ 0xa1c i.e. AngularVelocity | |
// .x = @0x0 | |
// .y = @0x0x8 | |
// .z = @0x10 | |
F32 mCameraYaw_a34; // @ 0xA34 | |
F32 mCameraPitch_a38; // @ 0xA38 | |
U32 mMysteryVar_a3c; // @ 0xA3C | |
U32 mMysteryVar_a40; // @ 0xA40 | |
bool mControllable_a44; // @ 0xA44 | |
bool mOOB_a45 // @ 0xa45 | |
U32 unk11_a48; // @ 0xa48 | |
U32 unk12_a4c; // @ 0xa4c // cam pos x? | |
U32 unk13_a50; // @ 0xa50 // cam pos y? | |
U32 unk14_a50; // @ 0xa54 // cam pos z? | |
U32 unk15_a50; // @ 0xa58 // cam dist? | |
U32 unk16_a5c; // @ 0xa5c // cam init flag? | |
SceneObject* mPad_a60; // @ 0xa60 | |
S8 mPadState_a64; // 0xa64 | |
// [padding] | |
U32 unk4_a68; // @ 0xa68 | |
U32 unk5_a6c; // @ 0xa6c | |
void* mMem_a70; // @ 0xa70 | |
struct ParticleRef | |
{ | |
bool flag; | |
U32 time; | |
ParticleEmitter* emitter; | |
}; | |
ParticleRef mParticles_a74[6]; // seems to start at a74 at least. Also referred to with a7c (+8) | |
// Ends at 0xabc | |
ParticleEmitter* mOtherParticles_0xabc; // @ 0xabc | |
ConcretePolyList *mPolyList_ac0; // @ 0xac0 | |
Vector<Point3F> pointInPolyVar1_c44; // @ 0xc44 | |
//U32 pointInPolyVar1_c48; // @ 0xc48 | |
//U32 pointInPolyVar1_c4c; // @ 0xc4c | |
Vector<U32> pointInPolyVar2_c50; // @ 0xc50 - 0xc5c | |
U32 unk_c5c; // @ 0xc5c | |
U32 unk_c60; // @ 0xc60 | |
double mysteryDouble_c64; // @ 0xc64 | |
double mysteryDouble_c6c; // @ 0xc6c | |
double mysteryDouble_c74; // @ 0xc74 | |
bool unk9_e08; // @ 0xe08 | |
// END: 0xe0c | |
public: | |
enum MarbleMode | |
{ | |
// | |
}; | |
struct PowerUpSlot | |
{ | |
U32 mId; | |
bool flag; | |
}; | |
Marble(); | |
// GameBase | |
bool onNewDataBlock(GameBaseData *dptr); | |
// SceneObject | |
void setTransform(const MatrixF &mat); | |
// SimObject | |
bool onAdd(); | |
void onRemove(); | |
void onEditorEnable(); | |
void onEditorDisable(); | |
void inspectPostApply(); | |
// NetObject | |
U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream); | |
void unpackUpdate(NetConnection *conn, BitStream *stream); | |
DECLARE_CONOBJECT(Marble); | |
static void initPersistFields(); | |
} | |
class MarbleUpdateEvent : public NetEvent | |
{ | |
public: | |
typedef NetEvent Parent; | |
MarbleUpdateEvent(); | |
~MarbleUpdateEvent(); | |
void pack(NetConnection *, BitStream *bstream); | |
void write(NetConnection *, BitStream *bstream); | |
void unpack(NetConnection *cptr, BitStream *bstream); | |
void process(NetConnection*); | |
DECLARE_CONOBJECT(MarbleUpdateEvent); | |
}; | |
MarbleData::MarbleData() | |
{ | |
mMinBounceSoundSpeed = 2.5f; | |
unk2_338 = 12f; | |
mMaxRollVelocity = 25f; | |
mAngularAcceleration = 18f; | |
mBrakingAcceleration = 8f; | |
mGravity = 20f; | |
mStaticFriction = 1.0f; | |
mKineticFriction = 0.9f; | |
mBounceKineticFriction = 0.2f; | |
mMaxDotSlide = 0.1f; | |
mBounceRestitution = 0.9f; | |
mAirAcceleration = 5.0f; | |
mEnergyRechargeRate = 1.0f; | |
mJumpImpulse = 1.0f; | |
unk3 = 3; | |
mMaxForceRadius = 1.0f; | |
mCameraDistance = 2.5f; | |
mMinBounceVel = 0.1f; | |
mMinTrailSpeed = 10f; | |
mMinBounceSpeed = 1.0f; | |
mBounceEmitter = NULL; | |
mTrailEmitter = NULL; | |
for (U32 i=0; i<6; i++) | |
{ | |
mPowerUpEmitter[i] = NULL; | |
mPowerUpTime[i] = 5000; | |
} | |
for (U32 i=0; i<NumSounds; i++) | |
{ | |
mSounds[i] = NULL; | |
} | |
// Guesses based on tge src (both are floats before emap) | |
shadowProjectionDistance = 0.4f; // @ 0x304 | |
shadowSphereAdjust = 0.01f; // @ 0x308 | |
} | |
void MarbleData::initPersistFields() | |
{ | |
addField("maxRollVelocity", TypeF32, Offset(mMaxRollVelocity, MarbleData), 0x1, 0x0); | |
addField("angularAcceleration", TypeF32, Offset(mAngularAcceleration, MarbleData), 0x1, 0x0); | |
addField("brakingAcceleration", TypeF32, Offset(mBrakingAcceleration, MarbleData), 0x1, 0x0); | |
addField("staticFriction", TypeF32, Offset(mStaticFriction, MarbleData), 0x1, 0x0); | |
addField("kineticFriction", TypeF32, Offset(mKineticFriction, MarbleData), 0x1, 0x0); | |
addField("bounceKineticFriction", TypeF32, Offset(mBounceKineticFriction, MarbleData), 0x1, 0x0); | |
addField("gravity", TypeF32, Offset(mGravity, MarbleData), 0x1, 0x0); | |
addField("maxDotSlide", TypeF32, Offset(mMaxDotSlide, MarbleData), 0x1, 0x0); | |
addField("bounceRestitution", TypeF32, Offset(mBounceRestitution, MarbleData), 0x1, 0x0); | |
addField("airAcceleration", TypeF32, Offset(mAirAcceleration, MarbleData), 0x1, 0x0); | |
addField("energyRechargeRate", TypeF32, Offset(mEnergyRechargeRate, MarbleData), 0x1, 0x0); | |
addField("jumpImpulse", TypeF32, Offset(mJumpImpulse, MarbleData), 0x1, 0x0); | |
addField("maxForceRadius", TypeF32, Offset(mCameraDistance, MarbleData), 0x1, 0x0); | |
addField("cameraDistance", TypeF32, Offset(mMaxForceRadius, MarbleData), 0x1, 0x0); | |
addField("minBounceVel", TypeF32, Offset(mMinBounceVel, MarbleData), 0x1, 0x0); | |
addField("minTrailSpeed", TypeF32, Offset(mMinTrailSpeed, MarbleData), 0x1, 0x0); | |
addField("minBounceSpeed", TypeF32, Offset(mMinBounceSpeed, MarbleData), 0x1, 0x0); | |
addField("bounceEmitter", TypeParticleEmitter, Offset(mBounceEmitter, MarbleData), 0x1, 0x0); | |
addField("trailEmitter", TypeParticleEmitter, Offset(mTrailEmitter, MarbleData), 0x1, 0x0); | |
addField("powerUpEmitter", TypeParticleEmitter, Offset(mPowerUpEmitter, MarbleData), 0x6, 0x0); | |
addField("powerUpTime", TypeS32, Offset(mPowerUpTime, MarbleData), 0x6, 0x0); | |
addField("RollHardSound", TypeAudioProfile, Offset(mSounds[RollHard], MarbleData), 0x1, 0x0); | |
addField("SlipSound", TypeAudioProfile, Offset(mSounds[Slip], MarbleData), 0x1, 0x0); | |
addField("Bounce1", TypeAudioProfile, Offset(mSounds[Bounce1], MarbleData), 0x1, 0x0); | |
addField("Bounce2", TypeAudioProfile, Offset(mSounds[Bounce2], MarbleData), 0x1, 0x0); | |
addField("Bounce3", TypeAudioProfile, Offset(mSounds[Bounce3], MarbleData), 0x1, 0x0); | |
addField("Bounce4", TypeAudioProfile, Offset(mSounds[Bounce4], MarbleData), 0x1, 0x0); | |
addField("JumpSound", TypeAudioProfile, Offset(mSounds[Jump], MarbleData), 0x1, 0x0); | |
Parent::initPersistFields(); | |
} | |
bool MarbleData::preload(bool server, char errorMsg[256]) | |
{ | |
if (Parent::preload(flag, errorMsg)) | |
{ | |
if (!server) | |
{ | |
for (int i=0; i<7; i++) | |
{ | |
Sim::findObject((SimObjectID)mSounds[i], mSounds[i]); | |
} | |
} | |
return true; | |
} | |
return false; | |
} | |
void Marble::onRemove() | |
{ | |
SceneGraph::removeShadowOccluder(mSceneManager_230); | |
removeFromScene(); | |
if (mRollSound_9c8 != NULL_AUDIOHANDLE) { | |
alxStop(mRollSound_9c8); | |
} | |
if (mSlipSound_9cc != NULL_AUDIOHANDLE) { | |
alxStop(mSlipSound_9cc); | |
} | |
Parent::onRemove(); | |
} | |
void Marble::setMode(Marble::MarbleMode mode) | |
{ | |
mMarbleMode_9c4 = mode; | |
NetObject::setMaskBits(0x40000000); | |
} | |
void Marble::processTick(Move const* move) | |
{ | |
ShapeBase::processTick(move); | |
} | |
/* | |
struct Move | |
{ | |
S32 px, py, pz; // @ 0x0, 0x4, 0x8 | |
U32 pyaw, ppitch, proll; // @ 0xc, 0x10, 0x14 | |
F32 x, y, z; // @ 0x18, 0x1c, 0x20 | |
F32 yaw, pitch, roll; // @ 0x24, 0x28, 0x2C | |
U32 id; // @ 0x30 | |
U32 sendCount; // @ 0x34 | |
bool freeLook; // @ 0x38 | |
bool trigger[MaxTriggerKeys]; // @ 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e 0x3f (6) (padded is 0x40) | |
}; | |
*/ | |
static U32 hashMove(Move const*m) | |
{ | |
U32 v1 = *((U32*)(m->x)); | |
ret ^= *((U32*)(m->y)); | |
ret ^= *((U32*)(m->z)); | |
ret ^= *((U32*)(m->yaw)); | |
ret ^= *((U32*)(m->pitch)); | |
ret ^= *((U32*)(m->roll)); | |
return ret; | |
} | |
void Marble::setVelocityD(Point3D const& vel) | |
{ | |
mVelocity_9ec = vel; | |
setMaskBits(0x18000000); | |
} | |
void Marble::setVelocityRotD(Point3D const& vel) | |
{ | |
mRotVelocity_a1c = vel; | |
setMaskBits(0x18000000); | |
} | |
void Marble::interpolateTick(F32 value) | |
{ | |
return Parent::interpolateTick(value); | |
} | |
void Marble::getPositionKey() | |
{ | |
return mPositionKey_9ac; | |
} | |
void Marble::setPowerUpId(U32 ident, bool flag) | |
{ | |
mPowerUpId_9b8 = ident; | |
if (flag) | |
{ | |
mPowerUpNum_9c0 = mPowerUpCounter_9bc; | |
mPowerUpCounter_9bc++; | |
setMaskBits(0x20000000); | |
} | |
else | |
{ | |
mPowerUpCounter_9bc++; | |
setMaskBits(0x20000000); | |
} | |
} | |
void Marble::setOOB(bool oob) | |
{ | |
mOOB_a45 = oob; | |
setMaskBits(0x40000000); | |
} | |
Point3D Marble::getVelocityD() const | |
{ | |
return mVelocity_9ec; | |
} | |
void Marble::renderImage(SceneState* state, SceneRenderImage* ri) | |
{ | |
Parent::renderImage(state, ri); | |
} | |
void Marble::initPersistFields() | |
{ | |
Parent::initPersistFields(); | |
addField("Controllable", TypeBool, Offset(Marble, mControllable_a44), 0x1, 0x0); | |
} | |
void Marble::playBounceSound(Marble::Contact& contact, F64 val) | |
{ | |
F64 dVar5 = val; | |
if (dVar5 < mDataBlock_9a8->mMinBounceSoundSpeed_334) | |
return; | |
F64 Var6; | |
Var6 = (F64)Platform::getRandom(); | |
Var6 = (F64)floorf((F64)(F32)Var6 * 3.9999); // @ 0x2d6f68 | |
int var_18h = Var6; | |
int iVar1 = var_18h + 2; | |
if (3 < var_18h) | |
{ | |
Con::printf("Fucky! %d", var_18h); // TOCHECK | |
return; | |
} | |
MarbleData* db = mDataBlock_9a8; // iVar3 | |
AudioDescription* iVar4 = db->mSounds[iVar1]->mDescriptionObject; // most likely | |
float origVolume = iVar4->mDescription->mVolume; // most likely | |
float scaledVolume = 1.0f; | |
if (dVar5 < db->unk2_338) { | |
scaledVolume = ((dVar5 - ((F64)db->mMinBounceSoundSpeed_334)) / | |
(F64)((db->mMaxBounceSoundSpeed_338) - (db->mMinBounceSoundSpeed_334))); | |
} | |
iVar4->mVolume = scaledVolume * origVolume; // volume hack | |
alxPlay(db->mSounds[iVar1], mObjToWorld_9c, NULL); | |
iVar4->mVolume = origVolume; | |
} | |
void Marble::victorySequence() | |
{ | |
// call vtable func on obj at 0x1b4 | |
// mysteryObject_1b4->vTable_1b4(0.100000001490116, 0, 0); | |
} | |
void Marble::bounceEmitter(F32 dt, Point3F const& axis) | |
{ | |
if (mBounceVariable_9b4 == 0x0) { | |
MarbleData* db = mDataBlock_9a8; // eax | |
if (db->mBounceEmitter != 0x0) { | |
double xmm0 = db->mMinBounceSpeed; | |
if (xmm0 <= 0x0) { | |
ParticleEmitter* emitter = new ParticleEmitter(); | |
emitter->onNewDataBlock(db->mBounceEmitter); | |
emitter->registerObject(); | |
emitter->emitParticles(mSimPosition_a04, false, axis, mVelocity_9ec, (int)(dt * 100)); | |
emitter->deleteWhenEmpty(); | |
mBounceVariable_9b4 = 300; | |
} | |
} | |
} | |
return eax; | |
} | |
// Seems to use static vars perhaps? (very bad for threading!) | |
Point3F* Marble::getPosition() | |
{ | |
static Point3F pos(0,0,0); | |
mat_a8.getColumn(3, &pos); | |
return &pos; | |
} | |
static char tmpBuf[0x64]; | |
ConsoleMethod(Marble, getPosition, const char*, 2, 2, "") | |
{ | |
Point3F pos = *object->getPosition(); | |
dSprintf(tmpBuf, sizeof(tmpBuf), "%f %f %f", pos.x, pos.y, pos.y); | |
return tmpBuf; | |
} | |
/* | |
ShapeBaseData::ShapeBaseData | |
eax = ConsoleObject::addField("shapeFile", 0x9, 0x48, 0x1, 0x0); | |
eax = ConsoleObject::addField("explosion", 0x1a, 0x60, 0x1, 0x0); | |
eax = ConsoleObject::addField("underwaterExplosion", 0x1a, 0x68, 0x1, 0x0); | |
eax = ConsoleObject::addField("debris", 0x26, 0x4c, 0x1, 0x0); | |
eax = ConsoleObject::addField("mass", 0x5, 0x70, 0x1, 0x0); | |
eax = ConsoleObject::addField("drag", 0x5, 0x74, 0x1, 0x0); | |
eax = ConsoleObject::addField("density", 0x5, 0x78, 0x1, 0x0); | |
eax = ConsoleObject::addField("maxEnergy", 0x5, 0x7c, 0x1, 0x0); | |
eax = ConsoleObject::addField("maxDamage", 0x5, 0x80, 0x1, 0x0); | |
eax = ConsoleObject::addField("disabledLevel", 0x5, 0x88, 0x1, 0x0); | |
eax = ConsoleObject::addField("destroyedLevel", 0x5, 0x8c, 0x1, 0x0); | |
eax = ConsoleObject::addField("repairRate", 0x5, 0x84, 0x1, 0x0); | |
eax = ConsoleObject::addField("cameraMaxDist", 0x5, 0x94, 0x1, 0x0); | |
eax = ConsoleObject::addField("cameraMinDist", 0x5, 0x98, 0x1, 0x0); | |
eax = ConsoleObject::addField("cameraDefaultFov", 0x5, 0x9c, 0x1, 0x0); | |
eax = ConsoleObject::addField("cameraMinFov", 0x5, 0xa0, 0x1, 0x0); | |
eax = ConsoleObject::addField("cameraMaxFov", 0x5, 0xa4, 0x1, 0x0); F32 | |
AFTER IS shape; | |
eax = ConsoleObject::addField("emap", 0x3, 0x30d, 0x1, 0x0); | |
eax = ConsoleObject::addField("aiAvoidThis", 0x3, 0x310, 0x1, 0x0); | |
eax = ConsoleObject::addField("isInvincible", 0x3, 0x311, 0x1, 0x0); | |
eax = ConsoleObject::addField("inheritEnergyFromMount", 0x3, 0x313, 0x1, 0x0); | |
eax = ConsoleObject::addField("renderWhenDestroyed", 0x3, 0x312, 0x1, 0x0); | |
eax = ConsoleObject::addField("debrisShapeName", 0x9, 0x54, 0x1, 0x0); | |
eax = ConsoleObject::addField("firstPersonOnly", 0x3, 0x30e, 0x1, 0x0); | |
eax = ConsoleObject::addField("useEyePoint", 0x3, 0x30f, 0x1, 0x0); | |
eax = ConsoleObject::addField("observeThroughObject", 0x3, 0x15a, 0x1, 0x0); | |
eax = ConsoleObject::addField("computeCRC", 0x3, 0xb0, 0x1, 0x0); | |
eax = ConsoleObject::addField("hudImageName", 0x7, 0x15c, 0x8, 0x0); | |
eax = ConsoleObject::addField("hudImageNameFriendly", 0x7, 0x15c, 0x8, 0x0); | |
eax = ConsoleObject::addField("hudImageNameEnemy", 0x7, 0x17c, 0x8, 0x0); | |
eax = ConsoleObject::addField("hudRenderCenter", 0x3, 0x1dc, 0x8, 0x0); | |
eax = ConsoleObject::addField("hudRenderModulated", 0x3, 0x1e4, 0x8, 0x0); | |
eax = ConsoleObject::addField("hudRenderAlways", 0x3, 0x1ec, 0x8, 0x0); | |
eax = ConsoleObject::addField("hudRenderDistance", 0x3, 0x1f4, 0x8, 0x0); | |
eax = ConsoleObject::addField("hudRenderName", 0x3, 0x1fc, 0x8, 0x0); | |
return eax; | |
*/ | |
bool Marble::onNewDataBlock(GameBaseData* db) | |
{ | |
if (!ShapeBase::onNewDataBlock(db)) | |
return false; | |
MarbleData* marbleDB = dynamic_cast<MarbleData*>(db); // eax | |
mDataBlock_9a8 = marbleDB; | |
if (db != NULL) | |
{ | |
TSShape* shape = db->shape; // @ 0xa8 | |
if (bool(shape)) { | |
// ebx = this | |
// edx = (this+0xa8) | |
mObjBox_128 = shape->bounds; | |
F32 dx = mObjBox_128.max.z - mObjBox_128.min.z; | |
F32 dy = mObjBox_128.max.y - mObjBox_128.min.y; | |
F32 dz = mObjBox_128.max.x - mObjBox_128.min.x; | |
mObjBox_128.min.z = (dx) * -0.5; | |
mObjBox_128.min.y = (dy) * -0.5; | |
mObjBox_128.min.x = (dz) * -0.5; | |
mObjBox_128.max.z = (dx) * 0.5; | |
mObjBox_128.max.y = (dy) * 0.5; | |
mObjBox_128.max.x = (dz) * 0.5; | |
mCollisionRadius_9d0 = (dx) * 0.5; | |
resetWorldBox(); | |
return true; | |
/* | |
// 6 values from 0x16c onwards | |
*(ebx + 0x128) = *(edx + 0x16c); // mObjBox_128.min.x = shape->bounds.min.x; | |
*(ebx + 0x12c) = *(edx + 0x170); // mObjBox_128.min.y = shape->bounds.min.y; | |
*(ebx + 0x130) = *(edx + 0x174); // mObjBox_128.min.z = shape->bounds.min.z; | |
*(ebx + 0x134) = *(edx + 0x178); // mObjBox_128.max.x = shape->bounds.max.x; | |
*(ebx + 0x138) = *(edx + 0x17c); // mObjBox_128.max.y = shape->bounds.max.y; | |
*(ebx + 0x13c) = *(edx + 0x180); // mObjBox_128.max.z = shape->bounds.max.z; | |
xmm3 = intrinsic_movss(xmm3, *(ebx + 0x13c)); // xmm3 = shape->bounds.max.z | |
xmm3 = intrinsic_subss(xmm3, *(ebx + 0x130)); // xmm3 = shape->bounds.max.z - shape->bounds.min.z | |
xmm4 = intrinsic_movss(xmm4, *(ebx + 0x138)); // xmm4 = shape->bounds.max.y | |
xmm4 = intrinsic_subss(xmm4, *(ebx + 0x12c)); // xmm4 = shape->bounds.max.y - shape->bounds.min.y | |
xmm2 = intrinsic_movss(xmm2, *(ebx + 0x134)); // xmm2 = shape->bounds.max.x | |
xmm2 = intrinsic_subss(xmm2, *(ebx + 0x128)); // xmm2 = shape->bounds.max.x - shape->bounds.min.x | |
xmm0 = intrinsic_movss(xmm0, *0x296248); // xmm0 = -0.5 | |
xmm1 = intrinsic_movaps(xmm1, xmm3); // xmm1 = xmm3 | |
xmm1 = intrinsic_mulss(xmm1, xmm0); // xmm1 = (shape->bounds.max.z - shape->bounds.min.z) * -0.5 | |
*(ebx + 0x130) = intrinsic_movss(*(ebx + 0x130), xmm1); // mObjBox_128.min.z = (shape->bounds.max.z - shape->bounds.min.z) * -0.5 | |
*(ebx + 0x12c) = intrinsic_movss(*(ebx + 0x12c), intrinsic_mulss(intrinsic_movaps(xmm1, xmm4), xmm0)); // mObjBox_128.min.y = (shape->bounds.max.y - shape->bounds.min.y) * -0.5 | |
xmm0 = intrinsic_mulss(xmm0, xmm2); // xmm0 = (shape->bounds.max.x - shape->bounds.min.x) * -0.5 | |
*(ebx + 0x128) = intrinsic_movss(*(ebx + 0x128), xmm0); // mObjBox_128.min.x = (shape->bounds.max.x - shape->bounds.min.x) * -0.5 | |
xmm0 = intrinsic_movss(xmm0, *0x2961d4); // 0.5 | |
xmm2 = intrinsic_mulss(xmm2, xmm0); // xmm2 = (shape->bounds.max.x - shape->bounds.min.x) * 0.5 | |
*(ebx + 0x13c) = intrinsic_movss(*(ebx + 0x13c), intrinsic_mulss(xmm3, xmm0)); // mObjBox_128.max.z | |
*(ebx + 0x138) = intrinsic_movss(*(ebx + 0x138), intrinsic_mulss(xmm4, xmm0)); // mObjBox_128.max.y | |
*(ebx + 0x134) = intrinsic_movss(*(ebx + 0x134), xmm2); // mObjBox_128.max.x | |
*(ebx + 0x9d0) = intrinsic_movss(*(ebx + 0x9d0), xmm2); // mImpulseVar_9d0*/ | |
} | |
} | |
} | |
void Marble::validateEyePoint(F32 t, MatrixF* m) | |
{ | |
// TODO | |
} | |
void Marble::setPosition(Point3D& pos, AngAxisF const& rot, F32 camPitch) | |
{ | |
MatrixF xfm = mObjToWorld_9c; | |
/* | |
// Copy mObjToWorld_9c to xfm | |
var_48 = *(esi + 0x9c); // 0,0 | |
var_44 = *(esi + 0xa0); // 0,1 | |
var_40 = *(esi + 0xa4); // 0,2 | |
// NO A8 (var_3C) | |
var_38 = *(esi + 0xac); // 1,0 | |
var_34 = *(esi + 0xb0); // 1,1 | |
var_30 = *(esi + 0xb4); // 1,2 | |
// NO B8 (var_2C) | |
var_28 = *(esi + 0xbc); // 2,0 | |
var_24 = *(esi + 0xc0); // 2,1 | |
var_20 = *(esi + 0xc4); // 2,2 | |
// NO C8 (var_1C) | |
var_18 = *(esi + 0xcc); // 3,0 | |
var_14 = *(esi + 0xd0); // 3,1 | |
var_10 = *(esi + 0xd4); // 3,2 | |
var_C = *(esi + 0xd8); // 3,3 | |
*/ | |
xfm.setPosition(pos); | |
/*xmm1 = intrinsic_cvtsd2ss(xmm1, *(int64_t *)(arg1 + 0x10)); // xmm1 = pos.z | |
xmm0 = intrinsic_cvtsd2ss(xmm0, *(int64_t *)(arg1 + 0x8)); // xmm0 = pos.y | |
var_3C = intrinsic_movss(var_3C, intrinsic_cvtsd2ss(xmm2, *(int64_t *)arg1)); // var_3C = pos.x | |
var_2C = intrinsic_movss(var_2C, xmm0); // var_2C = pos.y | |
var_1C = intrinsic_movss(var_1C, xmm1); // var_1C = pos.x | |
*/ | |
mSimPosition_a04 = pos; | |
/* | |
*(esi + 0xa04) = *arg1; | |
*(esi + 0xa08) = *(arg1 + 0x4); | |
*(esi + 0xa0c) = *(arg1 + 0x8); | |
*(esi + 0xa10) = *(arg1 + 0xc); | |
*(esi + 0xa14) = *(arg1 + 0x10); | |
*(esi + 0xa18) = *(arg1 + 0x14);*/ | |
setTransform(xfm); | |
setRenderTransform(xfm); | |
rot.setMatrix(&xfm); | |
VectorF forward = xfm.getForwardVector(); | |
double var_50 = atan2(forward.x, forward.y); // var_34(5) && var_44(1) equiv to getColumn(1) or getForwardVector() | |
mCameraYaw_a34 = var_50; | |
mCameraPitch_a38 = camPitch; | |
if ((mMaskBits_040 & IsGhost) == 0) | |
{ | |
mPositionKey_9ac++; | |
setMaskBits(0x18000000); | |
} | |
/* | |
// | |
xmm0 = intrinsic_cvtss2sd(xmm0, var_34); | |
xmm1 = intrinsic_cvtss2sd(xmm1, var_44); | |
var_60 = intrinsic_movsd(var_60, xmm0); | |
eax = atan2(intrinsic_movsd(arg2, xmm1), &var_48); | |
asm { fstp qword [ebp+var_50] }; | |
*(esi + 0xa34) = intrinsic_movss(*(esi + 0xa34), intrinsic_cvtsd2ss(xmm0, var_50)); | |
eax = var_16; | |
*(esi + 0xa38) = eax; | |
if ((*(int8_t *)(esi + 0x40) & 0x2) == 0x0) { | |
*(esi + 0x9ac) = *(esi + 0x9ac) + 0x1; | |
var_64 = 0x18000000; | |
eax = NetObject::setMaskBits(esi); | |
} | |
// | |
*/ | |
} | |
ConsoleMethod(Marble, setPosition, void 4, 4, "xfm, value") | |
{ | |
Point3F pos(0,0,0); | |
AngAxisF rot(Point3F(0,0,1),1); | |
dSScanf(argv[2], "%f %f %f %f %f %f %f", | |
&pos,x, &pos.y, &pos.z, &rot.axis.x, &rot.axis.y, &rot.axis.z, &rot.angle); | |
Point3F posD(pos); | |
object->setPosition(posD, rot, dAtof(argv[3])); | |
} | |
bool Marble::onAdd() | |
{ | |
if (Parent::onAdd()) | |
{ | |
addToScene(); | |
mSceneManager_230->addShadowOccluder(this); | |
U32 isGhostFlags = mMaskBits_040 & IsGhost; // eax | |
if (isGhostFlags == 0x0) | |
{ | |
mPositionKey_9ac++; | |
} | |
if (isGhostFlags == 0x0) | |
{ | |
MarbleData* db = mDataBlock_9a8; // edx | |
AudioDescription* rollDesc = mSounds[MarbleData::RollHard]->mDescription; | |
AudioDescription* slipDesc = mSounds[MarbleData::Slip]->mDescription; | |
F32 saveRoll = rollDesc->volume; | |
F32 saveSlip = slipDesc->volume; | |
rollDesc->volume = 0.0f; | |
slipDesc->volume = 0.0f; | |
mRollSound_9c8 = alxPlay(mDataBlock_9a8->mSounds[MarbleData::RollHard], &mObjToWorld_9c, NULL); // RollHard | |
mSlipSound_9cc = alxPlay(mDataBlock_9a8->mSounds[MarbleData::Slip], &mObjToWorld_9c, NULL); // Slip | |
rollDesc->volume = saveRoll; | |
slipDesc->volume = saveSlip; | |
return true; | |
/* | |
// NOTE: seems to be setting something in the AudioDescription then reverting it back after | |
// VOLUME? PRIORITY? | |
ecx = *(*(edx + 0x314) + 0x34); // RollHard | |
esi = *(ecx + 0x34); // RollHard var | |
xmm0 = intrinsic_movss(xmm0, *(*(*(edx + 0x318) + 0x34) + 0x34)); // Slip | |
var_1C = intrinsic_movss(var_1C, xmm0); // Slip SAVE | |
*(ecx + 0x34) = 0x0; // RollHard CLEAR | |
*(*(*(*(edi + 0x9a8) + 0x318) + 0x34) + 0x34) = 0x0; // 318 is Slip CLEAR | |
mRollSound_9c8 = alxPlay(mDataBlock_9a8->mSounds[RollHard], edi + 0x9c, 0x0); // RollHard | |
mSlipSound_9cc = alxPlay(mDataBlock_9a8->mSounds[Slip], edi + 0x9c, 0x0); // Slip] | |
*(*(*(*(edi + 0x9a8) + 0x314) + 0x34) + 0x34) = esi; // 314 = RollHard RESTORE | |
eax = *(edi + 0x9a8); // db | |
eax = *(eax + 0x318); // Slip | |
eax = *(eax + 0x34); // ->mDescription | |
*(eax + 0x34) = intrinsic_movss(*(eax + 0x34), intrinsic_movss(xmm0, var_1C)); // Slip RESTORE | |
*/ | |
} | |
return true; | |
} | |
return false; | |
} | |
void Marble::setPosition(Point3D& pos) | |
{ | |
MatrixF mat = mTransform; // i.e. copy from 0x9c mat | |
mat.setPosition(Point3F(pos.x, pos.y, pos.z)); | |
setTransform(mat); | |
setRenderTransform(mat); | |
setMaskBits(0x18000000); | |
} | |
void Marble::setTransform(const MatrixF &mat) | |
{ | |
Point3D dPos = mat.getPos(); | |
setPosition(Point3D(dPos.x, dPos.y, dPos.z)); | |
} | |
struct Poly { | |
PlaneF plane; // 0x0 - 0x10 | |
SceneObject* object; // 0x10 - 0x14 | |
U32 material; // 0x14 - 0x18 | |
U32 vertexStart; // 0x18 - 0x1c | |
U32 vertexCount; // 0x1c - 0x20 | |
U32 surfaceKey; // 0x20 - 0x24 | |
}; | |
bool Marble::pointWithinPolyZ(ConcretePolyList::Poly const& poly, Point3F const& point, Point3F const& otherPoint) | |
{/* | |
typedef Vector<PlaneF> PlaneList; | |
typedef Vector<Point3F> VertexList; | |
typedef Vector<Poly> PolyList; | |
typedef Vector<U32> IndexList; | |
PolyList mPolyList; | |
VertexList mVertexList; | |
IndexList mIndexList; | |
PlaneList mPolyPlaneList;*/ | |
Point3F* var_12 = &point; | |
Point3F* eax = otherPoint; | |
U32 edi = poly.vertexStart; | |
U32 esi = poly.vertexCount; | |
void* ecx = otherPoint; | |
U32* ebx = pointInPolyVar2_c50.address(); | |
U32* edx = pointInPolyVar1_c44.address(); | |
U32 var_34 = edx; | |
void* eax = pointInPolyVar2_c50[poly.vertexStart + (poly.vertexCount - 1)]; | |
float xmm6 = pointInPolyVar1_c44[idx].x; | |
float xmm5 = pointInPolyVar1_c44[idx].y; | |
float xmm1 = pointInPolyVar1_c44[idx].z; | |
if (poly.vertexCount == 0) | |
return true; | |
float var_30 = otherPoint.z; | |
float var_2C = otherPoint.y; | |
float var_28 = otherPoint.x; | |
float var_24 = var_12->z; | |
float var_20 = var_12->z; | |
float var_1c = var_12->z; | |
//edx = &pointInPolyVar2_c50[poly.vertexStart]; | |
//int ecx = 0; | |
for (U16* edx = &pointInPolyVar2_c50[poly.vertexStart], int ecx = 0; ecx < poly.vertexCount; ecx++) | |
{ | |
U16 eax = *edx; | |
float xmm0 = pointInPolyVar1_c44[eax].x; | |
float var_10 = xmm0 | |
xmm0 = pointInPolyVar1_c44[eax].y; | |
float var_14 = xmm0; | |
xmm0 = pointInPolyVar1_c44[eax].z; | |
float var_18 = xmm0; | |
float xmm4 = var_10; // pointInPolyVar1_c44[eax].x | |
xmm4 += var_28; // otherPoint.x | |
xmm4 -= var_10; // pointInPolyVar1_c44[eax].x | |
float xmm3 = var_14; // pointInPolyVar1_c44[eax].y; | |
xmm3 += var_2C; // otherPoint.y | |
xmm3 -= var_14; // pointInPolyVar1_c44[eax].y | |
xmm2 = intrinsic_movaps(xmm2, xmm0); | |
xmm2 = intrinsic_addss(xmm2, var_30); | |
xmm2 = intrinsic_subss(xmm2, xmm0); | |
xmm6 = intrinsic_subss(xmm6, var_10); | |
xmm5 = intrinsic_subss(xmm5, var_14); | |
xmm1 = intrinsic_subss(xmm1, xmm0); | |
xmm7 = intrinsic_movaps(xmm7, xmm3); | |
xmm7 = intrinsic_mulss(xmm7, xmm1); | |
xmm0 = intrinsic_movaps(xmm0, xmm2); | |
xmm0 = intrinsic_mulss(xmm0, xmm5); | |
xmm7 = intrinsic_subss(xmm7, xmm0); | |
xmm2 = intrinsic_mulss(xmm2, xmm6); | |
xmm1 = intrinsic_mulss(xmm1, xmm4); | |
xmm2 = intrinsic_subss(xmm2, xmm1); | |
xmm4 = intrinsic_mulss(xmm4, xmm5); | |
xmm3 = intrinsic_mulss(xmm3, xmm6); | |
xmm4 = intrinsic_subss(xmm4, xmm3); | |
xmm1 = intrinsic_movaps(xmm1, xmm7); | |
xmm1 = intrinsic_mulss(xmm1, xmm7); | |
xmm0 = intrinsic_movaps(xmm0, xmm2); | |
xmm0 = intrinsic_mulss(xmm0, xmm2); | |
xmm1 = intrinsic_addss(xmm1, xmm0); | |
xmm0 = intrinsic_movaps(xmm0, xmm4); | |
xmm0 = intrinsic_mulss(xmm0, xmm4); | |
xmm1 = intrinsic_addss(xmm1, xmm0); | |
xmm0 = intrinsic_pxor(xmm0, xmm0); | |
xmm1 = intrinsic_ucomiss(xmm1, xmm0); | |
if ((!PARITY(xmm1)) && (CPU_FLAGS & E)) { | |
xmm1 = intrinsic_pxor(xmm1, xmm1); | |
xmm1 = intrinsic_mulss(xmm1, var_10); | |
xmm0 = intrinsic_pxor(xmm0, xmm0); | |
xmm0 = intrinsic_mulss(xmm0, var_14); | |
xmm1 = intrinsic_addss(xmm1, xmm0); | |
xmm1 = intrinsic_addss(xmm1, var_18); | |
xmm1 = intrinsic_xorps(xmm1, 1.061e-314); | |
xmm6 = intrinsic_movss(xmm6, 1); | |
xmm2 = intrinsic_pxor(xmm2, xmm2); | |
xmm3 = intrinsic_movaps(xmm3, xmm2); | |
} | |
else { | |
xmm0 = intrinsic_sqrtss(xmm0, xmm1); | |
xmm1 = intrinsic_movss(xmm1, 1); | |
xmm1 = intrinsic_divss(xmm1, xmm0); | |
xmm3 = intrinsic_movaps(xmm3, xmm7); | |
xmm3 = intrinsic_mulss(xmm3, xmm1); | |
xmm2 = intrinsic_mulss(xmm2, xmm1); | |
xmm6 = intrinsic_movaps(xmm6, xmm1); | |
xmm6 = intrinsic_mulss(xmm6, xmm4); | |
xmm1 = intrinsic_movss(xmm1, var_10); | |
xmm1 = intrinsic_mulss(xmm1, xmm3); | |
xmm0 = intrinsic_movss(xmm0, var_14); | |
xmm0 = intrinsic_mulss(xmm0, xmm2); | |
xmm1 = intrinsic_addss(xmm1, xmm0); | |
xmm0 = intrinsic_movss(xmm0, var_18); | |
xmm0 = intrinsic_mulss(xmm0, xmm6); | |
xmm1 = intrinsic_addss(xmm1, xmm0); | |
xmm1 = intrinsic_xorps(xmm1, 1.061e-314); | |
} | |
xmm3 = intrinsic_mulss(xmm3, var_24); | |
xmm2 = intrinsic_mulss(xmm2, var_20); | |
xmm3 = intrinsic_addss(xmm3, xmm2); | |
xmm6 = intrinsic_mulss(xmm6, var_1C); | |
xmm3 = intrinsic_addss(xmm3, xmm6); | |
xmm3 = intrinsic_addss(xmm3, xmm1); | |
xmm0 = intrinsic_cvtss2sd(xmm0, xmm3); | |
xmm1 = intrinsic_movsd(xmm1, -0.003); | |
xmm1 = intrinsic_ucomisd(xmm1, xmm0); | |
if (xmm1 > 0) | |
return false; | |
//ecx = ecx + 0x1; | |
//edx = edx + 0x4; | |
xmm6 = var_10; | |
xmm5 = var_14; | |
xmm1 = var_18; | |
} | |
return false; | |
} | |
Marble::~Marble() | |
{ | |
for (U32 i=0; i<6; i++) | |
{ | |
ParticleRef* ptr = mParticles_a74[i]; | |
if (ptr->emitter != NULL) | |
ParticleEmitter::deleteWhenEmpty(ptr->emitter); | |
} | |
if (mOtherParticles_0xabc) { | |
ParticleEmitter::deleteWhenEmpty(); | |
} | |
delete polyList_ac0; | |
dFree(mMem_a70); | |
dFree(mMem_794); | |
} | |
void Marble::renderShadowVolumes(SceneState*) | |
{ | |
} | |
Marble::Marble() | |
{ | |
unk3_794 = NULL; | |
unk1_78c = NULL; | |
unk2_790 = NULL; | |
mMem_a70 = NULL; | |
unk4_a68 = NULL; | |
unk5_a6c = NULL; | |
mPolyList_ac0 = new ConcretePolyList(); // 0x21 bytes? | |
for (int i=33; i!=0; i--) | |
{ | |
// NOTE: not sure what this loop is doing | |
} | |
mMaskBits_040 |= 0x100; // also set in ShapeBase | |
mMaskBits_028 |= 0x4000; // TODO: figure out which var this is | |
unkf6_928 = 0; | |
unkf7_92c = 3.390625f; | |
double xmm0 = 0; | |
// NOTE: set assigns values in reverse | |
// group | |
unkPoint_918.set(0); | |
// group | |
unkPoint_930.set(0); | |
// group | |
unkPoint_948.set(0); | |
unkf20_964 = 1.0f; | |
unkf19_960 = 0; | |
lastMove_968 = NullMove; // @ 0x34d2e8 | |
// NOTE: Move should end at 9a8 | |
mBounceVariable_9b4 = 0; | |
double xmm2 = unkf6_928; // i.e. 0 | |
double xmm1 = unkPoint_918.z; // @0x920 | |
mMat_a8.m[0] = 0; | |
mMat_a8.m[4] = xmm1; // i.e. 0 | |
mMat_a8.m[8] = xmm2; // i.e. 0 | |
mMat_a8.setPosition(Point3F(0, xmm1, xmm2)); | |
//xmm2 = intrinsic_cvtsd2ss(xmm2, *(int64_t *)(esi + 0x928)); | |
//xmm1 = intrinsic_cvtsd2ss(xmm1, *(int64_t *)(esi + 0x920)); | |
//*(esi + 0xa8) = 0x0; | |
//*(esi + 0xb8) = intrinsic_movss(*(esi + 0xb8), xmm1); | |
//*(esi + 0xc8) = intrinsic_movss(*(esi + 0xc8), xmm2); | |
mPositionKey_9ac = 0; | |
mVelocity_9ec = Point3D(0,0,0); | |
/* | |
*(int64_t *)(esi + 0x9ec) = intrinsic_movsd(*(int64_t *)(esi + 0x9ec), xmm0); // velocity.x | |
*(int64_t *)(esi + 0x9f4) = intrinsic_movsd(*(int64_t *)(esi + 0x9f4), xmm0); // velocity.y | |
*(int64_t *)(esi + 0x9fc) = intrinsic_movsd(*(int64_t *)(esi + 0x9fc), xmm0);*/ // velocity.z | |
mysteryDouble_c64 = 0; | |
//*(int64_t *)(esi + 0xc64) = intrinsic_movsd(*(int64_t *)(esi + 0xc64), xmm0); | |
xmm1 = 1.0; | |
//xmm1 = intrinsic_movsd(xmm1, *(int64_t *)0x2d6d28); // 1.0 | |
mysteryDouble_c6c = 1.0; | |
mysteryDouble_c74 = 0; | |
/* *(int64_t *)(esi + 0xc6c) = intrinsic_movsd(*(int64_t *)(esi + 0xc6c), xmm1); // = 1 | |
*(int64_t *)(esi + 0xc74) = intrinsic_movsd(*(int64_t *)(esi + 0xc74), xmm0); */ | |
mCameraYaw_a34 = 0; | |
mCameraPitch_a38 = 0; | |
mRotVelocity_a1c = Point3D(0,0,0); | |
/* *(int64_t *)(esi + 0xa1c) = intrinsic_movsd(*(int64_t *)(esi + 0xa1c), xmm0); // x | |
*(int64_t *)(esi + 0xa24) = intrinsic_movsd(*(int64_t *)(esi + 0xa24), xmm0); // y | |
*(int64_t *)(esi + 0xa2c) = intrinsic_movsd(*(int64_t *)(esi + 0xa2c), xmm0); // z */ | |
mOtherPoint_9d4 = Point3D(0,0,1); | |
/* *(int64_t *)(esi + 0x9d4) = intrinsic_movsd(*(int64_t *)(esi + 0x9d4), xmm0); | |
*(int64_t *)(esi + 0x9dc) = intrinsic_movsd(*(int64_t *)(esi + 0x9dc), xmm0); | |
*(int64_t *)(esi + 0x9e4) = intrinsic_movsd(*(int64_t *)(esi + 0x9e4), xmm1); // = 1 | |
mSimPosition_a04 = Point3D(0,0,0); | |
/* | |
*(int64_t *)(esi + 0xa04) = intrinsic_movsd(*(int64_t *)(esi + 0xa04), xmm0); | |
*(int64_t *)(esi + 0xa0c) = intrinsic_movsd(*(int64_t *)(esi + 0xa0c), xmm0); | |
*(int64_t *)(esi + 0xa14) = intrinsic_movsd(*(int64_t *)(esi + 0xa14), xmm0);*/ | |
mImpulseFlag_9b0 = true; | |
mMysteryShapeBaseValue_c60 = 30; | |
mMysteryShapeBaseFlag_6b8 = true; // maybe mGenerateShadow? | |
mMysteryVar_a3c = 0; | |
mControllable_a44 = true; | |
mMysteryPoint_7b4 = Point3D(0,0,1); | |
/* *(int64_t *)(esi + 0x7b4) = intrinsic_movsd(*(int64_t *)(esi + 0x7b4), xmm0); | |
*(int64_t *)(esi + 0x7bc) = intrinsic_movsd(*(int64_t *)(esi + 0x7bc), xmm0); | |
*(int64_t *)(esi + 0x7c4) = intrinsic_movsd(*(int64_t *)(esi + 0x7c4), xmm1); // = 1 */ | |
unk123_7cc = 0; | |
unk123_7d0 = 0; | |
unk123_7d4 = 1.0f; | |
unk14_a50 = 0; | |
mCameraPitch_a38 = 0; | |
mCameraYaw_a34 = 0; | |
unk16_a5c = 0; | |
mPad_a60 = NULL; | |
mPadState_a64 = 0; | |
unk9_e08 = false; | |
for (int i=6; i>0; i--) // edx | |
{ | |
mParticles_a74[i].flag = false; | |
mParticles_a74[i].emitter = NULL; | |
} | |
mOtherParticles_0xabc = NULL; | |
mPowerUpId_9b8 = 0; | |
mPowerUpNum_9c0 = -1; | |
mPowerUpCounter_9bc = 0; | |
mMysteryVar_a40 = 0; | |
mRollSound_9c8 = 0; | |
mSlipSound_9cc = 0; | |
mMarbleMode_9c4 = 0; | |
mOOB_a45 = false; | |
} | |
bool Marble::pointWithinPoly(ConcretePolyList::Poly const& poly, Point3F const& pos) | |
{ | |
} | |
void rotateMatrix(MatrixF& mat, Point3F rot) | |
{ | |
sinf(); | |
cosf(); | |
for (int i=0; i<3; ++) | |
{ | |
} | |
/* could be variant of: | |
const float sinA = sinf( angleRadians ); | |
const float cosA = cosf( angleRadians ); | |
const float invCosA = 1.0f - cosA; | |
return mat3( (u.x * u.x * invCosA) + cosA, | |
(u.y * u.x * invCosA) - (sinA * u.z), | |
(u.z * u.x * invCosA) + (sinA * u.y), | |
(u.x * u.y * invCosA) + (sinA * u.z), | |
(u.y * u.y * invCosA) + cosA, | |
(u.z * u.y * invCosA) - (sinA * u.x), | |
(u.x * u.z * invCosA) - (sinA * u.y), | |
(u.y * u.z * invCosA) + (sinA * u.x), | |
(u.z * u.z * invCosA) + cosA | |
); | |
*/ | |
} | |
void Marble::advanceTime(F32 dt) | |
{ | |
ShapeBase::advanceTime(dt); | |
rotateMatrix(mObjToWorld_9c, mRotVelocity_a1c * dt); | |
} | |
S8 Marble::updatePadState() | |
{ | |
// calls pointWithinPolyZ | |
} | |
void Marble::clientStateUpdated(Point3F&, U32, U32, U32, Vector<Marble::MaterialCollision>&) | |
{ | |
// calls potentialEnterObject, | |
// queueCollision, notifyCollision, executef, setTransform, findObjects, | |
// updatePadState | |
} | |
void Marble::setPad(SceneObject* pad) | |
{ | |
mPad_a60 = pad; | |
mPadState_a64 = pad ? Marble::updatePadState() : NULL; | |
} | |
void Marble::applyImpulse(Point3F const& unused, Point3F const& applyVel) | |
{ | |
F32 impulseVar = mImpulseVar_9d0; | |
Point3F calc; | |
calc.y = (mVelocity_9ec.x / impulseVar) + mVelocity.y; // xmm2 | |
calc.x = (mVelocity_9ec.x / impulseVar) + mVelocity.x; // xmm1 | |
calc.z = (mVelocity_9ec.y / impulseVar) + mVelocity.z; // xmm0 | |
mVelocity_9ec = calc; | |
setMaskBits(0x18000000); | |
mImpulseFlag_9b0 = 1; | |
} | |
void Marble::advanceCamera(Move const*, U32) | |
{ | |
// uses gravity vars | |
} | |
void Marble::doPowerUp(S32 idx) | |
{ | |
// creates pfx and uses Sim::findObject | |
} | |
void Marble::controlPrePacketSend(GameConnection* connection) | |
{ | |
// seems to be new function originating from ShapeBase. Also used by Camera. | |
} | |
bool Marble::testMove(Point3D a, Point3D& b, F64& c, F64 d, U32 e, bool f) | |
{ | |
// big function | |
} | |
void Marble::computeFirstPlatformIntersect(F64& val) | |
{ | |
// another big function | |
} | |
void Marble::findContacts(U32 num) | |
{ | |
// BIG | |
} | |
void Marble::trailEmitter(U32 numMilliseconds) | |
{ | |
MarbleData* db = mDataBlock_9a8; // eax | |
if (db->mTrailEmitter == 0x0) | |
return; | |
float var_5C = mVelocity_9ec.len(); | |
double xmm0 = db->mMinTrailSpeed; | |
if (db->mMinTrailSpeed <= 0) | |
{ | |
if (mOtherParticles_0xabc == 0x0) | |
return; | |
mOtherParticles_0xabc->deleteWhenEmpty(); | |
mOtherParticles_0xabc = NULL; // effectively exits after this | |
return; | |
} | |
else if (mOtherParticles_0xabc == NULL) // else jmp to xmm* stuff | |
{ | |
// NOTE: ParticleEmitter is 0x2e4 bytes | |
mOtherParticles_0xabc = new ParticleEmitter(); | |
mOtherParticles_0xabc->onNewDataBlock(db->mTrailEmitter); | |
mOtherParticles_0xabc->registerObject(); | |
// NLI AFTER | |
if (mOtherParticles_0xabc == NULL) | |
return; | |
eax = *(edi + 0x9a8); | |
} | |
double xmm1 = db->mMinTrailSpeed; | |
double xmm0 = xmm1*2; // mMinTrailSpeed*2 | |
if (xmm0 > 0x0) { // (minTrailSpeed*2) > 0 | |
if (numMilliseconds >= 0) { | |
xmm0 = numMilliseconds; | |
} else { | |
// div 2, set 0x1 | |
xmm0 = (num >> 0x1) | (num & 0x1); | |
xmm0 += xmm0; | |
} | |
double xmm2 = var_5C; // i.e. velocity | |
var_5C = xmm2 - xmm1; // var_5C = velocity - minTrailSpeed | |
xmm2 /= xmm1; | |
xmm0 *= xmm2; // xmm0 = (velocity / minTrailSpeed) * velocity | |
numMilliseconds = (int)xmm0; | |
} | |
mOtherParticles_0xabc->emitParticles( mSimPosition_a04, true, mVelocity_9ec.normalize(), mVelocity_9ec, numMilliseconds ); | |
} | |
void Marble::getCameraTransform(F32*, MatrixF*) | |
{ | |
// uses testMove | |
} | |
void Marble::advancePhysics(Move const*, U32) | |
{ | |
// big | |
} | |
void Marble::readPacketData(GameConnection*, BitStream*) | |
{ | |
// TODO | |
} | |
void Marble::unpackUpdate(NetConnection*, BitStream*) | |
{ | |
// big | |
} | |
void Marble::writePacketData(GameConnection*, BitStream*) | |
{ | |
// TODO | |
} | |
U32 Marble::packUpdate(NetConnection*, U32, BitStream*) | |
{ | |
// big | |
} | |
MarbleUpdateEvent::MarbleUpdateEvent() | |
{ | |
} | |
MarbleUpdateEvent::~MarbleUpdateEvent() | |
{ | |
} | |
void MarbleUpdateEvent::pack(NetConnection *, BitStream *bstream) | |
{ | |
// TODO | |
} | |
void MarbleUpdateEvent::write(NetConnection *, BitStream *bstream) | |
{ | |
// TODO | |
} | |
void MarbleUpdateEvent::unpack(NetConnection *cptr, BitStream *bstream) | |
{ | |
// TODO | |
} | |
void MarbleUpdateEvent::process(NetConnection*) | |
{ | |
esi = arg0; | |
eax = arg_4; | |
ebx = *(eax + 0x324); // some pointer? | |
if (ebx != 0x0) { | |
Marble* m = dynamic_cast<Marble>(ebx); // -> edx | |
eax = *(ebx + 0x20); | |
if (eax == *(esi + 0x24)) { | |
if (edx != 0x0) { | |
var_18 = *(esi + 0x30); | |
var_1C = *(esi + 0x2c); | |
eax = *(esi + 0x28); | |
m->clientStateUpdated(edx, esi + 0x18, eax, var_1C, var_18); | |
} | |
} | |
} | |
return eax; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment