From 2e0f7510bf49dcb669baec409af748f9ee24e0a2 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Mon, 3 Feb 2025 13:18:43 -0700 Subject: [PATCH 01/12] gem work --- config/SZBE69/symbols.txt | 70 ++++++------ src/band3/bandtrack/Gem.cpp | 177 ++++++++++++++++++++++++++++++- src/band3/bandtrack/Gem.h | 41 ++++--- src/band3/bandtrack/GemManager.h | 4 + src/band3/bandtrack/Tail.h | 15 +++ src/system/beatmatch/VocalNote.h | 5 +- src/system/math/Vec.h | 2 + src/system/track/TrackDir.h | 2 +- src/system/utl/TimeConversion.h | 3 +- 9 files changed, 262 insertions(+), 57 deletions(-) diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index 88862c2f8..c9ccc9ce8 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -7223,7 +7223,7 @@ fn_800CA334 = .text:0x800CA334; // type:function size:0x30 __as__Q211stlpmtx_std75vector>FRCQ211stlpmtx_std75vector> = .text:0x800CA364; // type:function size:0x30 OnScreen__3GemFf = .text:0x800CA394; // type:function size:0x68 Poll__3GemFfffff = .text:0x800CA3FC; // type:function size:0x168 -fn_800CA564 = .text:0x800CA564; // type:function size:0x18 +CompareBounds__3GemFv = .text:0x800CA564; // type:function size:0x18 AddRep__3GemFR14GemRepTemplateP8RndGroup6SymbolRC11TrackConfigb = .text:0x800CA57C; // type:function size:0x26C __ct__9TransformFRC9Transform = .text:0x800CA7E8; // type:function size:0x7C __vc__Q211stlpmtx_std63vector<9Transform,Us,Q211stlpmtx_std24StlNodeAlloc<9Transform>>CFUl = .text:0x800CA864; // type:function size:0x10 @@ -7232,8 +7232,8 @@ back__Q211stlpmtx_std69vector__FPCcPCc_PCc = .text:0x800CB0CC; // type:function size:0x48 MakeString__FPCcPCci_PCc = .text:0x800CB114; // type:function size:0x60 @@ -7241,44 +7241,44 @@ Scale__FRC7Vector3RC7Vector3R7Vector3 = .text:0x800CB174; // type:function size: Set__7Vector3Ffff = .text:0x800CB1A4; // type:function size:0x10 fn_800CB1B4 = .text:0x800CB1B4; // type:function size:0x4 Multiply__FRC7Vector3RC9TransformR7Vector3 = .text:0x800CB1B8; // type:function size:0x4C -fn_800CB204 = .text:0x800CB204; // type:function size:0x40 +TickToSeconds__Fi = .text:0x800CB204; // type:function size:0x40 __ct__9TransformFv = .text:0x800CB244; // type:function size:0x30 fn_800CB274 = .text:0x800CB274; // type:function size:0xC -fn_800CB280 = .text:0x800CB280; // type:function size:0x3A0 +AddChordInstance__3GemF6Symbol = .text:0x800CB280; // type:function size:0x3A0 fn_800CB620 = .text:0x800CB620; // type:function size:0x4 fn_800CB624 = .text:0x800CB624; // type:function size:0x90 fn_800CB6B4 = .text:0x800CB6B4; // type:function size:0x4 -fn_800CB6B8 = .text:0x800CB6B8; // type:function size:0x248 +AddStrumInstance__3GemF6Symbol6Symbol = .text:0x800CB6B8; // type:function size:0x248 fn_800CB900 = .text:0x800CB900; // type:function size:0x70 fn_800CB970 = .text:0x800CB970; // type:function size:0x68 -fn_800CB9D8 = .text:0x800CB9D8; // type:function size:0x120 +AddWidgetInstanceImpl__3GemFP11TrackWidgeti = .text:0x800CB9D8; // type:function size:0x120 Scale__FRCQ23Hmx7Matrix3RC7Vector3RQ23Hmx7Matrix3 = .text:0x800CBAF8; // type:function size:0x5C Reset__9TransformFv = .text:0x800CBB54; // type:function size:0x34 Zero__7Vector3Fv = .text:0x800CBB88; // type:function size:0x18 Identity__Q23Hmx7Matrix3Fv = .text:0x800CBBA0; // type:function size:0x70 -fn_800CBC10 = .text:0x800CBC10; // type:function size:0x124 -fn_800CBD34 = .text:0x800CBD34; // type:function size:0x1E8 +AddHopoTails__3GemF6Symbol = .text:0x800CBC10; // type:function size:0x124 +RemoveAllInstances__3GemFv = .text:0x800CBD34; // type:function size:0x1E8 fn_800CBF1C = .text:0x800CBF1C; // type:function size:0x4 fn_800CBF20 = .text:0x800CBF20; // type:function size:0x8 fn_800CBF28 = .text:0x800CBF28; // type:function size:0x4 fn_800CBF2C = .text:0x800CBF2C; // type:function size:0x8 -fn_800CBF34 = .text:0x800CBF34; // type:function size:0xD0 -fn_800CC004 = .text:0x800CC004; // type:function size:0x9C -fn_800CC0A0 = .text:0x800CC0A0; // type:function size:0x1EC +SetType__3GemF6Symbol = .text:0x800CBF34; // type:function size:0xD0 +UpdateTailPositions__3GemFv = .text:0x800CC004; // type:function size:0x9C +CreateWidgetInstances__3GemF6Symbol = .text:0x800CC0A0; // type:function size:0x1EC fn_800CC28C = .text:0x800CC28C; // type:function size:0x8 fn_800CC294 = .text:0x800CC294; // type:function size:0x8 fn_800CC29C = .text:0x800CC29C; // type:function size:0x4 -fn_800CC2A0 = .text:0x800CC2A0; // type:function size:0x80 -fn_800CC320 = .text:0x800CC320; // type:function size:0x164 -fn_800CC484 = .text:0x800CC484; // type:function size:0x6C -fn_800CC4F0 = .text:0x800CC4F0; // type:function size:0x88 -fn_800CC578 = .text:0x800CC578; // type:function size:0xA8 -fn_800CC620 = .text:0x800CC620; // type:function size:0x60 -fn_800CC680 = .text:0x800CC680; // type:function size:0x28 -fn_800CC6A8 = .text:0x800CC6A8; // type:function size:0x1C -fn_800CC6C4 = .text:0x800CC6C4; // type:function size:0xE8 -fn_800CC7AC = .text:0x800CC7AC; // type:function size:0x8 -fn_800CC7B4 = .text:0x800CC7B4; // type:function size:0x54 +Hit__3GemFv = .text:0x800CC2A0; // type:function size:0x80 +PartialHit__3GemFUi = .text:0x800CC320; // type:function size:0x164 +Release__3GemFv = .text:0x800CC484; // type:function size:0x6C +ApplyDuration__3GemFfff = .text:0x800CC4F0; // type:function size:0x88 +ReleaseSlot__3GemFi = .text:0x800CC578; // type:function size:0xA8 +KillDuration__3GemFv = .text:0x800CC620; // type:function size:0x60 +Reset__3GemFv = .text:0x800CC680; // type:function size:0x28 +GetStart__3GemCFv = .text:0x800CC6A8; // type:function size:0x1C +InitChordInfo__3GemFib = .text:0x800CC6C4; // type:function size:0xE8 +SetFretPos__3GemFi = .text:0x800CC7AC; // type:function size:0x8 +GetChordFretLabelInfo__3GemCFR6StringRi = .text:0x800CC7B4; // type:function size:0x54 fn_800CC808 = .text:0x800CC808; // type:function size:0x154 fn_800CC95C = .text:0x800CC95C; // type:function size:0x58 fn_800CC9B4 = .text:0x800CC9B4; // type:function size:0x58 @@ -7582,9 +7582,9 @@ fn_800D488C = .text:0x800D488C; // type:function size:0x88 fn_800D4914 = .text:0x800D4914; // type:function size:0x2C fn_800D4940 = .text:0x800D4940; // type:function size:0x10 fn_800D4950 = .text:0x800D4950; // type:function size:0x24 -fn_800D4974 = .text:0x800D4974; // type:function size:0x94 +GetWidgetName__10GemManagerFR6Symboli6Symbol = .text:0x800D4974; // type:function size:0x94 fn_800D4A08 = .text:0x800D4A08; // type:function size:0x9C -fn_800D4AA4 = .text:0x800D4AA4; // type:function size:0x44 +GetSlotIntData__10GemManagerFi6Symbol = .text:0x800D4AA4; // type:function size:0x44 fn_800D4AE8 = .text:0x800D4AE8; // type:function size:0x64 fn_800D4B4C = .text:0x800D4B4C; // type:function size:0x44 fn_800D4B90 = .text:0x800D4B90; // type:function size:0x4 @@ -7595,7 +7595,7 @@ push_back__Q211stlpmtx_std40list>FRCi = .text fn_800D4D0C = .text:0x800D4D0C; // type:function size:0x54 fn_800D4D60 = .text:0x800D4D60; // type:function size:0x64 fn_800D4DC4 = .text:0x800D4DC4; // type:function size:0x50 -fn_800D4E14 = .text:0x800D4E14; // type:function size:0x7C +SlotEnabled__10GemManagerCFi = .text:0x800D4E14; // type:function size:0x7C fn_800D4E90 = .text:0x800D4E90; // type:function size:0x3C fn_800D4ECC = .text:0x800D4ECC; // type:function size:0x8C fn_800D4F58 = .text:0x800D4F58; // type:function size:0x238 @@ -7607,7 +7607,7 @@ fn_800D5228 = .text:0x800D5228; // type:function size:0x18 fn_800D5240 = .text:0x800D5240; // type:function size:0xF4 fn_800D5334 = .text:0x800D5334; // type:function size:0x40 fn_800D5374 = .text:0x800D5374; // type:function size:0x40 -fn_800D53B4 = .text:0x800D53B4; // type:function size:0xA0 +ClearGems__10GemManagerFb = .text:0x800D53B4; // type:function size:0xA0 fn_800D5454 = .text:0x800D5454; // type:function size:0xC fn_800D5460 = .text:0x800D5460; // type:function size:0x70 fn_800D54D0 = .text:0x800D54D0; // type:function size:0x70 @@ -7622,7 +7622,7 @@ fn_800D57F8 = .text:0x800D57F8; // type:function size:0x74 fn_800D586C = .text:0x800D586C; // type:function size:0x48 fn_800D58B4 = .text:0x800D58B4; // type:function size:0xD4 fn_800D5988 = .text:0x800D5988; // type:function size:0x28 -fn_800D59B0 = .text:0x800D59B0; // type:function size:0xA8 +GetWidgetByName__10GemManagerF6Symbol = .text:0x800D59B0; // type:function size:0xA8 fn_800D5A58 = .text:0x800D5A58; // type:function size:0xFC fn_800D5B54 = .text:0x800D5B54; // type:function size:0x58 fn_800D5BAC = .text:0x800D5BAC; // type:function size:0x44 @@ -7634,7 +7634,7 @@ fn_800D5CC0 = .text:0x800D5CC0; // type:function size:0x8 fn_800D5CC8 = .text:0x800D5CC8; // type:function size:0x4 fn_800D5CCC = .text:0x800D5CCC; // type:function size:0x40 fn_800D5D0C = .text:0x800D5D0C; // type:function size:0xA0 -fn_800D5DAC = .text:0x800D5DAC; // type:function size:0x8 +GetMaxSlots__10GemManagerCFv = .text:0x800D5DAC; // type:function size:0x8 fn_800D5DB4 = .text:0x800D5DB4; // type:function size:0x70 fn_800D5E24 = .text:0x800D5E24; // type:function size:0x68 fn_800D5E8C = .text:0x800D5E8C; // type:function size:0x68 @@ -8055,25 +8055,25 @@ fn_800E1338 = .text:0x800E1338; // type:function size:0x44 fn_800E137C = .text:0x800E137C; // type:function size:0x54 __dt__31ObjPtr<10RndEnviron,9ObjectDir>Fv = .text:0x800E13D0; // type:function size:0x80 __dt__32ObjPtr<11RndDrawable,9ObjectDir>Fv = .text:0x800E1450; // type:function size:0x84 -fn_800E14D4 = .text:0x800E14D4; // type:function size:0x11C +Init__4TailFiRC9Transformb6SymbolP8RndGroupRCQ24Tail9SlideInfoP4Tail = .text:0x800E14D4; // type:function size:0x11C fn_800E15F0 = .text:0x800E15F0; // type:function size:0x3C SetLocalXfm__16RndTransformableFRC9Transform = .text:0x800E162C; // type:function size:0x38 fn_800E1664 = .text:0x800E1664; // type:function size:0x24 fn_800E1688 = .text:0x800E1688; // type:function size:0x54 -fn_800E16DC = .text:0x800E16DC; // type:function size:0x138 +SetType__4TailF6Symbolb = .text:0x800E16DC; // type:function size:0x138 fn_800E1814 = .text:0x800E1814; // type:function size:0x8 fn_800E181C = .text:0x800E181C; // type:function size:0x8 fn_800E1824 = .text:0x800E1824; // type:function size:0x9C SetLocalRot__16RndTransformableFRCQ23Hmx7Matrix3 = .text:0x800E18C0; // type:function size:0x38 __as__Q23Hmx7Matrix3FRCQ23Hmx7Matrix3 = .text:0x800E18F8; // type:function size:0x34 fn_800E192C = .text:0x800E192C; // type:function size:0x78 -fn_800E19A4 = .text:0x800E19A4; // type:function size:0x8C +SetDuration__4TailFfff = .text:0x800E19A4; // type:function size:0x8C Max__Fff_f = .text:0x800E1A30; // type:function size:0x10 -fn_800E1A40 = .text:0x800E1A40; // type:function size:0x5C +Hit__4TailFv = .text:0x800E1A40; // type:function size:0x5C fn_800E1A9C = .text:0x800E1A9C; // type:function size:0x1C fn_800E1AB8 = .text:0x800E1AB8; // type:function size:0x64 fn_800E1B1C = .text:0x800E1B1C; // type:function size:0xC -fn_800E1B28 = .text:0x800E1B28; // type:function size:0x2AC +Poll__4TailFfff = .text:0x800E1B28; // type:function size:0x2AC fn_800E1DD4 = .text:0x800E1DD4; // type:function size:0x30 sin__3stdFf = .text:0x800E1E04; // type:function size:0x4 SinFloat__Fd = .text:0x800E1E08; // type:function size:0x24 @@ -43752,7 +43752,7 @@ __ct__Q211stlpmtx_std66list<12MeshInstance,Q211stlpmtx_std28StlNodeAlloc<12MeshI __ct__Q211stlpmtx_std72_List_impl<12MeshInstance,Q211stlpmtx_std28StlNodeAlloc<12MeshInstance>>FRCQ211stlpmtx_std28StlNodeAlloc<12MeshInstance> = .text:0x805428DC; // type:function size:0x30 __ct__Q211stlpmtx_std72_List_base<12MeshInstance,Q211stlpmtx_std28StlNodeAlloc<12MeshInstance>>FRCQ211stlpmtx_std28StlNodeAlloc<12MeshInstance> = .text:0x8054290C; // type:function size:0x60 __ct__30TrackWidgetImp<12MeshInstance>Fv = .text:0x8054296C; // type:function size:0x3C -fn_805429A8 = .text:0x805429A8; // type:function size:0x14 +SetScale__11TrackWidgetFf = .text:0x805429A8; // type:function size:0x14 IsFloatOne__Ff = .text:0x805429BC; // type:function size:0x40 CheckScales__11TrackWidgetCFv = .text:0x805429FC; // type:function size:0xD0 NewYOffset__11TrackWidgetCFf = .text:0x80542ACC; // type:function size:0x38 diff --git a/src/band3/bandtrack/Gem.cpp b/src/band3/bandtrack/Gem.cpp index 3c93b2e09..10f6516f5 100644 --- a/src/band3/bandtrack/Gem.cpp +++ b/src/band3/bandtrack/Gem.cpp @@ -1,6 +1,13 @@ #include "Gem.h" +#include "bandtrack/GemManager.h" +#include "bandtrack/TrackConfig.h" #include "beatmatch/RGUtl.h" #include "os/Debug.h" +#include "track/TrackWidget.h" +#include "utl/Std.h" +#include "utl/Symbols.h" +#include "utl/Symbols3.h" +#include "utl/TimeConversion.h" Gem::Gem( const GameGem &gg, unsigned int ui, float f1, float f2, bool b1, int i1, int i2, bool b2 @@ -11,7 +18,7 @@ Gem::Gem( InitChordInfo(i2, b2); } -Gem::~Gem() { mTails.clear(); } +Gem::~Gem() { DeleteAll(mTails); } Gem &Gem::operator=(const Gem &g) { (GameGem &)(*mGameGem) = *(g.mGameGem); @@ -37,6 +44,66 @@ bool Gem::OnScreen(float ms) { return (ms / 1000.0f) + bottomSeconds > mEnd; } +void Gem::Poll(float f1, float f2, float f3, float f4, float f5) { + if (CompareBounds()) { + float fvar1 = mStart; + if (f4 > fvar1) { + float fvar2 = mEnd - fvar1; + if (f4 < fvar2) + fvar2 = f4 - fvar1; + float fvar3 = mTailStart; + ApplyDuration( + mGemManager->mTrackDir->SecondsToY(fvar3), + mGemManager->mTrackDir->SecondsToY(f5 - fvar1), + mGemManager->mTrackDir->SecondsToY(fvar2) + ); + for (int i = 0; i < mTails.size(); i++) { + mTails[i]->Poll(f1, f2, f3); + } + } + } +} + +void Gem::AddRep( + GemRepTemplate &repTemp, RndGroup *grp, Symbol s, const TrackConfig &cfg, bool b5 +) { + static float startOffset = 1.5f; + SetType(s); + if (s != "invisible" && CompareBounds() && b5) { + float f9 = mGemManager->mTrackDir->SecondsToY(mGameGem->mMs / 1000.0f); + Tail *i1 = 0; + if (mTailStart < 0) + mTailStart = 0; + bool rg = UseRGChordStyle(); + float f10 = mGemManager->mTrackDir->SecondsToY(mEnd - mStart); + int i3 = mGemManager->GetMaxSlots(); + for (int i = 0; i < i3; i++) { + if ((mSlots & 1 << i) && (!rg || mGameGem->GetRGNoteType(i) != 1)) { + Tail *tail = new Tail(repTemp); + mTails.push_back(tail); + mTails.back()->SetDuration(0, 0, f10); + Tail::SlideInfo info; + if (mGameGem->LeftHandSlide()) { + info.unk0 = true; + if (unk_0x67_4) { + info.unk8 = startOffset; + info.unk4 = -startOffset; + } else { + info.unk4 = startOffset; + info.unk8 = -startOffset; + } + info.unkc = f10; + } + Transform tf90 = mGemManager->mTrackDir->mSlots[i]; + tf90.v.y = f9; + tail->Init(i, tf90, rg, s, grp, info, i1); + if (!i1 && !cfg.AllowsPartialHits()) + i1 = tail; + } + } + } +} + bool Gem::UseRGChordStyle() const { bool r = false; if (mGameGem->IsRealGuitarChord() || unk_0x67_1 || mGameGem->IsMuted()) @@ -44,6 +111,114 @@ bool Gem::UseRGChordStyle() const { return r; } +void Gem::RemoveRep() { + for (int i = 0; i < mTails.size(); i++) { + delete mTails[i]; + } + mTails.clear(); +} + +void Gem::AddInstance(Symbol s1, int i2) { + GemManager *mgr = mGemManager; + if (mgr && mgr->mTrackDir && mgr->SlotEnabled(i2)) { + TrackConfig *cfg = mGemManager->mTrackConfig; + Symbol s1b8; + Symbol s1bc = s1.mStr; + if (mHopo && !cfg->GetDisableHopos()) { + s1bc = MakeString("%s_hopo", s1bc.mStr); + } else if (Check66B0()) { + s1bc = MakeString("%s_cymbal", s1bc.mStr); + } + + if (unk_0x66_6) { + s1bc = MakeString("%s_arrhythmic", s1bc.mStr); + } + + if (mGemManager->GetWidgetName(s1b8, i2, s1bc) + && mGemManager->GetWidgetName(s1b8, i2, s1bc)) { + if (mGameGem->IsRealGuitar()) { + int i6 = mFretPos; + if (cfg->IsLefty()) + i6 = 4 - i6; + s1b8 = MakeString("%s%02d.wid", s1b8.mStr, i6); + } + AddWidgetInstanceImpl(mGemManager->GetWidgetByName(s1b8), i2); + } else + MILO_WARN( + "could not find widget for slot %d %s gem in %s", + i2, + s1.mStr, + mGemManager->mTrackDir->Name() + ); + + if (mBeard) { + Symbol s1c0; + if (mGemManager->GetWidgetName(s1c0, i2, beard)) { + TrackWidget *w2 = mGemManager->GetWidgetByName(s1c0); + Transform tf68; + mGemManager->mTrackDir->MakeWidgetXfm(i2, TickToSeconds(mBeardTick), tf68); + w2->AddInstance(Transform(tf68), TickToSeconds(GetBeardThreshold())); + } + } + + if (unk_0x3C != 0) { + Symbol s1c4; + if (mGemManager->GetWidgetName(s1c4, i2, mash)) { + TrackWidget *w2 = mGemManager->GetWidgetByName(s1c4); + Transform tf98; + mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem->mMs / 1000.0f, tf98); + w2->AddInstance(Transform(tf98), unk_0x3C); + } + } + + if (unk_0x65 != -1) { + Symbol s1c8; + if (mGemManager->GetWidgetName(s1c8, i2, fret_num)) { + TrackWidget *wcc = mGemManager->GetWidgetByName(s1c8); + Transform tfc8; + mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem->mMs / 1000.0f, tfc8); + Vector3 v164(0, 0, 0); + if (cfg->IsLefty()) { + v164.x = -v164.x; + } + Multiply(v164, tfc8, tfc8.v); + int i1 = mGemManager->GetSlotIntData(i2, is_white); + String str170(1, unk_0x65 + 'A'); + wcc->AddTextInstance(tfc8, str170, i1 == 0); + mWidgets.insert(wcc); + } + } + + if (mGameGem->IsRealGuitar() && mGameGem->GetFret(i2) != -1) { + Symbol s1d0; + if (mGemManager->GetWidgetName(s1d0, i2, fret_num)) { + TrackWidget *w1d4 = mGemManager->GetWidgetByName(s1d0); + Transform tff8; + mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem->mMs / 1000.0f, tff8); + float offset = mGemManager->mTrackDir->GetFretPosOffset(mFretPos); + if (cfg->IsLefty()) + offset = -offset; + static DataNode &rg_widget_scale = DataVariable("rg_widget_scale"); + float scaleFloat = rg_widget_scale.Float(); + if (scaleFloat > 0) + offset *= scaleFloat; + tff8.v.x += offset; + if (scaleFloat > 0) { + w1d4->SetScale(scaleFloat); + Scale( + tff8.v, + Vector3(1.0f / scaleFloat, 1.0f, 1.0f / scaleFloat), + tff8.v + ); + } + String str17c(RGFretNumberToString(mGameGem->GetFret(i2))); + w1d4->AddTextInstance(tff8, str17c, false); + mWidgets.insert(w1d4); + } + } + } +} + void Gem::AddStrumInstance(Symbol s1, Symbol s2) { if (mGemManager == NULL || mGemManager->mTrackConfig == 0) return; diff --git a/src/band3/bandtrack/Gem.h b/src/band3/bandtrack/Gem.h index 243f3515e..220722a93 100644 --- a/src/band3/bandtrack/Gem.h +++ b/src/band3/bandtrack/Gem.h @@ -3,6 +3,7 @@ #include "bandtrack/Tail.h" #include "beatmatch/GameGem.h" #include "track/TrackWidget.h" +#include "bandtrack/GemRepTemplate.h" #include "system/utl/TimeConversion.h" #include "types.h" #include @@ -14,7 +15,7 @@ class Gem { Gem &operator=(const Gem &); bool OnScreen(float); void Poll(float, float, float, float, float); - // void AddRep(GemRepTemplate&, RndGroup*, Symbol, const TrackConfig&, bool); + void AddRep(GemRepTemplate &, RndGroup *, Symbol, const TrackConfig &, bool); bool UseRGChordStyle() const; void RemoveRep(); void AddInstance(Symbol, int); @@ -39,26 +40,36 @@ class Gem { void SetFretPos(int); void GetChordFretLabelInfo(String &, int &) const; - GemManager *mGemManager; - const GameGem *mGameGem; - std::set mWidgets; - float mStart, mEnd, mTailStart; - int mSlots; - std::vector mTails; - int mBeardTick; - float unk_0x3C, unk_0x40; - int unk_0x44, unk_0x48; - class String unk_0x4C; - u8 unk_0x58; - int mFirstFret, mFirstFretString; - u8 mFretPos, unk_0x65; + bool CompareBounds() { return mStart < mEnd ? true : false; } + bool Check66B0() const { return unk_0x66_7; } + + GemManager *mGemManager; // 0x0 + const GameGem *mGameGem; // 0x4 + std::set mWidgets; // 0x8 + float mStart; // 0x20 + float mEnd; // 0x24 + float mTailStart; // 0x28 + int mSlots; // 0x2c + std::vector mTails; // 0x30 + int mBeardTick; // 0x38 + float unk_0x3C; // 0x3c + float unk_0x40; // 0x40 + int unk_0x44; // 0x44 + int unk_0x48; // 0x48 + class String unk_0x4C; // 0x4c + bool unk_0x58; // 0x58 + int mFirstFret; // 0x5c + int mFirstFretString; // 0x60 + char mFretPos; + char unk_0x65; bool mHit : 1; bool mMissed : 1; bool mReleased : 1; bool mHopo : 1; bool mInvisible : 1; bool mBeard : 1; - bool unk_0x66_6 : 1, unk_0x66_7 : 1; + bool unk_0x66_6 : 1; + bool unk_0x66_7 : 1; // cymbal? bool unk_0x67_0 : 1, unk_0x67_1 : 1, unk_0x67_2 : 1, unk_0x67_3 : 1, unk_0x67_4 : 1, unk_0x67_5 : 1, unk_0x67_6 : 1, unk_0x67_7 : 1; }; diff --git a/src/band3/bandtrack/GemManager.h b/src/band3/bandtrack/GemManager.h index 940bab933..582b7aefc 100644 --- a/src/band3/bandtrack/GemManager.h +++ b/src/band3/bandtrack/GemManager.h @@ -64,7 +64,11 @@ class GemManager { void UpdateSlotPositions(); Hmx::Object *GetSmasherObj(int); void HideGems(); + bool SlotEnabled(int) const; + int GetSlotIntData(int, Symbol); TrackDir *mTrackDir; TrackConfig *mTrackConfig; }; + +int GetBeardThreshold(); \ No newline at end of file diff --git a/src/band3/bandtrack/Tail.h b/src/band3/bandtrack/Tail.h index 4fb42091b..1d0db9dd2 100644 --- a/src/band3/bandtrack/Tail.h +++ b/src/band3/bandtrack/Tail.h @@ -1,8 +1,23 @@ #pragma once +#include "bandtrack/GemRepTemplate.h" class Tail { public: + struct SlideInfo { + SlideInfo() : unk0(0), unk4(0), unk8(0), unkc(0) {} + bool unk0; + float unk4; + float unk8; + float unkc; + }; + + Tail(GemRepTemplate &); + virtual ~Tail(); void Hit(); void Release(); void Done(); + void Poll(float, float, float); + void SetDuration(float, float, float); + void + Init(int, const Transform &, bool, Symbol, RndGroup *, const SlideInfo &, Tail *); }; diff --git a/src/system/beatmatch/VocalNote.h b/src/system/beatmatch/VocalNote.h index f0fb52813..b0df8fad1 100644 --- a/src/system/beatmatch/VocalNote.h +++ b/src/system/beatmatch/VocalNote.h @@ -1,5 +1,4 @@ -#ifndef BEATMATCH_VOCALNOTE_H -#define BEATMATCH_VOCALNOTE_H +#pragma once #include "utl/Str.h" #include "obj/Data.h" #include "utl/MBT.h" @@ -123,5 +122,3 @@ class VocalNoteList { DataArray *mFreestyleMinDuration; // 0x30 DataArray *mFreestylePad; // 0x34 }; - -#endif \ No newline at end of file diff --git a/src/system/math/Vec.h b/src/system/math/Vec.h index ee1687478..0618ccc44 100644 --- a/src/system/math/Vec.h +++ b/src/system/math/Vec.h @@ -199,6 +199,8 @@ class Vector4_16_01 { u16 x, y, z, w; }; +void Scale(const Vector3 &, const Vector3 &, Vector3 &); + inline void Scale(const Vector3 &v1, float f, Vector3 &dst) { dst.Set(v1.x * f, v1.y * f, v1.z * f); } diff --git a/src/system/track/TrackDir.h b/src/system/track/TrackDir.h index d817474d7..cdd38f379 100644 --- a/src/system/track/TrackDir.h +++ b/src/system/track/TrackDir.h @@ -30,7 +30,7 @@ class TrackDir : public PanelDir { virtual void SetDisplayRange(float) {} virtual void SetDisplayOffset(float, bool) {} virtual RndDir *SmasherPlate(); - virtual float GetFretPosOffset(int) const; + virtual float GetFretPosOffset(int) const { return 0; } virtual int GetNumFretPosOffsets() const { return 0; } virtual float GetCurrentChordLabelPosOffset() const; virtual int PrepareChordMesh(unsigned int); diff --git a/src/system/utl/TimeConversion.h b/src/system/utl/TimeConversion.h index e28d46f75..640555e52 100644 --- a/src/system/utl/TimeConversion.h +++ b/src/system/utl/TimeConversion.h @@ -11,4 +11,5 @@ float SecondsToBeat(float); float TickToSeconds(float); float BeatToSeconds(float); inline int MsToTickInt(float f) { return MsToTick(f); } -inline float TickToMs(int i) { return TickToMs((float)i); } \ No newline at end of file +inline float TickToMs(int i) { return TickToMs((float)i); } +inline float TickToSeconds(int i) { return TickToSeconds((float)i); } \ No newline at end of file From 98f902eee83a1d017563b6a119e162aa7aeffe67 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Mon, 3 Feb 2025 17:48:20 -0700 Subject: [PATCH 02/12] gem funcs --- config/SZBE69/symbols.txt | 18 +- src/band3/bandtrack/Gem.cpp | 343 ++++++++++++++++++++++++++--- src/band3/bandtrack/Gem.h | 4 +- src/band3/bandtrack/Tail.h | 1 + src/system/bandobj/GemTrackDir.cpp | 2 +- src/system/bandobj/GemTrackDir.h | 13 +- src/system/beatmatch/RGUtl.h | 5 +- src/system/beatmatch/SongData.h | 2 +- src/system/track/TrackDir.h | 9 +- 9 files changed, 334 insertions(+), 63 deletions(-) diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index c9ccc9ce8..db253cdb3 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -7239,7 +7239,7 @@ MakeString__FPCcPCc_PCc = .text:0x800CB0CC; // type:function size:0x48 MakeString__FPCcPCci_PCc = .text:0x800CB114; // type:function size:0x60 Scale__FRC7Vector3RC7Vector3R7Vector3 = .text:0x800CB174; // type:function size:0x30 Set__7Vector3Ffff = .text:0x800CB1A4; // type:function size:0x10 -fn_800CB1B4 = .text:0x800CB1B4; // type:function size:0x4 +insert__Q211stlpmtx_std103set,Q211stlpmtx_std28StlNodeAlloc>FRCP11TrackWidget = .text:0x800CB1B4; // type:function size:0x4 Multiply__FRC7Vector3RC9TransformR7Vector3 = .text:0x800CB1B8; // type:function size:0x4C TickToSeconds__Fi = .text:0x800CB204; // type:function size:0x40 __ct__9TransformFv = .text:0x800CB244; // type:function size:0x30 @@ -7284,7 +7284,7 @@ fn_800CC95C = .text:0x800CC95C; // type:function size:0x58 fn_800CC9B4 = .text:0x800CC9B4; // type:function size:0x58 fn_800CCA0C = .text:0x800CCA0C; // type:function size:0x60 fn_800CCA6C = .text:0x800CCA6C; // type:function size:0x68 -fn_800CCAD4 = .text:0x800CCAD4; // type:function size:0x15C +insert_unique__Q211stlpmtx_std208_Rb_tree,P11TrackWidget,Q211stlpmtx_std25_Identity,Q29stlp_priv27_SetTraitsT,Q211stlpmtx_std28StlNodeAlloc>FRCP11TrackWidget = .text:0x800CCAD4; // type:function size:0x15C fn_800CCC30 = .text:0x800CCC30; // type:function size:0x44 fn_800CCC74 = .text:0x800CCC74; // type:function size:0x18 fn_800CCC8C = .text:0x800CCC8C; // type:function size:0xB0 @@ -7583,7 +7583,7 @@ fn_800D4914 = .text:0x800D4914; // type:function size:0x2C fn_800D4940 = .text:0x800D4940; // type:function size:0x10 fn_800D4950 = .text:0x800D4950; // type:function size:0x24 GetWidgetName__10GemManagerFR6Symboli6Symbol = .text:0x800D4974; // type:function size:0x94 -fn_800D4A08 = .text:0x800D4A08; // type:function size:0x9C +GetChordWidgetName__10GemManagerF6Symbol6SymbolR6Symbol = .text:0x800D4A08; // type:function size:0x9C GetSlotIntData__10GemManagerFi6Symbol = .text:0x800D4AA4; // type:function size:0x44 fn_800D4AE8 = .text:0x800D4AE8; // type:function size:0x64 fn_800D4B4C = .text:0x800D4B4C; // type:function size:0x44 @@ -8070,8 +8070,8 @@ fn_800E192C = .text:0x800E192C; // type:function size:0x78 SetDuration__4TailFfff = .text:0x800E19A4; // type:function size:0x8C Max__Fff_f = .text:0x800E1A30; // type:function size:0x10 Hit__4TailFv = .text:0x800E1A40; // type:function size:0x5C -fn_800E1A9C = .text:0x800E1A9C; // type:function size:0x1C -fn_800E1AB8 = .text:0x800E1AB8; // type:function size:0x64 +Release__4TailFv = .text:0x800E1A9C; // type:function size:0x1C +Done__4TailFv = .text:0x800E1AB8; // type:function size:0x64 fn_800E1B1C = .text:0x800E1B1C; // type:function size:0xC Poll__4TailFfff = .text:0x800E1B28; // type:function size:0x2AC fn_800E1DD4 = .text:0x800E1DD4; // type:function size:0x30 @@ -19055,7 +19055,7 @@ fn_8022C648 = .text:0x8022C648; // type:function size:0x48 fn_8022C690 = .text:0x8022C690; // type:function size:0x8 ToggleModifierEnabled__11ModifierMgrF6Symbol = .text:0x8022C698; // type:function size:0x6C fn_8022C704 = .text:0x8022C704; // type:function size:0xC -IsModifierActive__11ModifierMgrF6Symbol = .text:0x8022C710; // type:function size:0x6C +IsModifierActive__11ModifierMgrCF6Symbol = .text:0x8022C710; // type:function size:0x6C IsModifierDelayedEffect__11ModifierMgrF6Symbol = .text:0x8022C77C; // type:function size:0x34 fn_8022C7B0 = .text:0x8022C7B0; // type:function size:0x80 fn_8022C830 = .text:0x8022C830; // type:function size:0x88 @@ -83132,8 +83132,8 @@ SymHopoGemCount = .bss:0x80983388; // type:object size:0x4 data:4byte SymHopoGemsHopoed = .bss:0x8098338C; // type:object size:0x8 data:4byte SymHopoPercentStatTrackerContribution = .bss:0x80983394; // type:object size:0x4 data:4byte SymHopoStatTrackerContribution = .bss:0x80983398; // type:object size:0x4 data:4byte -SymHopoTail = .bss:0x8098339C; // type:object size:0x4 -SymHopoTailMiss = .bss:0x809833A0; // type:object size:0x4 +hopo_tail = .bss:0x8098339C; // type:object size:0x4 +hopo_tail_miss = .bss:0x809833A0; // type:object size:0x4 hopo_threshold = .bss:0x809833A4; // type:object size:0x4 data:4byte SymHoposPercent = .bss:0x809833A8; // type:object size:0x8 horizontal = .bss:0x809833B0; // type:object size:0x4 @@ -83874,7 +83874,7 @@ SymMipMapK = .bss:0x809841A4; // type:object size:0x8 SymMirrorCam = .bss:0x809841AC; // type:object size:0x4 mirror_servo = .bss:0x809841B0; // type:object size:0x4 mirror_x = .bss:0x809841B4; // type:object size:0x4 -SymMiss = .bss:0x809841B8; // type:object size:0x4 data:4byte +miss = .bss:0x809841B8; // type:object size:0x4 data:4byte SymMissCount = .bss:0x809841BC; // type:object size:0x4 data:4byte SymMissNotify = .bss:0x809841C0; // type:object size:0x8 SymMissStreakCount = .bss:0x809841C8; // type:object size:0x4 data:4byte diff --git a/src/band3/bandtrack/Gem.cpp b/src/band3/bandtrack/Gem.cpp index 10f6516f5..1140442aa 100644 --- a/src/band3/bandtrack/Gem.cpp +++ b/src/band3/bandtrack/Gem.cpp @@ -2,11 +2,20 @@ #include "bandtrack/GemManager.h" #include "bandtrack/TrackConfig.h" #include "beatmatch/RGUtl.h" +#include "decomp.h" +#include "game/SongDB.h" +#include "math/Rand.h" +#include "meta_band/ModifierMgr.h" +#include "obj/Data.h" #include "os/Debug.h" +#include "rndobj/Mesh.h" #include "track/TrackWidget.h" +#include "utl/MBT.h" #include "utl/Std.h" #include "utl/Symbols.h" +#include "utl/Symbols2.h" #include "utl/Symbols3.h" +#include "utl/Symbols4.h" #include "utl/TimeConversion.h" Gem::Gem( @@ -104,12 +113,15 @@ void Gem::AddRep( } } -bool Gem::UseRGChordStyle() const { +#pragma push +#pragma force_active on +inline bool Gem::UseRGChordStyle() const { bool r = false; if (mGameGem->IsRealGuitarChord() || unk_0x67_1 || mGameGem->IsMuted()) r = true; return r; } +#pragma pop void Gem::RemoveRep() { for (int i = 0; i < mTails.size(); i++) { @@ -119,8 +131,7 @@ void Gem::RemoveRep() { } void Gem::AddInstance(Symbol s1, int i2) { - GemManager *mgr = mGemManager; - if (mgr && mgr->mTrackDir && mgr->SlotEnabled(i2)) { + if (mGemManager && mGemManager->mTrackDir && mGemManager->SlotEnabled(i2)) { TrackConfig *cfg = mGemManager->mTrackConfig; Symbol s1b8; Symbol s1bc = s1.mStr; @@ -157,7 +168,7 @@ void Gem::AddInstance(Symbol s1, int i2) { TrackWidget *w2 = mGemManager->GetWidgetByName(s1c0); Transform tf68; mGemManager->mTrackDir->MakeWidgetXfm(i2, TickToSeconds(mBeardTick), tf68); - w2->AddInstance(Transform(tf68), TickToSeconds(GetBeardThreshold())); + w2->AddInstance(tf68, TickToSeconds(GetBeardThreshold())); } } @@ -167,7 +178,7 @@ void Gem::AddInstance(Symbol s1, int i2) { TrackWidget *w2 = mGemManager->GetWidgetByName(s1c4); Transform tf98; mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem->mMs / 1000.0f, tf98); - w2->AddInstance(Transform(tf98), unk_0x3C); + w2->AddInstance(tf98, unk_0x3C); } } @@ -219,39 +230,241 @@ void Gem::AddInstance(Symbol s1, int i2) { } } +void Gem::AddChordInstance(Symbol s1) { + if (mGemManager && mGemManager->mTrackDir) { + float f1 = mGameGem->mMs / 1000.0f; + RndMesh *mesh = mGemManager->mTrackDir->GetChordMesh( + unk_0x44, mGemManager->mTrackConfig->IsLefty() + ); + TrackWidget *w5c = nullptr; + TrackWidget *w60 = nullptr; + TrackWidget *w10 = nullptr; + Symbol s64; + if (mGemManager->GetChordWidgetName(s1, chord, s64)) { + w5c = mGemManager->GetWidgetByName(s64); + mWidgets.insert(w5c); + } else + MILO_WARN( + "could not find widget for %s for %s chord gem in %s", + chord, + s1, + mGemManager->mTrackDir->Name() + ); + + if (!unk_0x67_3 && mFirstFretString != -1) { + Symbol s68; + if (mGemManager->GetChordWidgetName(s1, chord_fret, s68)) { + w60 = mGemManager->GetWidgetByName(s68); + mWidgets.insert(w60); + } else + MILO_WARN( + "could not find widget for %s for %s chord gem in %s", + chord_fret, + s1, + mGemManager->mTrackDir->Name() + ); + } + + if (!unk_0x67_2 && !unk_0x67_0 && !unk_0x4C.empty()) { + Symbol s6c; + if (mGemManager->GetChordWidgetName(s1, chord_label, s6c)) { + w10 = mGemManager->GetWidgetByName(s6c); + } else + MILO_WARN( + "could not find widget for %s for %s chord gem in %s", + chord_label, + s1, + mGemManager->mTrackDir->Name() + ); + } + + static std::vector fretNums; + if (fretNums.empty()) + fretNums.resize(6); + + bool mod = TheModifierMgr->IsModifierActive("mod_chord_numbers"); + bool b2 = true; + if (!mGameGem->ShowChordNums() && !mod) + b2 = false; + + for (int i = 0; i < 6; i++) { + if (i == mFirstFretString || b2) { + fretNums[i] = mGameGem->GetFret(i); + } else { + fretNums[i] = -1; + } + } + mGemManager->mTrackDir->AddChordRepImpl( + mesh, w5c, w60, w10, f1, fretNums, unk_0x4C + ); + } +} + void Gem::AddStrumInstance(Symbol s1, Symbol s2) { - if (mGemManager == NULL || mGemManager->mTrackConfig == 0) - return; - int lowString = mGameGem->GetLowestString(); - int highString = mGameGem->GetHighestString(); - MILO_ASSERT(lowString != -1, 572); - MILO_ASSERT(highString != -1, 573); - Symbol t0; - if (!mGemManager->GetChordWidgetName(s1, s2, t0)) { - MILO_WARN("could not find widget for %s for %s chord gem in %s", t0, s1, s2); - return; + if (mGemManager && mGemManager->mTrackDir) { + int lowString = mGameGem->GetLowestString(); + int highString = mGameGem->GetHighestString(); + MILO_ASSERT(lowString != -1, 572); + MILO_ASSERT(highString != -1, 573); + Symbol s88; + if (!mGemManager->GetChordWidgetName(s1, s2, s88)) { + MILO_WARN( + "could not find widget for %s for %s chord gem in %s", + s2, + s1, + mGemManager->mTrackDir->Name() + ); + } else { + int range = (highString - lowString) + 1; + bool lefty = mGemManager->mTrackConfig->IsLefty(); + if (s2 == area_strum) { + MILO_ASSERT_RANGE_EQ(range, 4, 6, 0x250); + char u6 = ' '; + switch (mGameGem->GetRGStrumType()) { + case 3: + u6 = 'L'; + if (lefty) + u6 = 'R'; + break; + case 1: + u6 = 'M'; + break; + case 2: + u6 = 'R'; + if (lefty) + u6 = 'L'; + break; + default: + MILO_FAIL("Invalid RG strum type"); + break; + } + s88 = MakeString("%s_%d%c.wid", s88, range, u6); + } else if (s2 == muted_strum) { + MILO_ASSERT_RANGE_EQ(range, 1, 6, 0x261); + s88 = MakeString("%s_%d.wid", s88, range); + } else + MILO_FAIL("Invalid strum type for real guitar strum gem"); + TrackWidget *w8c = mGemManager->GetWidgetByName(s88); + if (lefty) + lowString = highString; + Transform tf48; + mGemManager->mTrackDir->MakeWidgetXfm( + lowString, mGameGem->mMs / 1000.0f, tf48 + ); + w8c->AddInstance(tf48, 0); + mWidgets.insert(w8c); + } + } +} + +DECOMP_FORCEACTIVE(Gem, "mesh") + +void Gem::AddWidgetInstanceImpl(TrackWidget *w, int i) { + Transform tf38; + mGemManager->mTrackDir->MakeWidgetXfm(i, mGameGem->mMs / 1000.0f, tf38); + if (mGemManager->mTrackConfig->IsRealGuitarTrack()) { + static DataNode &rg_widget_scale = DataVariable("rg_widget_scale"); + float rgFloat = rg_widget_scale.Float(); + if (rgFloat > 0) { + Scale(tf38.m, Vector3(rgFloat, rgFloat, rgFloat), tf38.m); + } } + w->AddInstance(tf38, 0); + mWidgets.insert(w); } void Gem::AddHopoTails(Symbol s1) { - if (mGemManager != 0 && mGemManager->mTrackDir != 0) { - bool isRealGuitar = mGemManager->mTrackConfig->IsRealGuitarTrack(); + if (!mGemManager || !mGemManager->mTrackDir + || !mGemManager->mTrackConfig->IsRealGuitarTrack() || !mHopo || unk_0x66_6) + return; + else { + Symbol hopoSym = s1 == miss ? hopo_tail_miss : hopo_tail; + Symbol s20; + mGemManager->GetWidgetName(s20, 0, hopoSym); + TrackWidget *w = mGemManager->GetWidgetByName(s20); + int slots = mGemManager->GetMaxSlots(); + for (int i = 0; i < slots; i++) { + if (mSlots & 1 << i) { + AddWidgetInstanceImpl(w, i); + } + } + } +} - if (isRealGuitar && mHit) { - if (s1.mStr == "miss") { +void Gem::RemoveAllInstances() { + if (mGemManager && mGemManager->mTrackDir) { + float f1 = mGameGem->mMs / 1000.0f; + if (unk_0x44 != 0) { + FOREACH(it, mWidgets) { (*it)->RemoveAt(f1); } + } else { + int slots = mGemManager->GetMaxSlots(); + for (int i = 0; i < slots; i++) { + if (mSlots & 1 << i) { + FOREACH(it, mWidgets) { (*it)->RemoveAt(f1, i); } + if (mBeardTick != -1) { + Symbol s40; + if (mGemManager->GetWidgetName(s40, i, beard)) { + TrackWidget *w = mGemManager->GetWidgetByName(s40); + w->RemoveAt(TickToSeconds(mBeardTick)); + } + if (!mBeard) + mBeardTick = -1; + } + } } + } + mWidgets.clear(); + } +} - Symbol s2(""); - mGemManager->GetWidgetName(s2, 0, 0); - TrackWidget *widget = mGemManager->GetWidgetByName(s2); +void Gem::SetType(Symbol s) { + mInvisible = s == "invisible"; + RemoveAllInstances(); + if (!mInvisible) { + bool rg = UseRGChordStyle(); + for (int i = 0; i < mTails.size(); i++) { + mTails[i]->SetType(s, rg); + } + UpdateTailPositions(); + CreateWidgetInstances(s); + } +} - int maxSlots = mGemManager->GetMaxSlots(); +void Gem::UpdateTailPositions() { + if (CompareBounds()) { + for (int i = 0; i < mTails.size(); i++) { + } + } +} - for (int i = 0; i < maxSlots; i++) { - if (mSlots & (1 << i) != 0) { - AddWidgetInstanceImpl(widget, i); +void Gem::CreateWidgetInstances(Symbol s) { + if (mGameGem->IsRealGuitar() && mGameGem->IsMuted() && mSlots != 0) { + AddStrumInstance(s, muted_strum); + } else { + if (mGameGem->IsRealGuitarChord() && mSlots != 0) { + if (unk_0x44 != 0) { + AddChordInstance(s); + } else { + MILO_WARN( + "RG chord gem at %s has only ghost notes; gem will be invisible", + TickFormat( + mGameGem->GetTick(), *TheSongDB->GetSongData()->GetMeasureMap() + ) + ); + } + } else { + int slots = mGemManager->GetMaxSlots(); + for (int i = 0; i < slots; i++) { + if (mSlots & 1 << i) { + static DataNode &key_gem_fingering = + DataVariable("key_gem_fingering"); + if (key_gem_fingering.Int()) { + unk_0x65 = RandomFloat() * 5.0f + 1.0f; + } + AddInstance(s, i); } } + AddHopoTails(s); } } } @@ -266,12 +479,62 @@ void Gem::Hit() { mHit = true; } +void Gem::PartialHit(unsigned int ui) { + if (!mInvisible) { + mBeard = false; + float f1 = mGameGem->mMs / 1000.0f; + int slots = mGemManager->GetMaxSlots(); + FOREACH(it, mWidgets) { + TrackWidget *cur = *it; + for (int i = 0; i < slots; i++) { + int mask = 1 << i; + if (mSlots & mask && ui & mask) { + cur->RemoveAt(f1, i); + } + } + } + int tailIdx = 0; + for (int i = 0; i < slots; i++) { + int mask = 1 << i; + if (mSlots & mask) { + if (ui & mask && tailIdx < mTails.size()) { + mTails[tailIdx]->Hit(); + } + tailIdx++; + } + } + } +} + void Gem::Release() { for (int i = 0; i < mTails.size(); i++) mTails[i]->Release(); mReleased = true; } +void Gem::ApplyDuration(float f1, float f2, float f3) { + for (int i = 0; i < mTails.size(); i++) { + mTails[i]->SetDuration(f1, f2, f3); + } +} + +void Gem::ReleaseSlot(int slot) { + if (mTails.empty()) { + MILO_WARN("ReleaseSlot() called on a gem without tails!"); + } else { + MILO_ASSERT(slot < mGemManager->GetMaxSlots(), 0x3D2); + if (mSlots & 1 << slot) { + int tailIndex = 0; + for (int i = 0; i < slot; i++) { + if (mSlots & 1 << i) + tailIndex++; + } + MILO_ASSERT(tailIndex < mTails.size(), 0x3E0); + mTails[tailIndex]->Release(); + } + } +} + void Gem::KillDuration() { for (int i = 0; i < mTails.size(); i++) mTails[i]->Done(); @@ -286,16 +549,26 @@ void Gem::Reset() { mBeardTick = -1; } -float Gem::GetStart() const { - float val; - - if (!mBeard) { - val = mStart; - } else { - val = TickToSeconds(mBeardTick); +float Gem::GetStart() const { return mBeard ? TickToSeconds(mBeardTick) : mStart; } + +void Gem::InitChordInfo(int i1, bool b2) { + if (mGameGem->IsRealGuitarChord()) { + unk_0x44 = RGGetChordShapeID(*mGameGem, false); + unk_0x48 = RGGetChordShapeID(*mGameGem, true); + if (mGameGem->GetShowChordNames()) { + const char *name = mGameGem->GetChordNameOverride().mStr; + if (name[0] != '\0') { + char buf[32]; + RGParseOverrideChord(buf, 32, name); + unk_0x4C = buf; + } else { + char buf[32]; + RGGetChordName(buf, 32, *mGameGem, -1, i1, b2); + unk_0x4C = buf; + } + } + RGGetFretLabelInfo(*mGameGem, mFirstFretString, mFirstFret, true); } - - return val; } void Gem::SetFretPos(int i) { mFretPos = i; } diff --git a/src/band3/bandtrack/Gem.h b/src/band3/bandtrack/Gem.h index 220722a93..2ef4be4f7 100644 --- a/src/band3/bandtrack/Gem.h +++ b/src/band3/bandtrack/Gem.h @@ -54,8 +54,8 @@ class Gem { int mBeardTick; // 0x38 float unk_0x3C; // 0x3c float unk_0x40; // 0x40 - int unk_0x44; // 0x44 - int unk_0x48; // 0x48 + unsigned int unk_0x44; // 0x44 + unsigned int unk_0x48; // 0x48 class String unk_0x4C; // 0x4c bool unk_0x58; // 0x58 int mFirstFret; // 0x5c diff --git a/src/band3/bandtrack/Tail.h b/src/band3/bandtrack/Tail.h index 1d0db9dd2..0ec404999 100644 --- a/src/band3/bandtrack/Tail.h +++ b/src/band3/bandtrack/Tail.h @@ -18,6 +18,7 @@ class Tail { void Done(); void Poll(float, float, float); void SetDuration(float, float, float); + void SetType(Symbol, bool); void Init(int, const Transform &, bool, Symbol, RndGroup *, const SlideInfo &, Tail *); }; diff --git a/src/system/bandobj/GemTrackDir.cpp b/src/system/bandobj/GemTrackDir.cpp index 3bfd96e6b..9905811e3 100644 --- a/src/system/bandobj/GemTrackDir.cpp +++ b/src/system/bandobj/GemTrackDir.cpp @@ -1050,7 +1050,7 @@ DataNode GemTrackDir::OnDrawSampleChord(DataArray *da) { else fretNums[i] = -1; } - AddChordImpl(mesh, widget1, widget2, widget3, 0, fretNums, str78); + AddChordRepImpl(mesh, widget1, widget2, widget3, 0, fretNums, str78); return 0; } diff --git a/src/system/bandobj/GemTrackDir.h b/src/system/bandobj/GemTrackDir.h index c37bd7cfa..4c702ec8b 100644 --- a/src/system/bandobj/GemTrackDir.h +++ b/src/system/bandobj/GemTrackDir.h @@ -39,11 +39,11 @@ class GemTrackDir : public TrackDir, public BandTrack { virtual int GetNumFretPosOffsets() const { return mFretPosOffsets.size(); } virtual float GetCurrentChordLabelPosOffset() const; virtual int PrepareChordMesh(unsigned int); - virtual int GetChordMesh(unsigned int, bool); + virtual RndMesh *GetChordMesh(unsigned int, bool); virtual void SetUnisonProgress(float); virtual void ClearChordMeshRefCounts(); virtual void DeleteUnusedChordMeshes(); - virtual void AddChordImpl( + virtual void AddChordRepImpl( RndMesh *, TrackWidget *, TrackWidget *, @@ -109,15 +109,6 @@ class GemTrackDir : public TrackDir, public BandTrack { void UpdateLeftyFlip(bool); bool KeyShifting(); void FreeChordMeshes(); - void AddChordRepImpl( - RndMesh *, - TrackWidget *, - TrackWidget *, - TrackWidget *, - float, - const std::vector &, - String - ); void SetGemTrackID(int id) { mGemTrackDirID = id; } DataNode OnDrawSampleChord(DataArray *); diff --git a/src/system/beatmatch/RGUtl.h b/src/system/beatmatch/RGUtl.h index d03a6c5ac..6a7c0d1c9 100644 --- a/src/system/beatmatch/RGUtl.h +++ b/src/system/beatmatch/RGUtl.h @@ -31,4 +31,7 @@ void RGUnpackChordShapeID(unsigned int, std::vector &, std::vector *) void RGGameGemToRGState(const GameGem &, RGState &, bool); const char *RGGetNoteName(unsigned char, int); bool RGGetHeldFretRange(const GameGem &, int &, int &, bool); -unsigned int RGGetStrumBitMask(const GameGem &); \ No newline at end of file +unsigned int RGGetStrumBitMask(const GameGem &); +unsigned int RGGetChordShapeID(const GameGem &gem, bool b); +void RGGetChordName(char *, int, const GameGem &, int, int, bool); +void RGGetFretLabelInfo(const GameGem &, int &, int &, bool); \ No newline at end of file diff --git a/src/system/beatmatch/SongData.h b/src/system/beatmatch/SongData.h index f30aff4ae..f22e0627d 100644 --- a/src/system/beatmatch/SongData.h +++ b/src/system/beatmatch/SongData.h @@ -106,7 +106,7 @@ class SongData : public InternalSongParserSink, virtual SongPos CalcSongPos(float); virtual TempoMap *GetTempoMap() const { return mTempoMap; } virtual BeatMap *GetBeatMap() const; - virtual MeasureMap *GetMeasureMap() const; + virtual MeasureMap *GetMeasureMap() const { return mMeasureMap; } virtual void SetTrack(Symbol); virtual bool GetGem(int, int &, int &, int &); diff --git a/src/system/track/TrackDir.h b/src/system/track/TrackDir.h index cdd38f379..e12a082f7 100644 --- a/src/system/track/TrackDir.h +++ b/src/system/track/TrackDir.h @@ -1,6 +1,7 @@ #ifndef TRACK_TRACKDIR_H #define TRACK_TRACKDIR_H #include "obj/Object.h" +#include "os/Debug.h" #include "ui/PanelDir.h" #include "obj/ObjPtr_p.h" @@ -34,11 +35,11 @@ class TrackDir : public PanelDir { virtual int GetNumFretPosOffsets() const { return 0; } virtual float GetCurrentChordLabelPosOffset() const; virtual int PrepareChordMesh(unsigned int); - virtual int GetChordMesh(unsigned int, bool); + virtual RndMesh *GetChordMesh(unsigned int, bool) { return nullptr; } virtual void SetUnisonProgress(float) {} virtual void ClearChordMeshRefCounts(); virtual void DeleteUnusedChordMeshes(); - virtual void AddChordImpl( + virtual void AddChordRepImpl( RndMesh *, TrackWidget *, TrackWidget *, @@ -46,7 +47,9 @@ class TrackDir : public PanelDir { float, const std::vector &, class String - ); + ) { + MILO_ASSERT(0, 0x68); + } virtual ArpeggioShapePool *GetArpeggioShapePool(); virtual bool IsBlackKey(int) const; virtual void KeyMissLeft(); From d25afb4ee4710084461deef53fd4a03aebf14f74 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Mon, 3 Feb 2025 18:03:32 -0700 Subject: [PATCH 03/12] idek --- src/band3/bandtrack/Gem.cpp | 10 +++++----- src/band3/bandtrack/Gem.h | 10 +++++----- src/system/beatmatch/RGUtl.cpp | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/band3/bandtrack/Gem.cpp b/src/band3/bandtrack/Gem.cpp index 1140442aa..812402318 100644 --- a/src/band3/bandtrack/Gem.cpp +++ b/src/band3/bandtrack/Gem.cpp @@ -22,7 +22,7 @@ Gem::Gem( const GameGem &gg, unsigned int ui, float f1, float f2, bool b1, int i1, int i2, bool b2 ) : mGameGem(&gg), mStart(f1), mEnd(f2), mTailStart(0), mSlots(ui), mBeardTick(i1), - unk_0x3C(0), unk_0x40(0), unk_0x44(0), unk_0x48(0), unk_0x4C(""), + unk_0x3C(0), unk_0x40(0), unk_0x44(0), unk_0x48(0), mChordLabel(""), mFirstFretString(-1), mFretPos(0), unk_0x65(-1) { InitChordInfo(i2, b2); } @@ -265,7 +265,7 @@ void Gem::AddChordInstance(Symbol s1) { ); } - if (!unk_0x67_2 && !unk_0x67_0 && !unk_0x4C.empty()) { + if (!unk_0x67_2 && !unk_0x67_0 && !mChordLabel.empty()) { Symbol s6c; if (mGemManager->GetChordWidgetName(s1, chord_label, s6c)) { w10 = mGemManager->GetWidgetByName(s6c); @@ -295,7 +295,7 @@ void Gem::AddChordInstance(Symbol s1) { } } mGemManager->mTrackDir->AddChordRepImpl( - mesh, w5c, w60, w10, f1, fretNums, unk_0x4C + mesh, w5c, w60, w10, f1, fretNums, mChordLabel ); } } @@ -560,11 +560,11 @@ void Gem::InitChordInfo(int i1, bool b2) { if (name[0] != '\0') { char buf[32]; RGParseOverrideChord(buf, 32, name); - unk_0x4C = buf; + mChordLabel = buf; } else { char buf[32]; RGGetChordName(buf, 32, *mGameGem, -1, i1, b2); - unk_0x4C = buf; + mChordLabel = buf; } } RGGetFretLabelInfo(*mGameGem, mFirstFretString, mFirstFret, true); diff --git a/src/band3/bandtrack/Gem.h b/src/band3/bandtrack/Gem.h index 2ef4be4f7..0fdd6c99e 100644 --- a/src/band3/bandtrack/Gem.h +++ b/src/band3/bandtrack/Gem.h @@ -54,14 +54,14 @@ class Gem { int mBeardTick; // 0x38 float unk_0x3C; // 0x3c float unk_0x40; // 0x40 - unsigned int unk_0x44; // 0x44 - unsigned int unk_0x48; // 0x48 - class String unk_0x4C; // 0x4c + unsigned int unk_0x44; // 0x44 - some RG chord shape + unsigned int unk_0x48; // 0x48 - some other RG chord shape + class String mChordLabel; // 0x4c bool unk_0x58; // 0x58 int mFirstFret; // 0x5c int mFirstFretString; // 0x60 - char mFretPos; - char unk_0x65; + char mFretPos; // 0x64 + char unk_0x65; // 0x65 bool mHit : 1; bool mMissed : 1; bool mReleased : 1; diff --git a/src/system/beatmatch/RGUtl.cpp b/src/system/beatmatch/RGUtl.cpp index 7a94c1137..a842686fa 100644 --- a/src/system/beatmatch/RGUtl.cpp +++ b/src/system/beatmatch/RGUtl.cpp @@ -314,7 +314,7 @@ unsigned int RGGetChordShapeID(const GameGem &gem, bool b) { unsigned int mask = 0; for (unsigned int i = 0; i < 6; i++) { int fret = gem.GetFret(i); - if (!b && gem.GetRGNoteType(i) == 1) + if (!b && gem.GetRGNoteType(i) == kRGGhost) fret = -1; MILO_ASSERT(fret > -2, 0x2B4); fret = fret < 1 ? fret + 1 : Min(fret + range, 7); From 68af6d880ca60a12308d1c2d653ea5bfc7edb19a Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Mon, 3 Feb 2025 18:06:44 -0700 Subject: [PATCH 04/12] format gem --- src/band3/bandtrack/Gem.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/band3/bandtrack/Gem.cpp b/src/band3/bandtrack/Gem.cpp index 812402318..6e6d916d8 100644 --- a/src/band3/bandtrack/Gem.cpp +++ b/src/band3/bandtrack/Gem.cpp @@ -395,12 +395,16 @@ void Gem::RemoveAllInstances() { if (mGemManager && mGemManager->mTrackDir) { float f1 = mGameGem->mMs / 1000.0f; if (unk_0x44 != 0) { - FOREACH(it, mWidgets) { (*it)->RemoveAt(f1); } + FOREACH (it, mWidgets) { + (*it)->RemoveAt(f1); + } } else { int slots = mGemManager->GetMaxSlots(); for (int i = 0; i < slots; i++) { if (mSlots & 1 << i) { - FOREACH(it, mWidgets) { (*it)->RemoveAt(f1, i); } + FOREACH (it, mWidgets) { + (*it)->RemoveAt(f1, i); + } if (mBeardTick != -1) { Symbol s40; if (mGemManager->GetWidgetName(s40, i, beard)) { @@ -484,7 +488,7 @@ void Gem::PartialHit(unsigned int ui) { mBeard = false; float f1 = mGameGem->mMs / 1000.0f; int slots = mGemManager->GetMaxSlots(); - FOREACH(it, mWidgets) { + FOREACH (it, mWidgets) { TrackWidget *cur = *it; for (int i = 0; i < slots; i++) { int mask = 1 << i; From d15e60edc3b27a6e8d6241ad9bfc6000f15d4cc0 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Mon, 3 Feb 2025 19:27:10 -0700 Subject: [PATCH 05/12] begin work on gemmanager --- config/SZBE69/symbols.txt | 4 +- config/SZBE69_B8/objects.json | 2 +- src/band3/bandtrack/Gem.cpp | 96 +++++++++++++--------------- src/band3/bandtrack/Gem.h | 5 +- src/band3/bandtrack/GemManager.cpp | 42 ++++++++++++ src/band3/bandtrack/GemManager.h | 45 ++++++++++++- src/band3/bandtrack/GemRepTemplate.h | 1 + src/band3/bandtrack/NowBar.h | 2 +- src/system/rndobj/Trans.h | 7 +- 9 files changed, 143 insertions(+), 61 deletions(-) create mode 100644 src/band3/bandtrack/GemManager.cpp diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index db253cdb3..d31c1b73e 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -7375,7 +7375,7 @@ fn_800CE8F8 = .text:0x800CE8F8; // type:function size:0x40 fn_800CE938 = .text:0x800CE938; // type:function size:0x30 fn_800CE968 = .text:0x800CE968; // type:function size:0x30 fn_800CE998 = .text:0x800CE998; // type:function size:0x40 -fn_800CE9D8 = .text:0x800CE9D8; // type:function size:0xEC +__dt__10GemManagerFv = .text:0x800CE9D8; // type:function size:0xEC fn_800CEAC4 = .text:0x800CEAC4; // type:function size:0x4 fn_800CEAC8 = .text:0x800CEAC8; // type:function size:0x3C fn_800CEB04 = .text:0x800CEB04; // type:function size:0x40 @@ -7697,7 +7697,7 @@ fn_800D7998 = .text:0x800D7998; // type:function size:0x84 fn_800D7A1C = .text:0x800D7A1C; // type:function size:0x5C fn_800D7A78 = .text:0x800D7A78; // type:function size:0x5C fn_800D7AD4 = .text:0x800D7AD4; // type:function size:0x24 -fn_800D7AF8 = .text:0x800D7AF8; // type:function size:0x1E8 +Init__14GemRepTemplateFP9ObjectDir = .text:0x800D7AF8; // type:function size:0x1E8 Find<6RndMat>__9ObjectDirFPCcb_P6RndMat = .text:0x800D7CE0; // type:function size:0xA0 fn_800D7D80 = .text:0x800D7D80; // type:function size:0x68 fn_800D7DE8 = .text:0x800D7DE8; // type:function size:0x5C diff --git a/config/SZBE69_B8/objects.json b/config/SZBE69_B8/objects.json index 8bebdbb8a..96ee9f5ce 100644 --- a/config/SZBE69_B8/objects.json +++ b/config/SZBE69_B8/objects.json @@ -18,7 +18,7 @@ "cflags": "band3", "objects": { "band3/bandtrack/Gem.cpp": "NonMatching", - "band3/bandtrack/GemManager.cpp": "MISSING", + "band3/bandtrack/GemManager.cpp": "NonMatching", "band3/bandtrack/GemRepTemplate.cpp": "NonMatching", "band3/bandtrack/GemSmasher.cpp": "Matching", "band3/bandtrack/GemTrack.cpp": "NonMatching", diff --git a/src/band3/bandtrack/Gem.cpp b/src/band3/bandtrack/Gem.cpp index 6e6d916d8..c223b6d48 100644 --- a/src/band3/bandtrack/Gem.cpp +++ b/src/band3/bandtrack/Gem.cpp @@ -13,38 +13,36 @@ #include "utl/MBT.h" #include "utl/Std.h" #include "utl/Symbols.h" -#include "utl/Symbols2.h" -#include "utl/Symbols3.h" -#include "utl/Symbols4.h" #include "utl/TimeConversion.h" Gem::Gem( const GameGem &gg, unsigned int ui, float f1, float f2, bool b1, int i1, int i2, bool b2 ) - : mGameGem(&gg), mStart(f1), mEnd(f2), mTailStart(0), mSlots(ui), mBeardTick(i1), + : mGameGem(gg), mStart(f1), mEnd(f2), mTailStart(0), mSlots(ui), mBeardTick(i1), unk_0x3C(0), unk_0x40(0), unk_0x44(0), unk_0x48(0), mChordLabel(""), - mFirstFretString(-1), mFretPos(0), unk_0x65(-1) { + mFirstFretString(-1), mFretPos(0), unk_0x65(-1), mHit(0), mMissed(0), mReleased(0), + mHopo(0), mInvisible(0), mBeard(0), unk_0x67_0(0), unk_0x67_1(0), unk_0x67_2(0), + unk_0x67_3(0), unk_0x67_4(0) { InitChordInfo(i2, b2); } Gem::~Gem() { DeleteAll(mTails); } Gem &Gem::operator=(const Gem &g) { - (GameGem &)(*mGameGem) = *(g.mGameGem); + (GameGem &)mGameGem = g.mGameGem; mSlots = g.mSlots; - mStart = g.mStart; mTailStart = g.mTailStart; mEnd = g.mEnd; - mHopo = g.mHopo; mMissed = g.mMissed; mHit = g.mHit; mReleased = g.mReleased; mInvisible = g.mInvisible; - mTails = g.mTails; mWidgets = g.mWidgets; + unk_0x3C = g.unk_0x3C; + unk_0x40 = g.unk_0x40; } bool Gem::OnScreen(float ms) { @@ -79,7 +77,7 @@ void Gem::AddRep( static float startOffset = 1.5f; SetType(s); if (s != "invisible" && CompareBounds() && b5) { - float f9 = mGemManager->mTrackDir->SecondsToY(mGameGem->mMs / 1000.0f); + float f9 = mGemManager->mTrackDir->SecondsToY(mGameGem.mMs / 1000.0f); Tail *i1 = 0; if (mTailStart < 0) mTailStart = 0; @@ -87,12 +85,12 @@ void Gem::AddRep( float f10 = mGemManager->mTrackDir->SecondsToY(mEnd - mStart); int i3 = mGemManager->GetMaxSlots(); for (int i = 0; i < i3; i++) { - if ((mSlots & 1 << i) && (!rg || mGameGem->GetRGNoteType(i) != 1)) { + if ((mSlots & 1 << i) && (!rg || mGameGem.GetRGNoteType(i) != 1)) { Tail *tail = new Tail(repTemp); mTails.push_back(tail); mTails.back()->SetDuration(0, 0, f10); Tail::SlideInfo info; - if (mGameGem->LeftHandSlide()) { + if (mGameGem.LeftHandSlide()) { info.unk0 = true; if (unk_0x67_4) { info.unk8 = startOffset; @@ -117,7 +115,7 @@ void Gem::AddRep( #pragma force_active on inline bool Gem::UseRGChordStyle() const { bool r = false; - if (mGameGem->IsRealGuitarChord() || unk_0x67_1 || mGameGem->IsMuted()) + if (mGameGem.IsRealGuitarChord() || unk_0x67_1 || mGameGem.IsMuted()) r = true; return r; } @@ -132,10 +130,10 @@ void Gem::RemoveRep() { void Gem::AddInstance(Symbol s1, int i2) { if (mGemManager && mGemManager->mTrackDir && mGemManager->SlotEnabled(i2)) { - TrackConfig *cfg = mGemManager->mTrackConfig; + const TrackConfig &cfg = mGemManager->mTrackConfig; Symbol s1b8; Symbol s1bc = s1.mStr; - if (mHopo && !cfg->GetDisableHopos()) { + if (mHopo && !cfg.GetDisableHopos()) { s1bc = MakeString("%s_hopo", s1bc.mStr); } else if (Check66B0()) { s1bc = MakeString("%s_cymbal", s1bc.mStr); @@ -147,9 +145,9 @@ void Gem::AddInstance(Symbol s1, int i2) { if (mGemManager->GetWidgetName(s1b8, i2, s1bc) && mGemManager->GetWidgetName(s1b8, i2, s1bc)) { - if (mGameGem->IsRealGuitar()) { + if (mGameGem.IsRealGuitar()) { int i6 = mFretPos; - if (cfg->IsLefty()) + if (cfg.IsLefty()) i6 = 4 - i6; s1b8 = MakeString("%s%02d.wid", s1b8.mStr, i6); } @@ -177,7 +175,7 @@ void Gem::AddInstance(Symbol s1, int i2) { if (mGemManager->GetWidgetName(s1c4, i2, mash)) { TrackWidget *w2 = mGemManager->GetWidgetByName(s1c4); Transform tf98; - mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem->mMs / 1000.0f, tf98); + mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem.mMs / 1000.0f, tf98); w2->AddInstance(tf98, unk_0x3C); } } @@ -187,9 +185,9 @@ void Gem::AddInstance(Symbol s1, int i2) { if (mGemManager->GetWidgetName(s1c8, i2, fret_num)) { TrackWidget *wcc = mGemManager->GetWidgetByName(s1c8); Transform tfc8; - mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem->mMs / 1000.0f, tfc8); + mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem.mMs / 1000.0f, tfc8); Vector3 v164(0, 0, 0); - if (cfg->IsLefty()) { + if (cfg.IsLefty()) { v164.x = -v164.x; } Multiply(v164, tfc8, tfc8.v); @@ -200,14 +198,14 @@ void Gem::AddInstance(Symbol s1, int i2) { } } - if (mGameGem->IsRealGuitar() && mGameGem->GetFret(i2) != -1) { + if (mGameGem.IsRealGuitar() && mGameGem.GetFret(i2) != -1) { Symbol s1d0; if (mGemManager->GetWidgetName(s1d0, i2, fret_num)) { TrackWidget *w1d4 = mGemManager->GetWidgetByName(s1d0); Transform tff8; - mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem->mMs / 1000.0f, tff8); + mGemManager->mTrackDir->MakeWidgetXfm(i2, mGameGem.mMs / 1000.0f, tff8); float offset = mGemManager->mTrackDir->GetFretPosOffset(mFretPos); - if (cfg->IsLefty()) + if (cfg.IsLefty()) offset = -offset; static DataNode &rg_widget_scale = DataVariable("rg_widget_scale"); float scaleFloat = rg_widget_scale.Float(); @@ -222,7 +220,7 @@ void Gem::AddInstance(Symbol s1, int i2) { tff8.v ); } - String str17c(RGFretNumberToString(mGameGem->GetFret(i2))); + String str17c(RGFretNumberToString(mGameGem.GetFret(i2))); w1d4->AddTextInstance(tff8, str17c, false); mWidgets.insert(w1d4); } @@ -232,9 +230,9 @@ void Gem::AddInstance(Symbol s1, int i2) { void Gem::AddChordInstance(Symbol s1) { if (mGemManager && mGemManager->mTrackDir) { - float f1 = mGameGem->mMs / 1000.0f; + float f1 = mGameGem.mMs / 1000.0f; RndMesh *mesh = mGemManager->mTrackDir->GetChordMesh( - unk_0x44, mGemManager->mTrackConfig->IsLefty() + unk_0x44, mGemManager->mTrackConfig.IsLefty() ); TrackWidget *w5c = nullptr; TrackWidget *w60 = nullptr; @@ -284,12 +282,12 @@ void Gem::AddChordInstance(Symbol s1) { bool mod = TheModifierMgr->IsModifierActive("mod_chord_numbers"); bool b2 = true; - if (!mGameGem->ShowChordNums() && !mod) + if (!mGameGem.ShowChordNums() && !mod) b2 = false; for (int i = 0; i < 6; i++) { if (i == mFirstFretString || b2) { - fretNums[i] = mGameGem->GetFret(i); + fretNums[i] = mGameGem.GetFret(i); } else { fretNums[i] = -1; } @@ -302,8 +300,8 @@ void Gem::AddChordInstance(Symbol s1) { void Gem::AddStrumInstance(Symbol s1, Symbol s2) { if (mGemManager && mGemManager->mTrackDir) { - int lowString = mGameGem->GetLowestString(); - int highString = mGameGem->GetHighestString(); + int lowString = mGameGem.GetLowestString(); + int highString = mGameGem.GetHighestString(); MILO_ASSERT(lowString != -1, 572); MILO_ASSERT(highString != -1, 573); Symbol s88; @@ -316,11 +314,11 @@ void Gem::AddStrumInstance(Symbol s1, Symbol s2) { ); } else { int range = (highString - lowString) + 1; - bool lefty = mGemManager->mTrackConfig->IsLefty(); + bool lefty = mGemManager->mTrackConfig.IsLefty(); if (s2 == area_strum) { MILO_ASSERT_RANGE_EQ(range, 4, 6, 0x250); char u6 = ' '; - switch (mGameGem->GetRGStrumType()) { + switch (mGameGem.GetRGStrumType()) { case 3: u6 = 'L'; if (lefty) @@ -348,9 +346,7 @@ void Gem::AddStrumInstance(Symbol s1, Symbol s2) { if (lefty) lowString = highString; Transform tf48; - mGemManager->mTrackDir->MakeWidgetXfm( - lowString, mGameGem->mMs / 1000.0f, tf48 - ); + mGemManager->mTrackDir->MakeWidgetXfm(lowString, mGameGem.mMs / 1000.0f, tf48); w8c->AddInstance(tf48, 0); mWidgets.insert(w8c); } @@ -361,8 +357,8 @@ DECOMP_FORCEACTIVE(Gem, "mesh") void Gem::AddWidgetInstanceImpl(TrackWidget *w, int i) { Transform tf38; - mGemManager->mTrackDir->MakeWidgetXfm(i, mGameGem->mMs / 1000.0f, tf38); - if (mGemManager->mTrackConfig->IsRealGuitarTrack()) { + mGemManager->mTrackDir->MakeWidgetXfm(i, mGameGem.mMs / 1000.0f, tf38); + if (mGemManager->mTrackConfig.IsRealGuitarTrack()) { static DataNode &rg_widget_scale = DataVariable("rg_widget_scale"); float rgFloat = rg_widget_scale.Float(); if (rgFloat > 0) { @@ -375,7 +371,7 @@ void Gem::AddWidgetInstanceImpl(TrackWidget *w, int i) { void Gem::AddHopoTails(Symbol s1) { if (!mGemManager || !mGemManager->mTrackDir - || !mGemManager->mTrackConfig->IsRealGuitarTrack() || !mHopo || unk_0x66_6) + || !mGemManager->mTrackConfig.IsRealGuitarTrack() || !mHopo || unk_0x66_6) return; else { Symbol hopoSym = s1 == miss ? hopo_tail_miss : hopo_tail; @@ -393,7 +389,7 @@ void Gem::AddHopoTails(Symbol s1) { void Gem::RemoveAllInstances() { if (mGemManager && mGemManager->mTrackDir) { - float f1 = mGameGem->mMs / 1000.0f; + float f1 = mGameGem.mMs / 1000.0f; if (unk_0x44 != 0) { FOREACH (it, mWidgets) { (*it)->RemoveAt(f1); @@ -442,17 +438,17 @@ void Gem::UpdateTailPositions() { } void Gem::CreateWidgetInstances(Symbol s) { - if (mGameGem->IsRealGuitar() && mGameGem->IsMuted() && mSlots != 0) { + if (mGameGem.IsRealGuitar() && mGameGem.IsMuted() && mSlots != 0) { AddStrumInstance(s, muted_strum); } else { - if (mGameGem->IsRealGuitarChord() && mSlots != 0) { + if (mGameGem.IsRealGuitarChord() && mSlots != 0) { if (unk_0x44 != 0) { AddChordInstance(s); } else { MILO_WARN( "RG chord gem at %s has only ghost notes; gem will be invisible", TickFormat( - mGameGem->GetTick(), *TheSongDB->GetSongData()->GetMeasureMap() + mGameGem.GetTick(), *TheSongDB->GetSongData()->GetMeasureMap() ) ); } @@ -486,7 +482,7 @@ void Gem::Hit() { void Gem::PartialHit(unsigned int ui) { if (!mInvisible) { mBeard = false; - float f1 = mGameGem->mMs / 1000.0f; + float f1 = mGameGem.mMs / 1000.0f; int slots = mGemManager->GetMaxSlots(); FOREACH (it, mWidgets) { TrackWidget *cur = *it; @@ -556,22 +552,22 @@ void Gem::Reset() { float Gem::GetStart() const { return mBeard ? TickToSeconds(mBeardTick) : mStart; } void Gem::InitChordInfo(int i1, bool b2) { - if (mGameGem->IsRealGuitarChord()) { - unk_0x44 = RGGetChordShapeID(*mGameGem, false); - unk_0x48 = RGGetChordShapeID(*mGameGem, true); - if (mGameGem->GetShowChordNames()) { - const char *name = mGameGem->GetChordNameOverride().mStr; + if (mGameGem.IsRealGuitarChord()) { + unk_0x44 = RGGetChordShapeID(mGameGem, false); + unk_0x48 = RGGetChordShapeID(mGameGem, true); + if (mGameGem.GetShowChordNames()) { + const char *name = mGameGem.GetChordNameOverride().mStr; if (name[0] != '\0') { char buf[32]; RGParseOverrideChord(buf, 32, name); mChordLabel = buf; } else { char buf[32]; - RGGetChordName(buf, 32, *mGameGem, -1, i1, b2); + RGGetChordName(buf, 32, mGameGem, -1, i1, b2); mChordLabel = buf; } } - RGGetFretLabelInfo(*mGameGem, mFirstFretString, mFirstFret, true); + RGGetFretLabelInfo(mGameGem, mFirstFretString, mFirstFret, true); } } diff --git a/src/band3/bandtrack/Gem.h b/src/band3/bandtrack/Gem.h index 0fdd6c99e..10af3da0e 100644 --- a/src/band3/bandtrack/Gem.h +++ b/src/band3/bandtrack/Gem.h @@ -1,5 +1,4 @@ #pragma once -#include "bandtrack/GemManager.h" #include "bandtrack/Tail.h" #include "beatmatch/GameGem.h" #include "track/TrackWidget.h" @@ -8,6 +7,8 @@ #include "types.h" #include +class GemManager; + class Gem { public: Gem(const GameGem &, unsigned int, float, float, bool, int, int, bool); @@ -44,7 +45,7 @@ class Gem { bool Check66B0() const { return unk_0x66_7; } GemManager *mGemManager; // 0x0 - const GameGem *mGameGem; // 0x4 + const GameGem &mGameGem; // 0x4 std::set mWidgets; // 0x8 float mStart; // 0x20 float mEnd; // 0x24 diff --git a/src/band3/bandtrack/GemManager.cpp b/src/band3/bandtrack/GemManager.cpp new file mode 100644 index 000000000..e2393daae --- /dev/null +++ b/src/band3/bandtrack/GemManager.cpp @@ -0,0 +1,42 @@ +#include "bandtrack/GemManager.h" +#include "bandtrack/NowBar.h" +#include "obj/DataFunc.h" +#include "os/System.h" + +int sBeardThreshold = 480; + +int GetBeardThreshold() { return sBeardThreshold; } + +DataNode SetKeyGlow(DataArray *arr) { + sBeardThreshold = arr->Int(1); + return 0; +} + +GemManager::GemManager(const TrackConfig &cfg, TrackDir *dir) + : mTrackDir(dir), mTrackConfig(cfg), mTemplate(cfg), + mConfig(SystemConfig("track_graphics")), unk10(0), unk14(0), unk28(0), unk2c(0), + unkb8(0), mNowBar(0), unkc0(0), unkc1(0), unkc4(0), + unkc8(dir->SecondsToY(dir->TopSeconds())), + unkcc(dir->SecondsToY(dir->BottomSeconds())), unkf8(0), unkfc(0), unk100(0), + unk104(0), unk108(0), unk10c(0), unk118(0), unk12c(0), unk130(-1), unk134(960) { + mNowBar = new NowBar(mTrackDir, mTrackConfig); + mTemplate.Init(mTrackDir->Find("gem_tail", true)); + static bool firstPass = true; + if (firstPass) { + sBeardThreshold = + SystemConfig("track_graphics")->FindInt("key_glow_threshold_ticks"); + firstPass = false; + } + unk134 = SystemConfig("track_graphics")->FindInt("rg_run_space_ticks"); + SetupGems(0); + UpdateLeftyFlip(false); + DataRegisterFunc("set_key_glow", SetKeyGlow); + unk12c = mTrackDir->Find("chord_shape_outline", true)->mLocalXfm.v.y + 0.01f; + unkd8.reserve(10); +} + +GemManager::~GemManager() { + RELEASE(mNowBar); + ClearArpeggios(); + unk8.clear(); +} \ No newline at end of file diff --git a/src/band3/bandtrack/GemManager.h b/src/band3/bandtrack/GemManager.h index 582b7aefc..fccc605dc 100644 --- a/src/band3/bandtrack/GemManager.h +++ b/src/band3/bandtrack/GemManager.h @@ -1,5 +1,10 @@ #pragma once +#include "Gem.h" +#include "bandtrack/GemRepTemplate.h" +#include "bandtrack/NowBar.h" +#include "obj/Data.h" #include "obj/Object.h" +#include "track/TrackWidget.h" #include "utl/Symbol.h" #include "system/track/TrackDir.h" #include "TrackConfig.h" @@ -30,6 +35,9 @@ class PlayerState { class GemManager { public: + class HitGem { + public: + }; GemManager(const TrackConfig &, TrackDir *); ~GemManager(); @@ -66,9 +74,42 @@ class GemManager { void HideGems(); bool SlotEnabled(int) const; int GetSlotIntData(int, Symbol); + void ClearArpeggios(); - TrackDir *mTrackDir; - TrackConfig *mTrackConfig; + TrackDir *mTrackDir; // 0x0 + const TrackConfig &mTrackConfig; // 0x4 + std::vector unk8; + int unk10; + float unk14; + std::vector unk18; + std::list unk20; + int unk28; + int unk2c; + GemRepTemplate mTemplate; // 0x30 + DataArray *mConfig; // 0xb4 + bool unkb8; // 0xb8 + NowBar *mNowBar; // 0xbc + bool unkc0; + bool unkc1; + float unkc4; + float unkc8; + float unkcc; + std::list unkd0; + std::vector unkd8; + std::map unke0; + int unkf8; + int unkfc; + int unk100; + int unk104; + int unk108; + int unk10c; + std::vector unk110; + int unk118; + std::vector unk11c; + std::vector unk124; + float unk12c; + int unk130; + int unk134; }; int GetBeardThreshold(); \ No newline at end of file diff --git a/src/band3/bandtrack/GemRepTemplate.h b/src/band3/bandtrack/GemRepTemplate.h index 549b181f5..d74aeb210 100644 --- a/src/band3/bandtrack/GemRepTemplate.h +++ b/src/band3/bandtrack/GemRepTemplate.h @@ -6,6 +6,7 @@ #include class GemRepTemplate { +public: enum TailType { type0, type1, diff --git a/src/band3/bandtrack/NowBar.h b/src/band3/bandtrack/NowBar.h index 8a2ecf6b6..c795fbafb 100644 --- a/src/band3/bandtrack/NowBar.h +++ b/src/band3/bandtrack/NowBar.h @@ -6,7 +6,7 @@ class NowBar { public: NowBar(TrackDir *, const TrackConfig &); - + ~NowBar(); void Poll(float, bool); void Reset(bool); void Hit(float, int, bool, int, bool); diff --git a/src/system/rndobj/Trans.h b/src/system/rndobj/Trans.h index a83b6dacb..602b4f594 100644 --- a/src/system/rndobj/Trans.h +++ b/src/system/rndobj/Trans.h @@ -130,9 +130,10 @@ class RndTransformable : public virtual RndHighlightable { } void SetLocalPos(const Vector3 &vec) { - mLocalXfm.v.x = vec.x; - mLocalXfm.v.y = vec.y; - mLocalXfm.v.z = vec.z; + mLocalXfm.v = vec; + // mLocalXfm.v.x = vec.x; + // mLocalXfm.v.y = vec.y; + // mLocalXfm.v.z = vec.z; SetDirty(); } From ad15ff7b53da63b54dc012fdd4781a8a6a2615c3 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Mon, 3 Feb 2025 21:08:18 -0700 Subject: [PATCH 06/12] more gemmgr stuff --- config/SZBE69/symbols.txt | 40 ++++++++++++------------ src/band3/bandtrack/GemManager.cpp | 50 ++++++++++++++++++++++++++++-- src/band3/bandtrack/GemManager.h | 38 ++++++++++++++++------- src/system/track/TrackDir.h | 45 +++++++++++++-------------- 4 files changed, 114 insertions(+), 59 deletions(-) diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index d31c1b73e..2fab0e7d2 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -6890,7 +6890,7 @@ fn_800BE5FC = .text:0x800BE5FC; // type:function size:0xD4 __ct__15NamingResultMsgFii = .text:0x800BE6D0; // type:function size:0x8C Type__15NamingResultMsgFv = .text:0x800BE75C; // type:function size:0x4C fn_800BE7A8 = .text:0x800BE7A8; // type:function size:0x8 -ClipType__10CharDriverCFv = .text:0x800BE7B0; // type:function size:0x8 +MergedGet0x7C__FPv = .text:0x800BE7B0; // type:function size:0x8 fn_800BE7B8 = .text:0x800BE7B8; // type:function size:0xD4 __ct__21DeleteUserCompleteMsgFii = .text:0x800BE88C; // type:function size:0x8C Type__21DeleteUserCompleteMsgFv = .text:0x800BE918; // type:function size:0x4C @@ -7385,23 +7385,23 @@ fn_800CEBD8 = .text:0x800CEBD8; // type:function size:0x2C fn_800CEC04 = .text:0x800CEC04; // type:function size:0x58 fn_800CEC5C = .text:0x800CEC5C; // type:function size:0x28 fn_800CEC84 = .text:0x800CEC84; // type:function size:0x68 -fn_800CECEC = .text:0x800CECEC; // type:function size:0x188 +InitRGTuning__10GemManagerFP8BandUser = .text:0x800CECEC; // type:function size:0x188 reserve__Q211stlpmtx_std45vector>FUl = .text:0x800CEE74; // type:function size:0x4 -fn_800CEE78 = .text:0x800CEE78; // type:function size:0x4F0 +DrawTrackMasks__10GemManagerFii = .text:0x800CEE78; // type:function size:0x4F0 MergedGet0x48__FPv = .text:0x800CF368; // type:function size:0x8 Min__Fii_i = .text:0x800CF370; // type:function size:0x10 __vc__Q211stlpmtx_std77vector>FUl = .text:0x800CF380; // type:function size:0x10 __vc__Q211stlpmtx_std109vector>FUl = .text:0x800CF390; // type:function size:0x10 fn_800CF3A0 = .text:0x800CF3A0; // type:function size:0x8 -fn_800CF3A8 = .text:0x800CF3A8; // type:function size:0xB0 +ClearArpeggios__10GemManagerFv = .text:0x800CF3A8; // type:function size:0xB0 fn_800CF458 = .text:0x800CF458; // type:function size:0x4 fn_800CF45C = .text:0x800CF45C; // type:function size:0x3C -fn_800CF498 = .text:0x800CF498; // type:function size:0x8C +ResetArpeggios__10GemManagerFf = .text:0x800CF498; // type:function size:0x8C MsToTickInt__Ff = .text:0x800CF524; // type:function size:0x2C -fn_800CF550 = .text:0x800CF550; // type:function size:0x1C0 +UpdateArpeggios__10GemManagerFfb = .text:0x800CF550; // type:function size:0x1C0 fn_800CF710 = .text:0x800CF710; // type:function size:0x40 -fn_800CF750 = .text:0x800CF750; // type:function size:0xE4 -fn_800CF834 = .text:0x800CF834; // type:function size:0x2E0 +ClearTrackMasks__10GemManagerFv = .text:0x800CF750; // type:function size:0xE4 +SetupRealGuitarFretPos__10GemManagerFv = .text:0x800CF834; // type:function size:0x2E0 fn_800CFB14 = .text:0x800CFB14; // type:function size:0x58 fn_800CFB6C = .text:0x800CFB6C; // type:function size:0x80 fn_800CFBEC = .text:0x800CFBEC; // type:function size:0x80 @@ -7426,7 +7426,7 @@ fn_800CFF80 = .text:0x800CFF80; // type:function size:0xD4 fn_800D0054 = .text:0x800D0054; // type:function size:0x30 fn_800D0084 = .text:0x800D0084; // type:function size:0x30 fn_800D00B4 = .text:0x800D00B4; // type:function size:0x40 -fn_800D00F4 = .text:0x800D00F4; // type:function size:0x38C +ProcessRealGuitarRun__10GemManagerFRQ211stlpmtx_std59vector<7GameGem,Us,Q211stlpmtx_std22StlNodeAlloc<7GameGem>>Ri = .text:0x800D00F4; // type:function size:0x38C fn_800D0480 = .text:0x800D0480; // type:function size:0x4 fn_800D0484 = .text:0x800D0484; // type:function size:0x3C fn_800D04C0 = .text:0x800D04C0; // type:function size:0x40 @@ -7438,11 +7438,11 @@ fn_800D0618 = .text:0x800D0618; // type:function size:0x28 fn_800D0640 = .text:0x800D0640; // type:function size:0x68 max__11stlpmtx_stdFRCiRCi_RCi = .text:0x800D06A8; // type:function size:0x18 fn_800D06C0 = .text:0x800D06C0; // type:function size:0x18 -fn_800D06D8 = .text:0x800D06D8; // type:function size:0x348 -fn_800D0A20 = .text:0x800D0A20; // type:function size:0x14C +SetupRealGuitarImportantStrings__10GemManagerFv = .text:0x800D06D8; // type:function size:0x348 +SetupRealGuitarAreaStrumSections__10GemManagerFv = .text:0x800D0A20; // type:function size:0x14C fn_800D0B6C = .text:0x800D0B6C; // type:function size:0x10 __vc__Q211stlpmtx_std59vector<7GameGem,Us,Q211stlpmtx_std22StlNodeAlloc<7GameGem>>FUl = .text:0x800D0B7C; // type:function size:0x10 -fn_800D0B8C = .text:0x800D0B8C; // type:function size:0xE0C +SetupGems__10GemManagerFi = .text:0x800D0B8C; // type:function size:0xE0C fn_800D1998 = .text:0x800D1998; // type:function size:0x4 fn_800D199C = .text:0x800D199C; // type:function size:0x88 fn_800D1A24 = .text:0x800D1A24; // type:function size:0x2C @@ -7502,7 +7502,7 @@ fn_800D2448 = .text:0x800D2448; // type:function size:0x4 fn_800D244C = .text:0x800D244C; // type:function size:0x80 RollStartsAt__10GemManagerCFiRC7GameGemRiRUi = .text:0x800D24CC; // type:function size:0xDC TrillStartsAt__10GemManagerCFiRC7GameGemRi = .text:0x800D25A8; // type:function size:0xBC -fn_800D2664 = .text:0x800D2664; // type:function size:0x8 +SetGemsEnabled__10GemManagerFf = .text:0x800D2664; // type:function size:0x8 UpdateLeftyFlip__10GemManagerFv = .text:0x800D266C; // type:function size:0x5F8 fn_800D2C64 = .text:0x800D2C64; // type:function size:0x2C MergedGetF0xAC__FPv = .text:0x800D2C90; // type:function size:0x8 @@ -7517,16 +7517,16 @@ WorldXfm__16RndTransformableFv = .text:0x800D2EBC; // type:function size:0x1C Find<16RndTransformable>__9ObjectDirFPCcb_P16RndTransformable = .text:0x800D2ED8; // type:function size:0xA0 fn_800D2F78 = .text:0x800D2F78; // type:function size:0x8 fn_800D2F80 = .text:0x800D2F80; // type:function size:0x8 -fn_800D2F88 = .text:0x800D2F88; // type:function size:0xDC +Poll__10GemManagerFfRC11PlayerState = .text:0x800D2F88; // type:function size:0xDC fn_800D3064 = .text:0x800D3064; // type:function size:0x14 fn_800D3078 = .text:0x800D3078; // type:function size:0x20 -fn_800D3098 = .text:0x800D3098; // type:function size:0x1C8 +PollHelper__10GemManagerFfRC11PlayerState = .text:0x800D3098; // type:function size:0x1C8 max__11stlpmtx_stdFRCfRCf_RCf = .text:0x800D3260; // type:function size:0x18 fn_800D3278 = .text:0x800D3278; // type:function size:0x18 Max__Fii_i = .text:0x800D3290; // type:function size:0x10 fn_800D32A0 = .text:0x800D32A0; // type:function size:0xD8 -fn_800D3378 = .text:0x800D3378; // type:function size:0x44 -fn_800D33BC = .text:0x800D33BC; // type:function size:0x1C8 +AdvanceBegin__10GemManagerFv = .text:0x800D3378; // type:function size:0x44 +AdvanceEnd__10GemManagerFv = .text:0x800D33BC; // type:function size:0x1C8 MergedGet0x2C__FPv = .text:0x800D3584; // type:function size:0x8 Find<8RndGroup>__9ObjectDirFPCcb_P8RndGroup = .text:0x800D358C; // type:function size:0xA0 fn_800D362C = .text:0x800D362C; // type:function size:0x318 @@ -7572,7 +7572,7 @@ fn_800D4558 = .text:0x800D4558; // type:function size:0x8 fn_800D4560 = .text:0x800D4560; // type:function size:0x8 fn_800D4568 = .text:0x800D4568; // type:function size:0x44 fn_800D45AC = .text:0x800D45AC; // type:function size:0x8 -fn_800D45B4 = .text:0x800D45B4; // type:function size:0x174 +Jump__10GemManagerFf = .text:0x800D45B4; // type:function size:0x174 Clamp__Fiii_i = .text:0x800D4728; // type:function size:0x24 fn_800D474C = .text:0x800D474C; // type:function size:0x8 fn_800D4754 = .text:0x800D4754; // type:function size:0x8 @@ -7604,7 +7604,7 @@ fn_800D519C = .text:0x800D519C; // type:function size:0xC fn_800D51A8 = .text:0x800D51A8; // type:function size:0x40 fn_800D51E8 = .text:0x800D51E8; // type:function size:0x40 fn_800D5228 = .text:0x800D5228; // type:function size:0x18 -fn_800D5240 = .text:0x800D5240; // type:function size:0xF4 +UpdateGemStates__10GemManagerFv = .text:0x800D5240; // type:function size:0xF4 fn_800D5334 = .text:0x800D5334; // type:function size:0x40 fn_800D5374 = .text:0x800D5374; // type:function size:0x40 ClearGems__10GemManagerFb = .text:0x800D53B4; // type:function size:0xA0 @@ -8124,7 +8124,7 @@ fn_800E320C = .text:0x800E320C; // type:function size:0x38 fn_800E3244 = .text:0x800E3244; // type:function size:0x8 fn_800E324C = .text:0x800E324C; // type:function size:0x48 fn_800E3294 = .text:0x800E3294; // type:function size:0x54 -fn_800E32E8 = .text:0x800E32E8; // type:function size:0x8 +GetType__5TrackCFv = .text:0x800E32E8; // type:function size:0x8 fn_800E32F0 = .text:0x800E32F0; // type:function size:0x28 fn_800E3318 = .text:0x800E3318; // type:function size:0x74 fn_800E338C = .text:0x800E338C; // type:function size:0x14 diff --git a/src/band3/bandtrack/GemManager.cpp b/src/band3/bandtrack/GemManager.cpp index e2393daae..44ad9e9b1 100644 --- a/src/band3/bandtrack/GemManager.cpp +++ b/src/band3/bandtrack/GemManager.cpp @@ -1,7 +1,15 @@ #include "bandtrack/GemManager.h" +#include "bandobj/ArpeggioShape.h" #include "bandtrack/NowBar.h" +#include "bandtrack/Track.h" +#include "beatmatch/RGUtl.h" +#include "meta_band/BandSongMetadata.h" +#include "meta_band/BandSongMgr.h" +#include "meta_band/MetaPerformer.h" #include "obj/DataFunc.h" +#include "os/Debug.h" #include "os/System.h" +#include "utl/Symbols4.h" int sBeardThreshold = 480; @@ -14,8 +22,8 @@ DataNode SetKeyGlow(DataArray *arr) { GemManager::GemManager(const TrackConfig &cfg, TrackDir *dir) : mTrackDir(dir), mTrackConfig(cfg), mTemplate(cfg), - mConfig(SystemConfig("track_graphics")), unk10(0), unk14(0), unk28(0), unk2c(0), - unkb8(0), mNowBar(0), unkc0(0), unkc1(0), unkc4(0), + mConfig(SystemConfig("track_graphics")), mGemData(0), unk14(0), mBegin(0), mEnd(0), + unkb8(0), mNowBar(0), unkc0(0), mInCoda(0), unkc4(0), unkc8(dir->SecondsToY(dir->TopSeconds())), unkcc(dir->SecondsToY(dir->BottomSeconds())), unkf8(0), unkfc(0), unk100(0), unk104(0), unk108(0), unk10c(0), unk118(0), unk12c(0), unk130(-1), unk134(960) { @@ -38,5 +46,41 @@ GemManager::GemManager(const TrackConfig &cfg, TrackDir *dir) GemManager::~GemManager() { RELEASE(mNowBar); ClearArpeggios(); - unk8.clear(); + mGems.clear(); +} + +void GemManager::InitRGTuning(BandUser *bandUser) { + MILO_ASSERT(bandUser, 0xAE); + bool isRG = bandUser->GetTrack()->GetType() == real_guitar; + bool isRB = bandUser->GetTrack()->GetType() == real_bass; + if (isRG || isRB) { + BandSongMetadata *metadata = (BandSongMetadata *)TheSongMgr->Data( + TheSongMgr->GetSongIDFromShortName(MetaPerformer::Current()->Song(), true) + ); + std::vector vec18; + if (isRG) { + vec18.reserve(6); + for (int i = 0; i < 6; i++) { + vec18.push_back(metadata->RealGuitarTuning(i)); + } + } else { + vec18.reserve(4); + for (int i = 0; i < 4; i++) { + vec18.push_back(metadata->RealBassTuning(i)); + } + } + RGSetTuning(vec18); + } +} + +void GemManager::ClearArpeggios() { + ArpeggioShapePool *pool = mTrackDir->GetArpeggioShapePool(); + while (!mActiveArpeggios.empty()) { + pool->ReleaseArpeggioShape(mActiveArpeggios.back()->unkc); + mActiveArpeggios.pop_back(); + } + while (!mExpiredArpeggios.empty()) { + pool->ReleaseArpeggioShape(mExpiredArpeggios.back()->unkc); + mExpiredArpeggios.pop_back(); + } } \ No newline at end of file diff --git a/src/band3/bandtrack/GemManager.h b/src/band3/bandtrack/GemManager.h index fccc605dc..d46ada5b3 100644 --- a/src/band3/bandtrack/GemManager.h +++ b/src/band3/bandtrack/GemManager.h @@ -1,7 +1,9 @@ #pragma once #include "Gem.h" +#include "bandobj/ArpeggioShape.h" #include "bandtrack/GemRepTemplate.h" #include "bandtrack/NowBar.h" +#include "game/Player.h" #include "obj/Data.h" #include "obj/Object.h" #include "track/TrackWidget.h" @@ -37,6 +39,17 @@ class GemManager { public: class HitGem { public: + int unk0; + int unk4; + int unk8; + }; + class ArpeggioPhrase { + public: + int unk0; + int unk4; + int unk8; + ArpeggioShape *unkc; + bool unk10; }; GemManager(const TrackConfig &, TrackDir *); ~GemManager(); @@ -75,38 +88,39 @@ class GemManager { bool SlotEnabled(int) const; int GetSlotIntData(int, Symbol); void ClearArpeggios(); + void InitRGTuning(BandUser *); TrackDir *mTrackDir; // 0x0 const TrackConfig &mTrackConfig; // 0x4 - std::vector unk8; - int unk10; + std::vector mGems; // 0x8 + DataArray *mGemData; // 0x10 float unk14; - std::vector unk18; - std::list unk20; - int unk28; - int unk2c; + std::vector mMissedPhrases; // 0x18 + std::list mHitGems; // 0x20 + int mBegin; // 0x28 + int mEnd; // 0x2c GemRepTemplate mTemplate; // 0x30 DataArray *mConfig; // 0xb4 bool unkb8; // 0xb8 NowBar *mNowBar; // 0xbc bool unkc0; - bool unkc1; + bool mInCoda; // 0xc1 float unkc4; float unkc8; float unkcc; std::list unkd0; - std::vector unkd8; - std::map unke0; + std::vector unkd8; + std::map mWidgets; // 0xe0 int unkf8; int unkfc; int unk100; int unk104; int unk108; int unk10c; - std::vector unk110; + std::vector mArpeggioPhrases; // 0x110 int unk118; - std::vector unk11c; - std::vector unk124; + std::vector mActiveArpeggios; // 0x11c + std::vector mExpiredArpeggios; // 0x124 float unk12c; int unk130; int unk134; diff --git a/src/system/track/TrackDir.h b/src/system/track/TrackDir.h index e12a082f7..d397af07b 100644 --- a/src/system/track/TrackDir.h +++ b/src/system/track/TrackDir.h @@ -1,5 +1,4 @@ -#ifndef TRACK_TRACKDIR_H -#define TRACK_TRACKDIR_H +#pragma once #include "obj/Object.h" #include "os/Debug.h" #include "ui/PanelDir.h" @@ -33,7 +32,7 @@ class TrackDir : public PanelDir { virtual RndDir *SmasherPlate(); virtual float GetFretPosOffset(int) const { return 0; } virtual int GetNumFretPosOffsets() const { return 0; } - virtual float GetCurrentChordLabelPosOffset() const; + virtual float GetCurrentChordLabelPosOffset() const { return 0; } virtual int PrepareChordMesh(unsigned int); virtual RndMesh *GetChordMesh(unsigned int, bool) { return nullptr; } virtual void SetUnisonProgress(float) {} @@ -50,7 +49,7 @@ class TrackDir : public PanelDir { ) { MILO_ASSERT(0, 0x68); } - virtual ArpeggioShapePool *GetArpeggioShapePool(); + virtual ArpeggioShapePool *GetArpeggioShapePool() { return nullptr; } virtual bool IsBlackKey(int) const; virtual void KeyMissLeft(); virtual void KeyMissRight(); @@ -87,8 +86,8 @@ class TrackDir : public PanelDir { static void Register() { REGISTER_OBJ_FACTORY(TrackDir); } bool mRunning; // 0x1d6 - ObjPtr mDrawGroup; // 0x1d8 - ObjPtr mAnimGroup; // 0x1e4 + ObjPtr mDrawGroup; // 0x1d8 + ObjPtr mAnimGroup; // 0x1e4 float mYPerSecond; // 0x1f0 float mTopY; // 0x1f4 float mBottomY; // 0x1f8 @@ -96,22 +95,22 @@ class TrackDir : public PanelDir { std::vector vec2; // 0x204 bool mWarnOnResort; // 0x20c std::vector mActiveWidgets; // 0x210 - ObjPtr mShowingWhenEnabled; // 0x218 - ObjPtr mStationaryBack; // 0x224 - ObjPtr mKeyShiftStationaryBack; // 0x230 - ObjPtr mStationaryBackAfterKeyShift; // 0x23c - ObjPtr mMovingBack; // 0x248 - ObjPtr mKeyShiftMovingBack; // 0x254 - ObjPtr mKeyShiftStationaryMiddle; // 0x260 - ObjPtr mStationaryMiddle; // 0x26c - ObjPtr mMovingFront; // 0x278 - ObjPtr mKeyShiftMovingFront; // 0x284 - ObjPtr mKeyShiftStationaryFront; // 0x290 - ObjPtr mStationaryFront; // 0x29c - ObjPtr mAlwaysShowing; // 0x2a8 - ObjPtr mRotatorCam; // 0x2b4 - ObjPtr mTrack; // 0x2c0 - ObjPtr mTrackGems; // 0x2cc + ObjPtr mShowingWhenEnabled; // 0x218 + ObjPtr mStationaryBack; // 0x224 + ObjPtr mKeyShiftStationaryBack; // 0x230 + ObjPtr mStationaryBackAfterKeyShift; // 0x23c + ObjPtr mMovingBack; // 0x248 + ObjPtr mKeyShiftMovingBack; // 0x254 + ObjPtr mKeyShiftStationaryMiddle; // 0x260 + ObjPtr mStationaryMiddle; // 0x26c + ObjPtr mMovingFront; // 0x278 + ObjPtr mKeyShiftMovingFront; // 0x284 + ObjPtr mKeyShiftStationaryFront; // 0x290 + ObjPtr mStationaryFront; // 0x29c + ObjPtr mAlwaysShowing; // 0x2a8 + ObjPtr mRotatorCam; // 0x2b4 + ObjPtr mTrack; // 0x2c0 + ObjPtr mTrackGems; // 0x2cc Transform unk2d8; Transform unk308; Transform unk338; @@ -120,5 +119,3 @@ class TrackDir : public PanelDir { TrackTest *mTest; // 0x36c #endif }; - -#endif // TRACK_TRACKDIR_H \ No newline at end of file From 3c8f87988decbe5dcc805c7f9b4598e14159c4b5 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:07:07 -0700 Subject: [PATCH 07/12] more gemmgr stuff --- config/SZBE69/symbols.txt | 16 +-- src/band3/bandtrack/Gem.h | 1 + src/band3/bandtrack/GemManager.cpp | 210 ++++++++++++++++++++++++++++- src/band3/bandtrack/GemManager.h | 9 +- src/band3/game/Game.h | 6 +- src/band3/game/Player.h | 1 + src/band3/game/SongDB.h | 4 + src/band3/game/TrainerPanel.h | 5 +- src/system/utl/MemMgr.h | 6 +- src/system/utl/PoolAlloc.h | 3 +- 10 files changed, 245 insertions(+), 16 deletions(-) diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index 2fab0e7d2..d5bab2f08 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -7392,14 +7392,14 @@ MergedGet0x48__FPv = .text:0x800CF368; // type:function size:0x8 Min__Fii_i = .text:0x800CF370; // type:function size:0x10 __vc__Q211stlpmtx_std77vector>FUl = .text:0x800CF380; // type:function size:0x10 __vc__Q211stlpmtx_std109vector>FUl = .text:0x800CF390; // type:function size:0x10 -fn_800CF3A0 = .text:0x800CF3A0; // type:function size:0x8 +MergedGetB0x24__FPv = .text:0x800CF3A0; // type:function size:0x8 ClearArpeggios__10GemManagerFv = .text:0x800CF3A8; // type:function size:0xB0 fn_800CF458 = .text:0x800CF458; // type:function size:0x4 fn_800CF45C = .text:0x800CF45C; // type:function size:0x3C ResetArpeggios__10GemManagerFf = .text:0x800CF498; // type:function size:0x8C MsToTickInt__Ff = .text:0x800CF524; // type:function size:0x2C UpdateArpeggios__10GemManagerFfb = .text:0x800CF550; // type:function size:0x1C0 -fn_800CF710 = .text:0x800CF710; // type:function size:0x40 +TickToMs__Fi = .text:0x800CF710; // type:function size:0x40 ClearTrackMasks__10GemManagerFv = .text:0x800CF750; // type:function size:0xE4 SetupRealGuitarFretPos__10GemManagerFv = .text:0x800CF834; // type:function size:0x2E0 fn_800CFB14 = .text:0x800CFB14; // type:function size:0x58 @@ -13193,8 +13193,8 @@ fn_8017543C = .text:0x8017543C; // type:function size:0x60 fn_8017549C = .text:0x8017549C; // type:function size:0x60 fn_801754FC = .text:0x801754FC; // type:function size:0x78 fn_80175574 = .text:0x80175574; // type:function size:0x74 -fn_801755E8 = .text:0x801755E8; // type:function size:0xB0 -fn_80175698 = .text:0x80175698; // type:function size:0x24 +GetLoopTick__FiRi = .text:0x801755E8; // type:function size:0xB0 +GetLoopTick__Fi = .text:0x80175698; // type:function size:0x24 fn_801756BC = .text:0x801756BC; // type:function size:0x6C fn_80175728 = .text:0x80175728; // type:function size:0x114 fn_8017583C = .text:0x8017583C; // type:function size:0x5C @@ -78177,7 +78177,7 @@ lbl_808FB4C0 = .bss:0x808FB4C0; // type:object size:0x10 lbl_808FB4D0 = .bss:0x808FB4D0; // type:object size:0x8 lbl_808FB4D8 = .bss:0x808FB4D8; // type:object size:0x10 lbl_808FB4E8 = .bss:0x808FB4E8; // type:object size:0x190 -lbl_808FB678 = .bss:0x808FB678; // type:object size:0x4 data:4byte +TheTrainerPanel = .bss:0x808FB678; // type:object size:0x4 data:4byte lbl_808FB67C = .bss:0x808FB67C; // type:object size:0xC lbl_808FB688 = .bss:0x808FB688; // type:object size:0x8 lbl_808FB690 = .bss:0x808FB690; // type:object size:0x10 @@ -80487,7 +80487,7 @@ undo_handled_by = .bss:0x8097FF50; // type:object size:0x4 SymUnexpected = .bss:0x8097FF54; // type:object size:0x4 data:4byte unfocused_background_group = .bss:0x8097FF58; // type:object size:0x4 SymUnhandled = .bss:0x8097FF5C; // type:object size:0x14 data:4byte -SymUnison = .bss:0x8097FF70; // type:object size:0x4 data:4byte +unison = .bss:0x8097FF70; // type:object size:0x4 data:4byte SymUnisonEnd = .bss:0x8097FF74; // type:object size:0x8 SymUnisonPercent = .bss:0x8097FF7C; // type:object size:0x4 SymUnisonPhraseCount = .bss:0x8097FF80; // type:object size:0x4 data:4byte @@ -81174,7 +81174,7 @@ SymAreFillsForced = .bss:0x80980D5C; // type:object size:0x4 SymAreInvitesAllowed = .bss:0x80980D60; // type:object size:0x4 are_sfx_enabled = .bss:0x80980D64; // type:object size:0x4 SymAreaStrum = .bss:0x80980D68; // type:object size:0x4 -SymArpeggio = .bss:0x80980D6C; // type:object size:0x4 data:4byte +arpeggio = .bss:0x80980D6C; // type:object size:0x4 data:4byte SymArray = .bss:0x80980D70; // type:object size:0x4 data:4byte arrow_A = .bss:0x80980D74; // type:object size:0x4 data:4byte arrow_B = .bss:0x80980D78; // type:object size:0x4 data:4byte @@ -81580,7 +81580,7 @@ chin_num = .bss:0x809814E4; // type:object size:0x4 chin_width = .bss:0x809814E8; // type:object size:0xC SymChoosing = .bss:0x809814F4; // type:object size:0x4 data:4byte SymChord = .bss:0x809814F8; // type:object size:0x4 data:4byte -SymChordFret = .bss:0x809814FC; // type:object size:0x8 data:4byte +chord_fret = .bss:0x809814FC; // type:object size:0x8 data:4byte SymChordLabel = .bss:0x80981504; // type:object size:0x4 data:4byte SymChordLabelPosOffset = .bss:0x80981508; // type:object size:0x4 SymChordSourceMesh = .bss:0x8098150C; // type:object size:0xC diff --git a/src/band3/bandtrack/Gem.h b/src/band3/bandtrack/Gem.h index 10af3da0e..1e1c352f5 100644 --- a/src/band3/bandtrack/Gem.h +++ b/src/band3/bandtrack/Gem.h @@ -43,6 +43,7 @@ class Gem { bool CompareBounds() { return mStart < mEnd ? true : false; } bool Check66B0() const { return unk_0x66_7; } + const GameGem &GetGameGem() const { return mGameGem; } GemManager *mGemManager; // 0x0 const GameGem &mGameGem; // 0x4 diff --git a/src/band3/bandtrack/GemManager.cpp b/src/band3/bandtrack/GemManager.cpp index 44ad9e9b1..b67b480f7 100644 --- a/src/band3/bandtrack/GemManager.cpp +++ b/src/band3/bandtrack/GemManager.cpp @@ -2,14 +2,24 @@ #include "bandobj/ArpeggioShape.h" #include "bandtrack/NowBar.h" #include "bandtrack/Track.h" +#include "beatmatch/GameGem.h" #include "beatmatch/RGUtl.h" +#include "game/BandUser.h" +#include "game/Game.h" +#include "game/SongDB.h" #include "meta_band/BandSongMetadata.h" #include "meta_band/BandSongMgr.h" #include "meta_band/MetaPerformer.h" +#include "game/TrainerPanel.h" +#include "obj/Data.h" #include "obj/DataFunc.h" #include "os/Debug.h" #include "os/System.h" +#include "track/TrackWidget.h" +#include "utl/Symbols.h" +#include "utl/Symbols2.h" #include "utl/Symbols4.h" +#include "utl/TimeConversion.h" int sBeardThreshold = 480; @@ -73,14 +83,210 @@ void GemManager::InitRGTuning(BandUser *bandUser) { } } +void GemManager::DrawTrackMasks(int i1, int i2) { + for (int i = i2 != -1 ? i2 : i1; i <= i1; i += 0xf0) { + if (i > unk10c) { + int i174 = 0; + int i3 = i; + if (TheGame->InTrainer()) { + i3 = GetLoopTick(i, i174); + } + i3 = TheSongDB->GetCommonPhraseID(mTrackConfig.TrackNum(), i3); + Extent ext170(-1, -1); + if (i3 != -1 && TheSongDB->IsUnisonPhrase(i3)) { + if (TheSongDB->GetCommonPhraseExtent( + mTrackConfig.TrackNum(), i3, ext170 + )) { + Symbol nameSym = mGemData->FindArray(unison, false)->Sym(1); + TrackWidget *w = GetWidgetByName(nameSym); + Transform tf98; + tf98.Reset(); + tf98.v.y = mTrackDir->SecondsToY(TickToSeconds(ext170.unk0 + i174)); + w->AddInstance( + tf98, TickToSeconds(ext170.unk4) - TickToSeconds(ext170.unk0) + ); + unk10c = ext170.unk4 + i174; + } + } + } + } + + for (; unk118 < mArpeggioPhrases.size(); unk118++) { + ArpeggioPhrase *curPhrase = &mArpeggioPhrases[unk118]; + if (curPhrase->unk4 >= i2) + continue; + if (curPhrase->unk0 > i1) + break; + Gem &curGem = mGems[curPhrase->unk8]; + ArpeggioShapePool *pool = mTrackDir->GetArpeggioShapePool(); + ArpeggioShape *poolShape = pool->GetArpeggioShape(); + bool lefty = mTrackConfig.IsLefty(); + float f11 = mTrackDir->SecondsToY(TickToSeconds(curPhrase->unk0)); + if (curPhrase->unk10) { + poolShape->ShowChordShape(false); + } else { + Symbol nameSym = mGemData->FindArray(arpeggio, false)->Sym(1); + TrackWidget *w5 = GetWidgetByName(nameSym); + Transform tfc8; + tfc8.Reset(); + tfc8.v.y = f11; + int i10 = curPhrase->unk4; + if (TheTrainerPanel && TheGame->InTrainer()) { + i10 = Min( + curPhrase->unk4, + (curPhrase->unk0 + - (GetLoopTick(curPhrase->unk0) + - TheTrainerPanel->GetCurrentStartTick())) + + TheTrainerPanel->GetLoopTicks(TheTrainerPanel->GetCurrSection()) + ); + curPhrase->unk4 = i10; + } + w5->AddInstance(tfc8, TickToSeconds(i10) - TickToSeconds(curPhrase->unk0)); + RndMesh *mesh = mTrackDir->GetChordMesh(curGem.unk_0x48, lefty); + poolShape->SetChordShape(mesh); + poolShape->ShowChordShape(true); + String str168; + int i180 = -1; + curGem.GetChordFretLabelInfo(str168, i180); + Transform tff8; + mTrackDir->MakeSlotXfm(i180, tff8); + Symbol s184; + if (GetChordWidgetName(normal, chord_fret, s184)) { + TrackWidget *w10 = GetWidgetByName(s184); + if (w10) + w10->ApplyOffsets(tff8); + } + poolShape->SetFretNumber(str168, tff8.v); + } + poolShape->SetYPos(f11); + poolShape->SetChordLabel( + curGem.mChordLabel, mTrackDir->GetCurrentChordLabelPosOffset(), lefty + ); + poolShape->HookupToParentGroup(); + curPhrase->mShape = poolShape; + mActiveArpeggios.push_back(curPhrase); + } +} + void GemManager::ClearArpeggios() { ArpeggioShapePool *pool = mTrackDir->GetArpeggioShapePool(); while (!mActiveArpeggios.empty()) { - pool->ReleaseArpeggioShape(mActiveArpeggios.back()->unkc); + pool->ReleaseArpeggioShape(mActiveArpeggios.back()->mShape); mActiveArpeggios.pop_back(); } while (!mExpiredArpeggios.empty()) { - pool->ReleaseArpeggioShape(mExpiredArpeggios.back()->unkc); + pool->ReleaseArpeggioShape(mExpiredArpeggios.back()->mShape); mExpiredArpeggios.pop_back(); } +} + +void GemManager::ResetArpeggios(float f1) { + ClearArpeggios(); + unk118 = 0; + int tick = MsToTickInt(f1); + for (; unk118 < mArpeggioPhrases.size() && mArpeggioPhrases[unk118].unk4 < tick; + unk118++) + ; +} + +void GemManager::UpdateArpeggios(float f1, bool b2) { + float ms = mTrackDir->YToSeconds(unk12c) * 1000.0f + f1; + int i1 = MsToTickInt(ms); + while (!mActiveArpeggios.empty()) { + ArpeggioPhrase *currentArpeggio = mActiveArpeggios.front(); + MILO_ASSERT(currentArpeggio->mShape, 0x185); + if (currentArpeggio->unk4 < i1) { + currentArpeggio->mShape->FadeOutChordShape(); + mExpiredArpeggios.push_back(currentArpeggio); + mActiveArpeggios.erase(mActiveArpeggios.begin()); + } else { + if (!b2 || !currentArpeggio->unk10) { + if (currentArpeggio->unk0 > i1) { + ms = TickToMs(currentArpeggio->unk0); + } + currentArpeggio->mShape->SetYPos(mTrackDir->SecondsToY(ms / 1000.0f)); + } + break; + } + } + ms = mTrackDir->SecondsToY((f1 / 1000.0f + mTrackDir->BottomSeconds()) - 0.5f); + while (!mExpiredArpeggios.empty() && mExpiredArpeggios.front()->mShape->GetYPos() < ms + ) { + MILO_ASSERT(mExpiredArpeggios.front()->mShape, 0x1A8); + mTrackDir->GetArpeggioShapePool()->ReleaseArpeggioShape( + mExpiredArpeggios.front()->mShape + ); + mExpiredArpeggios.erase(mExpiredArpeggios.begin()); + } +} + +void GemManager::ClearTrackMasks() { + if (mGemData) { + DataArray *arpArr = mGemData->FindArray(arpeggio, false); + if (arpArr) { + Symbol name = arpArr->Sym(1); + GetWidgetByName(name)->Clear(); + } + DataArray *unisonArr = mGemData->FindArray(unison, false); + if (unisonArr) { + Symbol name = unisonArr->Sym(1); + GetWidgetByName(name)->Clear(); + } + unk10c = 0; + } +} + +void GemManager::SetupRealGuitarFretPos() { + const BandUser *bandUser = mTrackConfig.GetBandUser(); + bool isRG = bandUser->GetTrack()->GetType() == real_guitar; + bool isRB = bandUser->GetTrack()->GetType() == real_bass; + if (isRG || isRB) { + std::vector gameGems; + int i2 = -1; + int i38 = 0; + int i3c = -1; + for (int i = 0; i < mGems.size(); i++) { + const GameGem &curGameGem = mGems[i].GetGameGem(); + if (i3c != -1 && curGameGem.GetTick() > i3c) { + ProcessRealGuitarRun(gameGems, i38); + i2 = curGameGem.GetLowestString(); + i3c = -1; + if (!curGameGem.IsRealGuitarChord()) { + gameGems.push_back(curGameGem); + } + } else if (curGameGem.IsRealGuitarChord()) { + ProcessRealGuitarRun(gameGems, i38); + i2 = -1; + i38++; + } else if (curGameGem.IsMuted()) { + ProcessRealGuitarRun(gameGems, i38); + i2 = curGameGem.GetLowestString(); + i38++; + } else if (i2 != (int)curGameGem.GetLowestString()) { + ProcessRealGuitarRun(gameGems, i38); + i2 = curGameGem.GetLowestString(); + gameGems.push_back(curGameGem); + } else { + if (!gameGems.empty()) { + GameGem &last = gameGems.back(); + if (curGameGem.GetTick() - last.GetTick() > unk134) { + ProcessRealGuitarRun(gameGems, i38); + i2 = curGameGem.GetLowestString(); + gameGems.push_back(curGameGem); + continue; + } + } + if (i3c == -1) { + if (TrillStartsAt(mTrackConfig.TrackNum(), curGameGem, i3c)) { + ProcessRealGuitarRun(gameGems, i38); + i2 = curGameGem.GetLowestString(); + gameGems.push_back(curGameGem); + continue; + } + } + gameGems.push_back(curGameGem); + } + } + ProcessRealGuitarRun(gameGems, i38); + } } \ No newline at end of file diff --git a/src/band3/bandtrack/GemManager.h b/src/band3/bandtrack/GemManager.h index d46ada5b3..56bb75c5f 100644 --- a/src/band3/bandtrack/GemManager.h +++ b/src/band3/bandtrack/GemManager.h @@ -48,7 +48,7 @@ class GemManager { int unk0; int unk4; int unk8; - ArpeggioShape *unkc; + ArpeggioShape *mShape; // 0xc bool unk10; }; GemManager(const TrackConfig &, TrackDir *); @@ -89,6 +89,13 @@ class GemManager { int GetSlotIntData(int, Symbol); void ClearArpeggios(); void InitRGTuning(BandUser *); + void DrawTrackMasks(int, int); + void ResetArpeggios(float); + void UpdateArpeggios(float, bool); + void ClearTrackMasks(); + void SetupRealGuitarFretPos(); + void ProcessRealGuitarRun(std::vector &, int &); + bool TrillStartsAt(int, const GameGem &, int &) const; TrackDir *mTrackDir; // 0x0 const TrackConfig &mTrackConfig; // 0x4 diff --git a/src/band3/game/Game.h b/src/band3/game/Game.h index 063062943..92fddc8a7 100644 --- a/src/band3/game/Game.h +++ b/src/band3/game/Game.h @@ -27,8 +27,12 @@ class Game : public Hmx::Object { void OnRemoteTrackerEndStreak(Player *, int, int); void OnPlayerQuarantined(Player *); Band *GetBand(); + bool InTrainer() const { return unk24; } - u8 pad[0x4C]; + int unk1c; + int unk20; + bool unk24; + u8 pad[0x40]; bool mIsPaused; // 0x68 iunno u8 pad2[115]; float unk_0xdc; diff --git a/src/band3/game/Player.h b/src/band3/game/Player.h index 10679e9f5..b7cb5bfc1 100644 --- a/src/band3/game/Player.h +++ b/src/band3/game/Player.h @@ -34,6 +34,7 @@ class PersistentPlayerData { class Extent { public: + Extent(int x, int y) : unk0(x), unk4(y) {} int unk0; int unk4; }; diff --git a/src/band3/game/SongDB.h b/src/band3/game/SongDB.h index 3018fc801..7ce1e36be 100644 --- a/src/band3/game/SongDB.h +++ b/src/band3/game/SongDB.h @@ -4,6 +4,7 @@ #include "game/MultiplayerAnalyzer.h" #include "game/Defines.h" #include "midi/DataEvent.h" +#include "game/Player.h" #include class SongDB : public SongParserSink { @@ -60,6 +61,9 @@ class SongDB : public SongParserSink { int GetBeatsPerMeasure(int) const; int NumCommonPhrases() const; int GetCommonPhraseTracks(int) const; + int GetCommonPhraseID(int, int) const; + bool IsUnisonPhrase(int) const; + bool GetCommonPhraseExtent(int, int, Extent &); SongData *GetSongData() { return mSongData; } diff --git a/src/band3/game/TrainerPanel.h b/src/band3/game/TrainerPanel.h index 31b36a3e8..a966b27cd 100644 --- a/src/band3/game/TrainerPanel.h +++ b/src/band3/game/TrainerPanel.h @@ -96,4 +96,7 @@ class TrainerPanel : public UIPanel { std::vector unk4c; // 0x4c }; -extern TrainerPanel *TheTrainerPanel; \ No newline at end of file +extern TrainerPanel *TheTrainerPanel; + +int GetLoopTick(int, int &); +int GetLoopTick(int); \ No newline at end of file diff --git a/src/system/utl/MemMgr.h b/src/system/utl/MemMgr.h index 1002dac5d..1d6c866b8 100644 --- a/src/system/utl/MemMgr.h +++ b/src/system/utl/MemMgr.h @@ -57,10 +57,12 @@ class MemTempHeap { }; #define NEW_OVERLOAD \ - void *operator new(size_t t) { return _MemAlloc(t, 0); } + void *operator new(size_t t) { return _MemAlloc(t, 0); } \ + void *operator new(size_t, void *place) { return place; } #define NEW_ARRAY_OVERLOAD \ - void *operator new[](size_t t) { return _MemAlloc(t, 0); } + void *operator new[](size_t t) { return _MemAlloc(t, 0); } \ + void *operator new[](size_t, void *place) { return place; } #define DELETE_OVERLOAD \ void operator delete(void *v) { _MemFree(v); } diff --git a/src/system/utl/PoolAlloc.h b/src/system/utl/PoolAlloc.h index 0089df34d..c8a2310f1 100644 --- a/src/system/utl/PoolAlloc.h +++ b/src/system/utl/PoolAlloc.h @@ -46,7 +46,8 @@ void *_PoolAlloc(int, int, PoolType); void _PoolFree(int, PoolType, void *); #define NEW_POOL_OVERLOAD(obj) \ - void *operator new(size_t s) { return _PoolAlloc(s, sizeof(obj), FastPool); } + void *operator new(size_t s) { return _PoolAlloc(s, sizeof(obj), FastPool); } \ + void *operator new(size_t, void *place) { return place; } #define DELETE_POOL_OVERLOAD(obj) \ void operator delete(void *v) { _PoolFree(sizeof(obj), FastPool, v); } From 5fd2a94a8255aa9aab4f857306aca593690533ab Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Tue, 4 Feb 2025 17:09:21 -0700 Subject: [PATCH 08/12] more gemmgr work --- config/SZBE69/symbols.txt | 84 ++++----- src/band3/bandtrack/Gem.h | 6 +- src/band3/bandtrack/GemManager.cpp | 292 ++++++++++++++++++++++++++++- src/band3/bandtrack/GemManager.h | 27 ++- src/band3/bandtrack/GemSmasher.h | 1 + src/band3/bandtrack/NowBar.h | 1 + src/system/beatmatch/GameGem.h | 1 + 7 files changed, 364 insertions(+), 48 deletions(-) diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index d5bab2f08..82b445909 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -7499,11 +7499,11 @@ fn_800D2360 = .text:0x800D2360; // type:function size:0x58 fn_800D23B8 = .text:0x800D23B8; // type:function size:0x28 fn_800D23E0 = .text:0x800D23E0; // type:function size:0x68 fn_800D2448 = .text:0x800D2448; // type:function size:0x4 -fn_800D244C = .text:0x800D244C; // type:function size:0x80 +EndRepeatedChordPhrase__10GemManagerFRiRiRi = .text:0x800D244C; // type:function size:0x80 RollStartsAt__10GemManagerCFiRC7GameGemRiRUi = .text:0x800D24CC; // type:function size:0xDC TrillStartsAt__10GemManagerCFiRC7GameGemRi = .text:0x800D25A8; // type:function size:0xBC SetGemsEnabled__10GemManagerFf = .text:0x800D2664; // type:function size:0x8 -UpdateLeftyFlip__10GemManagerFv = .text:0x800D266C; // type:function size:0x5F8 +UpdateLeftyFlip__10GemManagerFb = .text:0x800D266C; // type:function size:0x5F8 fn_800D2C64 = .text:0x800D2C64; // type:function size:0x2C MergedGetF0xAC__FPv = .text:0x800D2C90; // type:function size:0x8 Find<11TrackWidget>__9ObjectDirFPCcb_P11TrackWidget = .text:0x800D2C98; // type:function size:0xA0 @@ -7511,12 +7511,12 @@ fn_800D2D38 = .text:0x800D2D38; // type:function size:0x40 __vc__Q211stlpmtx_std45vector>CFUl = .text:0x800D2D78; // type:function size:0xC fn_800D2D84 = .text:0x800D2D84; // type:function size:0x8 fn_800D2D8C = .text:0x800D2D8C; // type:function size:0x8 -fn_800D2D94 = .text:0x800D2D94; // type:function size:0xE4 +UpdateSlotPositions__10GemManagerFv = .text:0x800D2D94; // type:function size:0xE4 __as__9TransformFRC9Transform = .text:0x800D2E78; // type:function size:0x44 WorldXfm__16RndTransformableFv = .text:0x800D2EBC; // type:function size:0x1C Find<16RndTransformable>__9ObjectDirFPCcb_P16RndTransformable = .text:0x800D2ED8; // type:function size:0xA0 -fn_800D2F78 = .text:0x800D2F78; // type:function size:0x8 -fn_800D2F80 = .text:0x800D2F80; // type:function size:0x8 +GetNumGems__10GemManagerCFv = .text:0x800D2F78; // type:function size:0x8 +GetGem__10GemManagerCFi = .text:0x800D2F80; // type:function size:0x8 Poll__10GemManagerFfRC11PlayerState = .text:0x800D2F88; // type:function size:0xDC fn_800D3064 = .text:0x800D3064; // type:function size:0x14 fn_800D3078 = .text:0x800D3078; // type:function size:0x20 @@ -7524,37 +7524,37 @@ PollHelper__10GemManagerFfRC11PlayerState = .text:0x800D3098; // type:function s max__11stlpmtx_stdFRCfRCf_RCf = .text:0x800D3260; // type:function size:0x18 fn_800D3278 = .text:0x800D3278; // type:function size:0x18 Max__Fii_i = .text:0x800D3290; // type:function size:0x10 -fn_800D32A0 = .text:0x800D32A0; // type:function size:0xD8 +PollVisibleGems__10GemManagerFff = .text:0x800D32A0; // type:function size:0xD8 AdvanceBegin__10GemManagerFv = .text:0x800D3378; // type:function size:0x44 AdvanceEnd__10GemManagerFv = .text:0x800D33BC; // type:function size:0x1C8 MergedGet0x2C__FPv = .text:0x800D3584; // type:function size:0x8 Find<8RndGroup>__9ObjectDirFPCcb_P8RndGroup = .text:0x800D358C; // type:function size:0xA0 -fn_800D362C = .text:0x800D362C; // type:function size:0x318 +AddChordBracket__10GemManagerF6SymbolUif = .text:0x800D362C; // type:function size:0x318 MaxEq__FRiRCi_b = .text:0x800D3944; // type:function size:0x24 MinEq__FRiRCi_b = .text:0x800D3968; // type:function size:0x24 MergedGetF0xDC__FPv = .text:0x800D398C; // type:function size:0x8 -fn_800D3994 = .text:0x800D3994; // type:function size:0x74 -fn_800D3A08 = .text:0x800D3A08; // type:function size:0x15C +RememberChordWidget__10GemManagerFP11TrackWidget = .text:0x800D3994; // type:function size:0x74 +CheckRemoveChordBracket__10GemManagerFi = .text:0x800D3A08; // type:function size:0x15C fn_800D3B64 = .text:0x800D3B64; // type:function size:0x40 -fn_800D3BA4 = .text:0x800D3BA4; // type:function size:0x90 -fn_800D3C34 = .text:0x800D3C34; // type:function size:0x154 +AddWidgetInstanceImpl__10GemManagerFP11TrackWidgetif = .text:0x800D3BA4; // type:function size:0x90 +PollHitGems__10GemManagerFf = .text:0x800D3C34; // type:function size:0x154 fn_800D3D88 = .text:0x800D3D88; // type:function size:0x4 fn_800D3D8C = .text:0x800D3D8C; // type:function size:0x4 fn_800D3D90 = .text:0x800D3D90; // type:function size:0x8 MergedGetF0x24__FPv = .text:0x800D3D98; // type:function size:0x8 -fn_800D3DA0 = .text:0x800D3DA0; // type:function size:0xC +Released__3GemCFv = .text:0x800D3DA0; // type:function size:0xC fn_800D3DAC = .text:0x800D3DAC; // type:function size:0x4 fn_800D3DB0 = .text:0x800D3DB0; // type:function size:0x8 MergedGetF0x3C__FPv = .text:0x800D3DB8; // type:function size:0x8 -fn_800D3DC0 = .text:0x800D3DC0; // type:function size:0x64 -fn_800D3E24 = .text:0x800D3E24; // type:function size:0xD0 -fn_800D3EF4 = .text:0x800D3EF4; // type:function size:0x78 +ReleaseSlot__10GemManagerFii = .text:0x800D3DC0; // type:function size:0x64 +ReleaseHitGems__10GemManagerFv = .text:0x800D3E24; // type:function size:0xD0 +PruneHitGems__10GemManagerFf = .text:0x800D3EF4; // type:function size:0x78 fn_800D3F6C = .text:0x800D3F6C; // type:function size:0x4 fn_800D3F70 = .text:0x800D3F70; // type:function size:0x44 fn_800D3FB4 = .text:0x800D3FB4; // type:function size:0x6C fn_800D4020 = .text:0x800D4020; // type:function size:0x2C fn_800D404C = .text:0x800D404C; // type:function size:0x30 -fn_800D407C = .text:0x800D407C; // type:function size:0x124 +Hit__10GemManagerFfii = .text:0x800D407C; // type:function size:0x124 fn_800D41A0 = .text:0x800D41A0; // type:function size:0x4 fn_800D41A4 = .text:0x800D41A4; // type:function size:0x54 fn_800D41F8 = .text:0x800D41F8; // type:function size:0x64 @@ -7562,21 +7562,21 @@ fn_800D425C = .text:0x800D425C; // type:function size:0x50 fn_800D42AC = .text:0x800D42AC; // type:function size:0x10 fn_800D42BC = .text:0x800D42BC; // type:function size:0x1C fn_800D42D8 = .text:0x800D42D8; // type:function size:0x10 -fn_800D42E8 = .text:0x800D42E8; // type:function size:0x94 -fn_800D437C = .text:0x800D437C; // type:function size:0x28 -fn_800D43A4 = .text:0x800D43A4; // type:function size:0x4 -fn_800D43A8 = .text:0x800D43A8; // type:function size:0xD0 -fn_800D4478 = .text:0x800D4478; // type:function size:0x8 -fn_800D4480 = .text:0x800D4480; // type:function size:0xD8 -fn_800D4558 = .text:0x800D4558; // type:function size:0x8 -fn_800D4560 = .text:0x800D4560; // type:function size:0x8 -fn_800D4568 = .text:0x800D4568; // type:function size:0x44 -fn_800D45AC = .text:0x800D45AC; // type:function size:0x8 +Miss__10GemManagerFfii = .text:0x800D42E8; // type:function size:0x94 +Pass__10GemManagerFi = .text:0x800D437C; // type:function size:0x28 +Ignore__10GemManagerFi = .text:0x800D43A4; // type:function size:0x4 +PartialHit__10GemManagerFfiUii = .text:0x800D43A8; // type:function size:0xD0 +FillHit__10GemManagerFii = .text:0x800D4478; // type:function size:0x8 +Released__10GemManagerFfi = .text:0x800D4480; // type:function size:0xD8 +SetSmasherGlowing__10GemManagerFib = .text:0x800D4558; // type:function size:0x8 +PopSmasher__10GemManagerFi = .text:0x800D4560; // type:function size:0x8 +GetSmasherObj__10GemManagerFi = .text:0x800D4568; // type:function size:0x44 +ResetSmashers__10GemManagerFb = .text:0x800D45AC; // type:function size:0x8 Jump__10GemManagerFf = .text:0x800D45B4; // type:function size:0x174 Clamp__Fiii_i = .text:0x800D4728; // type:function size:0x24 -fn_800D474C = .text:0x800D474C; // type:function size:0x8 -fn_800D4754 = .text:0x800D4754; // type:function size:0x8 -fn_800D475C = .text:0x800D475C; // type:function size:0x12C +SetBonusGems__10GemManagerFbRC11PlayerState = .text:0x800D474C; // type:function size:0x8 +SetInCoda__10GemManagerFb = .text:0x800D4754; // type:function size:0x8 +OnMissPhrase__10GemManagerFi = .text:0x800D475C; // type:function size:0x12C fn_800D4888 = .text:0x800D4888; // type:function size:0x4 fn_800D488C = .text:0x800D488C; // type:function size:0x88 fn_800D4914 = .text:0x800D4914; // type:function size:0x2C @@ -7598,7 +7598,7 @@ fn_800D4DC4 = .text:0x800D4DC4; // type:function size:0x50 SlotEnabled__10GemManagerCFi = .text:0x800D4E14; // type:function size:0x7C fn_800D4E90 = .text:0x800D4E90; // type:function size:0x3C fn_800D4ECC = .text:0x800D4ECC; // type:function size:0x8C -fn_800D4F58 = .text:0x800D4F58; // type:function size:0x238 +GetTypeForGem__10GemManagerFi = .text:0x800D4F58; // type:function size:0x238 fn_800D5190 = .text:0x800D5190; // type:function size:0xC fn_800D519C = .text:0x800D519C; // type:function size:0xC fn_800D51A8 = .text:0x800D51A8; // type:function size:0x40 @@ -7612,7 +7612,7 @@ fn_800D5454 = .text:0x800D5454; // type:function size:0xC fn_800D5460 = .text:0x800D5460; // type:function size:0x70 fn_800D54D0 = .text:0x800D54D0; // type:function size:0x70 fn_800D5540 = .text:0x800D5540; // type:function size:0x44 -fn_800D5584 = .text:0x800D5584; // type:function size:0x110 +IsSpotlightGem__10GemManagerFiRb = .text:0x800D5584; // type:function size:0x110 MergedGet0x1DC__FPv = .text:0x800D5694; // type:function size:0x8 fn_800D569C = .text:0x800D569C; // type:function size:0x8 fn_800D56A4 = .text:0x800D56A4; // type:function size:0xC0 @@ -8026,16 +8026,16 @@ fn_800E02AC = .text:0x800E02AC; // type:function size:0x60 fn_800E030C = .text:0x800E030C; // type:function size:0x5C fn_800E0368 = .text:0x800E0368; // type:function size:0x5C fn_800E03C4 = .text:0x800E03C4; // type:function size:0xC -fn_800E03D0 = .text:0x800E03D0; // type:function size:0x4 -fn_800E03D4 = .text:0x800E03D4; // type:function size:0x68 -fn_800E043C = .text:0x800E043C; // type:function size:0x2AC -fn_800E06E8 = .text:0x800E06E8; // type:function size:0xE4 -fn_800E07CC = .text:0x800E07CC; // type:function size:0x150 -fn_800E091C = .text:0x800E091C; // type:function size:0x34 -fn_800E0950 = .text:0x800E0950; // type:function size:0x90 -fn_800E09E0 = .text:0x800E09E0; // type:function size:0xC0 -fn_800E0AA0 = .text:0x800E0AA0; // type:function size:0x98 -fn_800E0B38 = .text:0x800E0B38; // type:function size:0x58 +Poll__6NowBarFfb = .text:0x800E03D0; // type:function size:0x4 +Reset__6NowBarFb = .text:0x800E03D4; // type:function size:0x68 +Hit__6NowBarFfibib = .text:0x800E043C; // type:function size:0x2AC +Miss__6NowBarFfi = .text:0x800E06E8; // type:function size:0xE4 +PartialHit__6NowBarFiUibi = .text:0x800E07CC; // type:function size:0x150 +FillHit__6NowBarFii = .text:0x800E091C; // type:function size:0x34 +PopSmasher__6NowBarFi = .text:0x800E0950; // type:function size:0x90 +SetSmasherGlowing__6NowBarFib = .text:0x800E09E0; // type:function size:0xC0 +StopBurning__6NowBarFUi = .text:0x800E0AA0; // type:function size:0x98 +FindSmasher__6NowBarCFi = .text:0x800E0B38; // type:function size:0x58 fn_800E0B90 = .text:0x800E0B90; // type:function size:0xB4 __ct__4TailFR14GemRepTemplate = .text:0x800E0C44; // type:function size:0x140 __dt__16ATanInterpolatorFv = .text:0x800E0D84; // type:function size:0x68 @@ -10578,7 +10578,7 @@ SetPlayed__7GameGemFb = .text:0x8012D150; // type:function size:0x10 fn_8012D160 = .text:0x8012D160; // type:function size:0x88 fn_8012D1E8 = .text:0x8012D1E8; // type:function size:0x198 fn_8012D380 = .text:0x8012D380; // type:function size:0x8 -fn_8012D388 = .text:0x8012D388; // type:function size:0xDC +ShouldLoop__15GemTrainerPanelCFi = .text:0x8012D388; // type:function size:0xDC ClearGems__15GemTrainerPanelFv = .text:0x8012D464; // type:function size:0x74 SetSpeedRatio__15GemTrainerPanelFf = .text:0x8012D4D8; // type:function size:0x80 fn_8012D558 = .text:0x8012D558; // type:function size:0x94 diff --git a/src/band3/bandtrack/Gem.h b/src/band3/bandtrack/Gem.h index 1e1c352f5..646c749dd 100644 --- a/src/band3/bandtrack/Gem.h +++ b/src/band3/bandtrack/Gem.h @@ -41,9 +41,11 @@ class Gem { void SetFretPos(int); void GetChordFretLabelInfo(String &, int &) const; - bool CompareBounds() { return mStart < mEnd ? true : false; } + bool CompareBounds() { return mEnd > mStart ? true : false; } bool Check66B0() const { return unk_0x66_7; } const GameGem &GetGameGem() const { return mGameGem; } + unsigned int Slots() const { return mSlots; } + bool Released() const { return mReleased; } GemManager *mGemManager; // 0x0 const GameGem &mGameGem; // 0x4 @@ -51,7 +53,7 @@ class Gem { float mStart; // 0x20 float mEnd; // 0x24 float mTailStart; // 0x28 - int mSlots; // 0x2c + unsigned int mSlots; // 0x2c std::vector mTails; // 0x30 int mBeardTick; // 0x38 float unk_0x3C; // 0x3c diff --git a/src/band3/bandtrack/GemManager.cpp b/src/band3/bandtrack/GemManager.cpp index b67b480f7..e25be8cda 100644 --- a/src/band3/bandtrack/GemManager.cpp +++ b/src/band3/bandtrack/GemManager.cpp @@ -15,6 +15,8 @@ #include "obj/DataFunc.h" #include "os/Debug.h" #include "os/System.h" +#include "rndobj/Group.h" +#include "rndobj/Trans.h" #include "track/TrackWidget.h" #include "utl/Symbols.h" #include "utl/Symbols2.h" @@ -289,4 +291,292 @@ void GemManager::SetupRealGuitarFretPos() { } ProcessRealGuitarRun(gameGems, i38); } -} \ No newline at end of file +} + +void GemManager::ProcessRealGuitarRun(std::vector &gems, int &iref) { + if (!gems.empty()) { + if (gems.size() == 1) { + mGems[iref].SetFretPos(2); + } else { + int i3 = mGems[iref].GetGameGem().GetLowestString(); + unsigned int u10 = 0; + for (int i = 0; i < gems.size(); i++) { + const GameGem &curGem = mGems[iref + i].GetGameGem(); + u10 |= 1 << curGem.GetFret(i3); + } + int i2 = -1; + int i9 = 0; + int i5c = 100000; + int i60 = -1; + for (int i = 0; i < 0x16; i++) { + if (u10 & 1 << i) { + i5c = std::min(i5c, i); + i60 = std::max(i60, i); + i9++; + } + } + if (i9 > 5) { + i2 = mGems[iref].GetGameGem().GetFret(i3); + if (i60 - i2 < 5) { + i9 = 4 - (i60 - i2); + } else { + i9 = 2; + if (i2 - i5c < 5) { + i9 = i2 - i5c; + } + mGems[iref].SetFretPos(i9); + for (int i = 1; i < gems.size(); i++) { + int i1 = mGems[iref + i].GetGameGem().GetFret(i3); + if (i2 < i1) { + i9 = (i9 + 1) % 5; + i2 = i1; + } else if (i1 < i2) { + i9--; + i2 = i1; + if (i9 < 0) { + i9 = 4; + } + } + mGems[iref + i].SetFretPos(i9); + } + } + } else { + if (i5c == i2) { + for (int i = 0; i < gems.size(); i++) { + mGems[iref + i].SetFretPos(2); + } + } else { + i2 -= i5c; + for (int i = 0; i < gems.size(); i++) { + float gemfloat = mGems[iref + i].GetGameGem().GetFret(i3) - i5c; + int i68 = (5.0f / i2) * gemfloat; + i68 = std::min(i68, 4); + mGems[iref + i].SetFretPos(i68); + } + } + } + } + iref += gems.size(); + gems.clear(); + } +} + +void GemManager::SetupRealGuitarImportantStrings() { + const BandUser *bandUser = mTrackConfig.GetBandUser(); + bool isRG = bandUser->GetTrack()->GetType() == real_guitar; + bool isRB = bandUser->GetTrack()->GetType() == real_bass; + if (isRG || isRB) { + for (int i = 1; i < mGems.size(); i++) { + } + } +} + +void GemManager::EndRepeatedChordPhrase( + int &repeatedChordStartTick, int &repeatedChordEndTick, int &i3 +) { + if (i3 != -1) { + MILO_ASSERT(repeatedChordStartTick != -1, 0x56D); + MILO_ASSERT(repeatedChordEndTick != -1, 0x56E); + ArpeggioPhrase phrase(repeatedChordStartTick, repeatedChordEndTick, i3); + phrase.unk10 = true; + mArpeggioPhrases.push_back(phrase); + i3 = -1; + repeatedChordStartTick = -1; + repeatedChordEndTick = -1; + } +} + +bool GemManager::RollStartsAt(int i1, const GameGem &gem, int &iref, unsigned int &uiref) + const { + int tick = GetLoopTick(gem.GetTick()); + bool ret; + if (gem.IsRealGuitar()) { + ret = TheSongDB->GetSongData()->RGRollStartsAt(i1, tick, iref); + } else { + ret = TheSongDB->GetSongData()->RollStartsAt(i1, tick, iref); + } + if (ret) { + uiref = TheSongDB->GetSongData()->GetRollingSlotsAtTick(i1, tick); + } + iref += gem.GetTick() - tick; + return ret; +} + +bool GemManager::TrillStartsAt(int i1, const GameGem &gem, int &iref) const { + int tick = GetLoopTick(gem.GetTick()); + bool ret; + if (gem.IsRealGuitar()) { + ret = TheSongDB->GetSongData()->RGTrillStartsAt(i1, tick, iref); + } else { + ret = TheSongDB->GetSongData()->TrillStartsAt(i1, tick, iref); + } + if (ret) { + iref += gem.GetTick() - tick; + } + return ret; +} + +void GemManager::SetGemsEnabled(float f) { + unk14 = f; + UpdateGemStates(); +} + +void GemManager::UpdateSlotPositions() { + Transform tf48; + for (int i = 0; i < GetMaxSlots(); i++) { + RndDir *dir = mNowBar->FindSmasher(i)->Dir(); + RndTransformable *smashTrans = + dir->Find("smasher.trans", false); + if (smashTrans) { + tf48 = smashTrans->WorldXfm(); + } else + tf48 = dir->WorldXfm(); + mTrackDir->SetSlotXfm(i, tf48); + } + for (int i = mBegin; i < mEnd; i++) { + mGems[i].UpdateTailPositions(); + } +} + +int GemManager::GetNumGems() const { return mGems.size(); } +const Gem &GemManager::GetGem(int idx) const { return mGems[idx]; } + +void GemManager::PollVisibleGems(float f1, float f2) { + float div = f1 / 1000.0f; + float top = mTrackDir->TopSeconds() + div; + float bot = mTrackDir->BottomSeconds() + div; + for (int i = mBegin; i < mEnd; i++) { + mGems[i].Poll(f1, f2, unkc4, top, bot); + } +} + +void GemManager::AdvanceBegin() { + mGems[mBegin].RemoveRep(); + mBegin++; +} + +void GemManager::AdvanceEnd() { + Gem &lastGem = mGems[mEnd]; + Symbol gemType = GetTypeForGem(mEnd); + if (!unkf8) { + if (mTrackConfig.IsKeyboardTrack()) { + unkf8 = mTrackDir->Find("key_shift_tails.grp", true); + } else + unkf8 = mTrackDir->Find("tails.grp", true); + } + unsigned int slots = lastGem.Slots(); + lastGem.AddRep(mTemplate, unkf8, gemType, mTrackConfig, true); + mEnd++; + if (mTrackConfig.IsKeyboardTrack()) { + int tick = lastGem.GetGameGem().GetTick(); + for (; mEnd < mGems.size() && tick == mGems[mEnd].GetGameGem().GetTick(); + mEnd++) { + Symbol curGemType = GetTypeForGem(mEnd); + Gem &curGem = mGems[mEnd]; + slots |= curGem.Slots(); + curGem.AddRep(mTemplate, unkf8, curGemType, mTrackConfig, true); + } + AddChordBracket(gemType, slots, lastGem.GetGameGem().GetMs()); + } +} + +void GemManager::RememberChordWidget(TrackWidget *w) { + for (int i = 0; i < unkd8.size(); i++) { + if (unkd8[i] == w) + return; + } + unkd8.push_back(w); +} + +void GemManager::AddWidgetInstanceImpl(TrackWidget *w, int ui, float f) { + Transform tf58; + mTrackDir->MakeWidgetXfm(ui, f / 1000.0f, tf58); + w->AddInstance(tf58, 0); +} + +void GemManager::ReleaseSlot(int gem_id, int slot) { + MILO_ASSERT(gem_id < mGems.size(), 0x7C4); + mGems[gem_id].ReleaseSlot(slot); + mNowBar->StopBurning(1 << slot); +} + +void GemManager::ReleaseHitGems() { + FOREACH (it, mHitGems) { + Gem &gem = mGems[it->unk4]; + if (gem.CompareBounds() && !gem.Released()) { + gem.KillDuration(); + gem.Release(); + } + mNowBar->StopBurning(gem.Slots()); + } +} + +void GemManager::PruneHitGems(float f1) { + while (!mHitGems.empty()) { + if (mGems[mHitGems.front().unk4].OnScreen(f1)) + break; + else + mHitGems.pop_front(); + } +} + +void GemManager::Hit(float f1, int i2, int i3) { + if (!mTrackConfig.AllowsOverlappingGems()) { + ReleaseHitGems(); + } + mGems[i2].Hit(); + mHitGems.push_back(HitGem(f1, i2, mGems[i2].Slots())); + if (mTrackConfig.IsKeyboardTrack()) { + CheckRemoveChordBracket(i2); + } + bool b28 = false; + if (IsSpotlightGem(i2, b28)) { + i3 |= 2; + if (!IsSpotlightGem(i2 + 1, b28)) { + i3 |= 4; + } + } + mNowBar->Hit(f1, i2, mInCoda, i3, mGems[i2].UseRGChordStyle()); +} + +void GemManager::Miss(float f1, int, int slot) { + if (slot != -1) { + MILO_ASSERT(slot >= 0 && slot < GetMaxSlots(), 0x81A); + if (!mTrackConfig.AllowsOverlappingGems() && mNowBar->unk_0x8 != -1) { + Released(f1, mNowBar->unk_0x8); + } + mNowBar->Miss(f1, slot); + } +} + +void GemManager::Pass(int i1) { mGems[i1].Miss(); } +void GemManager::Ignore(int) {} + +void GemManager::PartialHit(float f1, int i2, unsigned int ui, int i4) { + mGems[i2].PartialHit(ui); + bool b28 = false; + if (IsSpotlightGem(i2, b28)) { + i4 |= 2; + if (!IsSpotlightGem(i2 + 1, b28)) { + i4 |= 4; + } + } + mNowBar->PartialHit(i2, ui, mInCoda, i4); + mHitGems.push_back(HitGem(f1, i2, ui)); +} + +void GemManager::FillHit(int i1, int i2) { mNowBar->FillHit(i1, i2); } + +void GemManager::Released(float f1, int i2) { + Gem &gem = mGems[i2]; + if (gem.CompareBounds()) { + if (!gem.GetGameGem().LeftHandSlide() && !gem.Released()) { + gem.Release(); + } + } +} + +#pragma push +#pragma force_active on +inline int GemManager::GetMaxSlots() const { return mTrackConfig.GetMaxSlots(); } +#pragma pop diff --git a/src/band3/bandtrack/GemManager.h b/src/band3/bandtrack/GemManager.h index 56bb75c5f..907d5bc56 100644 --- a/src/band3/bandtrack/GemManager.h +++ b/src/band3/bandtrack/GemManager.h @@ -3,6 +3,7 @@ #include "bandobj/ArpeggioShape.h" #include "bandtrack/GemRepTemplate.h" #include "bandtrack/NowBar.h" +#include "beatmatch/InternalSongParserSink.h" #include "game/Player.h" #include "obj/Data.h" #include "obj/Object.h" @@ -39,12 +40,15 @@ class GemManager { public: class HitGem { public: - int unk0; + HitGem(float f, int x, int y) : unk0(f), unk4(x), unk8(y) {} + float unk0; int unk4; - int unk8; + unsigned int unk8; }; class ArpeggioPhrase { public: + ArpeggioPhrase(int x, int y, int z) + : unk0(x), unk4(y), unk8(z), mShape(0), unk10(0) {} int unk0; int unk4; int unk8; @@ -96,6 +100,23 @@ class GemManager { void SetupRealGuitarFretPos(); void ProcessRealGuitarRun(std::vector &, int &); bool TrillStartsAt(int, const GameGem &, int &) const; + void SetupRealGuitarImportantStrings(); + void EndRepeatedChordPhrase(int &, int &, int &); + bool RollStartsAt(int, const GameGem &, int &, unsigned int &) const; + int GetNumGems() const; + const Gem &GetGem(int) const; + void AdvanceBegin(); + void AdvanceEnd(); + Symbol GetTypeForGem(int); + void AddChordBracket(Symbol, unsigned int, float); + void PollVisibleGems(float, float); + void RememberChordWidget(TrackWidget *); + void AddWidgetInstanceImpl(TrackWidget *, int, float); + void ReleaseSlot(int, int); + void ReleaseHitGems(); + void CheckRemoveChordBracket(int); + bool IsSpotlightGem(int, bool &); + void PruneHitGems(float); TrackDir *mTrackDir; // 0x0 const TrackConfig &mTrackConfig; // 0x4 @@ -118,7 +139,7 @@ class GemManager { std::list unkd0; std::vector unkd8; std::map mWidgets; // 0xe0 - int unkf8; + RndGroup *unkf8; // 0xf8 int unkfc; int unk100; int unk104; diff --git a/src/band3/bandtrack/GemSmasher.h b/src/band3/bandtrack/GemSmasher.h index 1d0fb6a72..de35769f7 100644 --- a/src/band3/bandtrack/GemSmasher.h +++ b/src/band3/bandtrack/GemSmasher.h @@ -9,6 +9,7 @@ class GemSmasher { GemSmasher(int, RndDir *, bool); ~GemSmasher(); void Reset(bool); + RndDir *Dir() const { return mDir; } int mSlot; // 0x0 RndDir *mDir; diff --git a/src/band3/bandtrack/NowBar.h b/src/band3/bandtrack/NowBar.h index c795fbafb..669fa34cc 100644 --- a/src/band3/bandtrack/NowBar.h +++ b/src/band3/bandtrack/NowBar.h @@ -15,6 +15,7 @@ class NowBar { void FillHit(int, int); void SetSmasherGlowing(int, bool); void StopBurning(unsigned int); + void PartialHit(int, unsigned int, bool, int); GemSmasher *FindSmasher(int) const; diff --git a/src/system/beatmatch/GameGem.h b/src/system/beatmatch/GameGem.h index 985799ea8..8f20da511 100644 --- a/src/system/beatmatch/GameGem.h +++ b/src/system/beatmatch/GameGem.h @@ -59,6 +59,7 @@ class GameGem { unsigned int GetSlots() const { return mSlots; } bool GetForceStrum() const { return mForceStrum; } int GetDurationTicks() const { return mDurationTicks; } + float GetMs() const { return mMs; } bool CompareTimes(const GameGem &g1, const GameGem &g2) { return g1.mMs < g2.mMs; } From ff133bdc057b1b94e7487113ffd693b945b8fb96 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Tue, 4 Feb 2025 18:03:27 -0700 Subject: [PATCH 09/12] fill out game --- config/SZBE69_B8/objects.json | 2 +- src/band3/game/Game.cpp | 66 ++++++++++++++ src/band3/game/Game.h | 116 ++++++++++++++++++++++-- src/band3/game/OverdriveTimeTracker.cpp | 2 +- src/band3/meta_band/OvershellPanel.h | 5 +- src/system/beatmatch/BeatMasterSink.h | 5 +- 6 files changed, 180 insertions(+), 16 deletions(-) create mode 100644 src/band3/game/Game.cpp diff --git a/config/SZBE69_B8/objects.json b/config/SZBE69_B8/objects.json index 96ee9f5ce..441f95116 100644 --- a/config/SZBE69_B8/objects.json +++ b/config/SZBE69_B8/objects.json @@ -47,7 +47,7 @@ "band3/game/FocusTracker.cpp": "NonMatching", "band3/game/FreestylePanel.cpp": "MISSING", "band3/game/FretHand.cpp": "NonMatching", - "band3/game/Game.cpp": "MISSING", + "band3/game/Game.cpp": "NonMatching", "band3/game/GameConfig.cpp": "NonMatching", "band3/game/GameMic.cpp": "MISSING", "band3/game/GameMicManager.cpp": "MISSING", diff --git a/src/band3/game/Game.cpp b/src/band3/game/Game.cpp new file mode 100644 index 000000000..51a7f1be3 --- /dev/null +++ b/src/band3/game/Game.cpp @@ -0,0 +1,66 @@ +#include "game/Game.h" +#include "beatmatch/BeatMaster.h" +#include "game/BandUser.h" +#include "game/BandUserMgr.h" +#include "game/GameMode.h" +#include "game/Shuttle.h" +#include "game/SongDB.h" +#include "meta_band/BandUI.h" +#include "meta_band/SessionMgr.h" +#include "meta_band/OvershellPanel.h" +#include "net/NetSession.h" +#include "os/Debug.h" +#include "ui/UIScreen.h" + +Game *TheGame; + +Game::Game() + : mSongDB(new SongDB()), unk58(0), mIsPaused(0), unk69(0), unk6a(0), unk6b(0), + unk6c(0), unk6d(0), unk6e(0), unk6f(0), unk70(0), unkac(0), unkb0(0), unkb4(1.0f), + unkb8(0), unkb9(1), unkbc(0), unkc0(0), unkc4(0), unkc8(0), unkcc(0), unkd0(0), + mShuttle(new Shuttle()), unkdc(-1), unk11c(-1), unk120(0), unk121(0), unk124(0), + unk128(0), unk12c(0), unk130(0), unk134(0), unk138(0), unk139(1), unk13c(-1), + unk140(-1), unk144(0), unk148(0), unk14c(-1), unk150(1) { + MILO_ASSERT(!TheSongDB, 0xCE); + TheSongDB = mSongDB; + TheGame = this; + SetName("beatmatch", ObjectDir::sMainDir); + mMaster = + new BeatMaster(mSongDB->GetSongData(), TheBandUserMgr->GetNumParticipants()); + mMaster->RegisterSink(*this); + TheNetSession->AddSink(this, GameEndedMsg::Type()); + TheSessionMgr->AddSink(this, LocalUserLeftMsg::Type()); + TheSessionMgr->AddSink(this, RemoteUserLeftMsg::Type()); + TheSessionMgr->AddSink(this, RemoteLeaderLeftMsg::Type()); + TheBandUI.AddSink(this, "required_song_options_chosen"); + TheBandUI.AddSink(this, NewOvershellLocalUserMsg::Type()); + TheBandUI.AddSink(this, UIScreenChangeMsg::Type()); +} + +Game::Properties::Properties() + : mInTrainer(TheGameMode->InMode("trainer")), + mInDrumTrainer(TheGameMode->InMode("drum_trainer")), + mInPracticeMode(TheGameMode->InMode("practice")), + mAllowOverdrivePhrases(TheGameMode->Property("allow_overdrive_phrases", true)->Int() + ), + mEndWithSong(TheGameMode->Property("end_with_song", true)->Int()), + mForceUseCymbals(TheGameMode->Property("force_use_cymbals", true)->Int()), + mForceDontUseCymbals(TheGameMode->Property("force_dont_use_cymbals", true)->Int()), + mAllowAutoVocals(TheGameMode->Property("allow_auto_vocals", true)->Int()), + mHasSongSections(TheGameMode->Property("has_song_sections", true)->Int()), + mLoadChars(TheGameMode->Property("load_chars", true)->Int()), + mLetterbox(TheGameMode->Property("letterbox", true)->Int()), + mCrowdReacts(TheGameMode->Property("crowd_reacts", true)->Int()), + mIsPractice(TheGameMode->Property("is_practice", true)->Int()), + mEnableWhammy(TheGameMode->Property("enable_whammy", true)->Int()), + mEnableCapstrip(TheGameMode->Property("enable_capstrip", true)->Int()), + mDisableGuitarFx(TheGameMode->Property("disable_guitar_fx", true)->Int()), + mDisableKeysFx(TheGameMode->Property("disable_keys_fx", true)->Int()), + mEnableOverdrive(TheGameMode->Property("enable_overdrive", true)->Int()), + mEnableCoda(TheGameMode->Property("enable_coda", true)->Int()), + mCanSolo(TheGameMode->Property("can_solo", true)->Int()), + mHasBeatMask(TheGameMode->Property("has_beat_mask", true)->Int()), + mCanLose(TheGameMode->Property("can_lose", true)->Int()), + mEnableStreak(TheGameMode->Property("enable_streak", true)->Int()), + mShowStars(TheGameMode->Property("show_stars", true)->Int()), + mPlayStarSfx(TheGameMode->Property("play_star_sfx", true)->Int()) {} \ No newline at end of file diff --git a/src/band3/game/Game.h b/src/band3/game/Game.h index 92fddc8a7..55f557cc1 100644 --- a/src/band3/game/Game.h +++ b/src/band3/game/Game.h @@ -1,13 +1,56 @@ #pragma once +#include "Shuttle.h" +#include "beatmatch/BeatMaster.h" +#include "beatmatch/BeatMasterSink.h" #include "game/BandUser.h" #include "game/Player.h" +#include "game/SongDB.h" +#include "math/Interp.h" +#include "obj/Msg.h" #include "obj/Object.h" +#include "os/DiscErrorMgr_Wii.h" +#include "os/Timer.h" #include "types.h" +#include "utl/SongPos.h" -class Game : public Hmx::Object { +class Game : public BeatMasterSink, public Hmx::Object, public DiscErrorMgrWii::Callback { public: + struct Properties { + Properties(); + + bool mInTrainer; // 0x0 + bool mInDrumTrainer; // 0x1 + bool mInPracticeMode; // 0x2 + bool mAllowOverdrivePhrases; // 0x3 + bool mEndWithSong; // 0x4 + bool mForceUseCymbals; // 0x5 + bool mForceDontUseCymbals; // 0x6 + bool mAllowAutoVocals; // 0x7 + bool mHasSongSections; // 0x8 + bool mLoadChars; // 0x9 + bool mLetterbox; // 0xa + bool mCrowdReacts; // 0xb + bool mIsPractice; // 0xc + bool mEnableWhammy; // 0xd + bool mEnableCapstrip; // 0xe + bool mDisableGuitarFx; // 0xf + bool mDisableKeysFx; // 0x10 + bool mEnableOverdrive; // 0x11 + bool mEnableCoda; // 0x12 + bool mCanSolo; // 0x13 + bool mHasBeatMask; // 0x14 + bool mCanLose; // 0x15 + bool mEnableStreak; // 0x16 + bool mShowStars; // 0x17 + bool mPlayStarSfx; // 0x18 + }; Game(); virtual ~Game(); + virtual void Beat(int, int); + virtual void UpdateSongPos(const SongPos &); + virtual void HandleSubmix(int, const char *); + virtual DataNode Handle(DataArray *, bool); + virtual void DiscErrorEnd() {} void SetPaused(bool, bool, bool); void SetGameOver(bool); @@ -27,15 +70,70 @@ class Game : public Hmx::Object { void OnRemoteTrackerEndStreak(Player *, int, int); void OnPlayerQuarantined(Player *); Band *GetBand(); - bool InTrainer() const { return unk24; } + bool InTrainer() const; + + Properties mProperties; // 0x24 + SongPos mSongPos; // 0x40 + SongDB *mSongDB; // 0x54 + int unk58; + BeatMaster *mMaster; // 0x5c + std::vector unk60; + bool mIsPaused; // 0x68 + bool unk69; + bool unk6a; + bool unk6b; + bool unk6c; + bool unk6d; + bool unk6e; + bool unk6f; + float unk70; + int unk74; + Timer unk78; + int unka8; + float unkac; + bool unkb0; + float unkb4; + bool unkb8; + bool unkb9; + int unkbc; + float unkc0; + bool unkc4; + int unkc8; + int unkcc; + int unkd0; + Shuttle *mShuttle; // 0xd4 + int unkd8; + float unkdc; + ATanInterpolator mInterpolator; // 0xe0 + float unk11c; + bool unk120; + bool unk121; + float unk124; + float unk128; + bool unk12c; + float unk130; + float unk134; + bool unk138; + bool unk139; + int unk13c; + float unk140; + int unk144; + bool unk148; + float unk14c; + bool unk150; + std::vector unk154; - int unk1c; - int unk20; - bool unk24; - u8 pad[0x40]; - bool mIsPaused; // 0x68 iunno - u8 pad2[115]; - float unk_0xdc; + // int unk1c; + // int unk20; + // bool unk24; + // u8 pad[0x40]; + // bool mIsPaused; // 0x68 iunno + // u8 pad2[115]; + // float unk_0xdc; }; +DECLARE_MESSAGE(GameEndedMsg, "game_ended"); +END_MESSAGE +; + extern Game * /*you just lost*/ TheGame; diff --git a/src/band3/game/OverdriveTimeTracker.cpp b/src/band3/game/OverdriveTimeTracker.cpp index 22479838a..d35516092 100644 --- a/src/band3/game/OverdriveTimeTracker.cpp +++ b/src/band3/game/OverdriveTimeTracker.cpp @@ -28,7 +28,7 @@ void OverdriveTimeTracker::FirstFrame_(float) { void OverdriveTimeTracker::Poll_(float f) { MILO_ASSERT(TheGame, 0x3E); - if (TheGame->unk_0xdc != -1 || mSource->IsFinished()) + if (TheGame->unkdc != -1 || mSource->IsFinished()) return; else { bool o2 = false; diff --git a/src/band3/meta_band/OvershellPanel.h b/src/band3/meta_band/OvershellPanel.h index 5b6e54c88..3feeb17f4 100644 --- a/src/band3/meta_band/OvershellPanel.h +++ b/src/band3/meta_band/OvershellPanel.h @@ -61,4 +61,7 @@ class OvershellPanel : public UIPanel, public Synchronizable, public MsgSource { std::vector unk4c0; bool unk4c8; int unk4cc; -}; \ No newline at end of file +}; + +DECLARE_MESSAGE(NewOvershellLocalUserMsg, "new_overshell_local_user_msg") +END_MESSAGE \ No newline at end of file diff --git a/src/system/beatmatch/BeatMasterSink.h b/src/system/beatmatch/BeatMasterSink.h index a797e681e..4caf8580d 100644 --- a/src/system/beatmatch/BeatMasterSink.h +++ b/src/system/beatmatch/BeatMasterSink.h @@ -1,5 +1,4 @@ -#ifndef BEATMATCH_BEATMASTERSINK_H -#define BEATMATCH_BEATMASTERSINK_H +#pragma once #include "utl/SongPos.h" class BeatMasterSink { @@ -10,5 +9,3 @@ class BeatMasterSink { virtual void UpdateSongPos(const SongPos &) = 0; virtual void HandleSubmix(int, const char *) = 0; }; - -#endif From 1c1d2e320ab9af2600159e9542a8878b4040eb1e Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:53:03 -0700 Subject: [PATCH 10/12] gemmgr work --- config/SZBE69/symbols.txt | 6 +- src/band3/bandtrack/Gem.h | 1 + src/band3/bandtrack/GemManager.cpp | 215 ++++++++++++++++++++++++++++- src/band3/bandtrack/GemManager.h | 15 +- src/band3/game/Game.h | 2 +- src/band3/game/Player.h | 2 +- 6 files changed, 225 insertions(+), 16 deletions(-) diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index 82b445909..32965703b 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -7585,7 +7585,7 @@ fn_800D4950 = .text:0x800D4950; // type:function size:0x24 GetWidgetName__10GemManagerFR6Symboli6Symbol = .text:0x800D4974; // type:function size:0x94 GetChordWidgetName__10GemManagerF6Symbol6SymbolR6Symbol = .text:0x800D4A08; // type:function size:0x9C GetSlotIntData__10GemManagerFi6Symbol = .text:0x800D4AA4; // type:function size:0x44 -fn_800D4AE8 = .text:0x800D4AE8; // type:function size:0x64 +GetSlotsForGem__10GemManagerFi = .text:0x800D4AE8; // type:function size:0x64 fn_800D4B4C = .text:0x800D4B4C; // type:function size:0x44 fn_800D4B90 = .text:0x800D4B90; // type:function size:0x4 fn_800D4B94 = .text:0x800D4B94; // type:function size:0xC4 @@ -7910,7 +7910,7 @@ fn_800DD798 = .text:0x800DD798; // type:function size:0x14 fn_800DD7AC = .text:0x800DD7AC; // type:function size:0x10 HandleNewSong__8GemTrackFv = .text:0x800DD7BC; // type:function size:0x98 fn_800DD854 = .text:0x800DD854; // type:function size:0x64 -fn_800DD8B8 = .text:0x800DD8B8; // type:function size:0x5C +Hit__8GemTrackFfii = .text:0x800DD8B8; // type:function size:0x5C fn_800DD914 = .text:0x800DD914; // type:function size:0x8 fn_800DD91C = .text:0x800DD91C; // type:function size:0x60 fn_800DD97C = .text:0x800DD97C; // type:function size:0x8 @@ -12190,7 +12190,7 @@ fn_8015AB10 = .text:0x8015AB10; // type:function size:0xAC fn_8015ABBC = .text:0x8015ABBC; // type:function size:0x24 fn_8015ABE0 = .text:0x8015ABE0; // type:function size:0x14 fn_8015ABF4 = .text:0x8015ABF4; // type:function size:0x18 -fn_8015AC0C = .text:0x8015AC0C; // type:function size:0xD0 +GetCommonPhraseExtent__6SongDBFiiR6Extent = .text:0x8015AC0C; // type:function size:0xD0 fn_8015ACDC = .text:0x8015ACDC; // type:function size:0x54 fn_8015AD30 = .text:0x8015AD30; // type:function size:0x38 fn_8015AD68 = .text:0x8015AD68; // type:function size:0x38 diff --git a/src/band3/bandtrack/Gem.h b/src/band3/bandtrack/Gem.h index 646c749dd..3317b35d7 100644 --- a/src/band3/bandtrack/Gem.h +++ b/src/band3/bandtrack/Gem.h @@ -46,6 +46,7 @@ class Gem { const GameGem &GetGameGem() const { return mGameGem; } unsigned int Slots() const { return mSlots; } bool Released() const { return mReleased; } + bool GetHit() const { return mHit; } GemManager *mGemManager; // 0x0 const GameGem &mGameGem; // 0x4 diff --git a/src/band3/bandtrack/GemManager.cpp b/src/band3/bandtrack/GemManager.cpp index e25be8cda..28ef1d612 100644 --- a/src/band3/bandtrack/GemManager.cpp +++ b/src/band3/bandtrack/GemManager.cpp @@ -2,10 +2,12 @@ #include "bandobj/ArpeggioShape.h" #include "bandtrack/NowBar.h" #include "bandtrack/Track.h" +#include "beatmatch/FillInfo.h" #include "beatmatch/GameGem.h" #include "beatmatch/RGUtl.h" #include "game/BandUser.h" #include "game/Game.h" +#include "game/Player.h" #include "game/SongDB.h" #include "meta_band/BandSongMetadata.h" #include "meta_band/BandSongMgr.h" @@ -13,6 +15,7 @@ #include "game/TrainerPanel.h" #include "obj/Data.h" #include "obj/DataFunc.h" +#include "obj/Task.h" #include "os/Debug.h" #include "os/System.h" #include "rndobj/Group.h" @@ -35,9 +38,9 @@ DataNode SetKeyGlow(DataArray *arr) { GemManager::GemManager(const TrackConfig &cfg, TrackDir *dir) : mTrackDir(dir), mTrackConfig(cfg), mTemplate(cfg), mConfig(SystemConfig("track_graphics")), mGemData(0), unk14(0), mBegin(0), mEnd(0), - unkb8(0), mNowBar(0), unkc0(0), mInCoda(0), unkc4(0), + unkb8(0), mNowBar(0), mBonusGems(0), mInCoda(0), unkc4(0), unkc8(dir->SecondsToY(dir->TopSeconds())), - unkcc(dir->SecondsToY(dir->BottomSeconds())), unkf8(0), unkfc(0), unk100(0), + unkcc(dir->SecondsToY(dir->BottomSeconds())), mTailsGrp(0), unkfc(0), unk100(0), unk104(0), unk108(0), unk10c(0), unk118(0), unk12c(0), unk130(-1), unk134(960) { mNowBar = new NowBar(mTrackDir, mTrackConfig); mTemplate.Init(mTrackDir->Find("gem_tail", true)); @@ -458,14 +461,14 @@ void GemManager::AdvanceBegin() { void GemManager::AdvanceEnd() { Gem &lastGem = mGems[mEnd]; Symbol gemType = GetTypeForGem(mEnd); - if (!unkf8) { + if (!mTailsGrp) { if (mTrackConfig.IsKeyboardTrack()) { - unkf8 = mTrackDir->Find("key_shift_tails.grp", true); + mTailsGrp = mTrackDir->Find("key_shift_tails.grp", true); } else - unkf8 = mTrackDir->Find("tails.grp", true); + mTailsGrp = mTrackDir->Find("tails.grp", true); } unsigned int slots = lastGem.Slots(); - lastGem.AddRep(mTemplate, unkf8, gemType, mTrackConfig, true); + lastGem.AddRep(mTemplate, mTailsGrp, gemType, mTrackConfig, true); mEnd++; if (mTrackConfig.IsKeyboardTrack()) { int tick = lastGem.GetGameGem().GetTick(); @@ -474,7 +477,7 @@ void GemManager::AdvanceEnd() { Symbol curGemType = GetTypeForGem(mEnd); Gem &curGem = mGems[mEnd]; slots |= curGem.Slots(); - curGem.AddRep(mTemplate, unkf8, curGemType, mTrackConfig, true); + curGem.AddRep(mTemplate, mTailsGrp, curGemType, mTrackConfig, true); } AddChordBracket(gemType, slots, lastGem.GetGameGem().GetMs()); } @@ -576,6 +579,204 @@ void GemManager::Released(float f1, int i2) { } } +void GemManager::SetSmasherGlowing(int i1, bool b2) { + mNowBar->SetSmasherGlowing(i1, b2); +} + +void GemManager::PopSmasher(int i1) { mNowBar->PopSmasher(i1); } + +void GemManager::ResetSmashers(bool b1) { mNowBar->Reset(b1); } + +void GemManager::Jump(float f1) { + while (mBegin < mEnd) + AdvanceBegin(); + mHitGems.clear(); + mMissedPhrases.clear(); + ClearTrackMasks(); + DrawTrackMasks(MsToTickInt(mTrackDir->TopSeconds() * 1000.0f + f1), MsToTickInt(f1)); + + float f5 = mTrackDir->BottomSeconds(); + int i1 = -1; + for (int i = 0; i < mEnd; i++) { + if (mGems[i].GetStart() < f1 / 1000.0f + f5) + continue; + if (i1 < 0) + i1 = i; + mGems[i].Reset(); + } + mBegin = i1; + mEnd = i1; + mBegin = Clamp(0, i1, i1); + mEnd = Clamp(0, mEnd, mEnd); + ResetArpeggios(f1); + PlayerState state; + PollHelper(f1, state); +} + +void GemManager::SetBonusGems(bool gems, const PlayerState &state) { + mBonusGems = gems; + UpdateGemStates(); +} + +void GemManager::SetInCoda(bool coda) { mInCoda = coda; } + +bool GemManager::OnMissPhrase(int i1) { + bool ret = true; + int tracknum = mTrackConfig.TrackNum(); + Extent ext18(0, 0); + if (TheSongDB->GetCommonPhraseExtent(tracknum, i1, ext18)) { + int i2 = MsToTickInt(TheTaskMgr.Seconds(TaskMgr::kRealTime) * 1000.0f); + if (!mMissedPhrases.empty()) { + Extent &back = mMissedPhrases.back(); + ret = back.unk4 != ext18.unk4; + if (ret) { + mMissedPhrases.push_back(Extent(i2, ext18.unk4)); + } else if (i2 != back.unk0) + return ret; + UpdateGemStates(); + } else { + mMissedPhrases.push_back(Extent(i2, ext18.unk4)); + UpdateGemStates(); + } + } + return ret; +} + +bool GemManager::GetWidgetName(Symbol &sref, int i2, Symbol s3) { + DataArray *arr = mGemData->FindArray(i2, false); + if (!arr) + return false; + else { + DataArray *symArr = arr->FindArray(s3, false); + if (!symArr) + return false; + else { + sref = symArr->Sym(1); + return true; + } + } +} + +bool GemManager::GetChordWidgetName(Symbol s1, Symbol s2, Symbol &sref) { + DataArray *arr = mGemData->FindArray(s2, false); + if (!arr) + return false; + else { + DataArray *symArr = arr->FindArray(s1, false); + if (!symArr) + return false; + else { + sref = symArr->Sym(1); + return true; + } + } +} + +int GemManager::GetSlotIntData(int i1, Symbol s2) { + DataArray *arr = mGemData->FindArray(i1, true); + return arr->FindInt(s2); +} + +int GemManager::GetSlotsForGem(int gem) { + if (gem < 0 || gem >= mGems.size()) + return 0; + else + return mGems[gem].Slots(); +} + +void GemManager::EnableSlot(int slot) { + if (!SlotEnabled(slot)) { + mDisabledSlotsList.remove(slot); + } +} + +void GemManager::DisableSlot(int slot) { + if (SlotEnabled(slot)) { + mDisabledSlotsList.push_back(slot); + } +} + +bool GemManager::SlotEnabled(int slot) const { + return std::find(mDisabledSlotsList.begin(), mDisabledSlotsList.end(), slot) + == mDisabledSlotsList.end(); +} + +void GemManager::ClearGems(bool b) { + for (int i = mBegin; i < mEnd; i++) { + Gem &curGem = mGems[i]; + if (b || (!curGem.GetHit() || curGem.CompareBounds()) && !curGem.Released()) { + curGem.RemoveAllInstances(); + curGem.RemoveRep(); + } + } +} + +void GemManager::ClearAllGems() { + for (int i = 0; i < mGems.size(); i++) { + Gem &curGem = mGems[i]; + curGem.Release(); + curGem.RemoveAllInstances(); + curGem.RemoveRep(); + } +} + +void GemManager::HideGems() { + for (int i = 0; i < mGems.size(); i++) { + mGems[i].SetType(invisible); + } +} + +void GemManager::ClearGem(int idx) { + Gem &curGem = mGems[idx]; + curGem.Release(); + curGem.RemoveAllInstances(); + curGem.RemoveRep(); +} + +bool GemManager::GetFill(int i1, FillExtent &ext) { + Player *player = mTrackConfig.GetBandUser()->GetPlayer(); + if (!player || !player->FillsEnabled(i1)) + return false; + else { + FillInfo *info = TheSongDB->GetSongData()->GetFillInfo(mTrackConfig.TrackNum()); + return !info ? false : info->FillAt(GetLoopTick(i1), ext, true); + } +} + +bool GemManager::IsInFill(int idx) { + Player *player = mTrackConfig.GetBandUser()->GetPlayer(); + if (player->AreFillsForced()) + return true; + else { + FillExtent ext(0, 0, 0); + return GetFill(idx, ext); + } +} + +bool GemManager::IsEndOfFill(int idx) { + bool ret = false; + FillExtent ext(0, 0, 0); + if (GetFill(idx, ext) && ext.end == idx) + ret = true; + return ret; +} + +void GemManager::ClearMissedPhrases() {} + +TrackWidget *GemManager::GetWidgetByName(Symbol name) { + if (mWidgets.find(name) == mWidgets.end()) { + mWidgets[name] = mTrackDir->Find(name.mStr, true); + } + return mWidgets[name]; +} + +void GemManager::UpdateEnabledSlots() { + unk108 = 0; + for (int i = 0; i < mGems.size(); i++) { + unk108 |= mGems[i].Slots(); + } +} + #pragma push #pragma force_active on inline int GemManager::GetMaxSlots() const { return mTrackConfig.GetMaxSlots(); } diff --git a/src/band3/bandtrack/GemManager.h b/src/band3/bandtrack/GemManager.h index 907d5bc56..d38316034 100644 --- a/src/band3/bandtrack/GemManager.h +++ b/src/band3/bandtrack/GemManager.h @@ -117,6 +117,13 @@ class GemManager { void CheckRemoveChordBracket(int); bool IsSpotlightGem(int, bool &); void PruneHitGems(float); + void PollHelper(float, const PlayerState &); + void EnableSlot(int); + void DisableSlot(int); + void ClearGem(int); + bool GetFill(int, FillExtent &); + bool IsInFill(int); + bool IsEndOfFill(int); TrackDir *mTrackDir; // 0x0 const TrackConfig &mTrackConfig; // 0x4 @@ -131,19 +138,19 @@ class GemManager { DataArray *mConfig; // 0xb4 bool unkb8; // 0xb8 NowBar *mNowBar; // 0xbc - bool unkc0; + bool mBonusGems; // 0xc0 bool mInCoda; // 0xc1 float unkc4; float unkc8; float unkcc; - std::list unkd0; + std::list mDisabledSlotsList; // 0xd0 std::vector unkd8; std::map mWidgets; // 0xe0 - RndGroup *unkf8; // 0xf8 + RndGroup *mTailsGrp; // 0xf8 int unkfc; int unk100; int unk104; - int unk108; + unsigned int unk108; int unk10c; std::vector mArpeggioPhrases; // 0x110 int unk118; diff --git a/src/band3/game/Game.h b/src/band3/game/Game.h index 55f557cc1..915c932ba 100644 --- a/src/band3/game/Game.h +++ b/src/band3/game/Game.h @@ -70,7 +70,7 @@ class Game : public BeatMasterSink, public Hmx::Object, public DiscErrorMgrWii:: void OnRemoteTrackerEndStreak(Player *, int, int); void OnPlayerQuarantined(Player *); Band *GetBand(); - bool InTrainer() const; + bool InTrainer() const { return mProperties.mInTrainer; } Properties mProperties; // 0x24 SongPos mSongPos; // 0x40 diff --git a/src/band3/game/Player.h b/src/band3/game/Player.h index b7cb5bfc1..a19142d9b 100644 --- a/src/band3/game/Player.h +++ b/src/band3/game/Player.h @@ -102,7 +102,7 @@ class Player : public Performer, public MsgSource { virtual void DisableFills() = 0; virtual void EnableDrumFills(bool) {} virtual bool FillsEnabled(int) = 0; - virtual bool AreFillsForced() const; + virtual bool AreFillsForced() const { return false; } virtual void EnterCoda(); virtual void ResetCodaPoints(); virtual void AddCodaPoints(); From 5d4ec4488424f1cc589e5252d1fbb6bcacbc3608 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:40:36 -0700 Subject: [PATCH 11/12] gemreptemplate work --- config/SZBE69/symbols.txt | 42 ++++----- src/band3/bandtrack/GemRepTemplate.cpp | 122 +++++++++++++++++-------- src/band3/bandtrack/GemRepTemplate.h | 21 ++--- src/band3/bandtrack/GemSmasher.h | 2 +- src/system/rndobj/Mesh.h | 2 +- 5 files changed, 116 insertions(+), 73 deletions(-) diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index 32965703b..2be4b697e 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -7687,35 +7687,35 @@ fn_800D75BC = .text:0x800D75BC; // type:function size:0x5C fn_800D7618 = .text:0x800D7618; // type:function size:0x10 fn_800D7628 = .text:0x800D7628; // type:function size:0x44 __ct__14GemRepTemplateFRC11TrackConfig = .text:0x800D766C; // type:function size:0x238 -fn_800D78A4 = .text:0x800D78A4; // type:function size:0x5C -fn_800D7900 = .text:0x800D7900; // type:function size:0xC +__dt__Q27RndMesh10VertVectorFv = .text:0x800D78A4; // type:function size:0x5C +clear__Q27RndMesh10VertVectorFv = .text:0x800D7900; // type:function size:0xC __ct__Q27RndMesh10VertVectorFv = .text:0x800D790C; // type:function size:0x14 __ct__7Vector2Fff = .text:0x800D7920; // type:function size:0xC scope:weak FindFloat__9DataArrayCF6Symbol = .text:0x800D792C; // type:function size:0x38 scope:weak Float__9DataArrayCFi = .text:0x800D7964; // type:function size:0x34 -fn_800D7998 = .text:0x800D7998; // type:function size:0x84 -fn_800D7A1C = .text:0x800D7A1C; // type:function size:0x5C +__dt__14GemRepTemplateFv = .text:0x800D7998; // type:function size:0x84 +DeleteAll>>__FRQ211stlpmtx_std61vector>_v = .text:0x800D7A1C; // type:function size:0x5C fn_800D7A78 = .text:0x800D7A78; // type:function size:0x5C fn_800D7AD4 = .text:0x800D7AD4; // type:function size:0x24 Init__14GemRepTemplateFP9ObjectDir = .text:0x800D7AF8; // type:function size:0x1E8 Find<6RndMat>__9ObjectDirFPCcb_P6RndMat = .text:0x800D7CE0; // type:function size:0xA0 -fn_800D7D80 = .text:0x800D7D80; // type:function size:0x68 -fn_800D7DE8 = .text:0x800D7DE8; // type:function size:0x5C -fn_800D7E44 = .text:0x800D7E44; // type:function size:0x94 +GetTail__14GemRepTemplateFv = .text:0x800D7D80; // type:function size:0x68 +ReturnTail__14GemRepTemplateFP7RndMesh = .text:0x800D7DE8; // type:function size:0x5C +CreateTail__14GemRepTemplateFv = .text:0x800D7E44; // type:function size:0x94 reserve__Q211stlpmtx_std73vector>FUl = .text:0x800D7ED8; // type:function size:0x4 Faces__7RndMeshFv = .text:0x800D7EDC; // type:function size:0x28 Verts__7RndMeshFv = .text:0x800D7F04; // type:function size:0x28 SetMutable__7RndMeshFi = .text:0x800D7F2C; // type:function size:0x34 New<7RndMesh>__Q23Hmx6ObjectFv_P7RndMesh = .text:0x800D7F60; // type:function size:0x48 StaticClassName__7RndMeshFv = .text:0x800D7FA8; // type:function size:0x4C -fn_800D7FF4 = .text:0x800D7FF4; // type:function size:0x38 -fn_800D802C = .text:0x800D802C; // type:function size:0x3C -fn_800D8068 = .text:0x800D8068; // type:function size:0xC4 -fn_800D812C = .text:0x800D812C; // type:function size:0x80 +GetRequiredVertCount__14GemRepTemplateCFi = .text:0x800D7FF4; // type:function size:0x38 +GetRequiredFaceCount__14GemRepTemplateCFi = .text:0x800D802C; // type:function size:0x3C +GetMatByTag__14GemRepTemplateFPCci = .text:0x800D8068; // type:function size:0xC4 +VertLess__FRCQ27RndMesh4VertRCQ27RndMesh4Vert = .text:0x800D812C; // type:function size:0x80 fabs__3stdFf = .text:0x800D81AC; // type:function size:0x4 -FAbsFloat__Fd = .text:0x800D81B0; // type:function size:0x24 -FAbs__Fd = .text:0x800D81D4; // type:function size:0x8 -fn_800D81DC = .text:0x800D81DC; // type:function size:0x144 +fabsf = .text:0x800D81B0; // type:function size:0x24 +fabs = .text:0x800D81D4; // type:function size:0x8 +SetupTailVerts__14GemRepTemplateFv = .text:0x800D81DC; // type:function size:0x144 fn_800D8320 = .text:0x800D8320; // type:function size:0x78 fn_800D8398 = .text:0x800D8398; // type:function size:0xD4 fn_800D846C = .text:0x800D846C; // type:function size:0xC @@ -7755,7 +7755,7 @@ Find<7RndMesh>__9ObjectDirFPCcb_P7RndMesh = .text:0x800D905C; // type:function s fn_800D90FC = .text:0x800D90FC; // type:function size:0x10 fn_800D910C = .text:0x800D910C; // type:function size:0x10 fn_800D911C = .text:0x800D911C; // type:function size:0x58 -fn_800D9174 = .text:0x800D9174; // type:function size:0x5C +SetSlotMat__14GemRepTemplateFiiP6RndMat = .text:0x800D9174; // type:function size:0x5C fn_800D91D0 = .text:0x800D91D0; // type:function size:0xCC fn_800D929C = .text:0x800D929C; // type:function size:0x5C fn_800D92F8 = .text:0x800D92F8; // type:function size:0xC @@ -82923,8 +82923,8 @@ guide_showing = .bss:0x80982FA0; // type:object size:0x4 guitar = .bss:0x80982FA4; // type:object size:0x4 data:4byte guitar_intensity = .bss:0x80982FA8; // type:object size:0x4 guitar_shift_button = .bss:0x80982FAC; // type:object size:0x4 data:4byte -SymGuitarSustainXScale = .bss:0x80982FB0; // type:object size:0x4 -SymGuitarSustainYPos = .bss:0x80982FB4; // type:object size:0x4 +guitar_sustain_x_scale = .bss:0x80982FB0; // type:object size:0x4 +guitar_sustain_y_pos = .bss:0x80982FB4; // type:object size:0x4 h = .bss:0x80982FB8; // type:object size:0x24 SymH2h = .bss:0x80982FDC; // type:object size:0x4 data:4byte hair = .bss:0x80982FE0; // type:object size:0x8 data:4byte @@ -84518,12 +84518,12 @@ lbl_80984EEC = .bss:0x80984EEC; // type:object size:0x4 lbl_80984EF0 = .bss:0x80984EF0; // type:object size:0x4 lbl_80984EF4 = .bss:0x80984EF4; // type:object size:0x4 lbl_80984EF8 = .bss:0x80984EF8; // type:object size:0x8 -lbl_80984F00 = .bss:0x80984F00; // type:object size:0x4 -lbl_80984F04 = .bss:0x80984F04; // type:object size:0x4 +real_guitar_sustain_x_scale = .bss:0x80984F00; // type:object size:0x4 +real_guitar_sustain_y_pos = .bss:0x80984F04; // type:object size:0x4 real_guitar_tuning = .bss:0x80984F08; // type:object size:0x4 data:4byte real_keys = .bss:0x80984F0C; // type:object size:0x4 data:4byte -lbl_80984F10 = .bss:0x80984F10; // type:object size:0x4 -lbl_80984F14 = .bss:0x80984F14; // type:object size:0x4 +real_keys_sustain_x_scale = .bss:0x80984F10; // type:object size:0x4 +real_keys_sustain_y_pos = .bss:0x80984F14; // type:object size:0x4 lbl_80984F18 = .bss:0x80984F18; // type:object size:0xC rebuild = .bss:0x80984F24; // type:object size:0x4 lbl_80984F28 = .bss:0x80984F28; // type:object size:0x4 diff --git a/src/band3/bandtrack/GemRepTemplate.cpp b/src/band3/bandtrack/GemRepTemplate.cpp index bff22eaf1..5881028f9 100644 --- a/src/band3/bandtrack/GemRepTemplate.cpp +++ b/src/band3/bandtrack/GemRepTemplate.cpp @@ -1,9 +1,15 @@ #include "GemRepTemplate.h" #include "bandtrack/GraphicsUtl.h" #include "bandtrack/TrackConfig.h" +#include "beatmatch/TrackType.h" #include "os/Debug.h" #include "os/System.h" #include "rndobj/Mat.h" +#include "rndobj/Mesh.h" +#include "utl/Std.h" +#include "utl/Symbol.h" +#include "utl/Symbols.h" +#include "utl/Symbols4.h" #include // needs to be an enum for value names to show in asserts @@ -13,40 +19,66 @@ enum { GemRepTemplate::GemRepTemplate(const TrackConfig &tc) : mConfig(SystemConfig("track_graphics", "gem")), - kTailPulseRate(mConfig->FindArray("tail_pulse_rate", true)->Float(1)), - kTailPulseSmoothing(mConfig->FindArray("tail_pulse_smoothing", true)->Float(1)), - kTailOffsetX(mConfig->FindArray("tail_offset_x", true)->Float(1)), - kTailMinAlpha(mConfig->FindArray("tail_min_alpha", true)->Float(1)), - kTailMaxAlpha(mConfig->FindArray("tail_max_alpha", true)->Float(1)), - kTailAlphaSmoothing(mConfig->FindArray("tail_alpha_smoothing", true)->Float(1)), - kTailFadeDistance(mConfig->FindArray("tail_fade_distance", true)->Float(1)), - kTailMaxLength(mConfig->FindArray("tail_max_length", true)->Float(1)), + kTailPulseRate(mConfig->FindFloat("tail_pulse_rate")), + kTailPulseSmoothing(mConfig->FindFloat("tail_pulse_smoothing")), + kTailOffsetX(mConfig->FindFloat("tail_offset_x")), + kTailMinAlpha(mConfig->FindFloat("tail_min_alpha")), + kTailMaxAlpha(mConfig->FindFloat("tail_max_alpha")), + kTailAlphaSmoothing(mConfig->FindFloat("tail_alpha_smoothing")), + kTailFadeDistance(mConfig->FindFloat("tail_fade_distance")), + kTailMaxLength(mConfig->FindFloat("tail_max_length")), kTailFrequencyRange( - mConfig->FindArray("tail_min_freq", true)->Float(1), - mConfig->FindArray("tail_max_freq", true)->Float(1) + mConfig->FindFloat("tail_min_freq"), mConfig->FindFloat("tail_max_freq") ), kTailAmplitudeRange( - mConfig->FindArray("tail_min_amp", true)->Float(1), - mConfig->FindArray("tail_max_amp", true)->Float(1) + mConfig->FindFloat("tail_min_amp"), mConfig->FindFloat("tail_max_amp") ), - mTrackCfg(tc), unk_0x3C(0), unk_0x40(1.0f), mObjectDir(NULL) { - mSlots = (RndMat **)new void *[tc.GetMaxSlots()]; // it doesn't call the ctors, so i - // have to do This to just alloc + mTrackCfg(tc), mTailClipY(0), mTailScaleX(1.0f), mObjectDir(NULL) { + mSlotMats = new RndMat *[tc.GetMaxSlots()]; } GemRepTemplate::~GemRepTemplate() { - RndMesh *end = *mTails.end(); - for (RndMesh *it = *mTails.begin(); it != end; it++) - delete it; // i hate how well this matches - mTails.clear(); - delete[] mSlots; + DeleteAll(mTails); + delete[] mSlotMats; } -void GemRepTemplate::Init(ObjectDir *) {} +void GemRepTemplate::Init(ObjectDir *dir) { + mObjectDir = dir; + int maxslots = mTrackCfg.GetMaxSlots(); + for (int i = 0; i < maxslots; i++) { + SetSlotMat(0, i, GetMatByTag("tail", i)); + } + mTailMiss = mObjectDir->Find("tail_miss.mat", true); + mTailBonus = mObjectDir->Find("tail_bonus.mat", true); + mTailChord = mObjectDir->Find("tail_chord.mat", true); + TrackType ty = mTrackCfg.GetBandUser()->GetTrackType(); + Symbol clipPropSym(gNullStr); + Symbol scalePropSym(gNullStr); + switch (ty) { + case kTrackRealKeys: + clipPropSym = real_keys_sustain_y_pos; + scalePropSym = real_keys_sustain_x_scale; + break; + case kTrackRealGuitar: + case kTrackRealBass: + clipPropSym = real_guitar_sustain_y_pos; + scalePropSym = real_guitar_sustain_x_scale; + break; + default: + clipPropSym = guitar_sustain_y_pos; + scalePropSym = guitar_sustain_x_scale; + break; + } + MILO_ASSERT(clipPropSym != gNullStr, 0x6B); + MILO_ASSERT(scalePropSym != gNullStr, 0x6C); + mTailClipY = mObjectDir->Property(clipPropSym, true)->Float(); + mTailScaleX = mObjectDir->Property(scalePropSym, true)->Float(); + SetupTailVerts(); +} RndMesh *GemRepTemplate::GetTail() { RndMesh *m; - if (mTails.size() == 0) + if (mTails.empty()) m = CreateTail(); else { m = mTails.back(); @@ -63,23 +95,29 @@ void GemRepTemplate::ReturnTail(RndMesh *m) { } RndMesh *GemRepTemplate::CreateTail() { + int count = mNumTailSections[0]; RndMesh *m = Hmx::Object::New(); m->SetMutable(0x3F); - m->Verts().reserve(mTailVerts.size() * (1 + mNumTailSections), true); - m->Faces().reserve((mTailVerts.size() - 1) * mNumTailSections * 2); + RndMesh::VertVector &verts = m->Verts(); + verts.reserve(GetRequiredVertCount(count), true); + std::vector &faces = m->Faces(); + faces.reserve(GetRequiredFaceCount(count)); return m; } -int GemRepTemplate::GetRequiredVertCount(int i) const { +#pragma push +#pragma force_active on +inline int GemRepTemplate::GetRequiredVertCount(int i) const { return mTailVerts.size() * (i + 1); } -int GemRepTemplate::GetRequiredFaceCount(int i) const { +inline int GemRepTemplate::GetRequiredFaceCount(int i) const { return (mTailVerts.size() - 1) * i * 2; } +#pragma pop RndMat *GemRepTemplate::GetMatByTag(const char *c, int slot) { - const char *s = mConfig->FindArray("mat_formats", true)->FindArray(c, true)->Str(1); + const char *s = mConfig->FindArray("mat_formats", true)->FindStr(c); return mObjectDir->Find( MakeString( "%s.mat", @@ -92,40 +130,48 @@ RndMat *GemRepTemplate::GetMatByTag(const char *c, int slot) { } bool VertLess(const RndMesh::Vert &v1, const RndMesh::Vert &v2) { - if ((float)std::fabs(double(v1.pos.y - v2.pos.y)) < 0.1f) { // nonsense regswap + if (std::fabs(v1.pos.y - v2.pos.y) < 0.1f) { return v1.pos.x < v2.pos.x; - } - return v1.pos.y < v2.pos.y; + } else + return v1.pos.y < v2.pos.y; } void GemRepTemplate::SetupTailVerts() { - mObjectDir->Find("tail02.mesh", false)->Verts() = mTailVerts; // where assert + mTailVerts = mObjectDir->Find("tail02.mesh", true)->Verts(); // where assert MILO_ASSERT(!(mTailVerts.size()%2), 212); std::sort(mTailVerts.begin(), mTailVerts.end(), VertLess); mCapVerts = mTailVerts; - int i = 420; - mTailVerts.resize(i, true); - mCapVerts.resize(i, true); + + int i4 = mTailVerts.size() / 2; + for (int i = 0; i < i4; i++) { + mCapVerts[i + i4] = mTailVerts[i]; + } + mTailVerts.resize(i4, true); + mCapVerts.resize(i4, true); + mNumTailSections[0] = 90; + mNumTailSections[1] = 2; + mTailSectionLength[0] = kTailMaxLength / mNumTailSections[0]; + mTailSectionLength[1] = kTailMaxLength - mTailSectionLength[0]; } int GemRepTemplate::GetNumTailSections(GemRepTemplate::TailType type) const { MILO_ASSERT(type < kNumTailTypes, 232); - return this[type * 4].mNumTailSections; // ???? + return mNumTailSections[type]; } float GemRepTemplate::GetTailSectionLength(GemRepTemplate::TailType type) const { MILO_ASSERT(type < kNumTailTypes, 238); - return this[type * 4].mTailSectionLen; // ???? + return mTailSectionLength[type]; } RndMat *GemRepTemplate::GetSlotMat(int matIndex, int slotIndex) const { MILO_ASSERT_RANGE(matIndex, 0, kNumGemSlotMats, 244); MILO_ASSERT_RANGE(slotIndex, 0, mTrackCfg.GetMaxSlots(), 245); - return mSlots[matIndex + slotIndex]; + return mSlotMats[matIndex + slotIndex]; } void GemRepTemplate::SetSlotMat(int matIndex, int slotIndex, RndMat *mat) { MILO_ASSERT_RANGE(matIndex, 0, kNumGemSlotMats, 251); MILO_ASSERT_RANGE(slotIndex, 0, mTrackCfg.GetMaxSlots(), 252); - mSlots[matIndex + slotIndex] = mat; + mSlotMats[matIndex + slotIndex] = mat; } diff --git a/src/band3/bandtrack/GemRepTemplate.h b/src/band3/bandtrack/GemRepTemplate.h index d74aeb210..8c65d0177 100644 --- a/src/band3/bandtrack/GemRepTemplate.h +++ b/src/band3/bandtrack/GemRepTemplate.h @@ -40,19 +40,16 @@ class GemRepTemplate { Vector2 kTailFrequencyRange; // 0x24 Vector2 kTailAmplitudeRange; // 0x2C const TrackConfig &mTrackCfg; // 0x34 - RndMat **mSlots; // 0x38 - float unk_0x3C; - float unk_0x40; + RndMat **mSlotMats; // 0x38 + float mTailClipY; // 0x3c + float mTailScaleX; // 0x40 ObjectDir *mObjectDir; // 0x44 - uint mNumTailSections; - u32 pad1; - float mTailSectionLen; - u32 pad2; - + int mNumTailSections[2]; // 0x48 + float mTailSectionLength[2]; // 0x50 RndMesh::VertVector mTailVerts; // 0x58 - RndMesh::VertVector mCapVerts; - - int pad[3]; - + RndMesh::VertVector mCapVerts; // 0x64 + RndMat *mTailMiss; // 0x70 + RndMat *mTailBonus; // 0x74 + RndMat *mTailChord; // 0x78 std::vector mTails; // 0x7C }; diff --git a/src/band3/bandtrack/GemSmasher.h b/src/band3/bandtrack/GemSmasher.h index de35769f7..d9fa388cc 100644 --- a/src/band3/bandtrack/GemSmasher.h +++ b/src/band3/bandtrack/GemSmasher.h @@ -56,7 +56,7 @@ class GemSmasher { EventTrigger *mReleaseTrig; // 0x5C EventTrigger *mMissAfterRelease; // 0x60 RndMesh *mGemSmasherGlow; // 0x64 - bool mGlowing, mBurning, unk_0x6A; + bool mGlowing, mBurning, unk_0x6A; // 0x6a - is keyboard track? bool Glowing() const; void SetGlowing(bool); // 0x68, 0x69, 0x6A }; diff --git a/src/system/rndobj/Mesh.h b/src/system/rndobj/Mesh.h index 36581c6a3..1e4fd3202 100644 --- a/src/system/rndobj/Mesh.h +++ b/src/system/rndobj/Mesh.h @@ -112,7 +112,7 @@ class RndMesh : public RndDrawable, public RndTransformable { } ~VertVector() { mCapacity = 0; - resize(0, true); + clear(); } int size() const { return mNumVerts; } bool empty() const { return mNumVerts == 0; } From a36a1279dbacde74faa8de5f30397b8dbc1fa9a4 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:45:36 -0700 Subject: [PATCH 12/12] gemsmasher refactor --- src/band3/bandtrack/GemSmasher.cpp | 6 +-- src/band3/bandtrack/GemSmasher.h | 86 +++++++++++++++--------------- 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/band3/bandtrack/GemSmasher.cpp b/src/band3/bandtrack/GemSmasher.cpp index bc6188447..d8565a273 100644 --- a/src/band3/bandtrack/GemSmasher.cpp +++ b/src/band3/bandtrack/GemSmasher.cpp @@ -10,7 +10,7 @@ GemSmasher::GemSmasher(int slot, RndDir *dir, bool keys) mMissTrig(NULL), mBurnTrig(NULL), mBurnBonusTrig(NULL), mBurnChordTrig(NULL), mBREBurnTrig(NULL), mBREBurnChord(NULL), mStopBurnTrig(NULL), mPressTrig(NULL), mReleaseTrig(NULL), mMissAfterRelease(NULL), mGemSmasherGlow(NULL), mGlowing(false), - mBurning(false), unk_0x6A(keys) { + mBurning(false), mIsKeyboardTrack(keys) { if (mDir) { mHitSmashTrig = mDir->Find("hit.trig", false); if (mHitSmashTrig == NULL) @@ -125,7 +125,7 @@ void GemSmasher::CodaHitChord() { } void GemSmasher::Miss() { - if (unk_0x6A && !mGlowing) { + if (mIsKeyboardTrack && !mGlowing) { if (mMissAfterRelease) mMissAfterRelease->Trigger(); } else { @@ -193,7 +193,7 @@ void GemSmasher::FillHit(int i) { } void GemSmasher::SetGlowing(bool b) { - if (unk_0x6A) { + if (mIsKeyboardTrack) { bool test; if (mDir) test = mDir->mShowing; diff --git a/src/band3/bandtrack/GemSmasher.h b/src/band3/bandtrack/GemSmasher.h index d9fa388cc..80ae1fa01 100644 --- a/src/band3/bandtrack/GemSmasher.h +++ b/src/band3/bandtrack/GemSmasher.h @@ -10,53 +10,55 @@ class GemSmasher { ~GemSmasher(); void Reset(bool); RndDir *Dir() const { return mDir; } + bool Null() const; + bool Showing() const; + void Hit(); + void HitDrum(); + void HitDrumBonus(); + void HitCymbal(); + void HitCymbalBonus(); + void HitChord(); + void HitChordBonus(); + void HitBonus(); + void CodaHit(); + void CodaHitChord(); + void Miss(); + void Burn(); + void BurnBonus(); + void BurnChord(); + void CodaBurn(); + void CodaBurnChord(); + void StopBurn(); + void FillHit(int); + bool Glowing() const; + void SetGlowing(bool); int mSlot; // 0x0 - RndDir *mDir; - bool Null() const; - bool Showing() const; // 0x4 - EventTrigger *mHitSmashTrig; - void Hit(); // 0x8 - EventTrigger *mHitDrumsTrig; - void HitDrum(); // 0xC - EventTrigger *mHitDrumsBonus; - void HitDrumBonus(); // 0x10 - EventTrigger *mHitCymsTrig; - void HitCymbal(); // 0x14 - EventTrigger *mHitCymsBonus; - void HitCymbalBonus(); // 0x18 - EventTrigger *mHitChordTrig; - void HitChord(); // 0x1C - EventTrigger *mHitChordBonus; - void HitChordBonus(); // 0x20 - EventTrigger *mHitBonus; - void HitBonus(); // 0x24 - EventTrigger *mBREHitTrig; - void CodaHit(); // 0x28 - EventTrigger *mBREHitChord; - void CodaHitChord(); // 0x2C - EventTrigger *mMissTrig; - void Miss(); // 0x30 - EventTrigger *mBurnTrig; - void Burn(); // 0x34 - EventTrigger *mBurnBonusTrig; - void BurnBonus(); // 0x38 - EventTrigger *mBurnChordTrig; - void BurnChord(); // 0x3C - EventTrigger *mBREBurnTrig; - void CodaBurn(); // 0x40 - EventTrigger *mBREBurnChord; - void CodaBurnChord(); // 0x44 - EventTrigger *mStopBurnTrig; - void StopBurn(); // 0x48 - EventTrigger *mHitFillTrig; - void FillHit(int); // 0x4C + RndDir *mDir; // 0x4 + EventTrigger *mHitSmashTrig; // 0x8 + EventTrigger *mHitDrumsTrig; // 0xc + EventTrigger *mHitDrumsBonus; // 0x10 + EventTrigger *mHitCymsTrig; // 0x14 + EventTrigger *mHitCymsBonus; // 0x18 + EventTrigger *mHitChordTrig; // 0x1c + EventTrigger *mHitChordBonus; // 0x20 + EventTrigger *mHitBonus; // 0x24 + EventTrigger *mBREHitTrig; // 0x28 + EventTrigger *mBREHitChord; // 0x2c + EventTrigger *mMissTrig; // 0x30 + EventTrigger *mBurnTrig; // 0x34 + EventTrigger *mBurnBonusTrig; // 0x38 + EventTrigger *mBurnChordTrig; // 0x3c + EventTrigger *mBREBurnTrig; // 0x40 + EventTrigger *mBREBurnChord; // 0x44 + EventTrigger *mStopBurnTrig; // 0x48 + EventTrigger *mHitFillTrig; // 0x4c std::vector mMoreTriggers; // 0x50 EventTrigger *mPressTrig; // 0x58 EventTrigger *mReleaseTrig; // 0x5C EventTrigger *mMissAfterRelease; // 0x60 RndMesh *mGemSmasherGlow; // 0x64 - bool mGlowing, mBurning, unk_0x6A; // 0x6a - is keyboard track? - bool Glowing() const; - void SetGlowing(bool); // 0x68, 0x69, 0x6A + bool mGlowing; // 0x68 + bool mBurning; // 0x69 + bool mIsKeyboardTrack; // 0x6a - is keyboard track? };