Merge branch 'main' into nw4r-lyt

This commit is contained in:
Elijah Thomas
2024-06-09 23:49:04 -04:00
committed by GitHub
56 changed files with 2565 additions and 415 deletions
+37
View File
@@ -0,0 +1,37 @@
#include <d/tg/d_t_rock_boat.h>
#include <d/a/obj/d_a_obj_base.h>
SPECIAL_ACTOR_PROFILE(TAG_ROCK_BOAT, dTgRockBoat_c, fProfile::TAG_ROCK_BOAT, 0x173, 0, 3);
STATE_DEFINE(dTgRockBoat_c, Wait);
int dTgRockBoat_c::create() {
mStateMgr.changeState(StateID_Wait);
cooldown = 1;
return 1;
}
int dTgRockBoat_c::doDelete() {
return 1;
}
int dTgRockBoat_c::actorExecute() {
mStateMgr.executeState();
return 1;
}
int dTgRockBoat_c::draw() {
return 1;
}
void dTgRockBoat_c::initializeState_Wait() {}
void dTgRockBoat_c::executeState_Wait() {
if (cooldown > 0 && --cooldown == 0) {
dAcObjBase_c::create(fProfile::OBJ_ROCK_BOAT, roomid, (boatNum << 0x1c) | 0xff, &position, 0, 0, -1);
cooldown = 0x259;
if (++boatNum == 0xf) {
boatNum = 0;
}
}
}
void dTgRockBoat_c::finalizeState_Wait() {}
+100
View File
@@ -0,0 +1,100 @@
#include <d/tg/d_t_timer.h>
#include <toBeSorted/sceneflag_manager.h>
SPECIAL_ACTOR_PROFILE(TIMER_TAG, dTgTimer_c, fProfile::TAG_TIMER, 0x029F, 0, 0);
// TODO counter abstraction
bool increment(u16 *t) {
if (*t < 0xFFFF) {
(*t)++;
return true;
}
return false;
}
int dTgTimer_c::create() {
switch (getSubtypeFromParams()) {
case 0:
mGetTargetTimeFunc = dTgTimer_c::getConstant0x50_Thunk;
break;
case 1:
mTargetTime = getTimerFromParams() * 0x1e;
mGetTargetTimeFunc = getStoredTargetTime;
break;
default:
mTargetTime = getTimerFromParams();
mGetTargetTimeFunc = getStoredTargetTime;
break;
}
resetTimer();
return 1;
}
int dTgTimer_c::actorExecute() {
bool getFlag = SceneflagManager::sInstance->checkFlag(roomid, getCheckSceneflag());
if (getFlag) {
if (checkShouldTrigger()) {
SceneflagManager::sInstance->setFlag(roomid, getSetSceneflag());
} else {
incrementTimer();
}
} else {
resetTimer();
}
return 1;
}
int dTgTimer_c::getSubtypeFromParams() {
return params & 0xFF;
}
u16 dTgTimer_c::getTimerFromParams() {
return params >> 8 & 0xFF;
}
u16 dTgTimer_c::getCheckSceneflag() {
return params >> 0x10 & 0xFF;
}
u16 dTgTimer_c::getSetSceneflag() {
return params >> 0x18 & 0xFF;
}
u16 dTgTimer_c::getTimer() {
return mTimer;
}
u16 dTgTimer_c::getConstant0x50() {
return 0x50;
}
u16 dTgTimer_c::setTimer(u16 val) {
mTimer = val;
}
u16 dTgTimer_c::getTargetTime() {
return (this->*mGetTargetTimeFunc)();
}
void dTgTimer_c::resetTimer() {
setTimer(0);
}
void dTgTimer_c::incrementTimer() {
u16 t = getTimer();
increment(&t);
setTimer(t);
}
bool dTgTimer_c::checkShouldTrigger() {
return getTargetTime() <= getTimer();
}
u16 dTgTimer_c::getStoredTargetTime() {
return mTargetTime;
}
// TODO what causes this (likely weak) thunk?
u16 dTgTimer_c::getConstant0x50_Thunk() {
return getConstant0x50();
}
+114
View File
@@ -0,0 +1,114 @@
#include <c/c_math.h>
#include <d/tg/d_t_tumble_weed.h>
#include <m/m_vec.h>
SPECIAL_ACTOR_PROFILE(TAG_TUMBLE_WEED, dTgTumbleWeed_c, fProfile::TUMBLE_WEED_TAG, 0x0244, 0, 0);
STATE_DEFINE(dTgTumbleWeed_c, AreaOut);
STATE_DEFINE(dTgTumbleWeed_c, AreaIn);
STATE_DEFINE(dTgTumbleWeed_c, Wind);
int dTgTumbleWeed_c::create() {
tumbleweedTimer = 0;
windTimer = 0x96;
mStateMgr.changeState(StateID_AreaOut);
return 1;
}
u16 decr(u16 *num);
int dTgTumbleWeed_c::doDelete() {
return 1;
}
int dTgTumbleWeed_c::actorExecute() {
mStateMgr.executeState();
decr(&tumbleweedTimer);
return 1;
}
u16 decr(u16 *num) {
if (*num != 0) {
(*num)--;
}
return *num;
}
int dTgTumbleWeed_c::draw() {
return 1;
}
void dTgTumbleWeed_c::initializeState_AreaOut() {}
void dTgTumbleWeed_c::executeState_AreaOut() {
if (decr(&windTimer) == 0) {
windTimer = 0x96;
if (shouldDoWind()) {
mStateMgr.changeState(StateID_Wind);
return;
}
}
if (isWithinPlayerRadius(scale.x)) {
mStateMgr.changeState(StateID_AreaIn);
}
}
void dTgTumbleWeed_c::finalizeState_AreaOut() {}
void dTgTumbleWeed_c::initializeState_AreaIn() {}
void dTgTumbleWeed_c::executeState_AreaIn() {
if (tumbleweedTimer == 0) {
if (shouldSpawnTumbleweed()) {
doSpawnTumbleweed();
}
tumbleweedTimer = 600;
}
if (decr(&windTimer) == 0) {
windTimer = 0x96;
if (shouldDoWind()) {
mStateMgr.changeState(StateID_Wind);
return;
}
}
if (!isWithinPlayerRadius(scale.x)) {
mStateMgr.changeState(StateID_AreaOut);
}
}
void dTgTumbleWeed_c::finalizeState_AreaIn() {}
extern "C" void fn_475_1B00(fBase_c *, mVec3_c&);
void dTgTumbleWeed_c::initializeState_Wind() {
mVec3_c vec;
getWind(&vec);
if (childTumbleweed.p_owner != nullptr) {
fn_475_1B00(childTumbleweed.p_owner, vec);
}
}
void dTgTumbleWeed_c::executeState_Wind() {
if (isWithinPlayerRadius(scale.x)) {
mStateMgr.changeState(StateID_AreaIn);
} else {
mStateMgr.changeState(StateID_AreaOut);
}
}
void dTgTumbleWeed_c::finalizeState_Wind() {}
bool dTgTumbleWeed_c::shouldSpawnTumbleweed() {
bool spawnAllowed = false;
if (childTumbleweed.p_owner == nullptr && cM::rnd() <= 0.8f) {
spawnAllowed = true;
}
if (spawnAllowed) {
return true;
}
return false;
}
bool dTgTumbleWeed_c::shouldDoWind() {
return childTumbleweed.p_owner != nullptr && cM::rnd() <= 0.5f;
}
void dTgTumbleWeed_c::doSpawnTumbleweed() {
}
void dTgTumbleWeed_c::getWind(mVec3_c*) {}
+8 -11
View File
@@ -1,6 +1,8 @@
#include <d/d_dvd.h>
#include <m/m_dvd.h>
// clang-format off
#include <sized_string.h>
// clang-format on
namespace dDvd {
/** 800520f0 */
@@ -19,25 +21,20 @@ loader_c::loader_c() {
/** 80052130 */
loader_c::~loader_c() {}
// sprintf2
extern "C" void fn_8003D650(char *out, const char *fmt, ...);
/** 80052170 */
void *loader_c::request(const char *path, u8 mountDirection, EGG::Heap *heap) {
char buf[128];
if (mpBuffer != nullptr) {
return mpBuffer;
}
if (mpCommand == 0) {
mSize = -1;
mpHeap = heap != nullptr ? heap : mDvd::getArchiveHeap();
buf[0] = '\0';
fn_8003D650(buf, "US%s", path);
if (!mDvd::IsExistPath(buf)) {
fn_8003D650(buf, "%s", path);
SizedString<128> buf;
buf.sprintf("US%s", path);
if (!mDvd::IsExistPath(&buf)) {
buf.sprintf("%s", path);
}
mpCommand = mDvd_toMainRam_normal_c::create(buf, mountDirection, heap);
mpCommand = mDvd_toMainRam_normal_c::create(&buf, mountDirection, heap);
}
if (mpCommand != nullptr && mpCommand->mStatus != 0) {
mpBuffer = mpCommand->mDataPtr;
+398
View File
@@ -0,0 +1,398 @@
#include <d/d_rawarchive.h>
#include <rvl/VI.h>
class UnkManager {
public:
/* vtable at 8050df50 */
/** 800651c0 */
virtual void CreateArc(void *data, const char *path);
/** 800653d0 */
virtual void DestroyArc(const char *path);
u32 stage;
};
extern "C" int fn_80061B10(void *d, u32 len) {
u32 *data = (u32 *)d;
u32 result = 0;
// Compiler will unroll this loop
for (u32 len_words = len / 4; len_words != 0; len_words--) {
result += *data++;
}
return result;
}
extern "C" int fn_80061BA0(void *data, u32 len) {
int result = fn_80061B10(data, len);
return result != 0 ? result : -1;
}
extern "C" void fn_80061BE0(UnkManager *mgr, const char *name, size_t len) {
// Sets stage to all spaces
mgr->stage = 0x20202020;
// copies the stage name?
memcpy((char *)&mgr->stage, name, len);
}
dRawArcEntry_c::dRawArcEntry_c() {
mRefCount = 0;
mpDvdReq = nullptr;
mpArc = nullptr;
mpCommandHeap = nullptr;
mpData = nullptr;
mChecksum = 0;
mpFrmHeap = 0;
}
dRawArcEntry_c::~dRawArcEntry_c() {
// Wait for request to complete before destroying
if (mpDvdReq->mStatus == 0) {
do {
VIWaitForRetrace();
} while (mpDvdReq->mStatus == 0);
}
destroy(nullptr);
}
void dRawArcEntry_c::searchCallback(void *arg, void *data, const ARCDirEntry *entry, const char *path, bool ctrl) {
UnkManager *mgr = (UnkManager *)arg;
if (entry->isDir) {
int len = strlen(entry->name);
fn_80061BE0(mgr, entry->name, len <= 4 ? len : 4);
} else {
// dolphin: arg vtable at 8050df50
// any others?
if (ctrl) {
mgr->CreateArc(data, path);
// branch to 800651c0, sets up room
} else {
mgr->DestroyArc(path);
// branch to 800653d0, destroys room
}
}
}
void dRawArcEntry_c::searchCallback1(void *a, void *b, const ARCDirEntry *c, const char *d) {
searchCallback(a, b, c, d, true);
}
void dRawArcEntry_c::searchCallback2(void *a, void *b, const ARCDirEntry *c, const char *d) {
searchCallback(a, b, c, d, false);
}
bool dRawArcEntry_c::destroy(void *arg) {
if (mpDvdReq != nullptr) {
if (mpDvdReq->mStatus == 0) {
// Can't destroy if the request is still ongoing
return false;
}
mpArc = mpDvdReq->mDataPtr;
mpData = mpDvdReq->getArcBinary();
mAmountRead = mpDvdReq->mAmountRead;
mpCommandHeap = mpDvdReq->mHeap;
mpDvdReq->do_delete();
mpDvdReq = nullptr;
}
if (mpArc != nullptr) {
if (arg != nullptr) {
mpArc->searchInside(searchCallback2, arg);
}
if (mpFrmHeap != nullptr) {
mHeap::destroyFrmHeap(mpFrmHeap);
mpFrmHeap = nullptr;
}
mpArc->unmount();
mpArc = nullptr;
}
if (mpData != nullptr) {
EGG::Heap::free(mpData, nullptr);
mpData = nullptr;
}
mAmountRead = 0;
mChecksum = 0;
mpCommandHeap = 0;
return true;
}
bool dRawArcEntry_c::loadArcFromDiskChecked(const char *fileName, const char *dirName, u8 mountDirection,
EGG::Heap *heap) {
SizedString<128> path;
if (checkArcExistsOnDiskInner(path, fileName, dirName)) {
return loadArcFromDisk(fileName, &path, mountDirection, heap);
}
return false;
}
bool dRawArcEntry_c::loadArcFromDisk(const char *arcName, const char *arcPath, u8 mountDirection, EGG::Heap *heap) {
mpDvdReq = mDvd_mountMemArchive_c::create(arcPath, mountDirection, heap);
if (mpDvdReq == nullptr) {
return false;
}
mArcName = arcName;
return true;
}
BOOL dRawArcEntry_c::checkArcExistsOnDisk(const char *fileName, const char *dirName) {
SizedString<128> path;
return checkArcExistsOnDiskInner(path, fileName, dirName);
}
// sprintf2
extern "C" void fn_8003D650(char *out, const char *fmt, ...);
BOOL dRawArcEntry_c::checkArcExistsOnDiskInner(SizedString<128> &path, const char *fileName, const char *dirName) {
path.sprintf("/US/%s/%s.arc", dirName, fileName);
if (!mDvd::IsExistPath(&path)) {
path.sprintf("/%s/%s.arc", dirName, fileName);
if (!mDvd::IsExistPath(&path)) {
return false;
}
}
return true;
}
int dRawArcEntry_c::mount(const char *name, void *data, void *callbackArg, u8 mountDirection, EGG::Heap *heap) {
mArcName = name;
mpArc = EGG::Archive::mount(data, heap, (mountDirection == 0 || mountDirection == 1) ? 4 : -4);
if (mpArc == nullptr) {
return -1;
} else {
int result = onMount(callbackArg);
int ret = 0;
if (result == -1) {
ret = result;
}
return ret;
}
}
int dRawArcEntry_c::ensureLoadedMaybe(void *callbackArg) {
if (mpArc == nullptr) {
if (mpDvdReq == nullptr) {
return -1;
}
if (mpDvdReq->mStatus == 0) {
return 1;
}
mpArc = mpDvdReq->mDataPtr;
mpData = mpDvdReq->getArcBinary();
mAmountRead = mpDvdReq->mAmountRead;
if (mpData != nullptr) {
u32 blockSize = EGG::ExpHeap::getSizeForMBlock(mpData);
if (mAmountRead != blockSize) {
mAmountRead = blockSize;
}
}
mpCommandHeap = mpDvdReq->mHeap;
mpDvdReq->do_delete();
mpDvdReq = nullptr;
if (mpArc == nullptr) {
return -1;
}
mpFrmHeap = mHeap::makeHeapOnCurrentGameHeap(-1, name(), 0x20, 0);
if (mpFrmHeap == nullptr) {
return -1;
}
int result = onMount(callbackArg);
mHeap::restoreCurrentHeap();
mHeap::adjustFrmHeap(mpFrmHeap);
mChecksum = fn_80061BA0(mpData, mAmountRead);
if (result == -1) {
return result;
}
DCStoreRange(mpFrmHeap, mpFrmHeap->mHeapHandle->end - (u8 *)mpFrmHeap);
}
return 0;
}
int dRawArcEntry_c::onMount(void *callbackArg) {
mpArc->countFile();
if (callbackArg != nullptr) {
mpArc->searchInside(searchCallback1, callbackArg);
}
return 0;
}
dRawArcTable_c::dRawArcTable_c() {
mpEntries = nullptr;
mCount = 0;
mCallbackArg = nullptr;
}
dRawArcTable_c::~dRawArcTable_c() {
if (mpEntries) {
delete[] mpEntries;
mpEntries = nullptr;
mCount = 0;
}
}
bool dRawArcTable_c::init(u16 count, void *callbackArg, EGG::Heap *heap) {
mpEntries = new (heap, 0x04) dRawArcEntry_c[count]();
if (mpEntries == nullptr) {
return false;
}
mCount = count;
mCallbackArg = callbackArg;
return true;
}
BOOL dRawArcTable_c::getArcOrLoadFromDisk(const char *name, const char *dirName, u8 mountDirection, EGG::Heap *heap) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
entry = findEmptySlot();
if (entry == nullptr) {
return false;
}
bool result = entry->loadArcFromDiskChecked(name, dirName, mountDirection, heap);
if (!result) {
entry->destroy(mCallbackArg);
return false;
}
}
entry->increaseRefCount();
return true;
}
BOOL dRawArcTable_c::addEntryFromSuperArc(const char *name, void *data, u8 mountDirection, EGG::Heap *heap) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
entry = findEmptySlot();
if (entry == nullptr) {
return false;
}
int result = entry->mount(name, data, mCallbackArg, mountDirection, heap);
if (result != 0) {
entry->destroy(mCallbackArg);
return false;
}
}
entry->increaseRefCount();
return true;
}
int dRawArcTable_c::ensureLoadedMaybe2(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return -2;
}
return entry->ensureLoadedMaybe(mCallbackArg);
}
int dRawArcTable_c::ensureLoadedMaybe(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return -2;
}
return entry->ensureLoadedMaybe(mCallbackArg);
}
bool dRawArcTable_c::hasEntry(const char *name) {
return findEntry(name) != nullptr;
}
BOOL dRawArcTable_c::decreaseRefCount(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return false;
}
entry->decreaseRefCount();
if (!entry->isReferenced()) {
entry->destroy(mCallbackArg);
}
return true;
}
void *dRawArcTable_c::getDataFromOarc(const char *name, const char *path) {
void *data = nullptr;
dRawArcEntry_c *entry = findLoadedEntry(name);
if (entry != nullptr) {
EGG::Archive *arc = entry->getArc();
if (arc != nullptr) {
data = arc->getFile(path, nullptr);
}
}
return data;
}
void *dRawArcTable_c::getSubEntryData(const char *name, const char *path) {
void *data = nullptr;
dRawArcEntry_c *entry = findLoadedEntry(name);
if (entry != nullptr) {
EGG::Archive *arc = entry->getArc();
if (arc != nullptr) {
int num = arc->convertPathToEntryID(path);
if (num >= 0) {
data = arc->getFileFast(num, nullptr);
}
}
}
return data;
}
void *dRawArcTable_c::getLoadedArcData(const char *name) {
dRawArcEntry_c *entry = findLoadedEntry(name);
return entry == nullptr ? nullptr : entry->getData();
}
int dRawArcTable_c::ensureAllEntriesLoaded() {
dRawArcEntry_c *entry = mpEntries;
int result = 0;
for (int i = 0; i < mCount; i++) {
if (entry->isLoading()) {
result = entry->ensureLoadedMaybe(mCallbackArg);
if (result != 0) {
return result;
}
}
entry++;
}
return 0;
}
extern "C" bool strequals(const char *, const char *);
dRawArcEntry_c *dRawArcTable_c::findEntry(const char *name) const {
dRawArcEntry_c *entry = mpEntries;
for (int i = 0; i < mCount; i++) {
if (entry->isReferenced() && strequals(entry->name(), name)) {
return entry;
}
entry++;
}
return nullptr;
}
dRawArcEntry_c *dRawArcTable_c::findEmptySlot() {
dRawArcEntry_c *entry = mpEntries;
for (int i = 0; i < mCount; i++) {
if (!entry->isReferenced()) {
return entry;
}
entry++;
}
return nullptr;
}
dRawArcEntry_c *dRawArcTable_c::findLoadedEntry(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return nullptr;
} else if (entry->isNotLoaded()) {
return nullptr;
}
return entry;
}
+2 -3
View File
@@ -24,7 +24,6 @@ void (*fBase_c::sUnloadCallback)();
fBase_c::fBase_c()
: unique_ID(m_rootUniqueID), params(m_tmpCtData.params), profile_name(m_tmpCtData.prof_name),
group_type(m_tmpCtData.group_type), manager(this) {
fManager_c *mgr = &manager;
m_rootUniqueID = (fBaseID_e)(m_rootUniqueID + 1);
if (m_rootUniqueID == INVALID) {
@@ -33,8 +32,8 @@ fBase_c::fBase_c()
}
}
fManager_c::m_connectManage.addTreeNode(&mgr->connect_node, m_tmpCtData.connect_parent);
int searchTableIdx = mgr->getSearchTableNum();
fManager_c::m_connectManage.addTreeNode(&manager.connect_node, m_tmpCtData.connect_parent);
int searchTableIdx = manager.getSearchTableNum();
fManager_c::m_searchManage[searchTableIdx].prepend(&manager.search_node);
const fProfile::fBaseProfile_c *profile = (*fProfile::sProfileList)[profile_name];
+1 -1
View File
@@ -207,6 +207,6 @@ EGG::AssertHeap *mHeap::createAssertHeap(EGG::Heap *parent) {
return g_assertHeap;
}
EGG::Heap *mHeap::makeHeapOnCurrentGameHeap(size_t size, const char *name, u32 align, u32 flags) {
EGG::FrmHeap *mHeap::makeHeapOnCurrentGameHeap(size_t size, const char *name, u32 align, u32 flags) {
return makeFrmHeapAndUpdate(size, g_gameHeaps[0], name, align, flags);
}
+31
View File
@@ -0,0 +1,31 @@
#include <s/s_Phase.hpp>
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
sPhase_c::sPhase_c(phaseMethod **methodList, int count) {
mpMethodList = methodList;
mPhaseLength = count;
mCurrMethod = 0;
}
sPhase_c::METHOD_RESULT_e sPhase_c::callMethod(void *thisPtr) {
if (mCurrMethod >= mPhaseLength) {
return DONE;
}
METHOD_RESULT_e result = OK;
while (result == OK) {
result = (mpMethodList[mCurrMethod])(thisPtr);
if (result == OK) {
// Go to the next method
mCurrMethod++;
if (mCurrMethod >= mPhaseLength) {
return DONE;
}
}
}
return result;
}
+56
View File
@@ -0,0 +1,56 @@
#include <common.h>
#include <s/s_StateInterfaces.hpp>
#include <s/s_StateID.hpp>
#include <s/s_StateMethodUsr_FI.hpp>
#include <s/s_StateIDChk.hpp>
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
sStateID_c::NumberMemo_c sStateID_c::sm_numberMemo;
sStateID_c sStateID::null(nullptr);
sStateID_c::sStateID_c(const char *name) {
mpName = name;
mNumber = (name != nullptr) ? sm_numberMemo.get() : 0;
}
sStateID_c::~sStateID_c() {}
bool sStateID_c::isNull() const {
return mNumber == 0;
}
bool sStateID_c::isEqual(const sStateIDIf_c &other) const {
return number() == other.number();
}
bool sStateID_c::operator==(const sStateIDIf_c &other) const {
return isEqual(other);
}
bool sStateID_c::operator!=(const sStateIDIf_c &other) const {
return !isEqual(other);
}
bool sStateID_c::isSameName(const char *name) const {
// Just return false, the full implementation is in sFStateID_c
return false;
}
const char *sStateID_c::name() const {
return mpName;
}
unsigned int sStateID_c::number() const {
return mNumber;
}
sStateFctIf_c::~sStateFctIf_c() {}
sStateIDChkIf_c::~sStateIDChkIf_c() {}
sStateIDChk_c::~sStateIDChk_c() {}
sStateIDIf_c::~sStateIDIf_c() {}
sStateIf_c::~sStateIf_c() {}
sStateMethodIf_c::~sStateMethodIf_c() {}
sStateMethodUsr_FI_c::~sStateMethodUsr_FI_c() {}
sStateMgrIf_c::~sStateMgrIf_c() {}
+78
View File
@@ -0,0 +1,78 @@
#include <common.h>
#include <s/s_StateInterfaces.hpp>
#include <s/s_StateMethod.hpp>
#include <s/s_StateID.hpp>
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
sStateMethod_c::sStateMethod_c(sStateIDChkIf_c &checker, sStateFctIf_c &factory, const sStateIDIf_c &initialState) :
mpStateChk(checker),
mpStateFct(factory),
mInitFinalizeLock(false),
mExecutionLock(false),
mIsValid(false),
mStateChanged(false),
mRefreshStateMethod(false),
mpNewStateID(&initialState),
mpOldStateID(&sStateID::null),
mpStateID(&initialState),
mpState(nullptr) {
}
sStateMethod_c::~sStateMethod_c() {}
void sStateMethod_c::initializeStateMethod() {
if (!mpNewStateID->isNull() && !mInitFinalizeLock && !mIsValid) {
mInitFinalizeLock = true;
mpStateID = mpNewStateID;
int ret = initializeStateLocalMethod();
if (ret != 0) {
mIsValid = true;
} else {
mIsValid = false;
}
mInitFinalizeLock = false;
}
}
void sStateMethod_c::executeStateMethod() {
if (!mExecutionLock) {
// Skyward Sword change: Prevent runaway state changes?
int i = 2;
do {
if (mRefreshStateMethod) {
i--;
}
mRefreshStateMethod = false;
// We only want to execute if we have a valid next state
if (!mpNewStateID->isNull()) {
mExecutionLock = true;
executeStateLocalMethod();
mExecutionLock = false;
}
} while (mRefreshStateMethod && mStateChanged && i);
}
}
void sStateMethod_c::finalizeStateMethod() {
if (!mpNewStateID->isNull() && mIsValid && !mInitFinalizeLock) {
mInitFinalizeLock = true;
mpOldStateID = mpStateID;
finalizeStateLocalMethod();
mIsValid = false;
mInitFinalizeLock = false;
}
}
void sStateMethod_c::changeStateMethod(const sStateIDIf_c &newID) {
if (!newID.isNull()) {
mpNewStateID = &newID;
changeStateLocalMethod(newID);
mStateChanged = true;
}
}
+30
View File
@@ -0,0 +1,30 @@
#include <common.h>
#include <s/s_StateMethodUsr_FI.hpp>
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
sStateMethodUsr_FI_c::sStateMethodUsr_FI_c(sStateIDChkIf_c &check, sStateFctIf_c &factory, const sStateIDIf_c &state) :
sStateMethod_c(check, factory, state) {
}
int sStateMethodUsr_FI_c::initializeStateLocalMethod() {
mpState = mpStateFct.build(*getNewStateID()); // Create new state holder with the next state ID
mpState->initialize();
return 1;
}
void sStateMethodUsr_FI_c::executeStateLocalMethod() {
initializeStateMethod(); // Ensure we are in a valid state (this only actually initializes the state if !mIsValid)
mpState->execute();
}
void sStateMethodUsr_FI_c::finalizeStateLocalMethod() {
mpState->finalize();
mpStateFct.dispose(mpState);
}
void sStateMethodUsr_FI_c::changeStateLocalMethod(const sStateIDIf_c &newID) {
finalizeStateMethod(); // Terminate the current state
initializeStateMethod(); // Initialize the new state
}
@@ -0,0 +1,121 @@
#include <d/d_heap.h>
#include <toBeSorted/arc_managers/current_stage_arc_manager.h>
CurrentStageArcManager *CurrentStageArcManager::sInstance;
CurrentStageArcManager::CurrentStageArcManager() {
sInstance = this;
}
CurrentStageArcManager::~CurrentStageArcManager() {
sInstance = nullptr;
}
extern char lbl_80575250;
void CurrentStageArcManager::init(EGG::Heap *heap) {
mArcTable.init(18, &lbl_80575250, heap);
}
bool CurrentStageArcManager::setStage(const char *newStage) {
mStageName = newStage;
mCurrentLoadingStageArcName.sprintf("%s_stg_l0", mStageName);
if (dRawArcEntry_c::checkArcExistsOnDisk(&mCurrentLoadingStageArcName, getCurrentStageDirectory())) {
return (bool)mArcTable.getArcOrLoadFromDisk(&mCurrentLoadingStageArcName, getCurrentStageDirectory(), 0,
dHeap::work2Heap.heap);
} else {
mCurrentLoadingStageArcName.sprintf("%s_stg", mStageName);
return (bool)mArcTable.getArcOrLoadFromDisk(&mCurrentLoadingStageArcName, getCurrentStageDirectory(), 0,
dHeap::work2Heap.heap);
}
}
bool CurrentStageArcManager::decrement() {
return mArcTable.decreaseRefCount(&mCurrentLoadingStageArcName);
}
void *CurrentStageArcManager::getData(const char *fileName) {
return mArcTable.getDataFromOarc(&mCurrentLoadingStageArcName, fileName);
}
void *CurrentStageArcManager::getFileFromCurrentLay0Arc(const char *fileName) {
return mArcTable.getSubEntryData(&mCurrentLoadingStageArcName, fileName);
}
bool CurrentStageArcManager::loadFileFromExtraLayerArc(int layer) {
if (layer == 0) {
return true;
}
mStageExtraLayerArcName.sprintf("%s_stg_l%d", mStageName, layer);
if (dRawArcEntry_c::checkArcExistsOnDisk(&mStageExtraLayerArcName, getCurrentStageDirectory())) {
return (bool)mArcTable.getArcOrLoadFromDisk(&mStageExtraLayerArcName, getCurrentStageDirectory(), 0,
dHeap::work2Heap.heap);
} else {
return true;
}
}
bool CurrentStageArcManager::unloadExtraLayerArc() {
if (mArcTable.hasEntry(&mStageExtraLayerArcName)) {
return mArcTable.decreaseRefCount(&mStageExtraLayerArcName);
}
return true;
}
bool CurrentStageArcManager::loadRoomArc(int room) {
return (bool)mArcTable.getArcOrLoadFromDisk(getRoomArcDirectory(room), getCurrentStageDirectory(), 0,
dHeap::work2Heap.heap);
}
bool CurrentStageArcManager::addEntryFromSuperArc(const char *path, void *data) {
return (bool)mArcTable.addEntryFromSuperArc(path, data, 0, EGG::Heap::sCurrentHeap);
}
bool CurrentStageArcManager::unloadRoomArc(int room) {
mArcTable.decreaseRefCount(getRoomArcDirectory(room));
return true;
}
bool CurrentStageArcManager::decrement(const char *path) {
mArcTable.decreaseRefCount(path);
return true;
}
void *CurrentStageArcManager::loadFromRoomArc(int roomId, const char *fileName) {
return mArcTable.getDataFromOarc(getRoomArcDirectory(roomId), fileName);
}
void *CurrentStageArcManager::getDataFromRoomArc(int roomId, const char *fileName) {
return mArcTable.getSubEntryData(getRoomArcDirectory(roomId), fileName);
}
EGG::ExpHeap *getHeap() {
return dHeap::workExHeap.heap;
}
const char *CurrentStageArcManager::getCurrentStageDirectory() {
static SizedString<64> sStageDirTmp;
sStageDirTmp = "Stage/";
sStageDirTmp += &mStageName;
return &sStageDirTmp;
}
static SizedString<32> s_roomArcTmp;
const char *CurrentStageArcManager::getRoomArcDirectory(int room) const {
s_roomArcTmp.sprintf("%s_r%02d", mStageName, room);
return &s_roomArcTmp;
}
bool CurrentStageArcManager::create(EGG::Heap *heap) {
new (heap, 0x04) CurrentStageArcManager();
if (CurrentStageArcManager::sInstance == nullptr) {
return false;
}
CurrentStageArcManager::sInstance->init(heap);
return true;
}
@@ -0,0 +1,59 @@
#include <d/d_heap.h>
#include <toBeSorted/arc_managers/layout_arc_manager.h>
LayoutArcManager *LayoutArcManager::sInstance;
LayoutArcManager::LayoutArcManager() {
sInstance = this;
}
LayoutArcManager::~LayoutArcManager() {
sInstance = nullptr;
}
extern char lbl_80575250;
void LayoutArcManager::init(EGG::Heap *heap) {
mArcTable.init(16, &lbl_80575250, heap);
}
bool LayoutArcManager::loadLayoutArcFromDisk(const char *object, EGG::Heap *heap) {
if (heap == nullptr) {
heap = dHeap::layoutResHeap.heap;
}
return mArcTable.getArcOrLoadFromDisk(object, "Layout", 0, heap);
}
void LayoutArcManager::ensureLoaded1(const char *object) {
mArcTable.ensureLoadedMaybe2(object);
}
void LayoutArcManager::ensureLoaded2(const char *object) {
mArcTable.ensureLoadedMaybe(object);
}
bool LayoutArcManager::hasEntry(const char *object) {
return mArcTable.hasEntry(object);
}
bool LayoutArcManager::decrement(const char *path) {
return mArcTable.decreaseRefCount(path);
}
void *LayoutArcManager::getData(const char *oarcName, const char *fileName) {
return mArcTable.getDataFromOarc(oarcName, fileName);
}
void *LayoutArcManager::getLoadedData(const char *path) {
return mArcTable.getLoadedArcData(path);
}
bool LayoutArcManager::create(EGG::Heap *heap) {
new (heap, 0x04) LayoutArcManager();
if (LayoutArcManager::sInstance == nullptr) {
return false;
}
LayoutArcManager::sInstance->init(heap);
return true;
}
@@ -0,0 +1,92 @@
#include <d/d_heap.h>
#include <toBeSorted/arc_managers/oarc_manager.h>
OarcManager *OarcManager::sInstance;
OarcManager::OarcManager() {
sInstance = this;
}
OarcManager::~OarcManager() {
sInstance = nullptr;
}
extern char lbl_80575250;
void OarcManager::init(EGG::Heap *heap) {
mArcTable.init(200, &lbl_80575250, heap);
}
bool OarcManager::checkIfObjectArcExistsOnDisk(const char *object) {
return dRawArcEntry_c::checkArcExistsOnDisk(object, "Object");
}
bool OarcManager::loadObjectArcFromDisk(const char *object, EGG::Heap *heap) {
if (heap == nullptr) {
heap = dHeap::work2Heap.heap;
}
return mArcTable.getArcOrLoadFromDisk(object, "Object", 0, heap);
}
bool OarcManager::addEntryFromSuperArc(const char *object, void *data, EGG::Heap *heap) {
if (heap == nullptr) {
heap = EGG::Heap::sCurrentHeap;
}
return mArcTable.addEntryFromSuperArc(object, data, 0, heap);
}
void OarcManager::ensureLoaded1(const char *object) {
mArcTable.ensureLoadedMaybe2(object);
}
void OarcManager::ensureLoaded2(const char *object) {
mArcTable.ensureLoadedMaybe(object);
}
bool OarcManager::decrement(const char *path) {
return mArcTable.decreaseRefCount(path);
}
void *OarcManager::getData(const char *oarcName, const char *fileName) {
return mArcTable.getDataFromOarc(oarcName, fileName);
}
void *OarcManager::getMdlFromArc2(const char *oarcName) {
return mArcTable.getDataFromOarc(oarcName, "g3d/model.brres");
}
void *OarcManager::getMdlFromArc(const char *oarcName) {
return mArcTable.getSubEntryData(oarcName, "g3d/model.brres");
}
void *OarcManager::getZevFromArc(const char *oarcName) {
return mArcTable.getDataFromOarc(oarcName, "dat/zev.dat");
}
void *OarcManager::getDzbFromArc(const char *oarcName, const char *fileName) {
SizedString<32> str = "dzb/";
str += fileName;
str += ".dzb";
return mArcTable.getDataFromOarc(oarcName, &str);
}
void *OarcManager::getPlcFromArc(const char *oarcName, const char *fileName) {
SizedString<32> str = "dat/";
str += fileName;
str += ".plc";
return mArcTable.getDataFromOarc(oarcName, &str);
}
void *OarcManager::getSubEntryData(const char *oarcName, const char *fileName) {
return mArcTable.getSubEntryData(oarcName, fileName);
}
bool OarcManager::create(EGG::Heap *heap) {
new (heap, 0x04) OarcManager();
if (OarcManager::sInstance == nullptr) {
return false;
}
OarcManager::sInstance->init(heap);
return true;
}
+6 -29
View File
@@ -1,8 +1,9 @@
#include "toBeSorted/file_manager.h"
#include "f/f_base.h"
#include <m/m_heap.h>
// #include "libc.h"
#include <MSL_C/string.h>
// clang-format off
#include <sized_string.h>
// clang-format on
// This class here makes no sense and the name might
// be a total misnomer, but this gets the sinit section correct
@@ -101,29 +102,6 @@ u16 *FileManager::getStoryFlagsMut() {
/* 8000AA30 */ u16 *FileManager::getSkipFlags() {}
/* 8000AA40 */ void FileManager::setSkipFlagsChecked(u16 *flags, u32 offset, u16 count) {}
// This does strncat things - append src to dest
inline void fake_strncat(char *dest, const char *src, size_t max_len) {
if (src != nullptr) {
size_t len = strlen(dest);
size_t count = strlen(src);
count = len + count + 1 >= max_len ? max_len - len - 1 : count;
strncpy(dest + len, src, count);
// one instshuffle here - this should be (len + count),
// but then regalloc blows up and uses one more register in initFile
dest[count + len] = '\0';
}
}
// A function like this is inlined into in a bunch of area-related code
// It doesn't make a whole lot of sense to use strncat on a string just
// clipped to zero length...
inline void strnsth(char *dest, const char *src, size_t max_len) {
if (src != dest) {
dest[0] = '\0';
fake_strncat(dest, src, max_len);
}
}
/* 8000AAA0 */ void FileManager::initFile(int fileNum) {
mIsFileInvalid[1] = 1;
@@ -140,10 +118,9 @@ inline void strnsth(char *dest, const char *src, size_t max_len) {
file->selectedDowsingSlot = 0x8;
file->lastUsedPouchItemSlot = 0x8;
char buf[0x20];
buf[0] = '\0';
strnsth(buf, "F405", 0x20);
file->setAreaT1(buf);
SizedString<32> buf;
buf = "F405";
file->setAreaT1(&buf);
file->room_id_t1 = 0;
file->forced_layer_t1 = 0;
file->entrance_t1_load_flag = 1;
+2 -58
View File
@@ -1,64 +1,8 @@
#include "libc.h"
#include <common.h>
#include "toBeSorted/bitwise_flag_helper.h"
#include "toBeSorted/sceneflag_manager.h"
#include "toBeSorted/file_manager.h"
#include "toBeSorted/flag_space.h"
class SceneflagManager {
public:
FlagSpace mSceneflags;
FlagSpace mTempflags;
FlagSpace mZoneflags;
BitwiseFlagHelper mFlagHelper;
u16 mSceneIdx;
u8 mShouldCommit;
static u16 sTempFlags[4];
static u16 sSceneFlags[8];
static u16 sZoneFlags[0xFC];
static SceneflagManager *sInstance;
void doNothing();
void setShouldCommit(u16 flag);
SceneflagManager();
s32 isNotTempOrZoneFlag(u16 flag);
s32 isZoneFlag(u32 flag);
void updateFlagindex(u16 flagindex);
void copyFromSave(u32 flagindex);
void unsetAllTempflags();
void zoneflagsResetAll();
void zoneflagsResetForRoom(u16 roomId);
void unsetZoneAndTempflags();
void unsetAllZoneflags();
void unsetZoneflagsForRoom(u16 roomId);
u16 getZoneflagSlot(u16 roomId, u16 flag);
u16 getSceneflagSlotGlobal(u16 sceneIdx, u16 flag);
u16 getSceneflagSlot(u16 flag);
u16 getTempflagSlot(u16 flag);
bool checkZoneFlag(u16 roomId, u16 flag);
bool checkUncommittedZoneflag(u16 roomId, u16 flag);
u16 checkUncommittedZoneflag2(u16 roomId, u16 flag) {
return checkUncommittedZoneflag(roomId, flag);
}
bool checkUncommittedTempOrSceneflag(u16 flag);
u16 checkUncommittedTempOrSceneflag2(u16 flag) {
return checkUncommittedTempOrSceneflag(flag);
}
bool checkFlag(u16 roomId, u16 flag);
bool checkSceneflagGlobal(u16 sceneIdx, u16 flag);
bool checkTempOrSceneflag(u16 flag);
bool checkUncommittedFlag(u16 roomId, u16 flag);
void setZoneflag(u16 roomId, u16 flag);
void setFlag(u16 roomId, u16 flag);
void setSceneflagGlobal(u16 sceneIdx, u16 flag);
void setTempOrSceneflag(u16 flag);
void unsetZoneflag(u16 roomId, u16 flag);
void unsetFlag(u16 roomId, u16 flag);
void unsetSceneflagGlobal(u16 sceneIdx, u16 flag);
void unsetTempOrSceneflag(u16 flag);
s32 doCommit();
};
SceneflagManager *SceneflagManager::sInstance = nullptr;
u16 SceneflagManager::sTempFlags[] = {};
@@ -200,7 +144,7 @@ bool SceneflagManager::checkUncommittedTempOrSceneflag(u16 flag) {
// mFlagHelper.checkFlag(getSceneflagSlot2(flag), flag % 16, pData, mSceneflags.mCount);
}
}
bool SceneflagManager::checkFlag(u16 roomId, u16 flag) {
u16 SceneflagManager::checkFlag(u16 roomId, u16 flag) {
if (isZoneFlag(flag)) {
return checkZoneFlag(roomId, flag);
} else {