Skip to content

Instantly share code, notes, and snippets.

@jamesu
Last active November 22, 2020 16:03
Show Gist options
  • Save jamesu/e145349377ad6b6c31c217a94b95b6b0 to your computer and use it in GitHub Desktop.
Save jamesu/e145349377ad6b6c31c217a94b95b6b0 to your computer and use it in GitHub Desktop.
marble.cpp
/*
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