System: Implement TempSaveData - #1298
Conversation
TempSaveData
MonsterDruide1
left a comment
There was a problem hiding this comment.
@MonsterDruide1 reviewed 4 files and all commit messages, and made 9 comments.
Reviewable status: all files reviewed, 9 unresolved discussions (waiting on german77).
src/System/TempSaveData.h line 19 at r1 (raw file):
void initForScenario(); void resetMiniGame(); void setInfo(s32 worldIndex, s32 unknown);
Suggestion:
void setInfo(s32 worldIndex, s32 scenarioIndex);src/System/TempSaveData.h line 34 at r1 (raw file):
private: UniqObjInfo* mWordObjects = nullptr;
Suggestion:
UniqObjInfo* mWorldObjects = nullptr;src/System/TempSaveData.h line 36 at r1 (raw file):
UniqObjInfo* mWordObjects = nullptr; UniqObjInfo* mMiniGameObjects = nullptr; UniqObjInfo* mScenarioObjects = nullptr;
Might be turned into FixedHeapArray, moving its declaration from GameDataFile into some common header? Removes all those magical 64s.
Code quote:
UniqObjInfo* mWordObjects = nullptr;
UniqObjInfo* mMiniGameObjects = nullptr;
UniqObjInfo* mScenarioObjects = nullptr;src/System/TempSaveData.h line 38 at r1 (raw file):
UniqObjInfo* mScenarioObjects = nullptr; s32 mWorldIndex = -1; s32 _1c = -1;
same arg as for GameDataFile::startStage in GameDataHolder::startStage
Suggestion:
s32 mScenarioIndex = -1;src/System/TempSaveData.cpp line 19 at r1 (raw file):
mMiniGameObjects[i].clear(); mScenarioObjects[i].clear(); // BUG: Clearing multiple times the hashed values
This does not (potentially) result in faulty behaviour - clearing a map multiple times should be handled just fine (I hope!), so no further weird behaviour could emerge from this.
Suggestion:
// NOTE: Clearing multiple times the hashed valuessrc/System/TempSaveData.cpp line 51 at r1 (raw file):
} void deleteUniqObj(UniqObjInfo* objInfo, const al::PlacementId* placementId,
Suggestion:
static ALWAYS_INLINE s32 getUniqObjId(const UniqObjInfo* objInfo, const al::PlacementId* placementId,
const char* stageName) {
al::StringTmp<128> str;
placementId->makeString(&str);
s32 id = -1;
for (s32 i = 0; i < 64; i++) {
if (!objInfo[i].getStageName().isEmpty() &&
al::isEqualString(objInfo[i].getStageName().cstr(), stageName) &&
al::isEqualString(objInfo[i].getObjId(), str)) {
id = i;
break;
}
}
return id;
}
static ALWAYS_INLINE void deleteUniqObj(UniqObjInfo* objInfo, const al::PlacementId* placementId,src/System/TempSaveData.cpp line 78 at r1 (raw file):
break; } }
This block seems to be shared among three functions. Can it be made a separate static function to deduplicate?
Code quote:
s32 id = getUniqObjId(objInfo, placementId, stageName);
if (id != -1)
return;
for (s32 i = 0; i < 64; i++) {
if (objInfo[i].getStageName()->isEmpty()) {
placementId->makeString(objInfo[i].getObjId());
objInfo[i].getStageName()->format("%s", stageName);
break;
}
}src/System/TempSaveData.cpp line 134 at r1 (raw file):
} // NON_MATCHING: Wrong loading order https://decomp.me/scratch/OCYs2
Issue is that it your current code loads mWorldValues from the offset within TempSaveData twice, while the original only does it once.
However, I can't find a match with that information either. Best I can do is add this to StrTreeMap:
void put(const SafeString& key, const Value& value) {
auto* node = find(key);
if (node) {
node->value() = value;
return;
}
insert(key, value);
}... which results in a mismatch because the SafeString constructor is only called once at the very top, while it should be called twice (again for insert). Changing the type to const char* requires an inline to keep the function inline, but then results in the same mismatch as observed right now.
src/System/UniqObjInfo.h line 9 at r1 (raw file):
} class UniqObjInfo {
Given the Info name and full required transparency for member variables, maybe this is just a struct?
german77
left a comment
There was a problem hiding this comment.
@german77 made 9 comments.
Reviewable status: 1 of 8 files reviewed, 9 unresolved discussions (waiting on MonsterDruide1).
src/System/TempSaveData.h line 36 at r1 (raw file):
Previously, MonsterDruide1 wrote…
Might be turned into
FixedHeapArray, moving its declaration fromGameDataFileinto some common header? Removes all those magical64s.
Done.
src/System/TempSaveData.h line 38 at r1 (raw file):
Previously, MonsterDruide1 wrote…
same arg as for
GameDataFile::startStageinGameDataHolder::startStage
Done.
src/System/TempSaveData.cpp line 19 at r1 (raw file):
Previously, MonsterDruide1 wrote…
This does not (potentially) result in faulty behaviour - clearing a map multiple times should be handled just fine (I hope!), so no further weird behaviour could emerge from this.
Done. It might have a performance hit
src/System/TempSaveData.cpp line 78 at r1 (raw file):
Previously, MonsterDruide1 wrote…
This block seems to be shared among three functions. Can it be made a separate
staticfunction to deduplicate?
Done.
src/System/TempSaveData.cpp line 134 at r1 (raw file):
Previously, MonsterDruide1 wrote…
Issue is that it your current code loads
mWorldValuesfrom the offset withinTempSaveDatatwice, while the original only does it once.However, I can't find a match with that information either. Best I can do is add this to
StrTreeMap:void put(const SafeString& key, const Value& value) { auto* node = find(key); if (node) { node->value() = value; return; } insert(key, value); }... which results in a mismatch because the
SafeStringconstructor is only called once at the very top, while it should be called twice (again forinsert). Changing the type toconst char*requires aninlineto keep the function inline, but then results in the same mismatch as observed right now.
I will update this function once is pushed into sead. I will keep trying for a few days to find a match.
src/System/UniqObjInfo.h line 9 at r1 (raw file):
Previously, MonsterDruide1 wrote…
Given the
Infoname and full required transparency for member variables, maybe this is just astruct?
Done. Agreed
src/System/TempSaveData.h line 19 at r1 (raw file):
void initForScenario(); void resetMiniGame(); void setInfo(s32 worldIndex, s32 unknown);
Done.
src/System/TempSaveData.h line 34 at r1 (raw file):
private: UniqObjInfo* mWordObjects = nullptr;
Done.
src/System/TempSaveData.cpp line 51 at r1 (raw file):
} void deleteUniqObj(UniqObjInfo* objInfo, const al::PlacementId* placementId,
Done deleteUniqObj has a symbol and is not inlined
|
Depends on open-ead/sead#274 |
MonsterDruide1
left a comment
There was a problem hiding this comment.
@MonsterDruide1 reviewed 9 files and all commit messages, made 7 comments, and resolved 8 discussions.
Reviewable status: 9 of 10 files reviewed, 7 unresolved discussions (waiting on german77).
src/System/TempSaveData.cpp line 51 at r1 (raw file):
Previously, german77 (Narr the Reg) wrote…
Done deleteUniqObj has a symbol and is not inlined
Cannot confirm, I don't see this function anywhere, neither with nor without symbol?
lib/sead at r2 (raw file):
blocked by open-ead/sead#274
src/System/TempSaveData.cpp at r2 (raw file):
TODO: skim entire file again
src/System/TempSaveData.cpp line 36 at r2 (raw file):
static ALWAYS_INLINE s32 getUniqObjId(const UniqObjInfo* objInfo, const al::PlacementId* placementId, const char* stageName) {
Might need template <...> for FixedHeapArray again
then remove all ::maxObjEntries usages
Suggestion:
static ALWAYS_INLINE s32 getUniqObjId(const FixedHeapArray& objInfo,
const al::PlacementId* placementId, const char* stageName) {src/System/TempSaveData.cpp line 52 at r2 (raw file):
} static ALWAYS_INLINE void writeUniqObj(UniqObjInfo* objInfo, const al::PlacementId* placementId,
same here
src/System/TempSaveData.cpp line 67 at r2 (raw file):
} void deleteUniqObj(UniqObjInfo* objInfo, const al::PlacementId* placementId,
same here
src/System/TempSaveData.h line 35 at r2 (raw file):
s32 getWorldIndex() const { return mWorldIndex; } static const s32 maxObjEntries = 64;
Mark it not only as constant (= rodata), but "definitely known at compile time" - not sure if it has an effect on codegen, I could imagine const still putting this into .rodata.
Suggestion:
static constexpr s32 maxObjEntries = 64;
german77
left a comment
There was a problem hiding this comment.
@german77 made 1 comment.
Reviewable status: 9 of 10 files reviewed, 7 unresolved discussions (waiting on MonsterDruide1).
src/System/TempSaveData.cpp line 51 at r1 (raw file):
Previously, MonsterDruide1 wrote…
Cannot confirm, I don't see this function anywhere, neither with nor without symbol?
does 0x710053d55c is something you can see?
german77
left a comment
There was a problem hiding this comment.
@german77 made 4 comments.
Reviewable status: 9 of 10 files reviewed, 7 unresolved discussions (waiting on MonsterDruide1).
src/System/TempSaveData.h line 35 at r2 (raw file):
Previously, MonsterDruide1 wrote…
Mark it not only as
constant (= rodata), but "definitely known at compile time" - not sure if it has an effect on codegen, I could imagineconststill putting this into.rodata.
Done.
src/System/TempSaveData.cpp line 36 at r2 (raw file):
Previously, MonsterDruide1 wrote…
Might need
template <...>forFixedHeapArrayagainthen remove all
::maxObjEntriesusages
I already tried it messes up quite a bit of stuff for all functions https://decomp.me/scratch/G6BuN I believe FixedHeapArray is not providing any benefit to this class.
src/System/TempSaveData.cpp line 52 at r2 (raw file):
Previously, MonsterDruide1 wrote…
same here
Ditto
src/System/TempSaveData.cpp line 67 at r2 (raw file):
Previously, MonsterDruide1 wrote…
same here
Ditto
MonsterDruide1
left a comment
There was a problem hiding this comment.
@MonsterDruide1 reviewed 2 files and all commit messages, made 2 comments, and resolved 2 discussions.
Reviewable status: 9 of 10 files reviewed, 5 unresolved discussions (waiting on german77).
src/System/TempSaveData.cpp line 51 at r1 (raw file):
Previously, german77 (Narr the Reg) wrote…
does 0x710053d55c is something you can see?
Ah, function sorting broke for me for some reason. Agreed, that function exists.
src/System/TempSaveData.cpp line 36 at r2 (raw file):
Previously, german77 (Narr the Reg) wrote…
I already tried it messes up quite a bit of stuff for all functions https://decomp.me/scratch/G6BuN I believe FixedHeapArray is not providing any benefit to this class.
Fixed by removing & and just having it be an object of type FixedHeapArray.
Only looks slightly weird, because this would usually result in a copy of the object - but kind-of makes sense that a Heap array doesn't copy its entire contents, but just results in a shallow copy pointing to the same data, so ... I think it's still better than raw pointers.
german77
left a comment
There was a problem hiding this comment.
@german77 made 3 comments.
Reviewable status: 7 of 10 files reviewed, 5 unresolved discussions (waiting on MonsterDruide1).
src/System/TempSaveData.cpp line 36 at r2 (raw file):
Previously, MonsterDruide1 wrote…
Fixed by removing
&and just having it be an object of typeFixedHeapArray.
Only looks slightly weird, because this would usually result in a copy of the object - but kind-of makes sense that a Heap array doesn't copy its entire contents, but just results in a shallow copy pointing to the same data, so ... I think it's still better than raw pointers.
Done.
src/System/TempSaveData.cpp line 52 at r2 (raw file):
Previously, german77 (Narr the Reg) wrote…
Ditto
Done.
src/System/TempSaveData.cpp line 67 at r2 (raw file):
Previously, german77 (Narr the Reg) wrote…
Ditto
Done.
MonsterDruide1
left a comment
There was a problem hiding this comment.
@MonsterDruide1 reviewed 1 file and all commit messages, and resolved 3 discussions.
Reviewable status: 8 of 10 files reviewed, 2 unresolved discussions.
MonsterDruide1
left a comment
There was a problem hiding this comment.
@MonsterDruide1 made 1 comment and resolved 1 discussion.
Reviewable status: 8 of 10 files reviewed, 1 unresolved discussion (waiting on german77).
Previously, MonsterDruide1 wrote…
blocked by open-ead/sead#274
has been merged, this PR can be turned towards the finish line now.
Requires rebase, and this file should not be modified.
german77
left a comment
There was a problem hiding this comment.
@german77 made 1 comment.
Reviewable status: 8 of 10 files reviewed, 1 unresolved discussion (waiting on MonsterDruide1).
Previously, MonsterDruide1 wrote…
has been merged, this PR can be turned towards the finish line now.
Requires rebase, and this file should not be modified.
Done.
MonsterDruide1
left a comment
There was a problem hiding this comment.
@MonsterDruide1 reviewed 2 files and all commit messages, and resolved 1 discussion.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on german77).
I'm attempting to find the correct implementation for
StrTreeMap::allocBufferthis did not trigger the issue I was looking for.TempSaveData seems to store a list obj bool values and stage objects.
writeHashInWorldis not matching https://decomp.me/scratch/OCYs2This change is
Report for 1.0 (0de3c75 - c92df4d)
📈 Matched code: 15.40% (+0.04%, +4736 bytes)
✅ 23 new matches
System/TempSaveDataTempSaveData::TempSaveData()System/TempSaveDatasead::StrTreeMap<32, bool>::insert(sead::SafeStringBase<char> const&, bool const&)System/TempSaveDataTempSaveData::writeInWorld(al::PlacementId const*, char const*)System/TempSaveDataTempSaveData::writeInWorldResetMiniGame(al::PlacementId const*, char const*)System/TempSaveDataTempSaveData::writeInScenario(al::PlacementId const*, char const*)System/TempSaveDataTempSaveData::writeHashInWorld(char const*, bool)System/TempSaveDataTempSaveData::findHashValueInWorld(char const*) constSystem/TempSaveDatadeleteUniqObj(FixedHeapArray<UniqObjInfo, 64>, al::PlacementId const*, char const*)System/TempSaveDataTempSaveData::isOnInWorld(al::PlacementId const*, char const*) constSystem/TempSaveDataTempSaveData::isOnInWorldResetMiniGame(al::PlacementId const*, char const*) constSystem/TempSaveDataTempSaveData::isOnInScenario(al::PlacementId const*, char const*) constSystem/TempSaveDataTempSaveData::init()System/TempSaveDatavoid sead::TreeMapImpl<sead::SafeStringBase<char> >::forEach<sead::Delegate1<sead::StrTreeMap<32, bool>, sead::TreeMapNode<sead::SafeStringBase<char> >*> >(sead::TreeMapNode<sead::SafeStringBase<char> >*, sead::Delegate1<sead::StrTreeMap<32, bool>, sead::TreeMapNode<sead::SafeStringBase<char> >*> const&)System/TempSaveDatasead::Delegate1<sead::StrTreeMap<32, bool>, sead::TreeMapNode<sead::SafeStringBase<char> >*>::clone(sead::Heap*) constSystem/TempSaveDataTempSaveData::initForScenario()System/TempSaveDataTempSaveData::resetMiniGame()System/TempSaveDatasead::Delegate1<sead::StrTreeMap<32, bool>, sead::TreeMapNode<sead::SafeStringBase<char> >*>::invoke(sead::TreeMapNode<sead::SafeStringBase<char> >*)System/TempSaveDatasead::StrTreeMap<32, bool>::Node::erase_()System/TempSaveDatasead::StrTreeMap<32, bool>::eraseNodeForClear_(sead::TreeMapNode<sead::SafeStringBase<char> >*)System/TempSaveDataTempSaveData::setInfo(int, int)System/TempSaveDataTempSaveData::deleteInWorld(al::PlacementId const*, char const*)System/TempSaveDataTempSaveData::deleteInWorldResetMiniGame(al::PlacementId const*, char const*)System/TempSaveDatasead::StrTreeMap<32, bool>::Node::~Node()