diff --git a/config/SZBE69_B8/objects.json b/config/SZBE69_B8/objects.json index ac7dbcdc..88822ff9 100644 --- a/config/SZBE69_B8/objects.json +++ b/config/SZBE69_B8/objects.json @@ -351,6 +351,7 @@ "system/rndobj/EnvAnim.cpp": "NonMatching", "system/rndobj/EventTrigger.cpp": "NonMatching", "system/rndobj/Flare.cpp": "NonMatching", + "system/rndobj/Font.cpp": "NonMatching", "system/rndobj/Fur.cpp": "Matching", "system/rndobj/Graph.cpp": "NonMatching", "system/rndobj/Group.cpp": "NonMatching", @@ -363,6 +364,7 @@ "system/rndobj/MotionBlur.cpp": "NonMatching", "system/rndobj/Movie.cpp": "Matching", "system/rndobj/MultiMesh.cpp": { "status": "NonMatching", "extra_cflags": [""] }, + "system/rndobj/MultiMeshProxy.cpp": "NonMatching", "system/rndobj/Overlay.cpp": "NonMatching", "system/rndobj/Poll.cpp": "Matching", "system/rndobj/PollAnim.cpp": "NonMatching", diff --git a/config/SZBE69_B8/symbols.txt b/config/SZBE69_B8/symbols.txt index 86655556..64bfec2f 100644 --- a/config/SZBE69_B8/symbols.txt +++ b/config/SZBE69_B8/symbols.txt @@ -49903,7 +49903,7 @@ __vt__15LatencyCallback = .data:0x80B7DA28; // type:object size:0x10 scope:globa @62935 = .data:0x80B7DA48; // type:object size:0xC scope:local align:4 __RTTI__15LatencyCallback = .data:0x80B7DA58; // type:object size:0x8 scope:global align:8 __vt__Q210RndOverlay8Callback = .data:0x80B7DA60; // type:object size:0x10 scope:global align:8 -@STRING@Find__9ObjectDirFPCcb_PQ23Hmx6Object = .data:0x80B7DA70; // type:object size:0xC scope:local align:4 data:string +@STRING@Find__9ObjectDirFPCcb_PQ23Hmx6Object = .data:0x80B7DA70; // type:object size:0xC scope:global align:4 data:string @STRING@SetType__9GamePanelF6Symbol@1 = .data:0x80B7DA7C; // type:object size:0x1C scope:local align:4 data:string @STRING@SetType__9GamePanelF6Symbol@0 = .data:0x80B7DA98; // type:object size:0x6 scope:local align:4 data:string @STRING@SetType__9GamePanelF6Symbol = .data:0x80B7DAA0; // type:object size:0x8 scope:local align:8 data:string @@ -60905,7 +60905,7 @@ __FUNCTION__$23285 = .data:0x80C1EFB8; // type:object size:0x12 scope:local alig __vt__6RndDir = .data:0x80C1EFCC; // type:object size:0x24C scope:global align:4 @STRING@PropSync<11RndPollable>__FRP11RndPollableR8DataNodeP9DataArrayi6PropOp_b@0 = .data:0x80C1F218; // type:object size:0x27 scope:local align:4 data:string @STRING@PropSync<11RndPollable>__FRP11RndPollableR8DataNodeP9DataArrayi6PropOp_b = .data:0x80C1F240; // type:object size:0xD scope:local align:4 data:string -@STRING@New<11RndPostProc>__Q23Hmx6ObjectFv_P11RndPostProc = .data:0x80C1F250; // type:object size:0x1E scope:local align:4 data:string +@STRING@New<11RndPostProc>__Q23Hmx6ObjectFv_P11RndPostProc = .data:0x80C1F250; // type:object size:0x1E scope:global align:4 data:string @STRING@StaticClassName__11RndPostProcFv = .data:0x80C1F270; // type:object size:0x9 scope:global align:4 data:string @stringBase0 = .data:0x80C1F280; // type:object size:0xD0 scope:local align:8 data:string_table __vt__7DOFProc = .data:0x80C1F350; // type:object size:0x80 scope:global align:8 diff --git a/src/system/math/Geo.h b/src/system/math/Geo.h index 3cbd6b28..352684f2 100644 --- a/src/system/math/Geo.h +++ b/src/system/math/Geo.h @@ -1,6 +1,7 @@ #ifndef MATH_GEO_H #define MATH_GEO_H #include "math/Vec.h" +#include "math/Sphere.h" #include "utl/BinStream.h" class Segment { @@ -48,5 +49,6 @@ inline BinStream& operator>>(BinStream& bs, Box& box){ } void SetBSPParams(float f1, float f2, int r3, int r4, float f3); +bool Intersect(const Segment&, const Sphere&); #endif diff --git a/src/system/math/MathFuncs.h b/src/system/math/MathFuncs.h index c151f5ad..40fb2a2f 100644 --- a/src/system/math/MathFuncs.h +++ b/src/system/math/MathFuncs.h @@ -132,6 +132,19 @@ inline float ceil_f(double d){ return ceil(d); } +inline float Modulo(float f1, float f2) { + if (f2 == 0.0f) + return 0.0f; + float tmp = fmod_f(f1, f2); + if (tmp < 0.0f) + tmp += f2; + return tmp; +} + +inline float ModRange(float f1, float f2, float f3){ + return Modulo(f3 - f1, f2 - f1) + f1; +} + inline float fmod_f(double x, double y){ return fmod(x, y); } diff --git a/src/system/math/Mtx.h b/src/system/math/Mtx.h index 758f8913..b15434fd 100644 --- a/src/system/math/Mtx.h +++ b/src/system/math/Mtx.h @@ -166,6 +166,12 @@ class TransformNoScale { class Plane { public: + Plane(){} + + float Dot(const Vector3& vec) const { + return a * vec.x + b * vec.y + c * vec.z + d; + } + float a, b, c, d; }; diff --git a/src/system/math/Sphere.h b/src/system/math/Sphere.h index ddefab1d..53f17121 100644 --- a/src/system/math/Sphere.h +++ b/src/system/math/Sphere.h @@ -7,12 +7,30 @@ class Sphere { public: Sphere(){ Zero(); } void Zero(){ radius = 0.0f; center.Zero(); } - float Radius() const { return radius; } + float GetRadius() const { return radius; } + + Sphere& operator=(const Sphere& s){ + center = s.center; + radius = s.radius; + } + + void Set(const Vector3& vec, float f){ + center = vec; + radius = f; + } Vector3 center; float radius; }; +inline BinStream& operator>>(BinStream& bs, Sphere& s){ + Vector3 vec; + float f; + bs >> vec >> f; + s.Set(vec, f); + return bs; +} + bool operator>(const Sphere&, const Frustum&); #endif diff --git a/src/system/math/Vec.h b/src/system/math/Vec.h index 8c45a39e..50e9348f 100644 --- a/src/system/math/Vec.h +++ b/src/system/math/Vec.h @@ -97,6 +97,11 @@ class Vector4 { // Vector4(const Vector4 &); }; +inline BinStream& operator>>(BinStream& bs, Vector4& vec){ + bs >> vec.x >> vec.y >> vec.z >> vec.w; + return bs; +} + class Vector4_16_01 { public: //Vector4_16_01() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {} diff --git a/src/system/obj/Dir.h b/src/system/obj/Dir.h index 1f459807..cbb90cc0 100644 --- a/src/system/obj/Dir.h +++ b/src/system/obj/Dir.h @@ -191,8 +191,12 @@ class ObjectDir : public virtual Hmx::Object { DataNode OnFind(DataArray*); Hmx::Object* FindObject(const char*, bool); - template T* Find(const char* name, bool b) { - return dynamic_cast(FindObject(name, b)); + template T* Find(const char* name, bool parentDirs) { + T* castedObj = dynamic_cast(FindObject(name, false)); + if(!castedObj && parentDirs){ + MILO_FAIL(kNotObjectMsg, name, PathName(this) ? PathName(this) : "**no file**"); + } + return castedObj; } DECLARE_REVS; diff --git a/src/system/obj/DirLoader.cpp b/src/system/obj/DirLoader.cpp index 84b86681..3e41dd75 100644 --- a/src/system/obj/DirLoader.cpp +++ b/src/system/obj/DirLoader.cpp @@ -118,7 +118,7 @@ const char* DirLoader::CachedPath(const char* cc, bool b){ if((sCacheMode || b) && ext){ bool isMilo = strcmp(ext, "milo") == 0; if(isMilo){ - return MakeString("%s/gen/%s.milo_%s", FileGetPath(cc, 0), FileGetBase(cc, 0), PlatformSymbol(TheLoadMgr.mPlatform)); + return MakeString("%s/gen/%s.milo_%s", FileGetPath(cc, 0), FileGetBase(cc, 0), PlatformSymbol(TheLoadMgr.GetPlatform())); } } return cc; diff --git a/src/system/obj/ObjMacros.h b/src/system/obj/ObjMacros.h index 7a80ad0c..d08fe144 100644 --- a/src/system/obj/ObjMacros.h +++ b/src/system/obj/ObjMacros.h @@ -279,7 +279,7 @@ void objType::Load(BinStream& bs){ // for loading in a version number that isn't a class's gRev/gAltRev #define ASSERT_GLOBAL_REV(ver, rev_name) \ if (ver > rev_name){ \ - MILO_FAIL("%s can't load new %s version %d > %d", PathName(this), ClassName(), rev_name, ver); \ + MILO_FAIL("%s can't load new %s version %d > %d", PathName(this), ClassName(), ver, rev_name); \ } #define LOAD_SUPERCLASS(parent) \ diff --git a/src/system/obj/Object.h b/src/system/obj/Object.h index c06af63f..7af531aa 100644 --- a/src/system/obj/Object.h +++ b/src/system/obj/Object.h @@ -168,12 +168,12 @@ inline TextStream& operator<<(TextStream& ts, const Hmx::Object* obj){ return ts; } -inline unsigned short getHmxRev(int ui){ - return ui; +inline unsigned short getHmxRev(int packed){ + return packed; } -inline unsigned short getAltRev(int ui){ - return (unsigned int)ui >> 0x10; +inline unsigned short getAltRev(int packed){ + return (unsigned int)packed >> 0x10; } inline int packRevs(unsigned short alt, unsigned short rev){ diff --git a/src/system/os/ArkFile.cpp b/src/system/os/ArkFile.cpp index 640519f6..4f2f4828 100644 --- a/src/system/os/ArkFile.cpp +++ b/src/system/os/ArkFile.cpp @@ -36,7 +36,7 @@ bool ArkFile::ReadAsync(void* iBuff, int iBytes){ unsigned int last = mFilename.find_last_of('_'); bool met = last != String::npos; if(met){ - Symbol plat = PlatformSymbol(TheLoadMgr.mPlatform); + Symbol plat = PlatformSymbol(TheLoadMgr.GetPlatform()); const char* strIdx = mFilename.c_str() + last + 1; met = plat == strIdx; } diff --git a/src/system/os/AsyncFile.cpp b/src/system/os/AsyncFile.cpp index a79d85c2..a32963ec 100644 --- a/src/system/os/AsyncFile.cpp +++ b/src/system/os/AsyncFile.cpp @@ -38,7 +38,7 @@ void PrintDiscFile(const char* cc){ unsigned int last = fullPath.find_last_of('_'); bool lastFound = last != String::npos; if(lastFound){ - Symbol plat = PlatformSymbol(TheLoadMgr.mPlatform); + Symbol plat = PlatformSymbol(TheLoadMgr.GetPlatform()); lastFound = plat == fullPath.c_str() + last + 1; } fullPath = (lastFound) ? fullPath.substr(0, last) : fullPath; diff --git a/src/system/os/File.cpp b/src/system/os/File.cpp index 5eaf3c17..154408fa 100644 --- a/src/system/os/File.cpp +++ b/src/system/os/File.cpp @@ -94,7 +94,7 @@ static DataNode OnToggleFakeFileErrors(DataArray* da){ void OnFrameRateRecurseCB(const char* cc1, const char* cc2){ MILO_ASSERT(gFrameRateArray, 0x148); String str(cc2); - const char* keepStr = MakeString("_keep_%s.dta", PlatformSymbol(TheLoadMgr.mPlatform)); + const char* keepStr = MakeString("_keep_%s.dta", PlatformSymbol(TheLoadMgr.GetPlatform())); int theStrLen = strlen(str.c_str()); int keepLen = strlen(keepStr); str = str.substr(0, theStrLen - keepLen); @@ -104,7 +104,7 @@ void OnFrameRateRecurseCB(const char* cc1, const char* cc2){ static DataNode OnEnumerateFrameRateResults(DataArray* da){ DataNode ret(new DataArray(0), kDataArray); gFrameRateArray = ret.Array(0); - FileRecursePattern(MakeString("ui/framerate/venue_test/*%s", MakeString("_keep_%s.dta", PlatformSymbol(TheLoadMgr.mPlatform))), OnFrameRateRecurseCB, false); + FileRecursePattern(MakeString("ui/framerate/venue_test/*%s", MakeString("_keep_%s.dta", PlatformSymbol(TheLoadMgr.GetPlatform()))), OnFrameRateRecurseCB, false); gFrameRateArray = 0; return ret; } diff --git a/src/system/os/System.cpp b/src/system/os/System.cpp index 020f6b6e..0bb04179 100644 --- a/src/system/os/System.cpp +++ b/src/system/os/System.cpp @@ -52,7 +52,7 @@ namespace { SetUsingCD(true); FileStat stat; - if (FileGetStat(MakeString("gen/main_%s.hdr", PlatformSymbol(TheLoadMgr.mPlatform)), &stat) < 0) { + if (FileGetStat(MakeString("gen/main_%s.hdr", PlatformSymbol(TheLoadMgr.GetPlatform())), &stat) < 0) { SetUsingCD(false); } } diff --git a/src/system/rndobj/Anim.cpp b/src/system/rndobj/Anim.cpp index 4c1e0e8d..fd3f9d02 100644 --- a/src/system/rndobj/Anim.cpp +++ b/src/system/rndobj/Anim.cpp @@ -4,6 +4,7 @@ #include "rndobj/Group.h" #include "obj/DataUtl.h" #include "obj/PropSync_p.h" +#include "math/MathFuncs.h" #include "utl/Symbols.h" INIT_REVS(RndAnimatable) @@ -61,20 +62,20 @@ BEGIN_LOADS(RndAnimatable) int count; bs >> count; bool theLoop = false; - float theScale = 0.0f; + float theScale = 1.0f; float theOffset = 0.0f; float theMin = 0.0f; - float theMax = 1.0f; + float theMax = 0.0f; + int read; int unused1, unused2, unused3, unused4, unused5, unused6, unused7; while(count-- != 0){ - int read; bs >> read; switch(read){ case 0: - bs >> theMax >> theMin; + bs >> theScale >> theOffset; break; case 1: - bs >> theOffset >> theScale >> theLoop; + bs >> theMin >> theMax >> theLoop; break; case 2: bs >> unused1 >> unused2; @@ -88,16 +89,16 @@ BEGIN_LOADS(RndAnimatable) default: break; } } - if(theMax != 1.0f || theMin != 0.0f || (theOffset != theScale)){ + if(theScale != 1.0f || theOffset != 0.0f || (theMin != theMax)){ const char* filt = MakeString("%s.filt", FileGetBase(Name(), 0)); - class ObjectDir* thisDir = mDir; + class ObjectDir* thisDir = Dir(); RndAnimFilter* filtObj = Hmx::Object::New(); - if(filtObj) filtObj->SetName(filt, thisDir); - filtObj->SetProperty("anim", DataNode(filtObj)); - filtObj->SetProperty("scale", DataNode(theMax)); - filtObj->SetProperty("offset", DataNode(theOffset)); + if(filt) filtObj->SetName(filt, thisDir); + filtObj->SetProperty("anim", DataNode(this)); + filtObj->SetProperty("scale", DataNode(theScale)); + filtObj->SetProperty("offset", DataNode(theOffset)); filtObj->SetProperty("min", DataNode(theMin)); - filtObj->SetProperty("max", DataNode(theMax)); + filtObj->SetProperty("max", DataNode(theMax)); filtObj->SetProperty("loop", DataNode(theLoop)); } ObjPtrList animList(this, kObjListNoNull); @@ -141,12 +142,48 @@ void RndAnimatable::StopAnimation(){ } } -AnimTask* RndAnimatable::Animate(float blend, bool b, float f2){ +Task* RndAnimatable::Animate(float blend, bool wait, float delay){ AnimTask* task = new AnimTask(this, StartFrame(), EndFrame(), FramesPerUnit(), Loop(), blend); - if(b && task->mBlendTask){ - f2 += task->mBlendTask->TimeUntilEnd(); + if(wait && task->mBlendTask){ + delay += task->mBlendTask->TimeUntilEnd(); } - TheTaskMgr.Start(task, Units(), f2); + TheTaskMgr.Start(task, Units(), delay); + return task; +} + +Task* RndAnimatable::Animate(float blend, bool wait, float delay, Rate rate, float start, float end, float period, float scale, Symbol type){ + float fpu; + float taskStart = start; + if(type == dest) start = mFrame; + if(period){ + fpu = __fabs(end - taskStart); + fpu = fpu / period; + } + else fpu = scale * gRateFpu[rate]; + + AnimTask* task = new AnimTask(this, start, end, fpu, type == loop, blend); + if(wait){ + AnimTask* blendTask = task->mBlendTask; + if(blendTask){ + delay += blendTask->TimeUntilEnd(); + } + } + TheTaskMgr.Start(task, gRateUnits[rate], delay); + return task; +} + +Task* RndAnimatable::Animate(float start, float end, TaskUnits units, float period, float blend){ + float fpu; + if(period){ + fpu = __fabs(end - start); + fpu = fpu / period; + } + else { + const float fpus[3] = { 30.0f, 480.0f, 30.0f }; + fpu = fpus[units]; + } + AnimTask* task = new AnimTask(this, start, end, fpu, false, blend); + TheTaskMgr.Start(task, units, 0.0f); return task; } @@ -239,7 +276,7 @@ BEGIN_PROPSYNCS(RndAnimatable); SYNC_PROP_MODIFY(frame, mFrame, SetFrame(mFrame, 1.0f)); END_PROPSYNCS; -AnimTask::AnimTask(RndAnimatable* anim, float start, float end, float fpu, bool loop, float blend) : +AnimTask::AnimTask(RndAnimatable* anim, float start, float end, float fpu, bool loop, float blend) : mAnim(this, 0), mAnimTarget(this, 0), mBlendTask(this, 0), mBlending(0), mBlendTime(0.0f), mBlendPeriod(blend), mLoop(loop) { MILO_ASSERT(anim, 0x1DF); mMin = (end < start) ? end : start; @@ -258,16 +295,13 @@ AnimTask::AnimTask(RndAnimatable* anim, float start, float end, float fpu, bool std::vector::const_reverse_iterator ritEnd = target->Refs().rend(); for(; rit != ritEnd; ++rit){ Hmx::Object* owner = (*rit)->RefOwner(); - if(owner){ - bool isananimtask = owner->ClassName() == AnimTask::StaticClassName(); - if(isananimtask){ - mAnimTarget = owner; - break; - } + if(owner != NULL && owner->ClassName() == AnimTask::StaticClassName()){ + mBlendTask = (AnimTask*)owner; + break; } } } - if(mBlendPeriod != 0.0f && mBlendTask){ + if(mBlendPeriod && mBlendTask){ mBlendTask->mBlending = true; } mAnim = anim; @@ -305,4 +339,42 @@ void AnimTask::Replace(Hmx::Object* from, Hmx::Object* to){ delete this; } } +} + +// https://decomp.me/scratch/KmGP0 +void AnimTask::Poll(float time){ + float frame; + float blend = 1.0f; + float t = time; + if(mBlendPeriod){ + blend = t / mBlendPeriod; + if(blend >= 1.0f){ + blend = 1.0f; + AnimTask* blendtask = mBlendTask; + delete blendtask; + mBlendPeriod = 0.0f; + } + else { + if(!mBlendTask){ + float oldtime = mBlendTime; + mBlendTime = t; + blend = (t - oldtime) / (mBlendPeriod - oldtime); + } + } + } + else { + AnimTask* blendtask = mBlendTask; + if(blendtask) delete blendtask; + } + t = t * mScale + mOffset; + if(mLoop){ + frame = ModRange(mMin, mMax, t); + } + else { + frame = Clamp(mMin, mMax, t); + } + mAnim->SetFrame(frame, blend); + if(!mAnimTarget || !mLoop && !mBlending && mBlendPeriod == 0.0f && t > mMax || t < mMin || !mScale){ + delete this; + } } \ No newline at end of file diff --git a/src/system/rndobj/Anim.h b/src/system/rndobj/Anim.h index 8f90a81e..364cfe33 100644 --- a/src/system/rndobj/Anim.h +++ b/src/system/rndobj/Anim.h @@ -29,7 +29,7 @@ class RndAnimatable : public virtual Hmx::Object { virtual bool Loop(){ return 0; } virtual void StartAnim(){} virtual void EndAnim(){} - virtual void SetFrame(float, float); // weak + virtual void SetFrame(float frame, float blend); // weak virtual float StartFrame(){ return 0.0f; } virtual float EndFrame(){ return 0.0f; } virtual Hmx::Object* AnimTarget(){ return this; } @@ -45,8 +45,9 @@ class RndAnimatable : public virtual Hmx::Object { Rate GetRate(){ return mRate; } DataNode OnConvertFrames(DataArray*); - AnimTask* Animate(float, bool, float); - void Animate(float, float, TaskUnits, float, float); + Task* Animate(float, bool, float); + Task* Animate(float, bool, float, Rate, float, float, float, float, Symbol); + Task* Animate(float, float, TaskUnits, float, float); static TaskUnits RateToTaskUnits(Rate); TaskUnits Units() const; @@ -70,17 +71,17 @@ class AnimTask : public Task { NEW_POOL_OVERLOAD(AnimTask); DELETE_POOL_OVERLOAD(AnimTask); - ObjOwnerPtr mAnim; - ObjPtr mAnimTarget; - ObjPtr mBlendTask; - bool mBlending; - float mBlendTime; - float mBlendPeriod; - float mMin; - float mMax; - float mScale; - float mOffset; - bool mLoop; + ObjOwnerPtr mAnim; // 0x1c + ObjPtr mAnimTarget; // 0x28 + ObjPtr mBlendTask; // 0x34 + bool mBlending; // 0x40 + float mBlendTime; // 0x44 + float mBlendPeriod; // 0x48 + float mMin; // 0x4c + float mMax; // 0x50 + float mScale; // 0x54 + float mOffset; // 0x58 + bool mLoop; // 0x5c }; #endif diff --git a/src/system/rndobj/AnimFilter.cpp b/src/system/rndobj/AnimFilter.cpp index f87fb41c..c7297466 100644 --- a/src/system/rndobj/AnimFilter.cpp +++ b/src/system/rndobj/AnimFilter.cpp @@ -79,3 +79,16 @@ BEGIN_HANDLERS(RndAnimFilter) HANDLE_SUPERCLASS(Hmx::Object) HANDLE_CHECK(0xE3) END_HANDLERS + +BEGIN_PROPSYNCS(RndAnimFilter) + SYNC_PROP_SET(anim, mAnim, SetAnim(_val.Obj(0))) + SYNC_PROP_SET(scale, mScale, mScale = __fabs(_val.Float(0))) + SYNC_PROP(offset, mOffset) + SYNC_PROP(period, mPeriod) + SYNC_PROP(start, mStart) + SYNC_PROP(end, mEnd) + SYNC_PROP(snap, mSnap) + SYNC_PROP_MODIFY(jitter, mJitter, mJitterFrame = 0.0f) + SYNC_PROP(type, (int&)mType) + SYNC_SUPERCLASS(RndAnimatable) +END_PROPSYNCS \ No newline at end of file diff --git a/src/system/rndobj/Dir.cpp b/src/system/rndobj/Dir.cpp index b70c2180..f0cf14f0 100644 --- a/src/system/rndobj/Dir.cpp +++ b/src/system/rndobj/Dir.cpp @@ -2,8 +2,14 @@ #include "obj/Object.h" #include "rndobj/Trans.h" #include "utl/FilePath.h" +#include "obj/ObjVersion.h" +#include "rndobj/PostProc.h" #include "utl/Symbols.h" +INIT_REVS(RndDir) + +DECOMP_FORCEACTIVE(Dir, "", __FILE__) + RndDir::RndDir() : mEnv(this, 0) { } @@ -13,8 +19,31 @@ void RndDir::Replace(Hmx::Object* o1, Hmx::Object* o2){ RndTransformable::Replace(o1, o2); } +void RndDir::Export(DataArray* da, bool b){ + MsgSource::Export(da, b); + for(int i = 0; i < mSubDirs.size(); i++){ + if(mSubDirs[i]){ + mSubDirs[i]->Export(da, false); + } + } +} + SAVE_OBJ(RndDir, 0x1C1) +BEGIN_COPYS(RndDir) + COPY_SUPERCLASS(ObjectDir) + COPY_SUPERCLASS(RndAnimatable) + COPY_SUPERCLASS(RndDrawable) + COPY_SUPERCLASS(RndTransformable) + CREATE_COPY(RndDir) + BEGIN_COPYING_MEMBERS + if(ty != kCopyFromMax){ + COPY_MEMBER(mEnv) + COPY_MEMBER(mTestEvent) + } + END_COPYING_MEMBERS +END_COPYS + void RndDir::OldLoadProxies(BinStream& bs, int i) { int items; bs >> items; @@ -41,6 +70,46 @@ void RndDir::OldLoadProxies(BinStream& bs, int i) { void RndDir::Load(BinStream& bs) { ObjectDir::Load(bs); } +void RndDir::PreLoad(BinStream& bs){ + LOAD_REVS(bs); + ASSERT_REVS(0xA, 0); + PushRev(packRevs(gAltRev, gRev), this); + ObjectDir::PreLoad(bs); +} + +void RndDir::PostLoad(BinStream& bs){ + ObjectDir::PostLoad(bs); + int revs = PopRev(this); + gRev = getHmxRev(revs); + gAltRev = getAltRev(revs); + LOAD_SUPERCLASS(RndAnimatable) + LOAD_SUPERCLASS(RndDrawable) + if(gRev != 0) LOAD_SUPERCLASS(RndTransformable) + if(gRev > 1){ + if(gLoadingProxyFromDisk){ + ObjPtr envPtr(this, 0); + RndEnviron* envToSet = 0; + char buf[0x80]; + bs.ReadString(buf, 0x80); + if(envPtr && envPtr->Dir()){ + envPtr = dynamic_cast(envPtr->Dir()->FindObject(buf, false)); + } + else envPtr = 0; + } + else bs >> mEnv; + } + if(gRev > 2 && gRev != 9) bs >> mTestEvent; + if(gRev - 4 < 5){ + Symbol s; + bs >> s >> s; + } + if(gRev - 5 <= 2){ + RndPostProc* rpp = Hmx::Object::New(); + rpp->LoadRev(bs, gRev); + delete rpp; + } +} + BEGIN_HANDLERS(RndDir) HANDLE(show_objects, OnShowObjects) HANDLE(supported_events, OnSupportedEvents) @@ -68,8 +137,10 @@ DataNode RndDir::OnSupportedEvents(DataArray*) { } BEGIN_PROPSYNCS(RndDir) + SYNC_PROP_STATIC(environ, mEnv) SYNC_PROP(polls, mPolls) SYNC_PROP(draws, mDraws) + SYNC_PROP(test_event, mTestEvent) SYNC_SUPERCLASS(ObjectDir) SYNC_SUPERCLASS(RndTransformable) SYNC_SUPERCLASS(RndDrawable) diff --git a/src/system/rndobj/Dir.h b/src/system/rndobj/Dir.h index 32271cd4..189a8014 100644 --- a/src/system/rndobj/Dir.h +++ b/src/system/rndobj/Dir.h @@ -51,12 +51,14 @@ class RndDir : public ObjectDir, public RndDrawable, public RndAnimatable, publi DataNode OnShowObjects(DataArray*); DataNode OnSupportedEvents(DataArray*); + + DECLARE_REVS - std::vector mDraws; - std::vector mAnims; - std::vector mPolls; - ObjPtr mEnv; - Symbol mTestEvent; + std::vector mDraws; // 0x164 + std::vector mAnims; // 0x16c + std::vector mPolls; // 0x174 + ObjPtr mEnv; // 0x17c + Symbol mTestEvent; // 0x188 NEW_OVERLOAD; DELETE_OVERLOAD; diff --git a/src/system/rndobj/Draw.cpp b/src/system/rndobj/Draw.cpp index 462179e8..c9d5faac 100644 --- a/src/system/rndobj/Draw.cpp +++ b/src/system/rndobj/Draw.cpp @@ -1,9 +1,13 @@ #include "rndobj/Draw.h" #include "rndobj/Cam.h" #include "rndobj/Utl.h" -#include "utl/Symbols.h" +#include "math/Geo.h" #include "obj/PropSync_p.h" +#include "utl/Symbols.h" +HighlightStyle RndDrawable::sHighlightStyle; +bool RndDrawable::sForceSubpartSelection; +float RndDrawable::sNormalDisplayLength = 1.0f; int DRAW_REV = 3; RndDrawable::RndDrawable() : mShowing(1), mSphere(), mOrder(0.0f) { @@ -59,8 +63,13 @@ BEGIN_COPYS(RndDrawable) COPY_MEMBER(mSphere) } else { - if(mSphere.Radius() != 0.0f && c->mSphere.Radius() != 0.0f){ - COPY_MEMBER(mSphere) + float zero = 0.0f; + float rad = mSphere.GetRadius(); + if(rad != zero){ + rad = c->mSphere.GetRadius(); + if(rad != zero){ + COPY_MEMBER(mSphere) + } } } END_COPYING_MEMBERS @@ -68,14 +77,10 @@ END_COPYS SAVE_OBJ(RndDrawable, 0xAE) -extern bool gLoadingProxyFromDisk; - void RndDrawable::Load(BinStream& bs){ int rev; bs >> rev; - if (rev > DRAW_REV){ - MILO_FAIL("%s can't load new %s version %d > %d", PathName(this), ClassName(), rev, DRAW_REV); - } + ASSERT_GLOBAL_REV(rev, DRAW_REV); if(gLoadingProxyFromDisk){ bool dummy; bs >> dummy; @@ -85,17 +90,53 @@ void RndDrawable::Load(BinStream& bs){ bs >> bs_showing; mShowing = bs_showing; } - // more stuff involving ObjectDir + if(rev < 2){ + int count; + bs >> count; + RndGroup* grp = dynamic_cast(this); + if(count != 0){ + for(; count != 0; count--){ + char buf[0x80]; + bs.ReadString(buf, 0x80); + if(grp){ + Hmx::Object* found = Dir()->Find(buf, true); + RndEnviron* env = dynamic_cast(found); + if(env){ + if(grp->mEnv) MILO_WARN("%s won't set %s", grp->Name(), buf); + else grp->mEnv = env; + } + else { + RndCam* cam = dynamic_cast(found); + if(!cam){ + grp->RemoveObject(found); + grp->AddObject(found, 0); + } + } + } + else MILO_WARN("%s not in group", buf); + } + } + } + if(rev > 0) bs >> mSphere; + if(rev > 2){ + if(gLoadingProxyFromDisk){ + float dummy; + bs >> dummy; + } + else bs >> mOrder; + } } void RndDrawable::DumpLoad(BinStream& bs){ + unsigned char dummy; + int y, x, w; int rev; + int i, j; + int z; bs >> rev; MILO_ASSERT(rev < 4, 0xFD); - unsigned char dummy; bs >> dummy; - if(rev < 3){ - int i; + if(rev < 2){ char buf[0x80]; bs >> i; for(; i != 0; i--){ @@ -103,11 +144,9 @@ void RndDrawable::DumpLoad(BinStream& bs){ } } if(rev > 0){ - int w, x, y, z; bs >> w >> x >> y >> z; } if(rev > 2){ - int j; bs >> j; } if(rev > 3){ @@ -116,6 +155,53 @@ void RndDrawable::DumpLoad(BinStream& bs){ } } +bool RndDrawable::CollideSphere(const Segment& seg){ + if(!mShowing) return false; + else { + Sphere sphere; + if(MakeWorldSphere(sphere, false) && !Intersect(seg, sphere)) return false; + else return true; + } +} + +RndDrawable* RndDrawable::Collide(const Segment& seg, float& f, Plane& plane){ + static Timer* _t = AutoTimer::GetTimer("collide"); + AutoTimer t(_t, 50.0f, NULL, NULL); + if(!CollideSphere(seg)) return false; + else return CollideShowing(seg, f, plane); +} + +// retail: https://decomp.me/scratch/X3MyB +// debug: https://decomp.me/scratch/rLOfM +int RndDrawable::CollidePlane(const Plane& plane){ + if(!mShowing) return -1; + else { + Sphere sphere; + if(MakeWorldSphere(sphere, false)){ + const Vector3& vec = sphere.center; + float prod = plane.Dot(vec); + if(prod >= sphere.radius){ + return 1; + } + else return sphere.radius < -prod ? -1 : 0; + } + else return -1; + } +} + +void RndDrawable::CollideList(const Segment& seg, std::list& collisions){ + float f; + Plane pl; + RndDrawable* draw = Collide(seg, f, pl); + if(draw){ + RndDrawable::Collision coll; + coll.object = draw; + coll.distance = f; + coll.plane = pl; + collisions.push_back(coll); + } +} + BEGIN_HANDLERS(RndDrawable) HANDLE(set_showing, OnSetShowing) HANDLE(showing, OnShowing) @@ -136,7 +222,7 @@ DataNode RndDrawable::OnGetSphere(const DataArray* da){ *da->Var(2) = DataNode(mSphere.center.X()); *da->Var(3) = DataNode(mSphere.center.Y()); *da->Var(4) = DataNode(mSphere.center.Z()); - *da->Var(5) = DataNode(mSphere.Radius()); + *da->Var(5) = DataNode(mSphere.GetRadius()); return DataNode(0); } diff --git a/src/system/rndobj/Draw.h b/src/system/rndobj/Draw.h index fb66ccb8..c08e0711 100644 --- a/src/system/rndobj/Draw.h +++ b/src/system/rndobj/Draw.h @@ -18,6 +18,7 @@ enum HighlightStyle { class RndDrawable : public virtual RndHighlightable { public: struct Collision { + Collision(){} RndDrawable* object; // offset 0x0, size 0x4 float distance; // offset 0x4, size 0x4 Plane plane; // offset 0x10, size 0x10 @@ -49,6 +50,8 @@ class RndDrawable : public virtual RndHighlightable { virtual ~RndDrawable(){} bool DrawBudget(float); + bool CollideSphere(const Segment&); + RndDrawable* Collide(const Segment&, float&, Plane&); static void DumpLoad(BinStream&); static HighlightStyle sHighlightStyle; static float sNormalDisplayLength; diff --git a/src/system/rndobj/Env.cpp b/src/system/rndobj/Env.cpp index 2ae73c49..34f3a891 100644 --- a/src/system/rndobj/Env.cpp +++ b/src/system/rndobj/Env.cpp @@ -10,7 +10,7 @@ RndEnviron* RndEnviron::sCurrent; bool RndEnviron::sCurrentPosSet; Vector3 RndEnviron::sCurrentPos = Vector3(0,0,0); // BoxMapLighting RndEnviron::sGlobalLighting(); -static int ENVIRON_REV = 15; +int ENVIRON_REV = 15; void RndEnviron::Select(const Vector3* v) { sCurrent = this; @@ -27,12 +27,12 @@ void RndEnviron::Select(const Vector3* v) { mNumLightsPoint = 0; mNumLightsProj = 0; mHasPointCubeTex = false; - mAmbientAlpha = 0; + unk5c = 0; ReclassifyLights(); } RndEnviron::RndEnviron() : mLightsReal(this, kObjListNoNull), mLightsApprox(this, kObjListNoNull), mLightsOld(this, kObjListNoNull), mAmbientColor(0.0f, 0.0f, 0.0f), - mAmbientAlpha(0), mNumLightsReal(0), mNumLightsApprox(0), mNumLightsPoint(0), mNumLightsProj(0), mHasPointCubeTex(false), mAmbientFogOwner(this, this), + unk5c(0), mNumLightsReal(0), mNumLightsApprox(0), mNumLightsPoint(0), mNumLightsProj(0), mHasPointCubeTex(false), mAmbientFogOwner(this, this), mFogEnable(0), mFogStart(0.0f), mFogEnd(1.0f), mFogColor(), mFadeOut(0), mFadeStart(0.0f), mFadeEnd(1000.0f), mFadeMax(1.0f), mFadeRef(this, NULL), mLRFade(0.0f, 0.0f, 0.0f, 0.0f), mColorXfm(), mUseColorAdjust(0), mAnimateFromPreset(1), mAOEnabled(1), mAOStrength(1.0f), mUpdateTimer(), mIntensityAverage(0.0f), @@ -44,21 +44,72 @@ RndEnviron::~RndEnviron() { if (sCurrent == this) { sCurrent = NULL; sCurrentPosSet = NULL; - sCurrentPos.z = 0; - sCurrentPos.y = 0; - sCurrentPos.x = 0; + sCurrentPos.Zero(); } } SAVE_OBJ(RndEnviron, 119) -/*void RndEnviron::Load(BinStream& bs) { // some weird shit goin on in here - LOAD_REVS(bs) - ASSERT_REVS(ENVIRON_REV, 0) - if (gRev > 1) Hmx::Object::Load(bs); - if (gRev < 3) RndDrawable::DumpLoad(bs); - bs >> mFadeRef; -}*/ +BEGIN_LOADS(RndEnviron) + int rev; + bs >> rev; + ASSERT_GLOBAL_REV(rev, ENVIRON_REV) + if(rev > 1) LOAD_SUPERCLASS(Hmx::Object) + if(rev < 3) RndDrawable::DumpLoad(bs); + if(rev < 0xF) bs >> mLightsOld; + else { + bs >> mLightsReal; + bs >> mLightsApprox; + } + bs >> mAmbientColor >> mFogStart >> mFogEnd; + if(rev < 1){ + int dummy; + bs >> dummy; + } + bs >> mFogColor; + if(rev < 1){ + int enabled; + bs >> enabled; + mFogEnable = enabled; + } + else bs >> mFogEnable; + if(rev > 3) bs >> mAnimateFromPreset; + if(rev > 4){ + bs >> mFadeOut >> mFadeStart >> mFadeEnd; + if(rev > 5) bs >> mFadeMax; + } + if(rev > 8){ + bs >> mFadeRef >> mLRFade; + } + if(rev > 6){ + bs >> mAmbientFogOwner; + if(!mAmbientFogOwner){ + mAmbientFogOwner = this; + } + } + if(rev > 7){ + bs >> mUseColorAdjust; + mColorXfm.Load(bs); + } + if(rev > 9){ + if(rev < 0xD){ + int dummy; + bs >> dummy; + } + bs >> mAOStrength; + } + if(rev > 10){ + bs >> mIntensityRate >> mExposure >> mWhitePoint >> mUseToneMapping; + } + if(rev == 0xB){ + int dummy; + bs >> dummy; + } + else if(rev - 0xC <= 1U){ + int dummy; + bs >> dummy; + } +END_LOADS BEGIN_COPYS(RndEnviron) COPY_SUPERCLASS(Hmx::Object) @@ -108,8 +159,8 @@ bool RndEnviron::IsValidRealLight(const RndLight*) const { bool RndEnviron::IsLightInList(const RndLight* light, const ObjPtrList& pList) const { if(light == 0) return 0; - for(ObjPtrList::Node* it = pList.mNodes; it != 0; it = it->next){ - RndLight* itLight = it->obj; + for(ObjPtrList::iterator it = pList.begin(); it != pList.end(); ++it){ + RndLight* itLight = *it; if(itLight == light) return itLight; } return 0; @@ -156,41 +207,37 @@ void RndEnviron::ApplyApproxLighting(const _GXColor*) { } BEGIN_PROPSYNCS(RndEnviron) SYNC_PROP(lights_real, mLightsReal) SYNC_PROP(lights_approx, mLightsApprox) - SYNC_PROP(ambient_color, mAmbientFogOwner) - - SYNC_PROP(contrast, mColorXfm.mContrast) - // SYNC_PROP(in_lo, mColorXfm.mLevelInLo) - if (sym == in_lo) { - if (PropSync(mColorXfm.mLevelInLo, _val, _prop, _i + 1, _op)) { - if (!(_op & 0x11)) mColorXfm.AdjustColorXfm(); - return true; - } - return false; - } - // SYNC_PROP(in_hi, mColorXfm.mLevelInHi) - if (sym == in_hi) { - if (PropSync(mColorXfm.mLevelInHi, _val, _prop, _i + 1, _op)) { - if (!(_op & 0x11)) mColorXfm.AdjustColorXfm(); - return true; - } - return false; - } - // SYNC_PROP_ACTION(out_lo, mColorXfm.mLevelOutLo, 0x11, mColorXfm.AdjustColorXfm()) - if (sym == out_lo) { - if (PropSync(mColorXfm.mLevelOutLo, _val, _prop, _i + 1, _op)) { - if (!(_op & 0x11)) mColorXfm.AdjustColorXfm(); - return true; - } - return false; - } - // SYNC_PROP_ACTION(out_hi, mColorXfm.mLevelOutHi, 0x11, mColorXfm.AdjustColorXfm()) - if (sym == out_hi) { - if (PropSync(mColorXfm.mLevelOutHi, _val, _prop, _i + 1, _op)) { - if (!(_op & 0x11)) mColorXfm.AdjustColorXfm(); - return true; - } - return false; - } + SYNC_PROP(ambient_color, mAmbientFogOwner->mAmbientColor) + SYNC_PROP(ambient_alpha, mAmbientFogOwner->mAmbientColor.alpha) + SYNC_PROP(fog_enable, mAmbientFogOwner->mFogEnable) + SYNC_PROP(fog_start, mAmbientFogOwner->mFogStart) + SYNC_PROP(fog_end, mAmbientFogOwner->mFogEnd) + SYNC_PROP(fog_color, mAmbientFogOwner->mFogColor) + SYNC_PROP(ambient_fog_owner, mAmbientFogOwner) + SYNC_PROP(fade_out, mFadeOut) + SYNC_PROP(fade_start, mFadeStart) + SYNC_PROP(fade_end, mFadeEnd) + SYNC_PROP(fade_max, mFadeMax) + SYNC_PROP(fade_ref, mFadeRef) + SYNC_PROP(left_out, mLRFade.x) + SYNC_PROP(left_opaque, mLRFade.y) + SYNC_PROP(right_opaque, mLRFade.z) + SYNC_PROP(right_out, mLRFade.w) + SYNC_PROP(ao_strength, mAOStrength) + SYNC_PROP(intensity_rate, mIntensityRate) + SYNC_PROP(exposure, mExposure) + SYNC_PROP(white_point, mWhitePoint) + SYNC_PROP(tone_map, mUseToneMapping) + SYNC_PROP(use_color_adjust, mUseColorAdjust) + SYNC_PROP_MODIFY(hue, mColorXfm.mHue, mColorXfm.AdjustColorXfm()) + SYNC_PROP_MODIFY(saturation, mColorXfm.mSaturation, mColorXfm.AdjustColorXfm()) + SYNC_PROP_MODIFY(lightness, mColorXfm.mLightness, mColorXfm.AdjustColorXfm()) + SYNC_PROP_MODIFY(brightness, mColorXfm.mBrightness, mColorXfm.AdjustColorXfm()) + SYNC_PROP_MODIFY(contrast, mColorXfm.mContrast, mColorXfm.AdjustColorXfm()) + SYNC_PROP_MODIFY_ALT(in_lo, mColorXfm.mLevelInLo, mColorXfm.AdjustColorXfm()) + SYNC_PROP_MODIFY_ALT(in_hi, mColorXfm.mLevelInHi, mColorXfm.AdjustColorXfm()) + SYNC_PROP_MODIFY_ALT(out_lo, mColorXfm.mLevelOutLo, mColorXfm.AdjustColorXfm()) + SYNC_PROP_MODIFY_ALT(out_hi, mColorXfm.mLevelOutHi, mColorXfm.AdjustColorXfm()) SYNC_PROP(animate_from_preset, mAnimateFromPreset) END_PROPSYNCS diff --git a/src/system/rndobj/Env.h b/src/system/rndobj/Env.h index f743a0b8..565aaa7d 100644 --- a/src/system/rndobj/Env.h +++ b/src/system/rndobj/Env.h @@ -49,7 +49,7 @@ class RndEnviron : public Hmx::Object { ObjPtrList mLightsApprox; // 0x2c ObjPtrList mLightsOld; // 0x3c Hmx::Color mAmbientColor; // 0x4c - int mAmbientAlpha; // 0x5c + int unk5c; // 0x5c // mNumLightsReal, mNumLightsApprox, mNumLightsPoint, mNumLightsProj int mNumLightsReal; // 0x60 int mNumLightsApprox; // 0x64 diff --git a/src/system/rndobj/Font.cpp b/src/system/rndobj/Font.cpp new file mode 100644 index 00000000..782be6f7 --- /dev/null +++ b/src/system/rndobj/Font.cpp @@ -0,0 +1,20 @@ +#include "rndobj/Font.h" +#include "rndobj/Mat.h" + +RndFont::RndFont() : mMat(this, 0), mTextureOwner(this, this), unk4c(0), mBaseKerning(0.0f), mCellSize(1.0f, 1.0f), mDeprecatedSize(0.0f), mMonospace(0), unk6c(0.0f, 0.0f), mPacked(0), unk78(this, 0) { + +} + +void RndFont::Replace(Hmx::Object* from, Hmx::Object* to){ + Hmx::Object::Replace(from, to); + if(mTextureOwner == from){ + if(!to) mTextureOwner = this; + else { + mTextureOwner = dynamic_cast(to)->mTextureOwner; + } + } +} + +RndFont::~RndFont(){ + +} \ No newline at end of file diff --git a/src/system/rndobj/Font.h b/src/system/rndobj/Font.h index da048149..42f35555 100644 --- a/src/system/rndobj/Font.h +++ b/src/system/rndobj/Font.h @@ -1,13 +1,36 @@ #ifndef RNDOBJ_FONT_H #define RNDOBJ_FONT_H - #include "obj/Object.h" +#include "obj/ObjPtr_p.h" #include "utl/MemMgr.h" +#include + +class RndMat; + +struct MatChar { + float width; + float height; +}; class RndFont : public Hmx::Object { public: + + class CharInfo { + float unk0; + float unk4; + float charWidth; + float unkc; + }; + + class KernInfo { + short unk0; + short unk2; + int unk4; + }; + RndFont(); virtual ~RndFont(); + virtual void Replace(Hmx::Object*, Hmx::Object*); OBJ_CLASSNAME(Font); OBJ_SET_TYPE(Font); virtual DataNode Handle(DataArray*, bool); @@ -22,6 +45,19 @@ class RndFont : public Hmx::Object { static void Init(){ REGISTER_OBJ_FACTORY(RndFont) } + + ObjPtr mMat; // 0x1c + ObjOwnerPtr mTextureOwner; // 0x28 + std::map unk34; // 0x34 + int unk4c; // 0x4c + float mBaseKerning; // 0x50 + Vector2 mCellSize; // 0x54 - cell width, cell height + float mDeprecatedSize; // 0x5c + std::vector mChars; // 0x60 + bool mMonospace; // 0x68 + Vector2 unk6c; // 0x6c + bool mPacked; // 0x74 + ObjPtr unk78; // 0x78 }; #endif // RNDOBJ_FONT_H diff --git a/src/system/rndobj/Group.h b/src/system/rndobj/Group.h index 4637c987..c048e4a3 100644 --- a/src/system/rndobj/Group.h +++ b/src/system/rndobj/Group.h @@ -48,12 +48,12 @@ class RndGroup : public RndAnimatable, public RndDrawable, public RndTransformab REGISTER_OBJ_FACTORY(RndGroup) } - ObjPtrList mObjects; - ObjPtr mEnv; - ObjPtr mDrawOnly; - ObjPtr mLod; - float mLodScreenSize; - bool unkf8; + ObjPtrList mObjects; // 0xc0 + ObjPtr mEnv; // 0xd0 + ObjPtr mDrawOnly; // 0xdc + ObjPtr mLod; // 0xe8 + float mLodScreenSize; // 0xf4 + bool unkf8; // 0xf8 std::vector mAnims; std::vector mDraws; int asdf; diff --git a/src/system/rndobj/MultiMeshProxy.cpp b/src/system/rndobj/MultiMeshProxy.cpp new file mode 100644 index 00000000..56f63e12 --- /dev/null +++ b/src/system/rndobj/MultiMeshProxy.cpp @@ -0,0 +1,52 @@ +#include "rndobj/MultiMeshProxy.h" +#include "utl/Symbols.h" + +RndMultiMeshProxy::RndMultiMeshProxy() : mMultiMesh(this, 0), mIndex(0) { + +} + +void RndMultiMeshProxy::SetMultiMesh(RndMultiMesh* mesh, const std::list::iterator& it){ + mMultiMesh = 0; + if(mesh){ + mLocalXfm = (*it).mXfm; + mCache->SetDirty(); + } + mMultiMesh = mesh; + mIndex = it; +} + +void RndMultiMeshProxy::DrawShowing(){ + if(mMultiMesh){ + RndMesh* theMesh = mMultiMesh->mMesh; + if(theMesh){ + theMesh->SetWorldXfm(mIndex->mXfm); + mMultiMesh->mMesh->Draw(); + } + } +} + +void RndMultiMeshProxy::UpdatedWorldXfm(){ + if(mMultiMesh){ + Transform& tfm = (mCache->mFlags & 1) ? WorldXfm_Force() : mWorldXfm; + mIndex->mXfm = tfm; + } +} + +BEGIN_LOADS(RndMultiMeshProxy) + MILO_FAIL("Attempting to load a MultiMesh proxy"); +END_LOADS + +void RndMultiMeshProxy::Save(BinStream& bs){ + MILO_FAIL("Attempting to save a MultiMesh proxy"); +} + +BEGIN_COPYS(RndMultiMeshProxy) + MILO_FAIL("Attempting to copy a MultiMesh proxy"); +END_COPYS + +BEGIN_HANDLERS(RndMultiMeshProxy) + HANDLE_CHECK(0x3F) +END_HANDLERS + +BEGIN_PROPSYNCS(RndMultiMeshProxy) +END_PROPSYNCS \ No newline at end of file diff --git a/src/system/rndobj/MultiMeshProxy.h b/src/system/rndobj/MultiMeshProxy.h index 60e3a904..144e90be 100644 --- a/src/system/rndobj/MultiMeshProxy.h +++ b/src/system/rndobj/MultiMeshProxy.h @@ -2,6 +2,9 @@ #define RNDOBJ_MULTIMESHPROXY_H #include "rndobj/Trans.h" #include "rndobj/Draw.h" +#include "obj/ObjPtr_p.h" +#include "rndobj/MultiMesh.h" +#include class RndMultiMeshProxy : public RndTransformable, public RndDrawable { public: @@ -13,17 +16,22 @@ class RndMultiMeshProxy : public RndTransformable, public RndDrawable { virtual void Save(BinStream&); virtual void Copy(const Hmx::Object*, Hmx::Object::CopyType); virtual void Load(BinStream&); - virtual ~RndMultiMeshProxy(); - virtual void Highlight(); + virtual ~RndMultiMeshProxy(){} + virtual void Highlight(){ RndDrawable::Highlight(); } virtual void UpdatedWorldXfm(); virtual void DrawShowing(); + void SetMultiMesh(RndMultiMesh*, const std::list::iterator&); + NEW_OVERLOAD; DELETE_OVERLOAD; NEW_OBJ(RndMultiMeshProxy) static void Init(){ REGISTER_OBJ_FACTORY(RndMultiMeshProxy) } + + ObjPtr mMultiMesh; // 0xb0 + std::list::iterator mIndex; // 0xbc }; #endif diff --git a/src/system/rndobj/PostProc.h b/src/system/rndobj/PostProc.h index f5fa64ae..1d3f9313 100644 --- a/src/system/rndobj/PostProc.h +++ b/src/system/rndobj/PostProc.h @@ -62,6 +62,7 @@ class RndPostProc : public Hmx::Object, public PostProcessor { virtual void OnUnselect(); void Interp(const RndPostProc*, const RndPostProc*, float); + void LoadRev(BinStream&, int); DataNode OnAllowedNormalMap(const DataArray*); static void Reset(); diff --git a/src/system/rndobj/Tex.cpp b/src/system/rndobj/Tex.cpp index ea6dcd03..3d54d2d0 100644 --- a/src/system/rndobj/Tex.cpp +++ b/src/system/rndobj/Tex.cpp @@ -19,9 +19,10 @@ bool UseBottomMip() { void CopyBottomMip(RndBitmap& dst, const RndBitmap& src) { MILO_ASSERT(&src != &dst, 48); - const RndBitmap* dingus; - while (dingus->mMip) dingus = dingus->mMip; - dst.Create(src, dingus->mBpp, dingus->mOrder, NULL); + while (src.mMip) { + &src = src.mMip; + } + dst.Create(src, src.mBpp, src.mOrder, NULL); } RndTex::RndTex() : mMipMapK(-8.0f), mType(Regular), mWidth(0), mHeight(0), mBpp(32), mFilepath(), mNumMips(0), mOptimizeForPS3(0), mLoader(0) { @@ -34,9 +35,11 @@ RndTex::~RndTex() { } void RndTex::PlatformBppOrder(const char* cc, int& bpp, int& order, bool hasAlpha){ - Platform plat = TheLoadMgr.mPlatform; - if(plat < kPlatformXBox || kPlatformPS3 < plat){ - if(plat == kPlatformWii){ + Platform plat = TheLoadMgr.GetPlatform(); + bool bbb; + + switch (TheLoadMgr.GetPlatform()) { + case kPlatformWii: order = 8; if(hasAlpha){ order |= 0x100; @@ -44,26 +47,34 @@ void RndTex::PlatformBppOrder(const char* cc, int& bpp, int& order, bool hasAlph } else bpp = 4; order |= 0x40; - } - else if(plat == kPlatformNone) order = 0; - } - else { - bool bbb = false; - if(strstr(cc, "_norm")) bbb = true; + break; + + case kPlatformPS2: + break; - if(bbb){ - if(plat == kPlatformXBox) order = 0x20; - else if(plat == kPlatformPS3) order = 8; - else order = 0; - } - else { - order = hasAlpha ? 0x18 : 8; - } - if(order == 8) bpp = 4; - else if(order & 0x38U) bpp = 8; - else if(bbb) bpp = 0x18; - else if(bpp < 0x10) bpp = 0x10; - else order = 0; + case kPlatformXBox: + case kPlatformPC: + case kPlatformPS3: + bbb = cc && strstr(cc, "_norm"); + + if(bbb){ + if(plat == kPlatformXBox) order = 0x20; + else if(plat == kPlatformPS3) order = 8; + else order = 0; + } + else { + order = hasAlpha ? 0x18 : 8; + } + if(order == 8) bpp = 4; + else if(order & 0x38U) bpp = 8; + else if(bbb) bpp = 0x18; + else if(bpp < 0x10) bpp = 0x10; + break; + + + case kPlatformNone: + order = 0; + break; } } @@ -326,7 +337,7 @@ void RndTex::PostLoad(BinStream& bs){ else if(gRev > 3){ int i; bs >> i; - mMipMapK = i; + mMipMapK = i / 16.0f; } if(gRev > 6){ @@ -372,7 +383,7 @@ void RndTex::PostLoad(BinStream& bs){ mLoader = 0; } BufStream bufs(buffer, size, true); - if(buffer) bs = bufs; + if(buffer) &bs = &bufs; PresyncBitmap(); if(UseBottomMip()){ RndBitmap someotherbmap; @@ -389,7 +400,7 @@ void RndTex::PostLoad(BinStream& bs){ MILO_ASSERT(!mNumMips, 0x3BE); SetBitmap(mWidth, mHeight, mBpp, mType, false, 0); } - else if(TheLoadMgr.mPlatform != kPlatformNone){ + else if(TheLoadMgr.GetPlatform() != kPlatformNone){ MILO_ASSERT(!mNumMips, 0x3C7); SetBitmap(mLoader); mLoader = 0; @@ -423,40 +434,30 @@ BEGIN_COPYS(RndTex) END_COPYING_MEMBERS END_COPYS -// enum Type { -// Regular = 1, -// Rendered = 2, -// Movie = 4, -// BackBuffer = 8, -// FrontBuffer = 0x18, -// RenderedNoZ = 0x22, -// ShadowMap = 0x42, -// DepthVolumeMap = 0xA2, -// DensityMap = 0x122, -// Scratch = 0x200, -// DeviceTexture = 0x1000 -// }; - DECOMP_FORCEACTIVE(Tex, "Regular", "Rendered", "Movie", "BackBuffer", "FrontBuffer", "RenderedNoZ", "ShadowMap", "DepthVolumeMap", "DensityMap", "DeviceTexture", "Scratch" ) TextStream& operator<<(TextStream& ts, RndTex::Type ty){ - if(ty == RndTex::RenderedNoZ) ts << "RenderedNoZ"; - else if(ty < RndTex::RenderedNoZ){ - if(ty == RndTex::Movie) ts << "Movie"; - else if(ty < RndTex::Movie){ - if(ty == RndTex::Rendered) ts << "Rendered"; - else if(ty < RndTex::Rendered && ty > 0) ts << "Regular"; + if(ty <= RndTex::RenderedNoZ){ + if(ty <= RndTex::Movie){ + if(ty <= RndTex::Rendered){ + if(ty < RndTex::Rendered && ty > 0) ts << "Regular"; + else if(ty == RndTex::Rendered) ts << "Rendered"; + } + else if(ty == RndTex::Movie) ts << "Movie"; } - else if(ty == RndTex::FrontBuffer) ts << "FrontBuffer"; - else if(ty < RndTex::FrontBuffer && ty == RndTex::BackBuffer) ts << "BackBuffer"; + else if(ty <= RndTex::FrontBuffer){ + if(ty < RndTex::FrontBuffer && ty == RndTex::BackBuffer) ts << "BackBuffer"; + else if(ty == RndTex::FrontBuffer) ts << "FrontBuffer"; + } + else if(ty == RndTex::RenderedNoZ) ts << "RenderedNoZ"; } - else if(ty == RndTex::DensityMap) ts << "DensityMap"; - else if(ty < RndTex::DensityMap){ - if(ty == RndTex::DepthVolumeMap) ts << "DepthVolumeMap"; - else if(ty < RndTex::DepthVolumeMap && ty == RndTex::ShadowMap) ts << "ShadowMap"; + else if(ty <= RndTex::DensityMap){ + if(ty < RndTex::DepthVolumeMap && ty == RndTex::ShadowMap) ts << "ShadowMap"; + else if(ty == RndTex::DepthVolumeMap) ts << "DepthVolumeMap"; + else if(ty == RndTex::DensityMap) ts << "DensityMap"; } else if(ty == RndTex::DeviceTexture) ts << "DeviceTexture"; else if(ty < RndTex::DeviceTexture && ty == RndTex::Scratch) ts << "Scratch"; @@ -502,7 +503,7 @@ DataNode RndTex::OnSetBitmap(const DataArray* da) { DataNode RndTex::OnSetRendered(const DataArray*) { MILO_ASSERT(IsRenderTarget(), 1101); - SetBitmap(mWidth, mHeight, mBpp, mType, mNumMips, NULL); // this is *almost* it... but the `or` needs to be an `andc` + SetBitmap(mWidth, mHeight, mBpp, mType, mNumMips > 0, NULL); return DataNode(); } @@ -523,18 +524,6 @@ BEGIN_PROPSYNCS(RndTex) } SYNC_PROP(mip_map_k, mMipMapK) SYNC_PROP(optimize_for_ps3, mOptimizeForPS3) - if (sym == file_path) { // mfw have to manually branch predict - bool synced = PropSync(mFilepath, _val, _prop, _i + 1, _op); - if (synced) { - if (!(_op & (0x11))) { - SetBitmap(mFilepath); - ; - } - return true; - } - return false; - } + SYNC_PROP_MODIFY_ALT(file_path, mFilepath, SetBitmap(mFilepath)) END_PROPSYNCS #pragma pop - -int RndTex::TexelsPitch() const { return 0; } diff --git a/src/system/rndobj/Tex.h b/src/system/rndobj/Tex.h index bbd36bac..d5765d24 100644 --- a/src/system/rndobj/Tex.h +++ b/src/system/rndobj/Tex.h @@ -23,7 +23,6 @@ class RndTex : public Hmx::Object { DeviceTexture = 0x1000 }; - // be prepared for virtual spew... RndTex(); virtual ~RndTex(); OBJ_CLASSNAME(RndTex) @@ -44,7 +43,7 @@ class RndTex : public Hmx::Object { virtual void Compress() {} virtual bool TexelsLock(void*&) {return false;} virtual void TexelsUnlock() {} - virtual int TexelsPitch() const; + virtual int TexelsPitch() const { return 0; } virtual void Select(int) {} virtual void PresyncBitmap() {} virtual void SyncBitmap() {} diff --git a/src/system/rndobj/TexBlendController.cpp b/src/system/rndobj/TexBlendController.cpp index 1870f67d..0a3ec1ea 100644 --- a/src/system/rndobj/TexBlendController.cpp +++ b/src/system/rndobj/TexBlendController.cpp @@ -2,8 +2,9 @@ #include "rndobj/Mesh.h" #include "rndobj/Tex.h" #include "rndobj/Trans.h" -#include "utl/Symbols.h" +#include "math/MathFuncs.h" #include "obj/PropSync_p.h" +#include "utl/Symbols.h" unsigned short RndTexBlendController::gRev = 0; @@ -15,9 +16,30 @@ RndTexBlendController::~RndTexBlendController(){ } +bool RndTexBlendController::GetCurrentDistance(float& f) const { + +} + +void RndTexBlendController::UpdateReferenceDistance(){ + GetCurrentDistance(mReferenceDistance); + mMinDistance = Minimum(mMinDistance, mReferenceDistance); + mMaxDistance = Max(mMaxDistance, mReferenceDistance); +} + void RndTexBlendController::UpdateMinDistance(){ GetCurrentDistance(mMinDistance); - mMinDistance = (mReferenceDistance < mMinDistance) ? mReferenceDistance : mMinDistance; + mMinDistance = Minimum(mMinDistance, mReferenceDistance); +} + +void RndTexBlendController::UpdateMaxDistance(){ + GetCurrentDistance(mMaxDistance); + mMaxDistance = Max(mMaxDistance, mReferenceDistance); +} + +void RndTexBlendController::UpdateAllDistances(){ + UpdateReferenceDistance(); + mMinDistance = mReferenceDistance * 0.5f; + mMaxDistance = mReferenceDistance * 1.5f; } BEGIN_COPYS(RndTexBlendController) @@ -60,8 +82,8 @@ BEGIN_HANDLERS(RndTexBlendController) END_HANDLERS BEGIN_PROPSYNCS(RndTexBlendController) - SYNC_PROP_MODIFY(reference_object_1, mObject1, UpdateAllDistances()) - SYNC_PROP_MODIFY(reference_object_2, mObject2, UpdateAllDistances()) + SYNC_PROP_MODIFY_ALT(reference_object_1, mObject1, UpdateAllDistances()) + SYNC_PROP_MODIFY_ALT(reference_object_2, mObject2, UpdateAllDistances()) SYNC_PROP(mesh, mMesh) SYNC_PROP(base_distance, mReferenceDistance) SYNC_PROP(min_distance, mMinDistance) diff --git a/src/system/rndobj/TexBlendController.h b/src/system/rndobj/TexBlendController.h index e1bbb4ad..eb6f10ce 100644 --- a/src/system/rndobj/TexBlendController.h +++ b/src/system/rndobj/TexBlendController.h @@ -38,10 +38,10 @@ class RndTexBlendController : public Hmx::Object { ObjPtr mMesh; ObjPtr mObject1; ObjPtr mObject2; - float mReferenceDistance; - float mMinDistance; - float mMaxDistance; - ObjPtr mTex; + float mReferenceDistance; // 0x40 + float mMinDistance; // 0x44 + float mMaxDistance; // 0x48 + ObjPtr mTex; // 0x4c }; #endif diff --git a/src/system/utl/Loader.cpp b/src/system/utl/Loader.cpp index 2b10b284..3e835a1f 100644 --- a/src/system/utl/Loader.cpp +++ b/src/system/utl/Loader.cpp @@ -40,7 +40,7 @@ static DataNode OnSetLoaderPeriod(DataArray* da){ } static DataNode OnSysPlatformSym(DataArray* da){ - return DataNode(PlatformSymbol(TheLoadMgr.mPlatform)); + return DataNode(PlatformSymbol(TheLoadMgr.GetPlatform())); } void LoadMgr::Init(){ diff --git a/src/system/utl/Loader.h b/src/system/utl/Loader.h index bbc489aa..f739daa3 100644 --- a/src/system/utl/Loader.h +++ b/src/system/utl/Loader.h @@ -51,12 +51,13 @@ class LoadMgr { void SetEditMode(bool); void Init(); Loader* ForceGetLoader(const FilePath&); - bool EditMode() const { return mEditMode; } + inline bool EditMode() const { return mEditMode; } + inline Platform GetPlatform() const { return (Platform)mPlatform; } static const char* LoaderPosString(LoaderPos, bool); std::list mLoaders; - Platform mPlatform; + unsigned int mPlatform; bool mEditMode; bool mCacheMode; std::list > mFactories;