mirror of
https://github.com/zeldaret/ss
synced 2026-07-30 16:03:22 -04:00
Merge branch 'flags'
This commit is contained in:
@@ -1,18 +1,12 @@
|
||||
#include <types.h>
|
||||
#include <toBeSorted/bitwise_flag_helper.h>
|
||||
|
||||
class BitwiseFlagHelper {
|
||||
public:
|
||||
bool checkFlag(u16 slot, u16 shift, u16 *pData);
|
||||
void setFlag(u16 slot, u16 shift, u16 *pData);
|
||||
void unsetFlag(u16 slot, u16 shift, u16 *pData);
|
||||
};
|
||||
|
||||
bool BitwiseFlagHelper::checkFlag(u16 slot, u16 shift, u16 *pData) {
|
||||
bool BitwiseFlagHelper::checkFlag(u16 slot, u16 shift, const u16 *pData, u16 flagCount) {
|
||||
return (pData[slot] >> shift) & 1;
|
||||
}
|
||||
void BitwiseFlagHelper::setFlag(u16 slot, u16 shift, u16 *pData) {
|
||||
void BitwiseFlagHelper::setFlag(u16 slot, u16 shift, u16 *pData, u16 flagCount) {
|
||||
pData[slot] |= (1 << shift);
|
||||
}
|
||||
void BitwiseFlagHelper::unsetFlag(u16 slot, u16 shift, u16 *pData) {
|
||||
void BitwiseFlagHelper::unsetFlag(u16 slot, u16 shift, u16 *pData, u16 flagCount) {
|
||||
pData[slot] &= ~(1 << shift);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <libc.h>
|
||||
#include <types.h>
|
||||
#include <toBeSorted/file_manager.h>
|
||||
#include <toBeSorted/flag_space.h>
|
||||
|
||||
u16* FlagSpace::getFlagPtrChecked() {
|
||||
filemanagerCheck();
|
||||
return mpFlags;
|
||||
}
|
||||
u16* FlagSpace::getFlagPtrUnchecked() {
|
||||
return mpFlags;
|
||||
}
|
||||
void FlagSpace::unsetAll() {
|
||||
setAllToZero(0, mCount);
|
||||
}
|
||||
void FlagSpace::setAllToZero(u16 offset, u16 flagCount) {
|
||||
filemanagerCheck();
|
||||
memset(mpFlags + offset, 0, (u16)(flagCount * 2));
|
||||
}
|
||||
void FlagSpace::copyFromSaveFile2(u16 *pSaved, u16 offset, u16 flagCount) {
|
||||
filemanagerCheck();
|
||||
checkedMemcpy(mpFlags + offset, mCount * 2, pSaved, flagCount * 2);
|
||||
}
|
||||
|
||||
void FlagSpace::copyFromSaveFile(u16 *pSaved, u16 offset, u16 flagCount) {
|
||||
checkedMemcpy(mpFlags + offset, mCount * 2, pSaved, flagCount * 2);
|
||||
|
||||
}
|
||||
void FlagSpace::filemanagerCheck() {
|
||||
if (FileManager::sInstance->isFileUnk1[0]) {
|
||||
return;
|
||||
}
|
||||
while (true) {}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
#include <types.h>
|
||||
#include <libc.h>
|
||||
|
||||
#include "lib/rvl/macros.h"
|
||||
#include "toBeSorted/flag_space.h"
|
||||
#include "toBeSorted/file_manager.h"
|
||||
#include <toBeSorted/bitwise_flag_helper.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];
|
||||
// public:
|
||||
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[] = {};
|
||||
|
||||
void SceneflagManager::doNothing() {}
|
||||
void SceneflagManager::setShouldCommit(u16 flag) {
|
||||
mShouldCommit = 1;
|
||||
}
|
||||
SceneflagManager::SceneflagManager():
|
||||
mSceneflags(sSceneFlags, ARRAY_LENGTH(sSceneFlags)),
|
||||
mTempflags(sTempFlags, ARRAY_LENGTH(sTempFlags)),
|
||||
mZoneflags(sZoneFlags, ARRAY_LENGTH(sZoneFlags))
|
||||
{
|
||||
mSceneIdx = 0xFFFF;
|
||||
mShouldCommit = 0;
|
||||
}
|
||||
// SceneflagManager::SceneflagManager()
|
||||
// {
|
||||
// mSceneflags.init(sSceneFlags, ARRAY_LENGTH(sSceneFlags));
|
||||
// mTempflags.init(sTempFlags, ARRAY_LENGTH(sTempFlags));
|
||||
// mZoneflags.init(sZoneFlags, ARRAY_LENGTH(sZoneFlags));
|
||||
// mSceneIdx = 0xFFFF;
|
||||
// mShouldCommit = 0;
|
||||
// }
|
||||
s32 SceneflagManager::isNotTempOrZoneFlag(u16 flag) {
|
||||
// return ((s32)flag - 0x80) < 0;
|
||||
return flag < 0x80;
|
||||
}
|
||||
|
||||
inline s32 possiblyZoneFlag(u32 flag) {
|
||||
return flag >= 0xC0;
|
||||
}
|
||||
|
||||
s32 SceneflagManager::isZoneFlag(u32 flag) {
|
||||
if (possiblyZoneFlag(flag) && flag < 0x100) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
// return flag >= 0xC0 && flag < 0x100;
|
||||
}
|
||||
void SceneflagManager::updateFlagindex(u16 sceneIdx) {
|
||||
if (sceneIdx != mSceneIdx) {
|
||||
mSceneIdx = sceneIdx;
|
||||
mSceneflags.copyFromSaveFile2(FileManager::sInstance->getSceneflags() + sceneIdx * 8, 0, 8);
|
||||
unsetZoneAndTempflags();
|
||||
}
|
||||
}
|
||||
void SceneflagManager::copyFromSave(u32 sceneIdx) {
|
||||
// sceneIdx &= 0xFFFF;
|
||||
u16 sceneIdx2 = sceneIdx;
|
||||
// missing clrlwi, more inlines?
|
||||
mSceneIdx = sceneIdx2;
|
||||
mSceneflags.copyFromSaveFile2(FileManager::getInstance()->getSceneflags() + sceneIdx2 * 8, 0, 8);
|
||||
mTempflags.copyFromSaveFile(FileManager::getInstance()->getTempflags(), 0, mTempflags.mCount);
|
||||
mZoneflags.copyFromSaveFile(FileManager::getInstance()->getZoneflags(), 0, mZoneflags.mCount);
|
||||
}
|
||||
void SceneflagManager::unsetAllTempflags() {
|
||||
u16 flags[4];
|
||||
memset(flags, 0, sizeof(flags));
|
||||
FileManager::sInstance->setTempflags(flags, 0, 4);
|
||||
}
|
||||
void SceneflagManager::zoneflagsResetAll() {
|
||||
u16 flags[0xFC];
|
||||
memset(flags, 0, sizeof(flags));
|
||||
FileManager::sInstance->setZoneflags(flags, 0, 0xFC);
|
||||
}
|
||||
void SceneflagManager::zoneflagsResetForRoom(u16 roomId) {
|
||||
u16 flags[4];
|
||||
memset(flags, 0, sizeof(flags));
|
||||
// ? weird mask
|
||||
FileManager::sInstance->setZoneflags(flags, (roomId & 0x3FF) * 4, 4);
|
||||
}
|
||||
void SceneflagManager::unsetZoneAndTempflags() {
|
||||
unsetAllTempflags();
|
||||
mTempflags.unsetAll();
|
||||
unsetAllZoneflags();
|
||||
}
|
||||
void SceneflagManager::unsetAllZoneflags() {
|
||||
zoneflagsResetAll();
|
||||
mZoneflags.unsetAll();
|
||||
}
|
||||
void SceneflagManager::unsetZoneflagsForRoom(u16 roomId) {
|
||||
zoneflagsResetForRoom(roomId);
|
||||
// ? weird mask
|
||||
mZoneflags.setAllToZero((roomId & 0x3FF) * 4, 4);
|
||||
}
|
||||
u16 SceneflagManager::getZoneflagSlot(u16 roomId, u16 flag) {
|
||||
return (flag + roomId * 0x40) >> 4 & 0xFFF;
|
||||
}
|
||||
u16 SceneflagManager::getSceneflagSlotGlobal(u16 sceneIdx, u16 flag) {
|
||||
return (flag + sceneIdx * 0x80) >> 4 & 0xFFF;
|
||||
}
|
||||
u16 SceneflagManager::getSceneflagSlot(u16 flag) {
|
||||
return flag >> 4 & 0xFFF;
|
||||
}
|
||||
u16 SceneflagManager::getTempflagSlot(u16 flag) {
|
||||
return flag >> 4 & 0xFFF;
|
||||
}
|
||||
bool SceneflagManager::checkZoneFlag(u16 roomId, u16 flag) {
|
||||
if (flag == 0xFF) {
|
||||
return false;
|
||||
} else {
|
||||
u16 zoneflag = flag - 0xC0;
|
||||
u16* pData = FileManager::sInstance->getZoneflags();
|
||||
u16 slot = getZoneflagSlot(roomId, zoneflag);
|
||||
return mFlagHelper.checkFlag(slot, zoneflag % 16, pData, 0xFC);
|
||||
}
|
||||
}
|
||||
bool SceneflagManager::checkUncommittedZoneflag(u16 roomId, u16 flag) {
|
||||
if (flag == 0xFF) {
|
||||
return false;
|
||||
} else {
|
||||
u16* pData;
|
||||
u16 zoneflag = flag - 0xC0;
|
||||
pData = mZoneflags.getFlagPtrUnchecked();
|
||||
u16 slot = getZoneflagSlot(roomId, zoneflag);
|
||||
return mFlagHelper.checkFlag(slot, zoneflag % 16, pData, mZoneflags.mCount);
|
||||
}
|
||||
}
|
||||
inline bool checkSceneflag(SceneflagManager* mgr, u16 flag) {
|
||||
u16* pData;
|
||||
pData = mgr->mSceneflags.getFlagPtrUnchecked();
|
||||
// u16 slot = getSceneflagSlot2(flag);
|
||||
return mgr->mFlagHelper.checkFlag(mgr->getSceneflagSlot(flag), flag % 16, pData, mgr->mSceneflags.mCount);
|
||||
}
|
||||
bool SceneflagManager::checkUncommittedTempOrSceneflag(u16 flag) {
|
||||
if (flag >= 0x80) {
|
||||
u16* pData;
|
||||
u16 tempflag = flag - 0x80;
|
||||
pData = mTempflags.getFlagPtrUnchecked();
|
||||
u16 slot = getTempflagSlot(tempflag);
|
||||
return mFlagHelper.checkFlag(slot, tempflag % 16, pData, mTempflags.mCount);
|
||||
} else {
|
||||
return ::checkSceneflag(this, flag);
|
||||
// u16* pData;
|
||||
// pData = mSceneflags.getFlagPtr();
|
||||
// // u16 slot = getSceneflagSlot2(flag);
|
||||
// mFlagHelper.checkFlag(getSceneflagSlot2(flag), flag % 16, pData, mSceneflags.mCount);
|
||||
}
|
||||
}
|
||||
bool SceneflagManager::checkFlag(u16 roomId, u16 flag) {
|
||||
if (isZoneFlag(flag)) {
|
||||
return checkZoneFlag(roomId, flag);
|
||||
} else {
|
||||
return checkTempOrSceneflag(flag);
|
||||
}
|
||||
}
|
||||
bool SceneflagManager::checkSceneflagGlobal(u16 sceneIdx, u16 flag) {
|
||||
u16* pData = FileManager::sInstance->getSceneflags();
|
||||
return mFlagHelper.checkFlag(getSceneflagSlotGlobal(sceneIdx, flag), flag % 16, pData, 0x800);
|
||||
}
|
||||
bool SceneflagManager::checkTempOrSceneflag(u16 flag) {
|
||||
if (flag >= 0x80) {
|
||||
u16 tempflag = flag - 0x80;
|
||||
const u16* pData = FileManager::sInstance->getTempflags();
|
||||
u16 slot = getTempflagSlot(tempflag);
|
||||
return mFlagHelper.checkFlag(slot, tempflag % 16, pData, 4);
|
||||
} else {
|
||||
return checkSceneflagGlobal(mSceneIdx, flag);
|
||||
}
|
||||
}
|
||||
bool SceneflagManager::checkUncommittedFlag(u16 roomId, u16 flag) {
|
||||
if (isZoneFlag(flag)) {
|
||||
return checkUncommittedZoneflag(roomId, flag);
|
||||
} else {
|
||||
return checkUncommittedTempOrSceneflag(flag);
|
||||
}
|
||||
}
|
||||
void SceneflagManager::setZoneflag(u16 roomId, u16 flag) {
|
||||
if (checkUncommittedZoneflag2(roomId, flag) != 1 && flag != 0xFF) {
|
||||
u16* pData;
|
||||
u16 zoneflag = flag - 0xC0;
|
||||
pData = mZoneflags.getFlagPtrChecked();
|
||||
u16 slot = getZoneflagSlot(roomId, zoneflag);
|
||||
mFlagHelper.setFlag(slot, zoneflag % 16, pData, mZoneflags.mCount);
|
||||
setShouldCommit(flag);
|
||||
}
|
||||
}
|
||||
void SceneflagManager::setFlag(u16 roomId, u16 flag) {
|
||||
if (isZoneFlag(flag)) {
|
||||
setZoneflag(roomId, flag);
|
||||
} else {
|
||||
setTempOrSceneflag(flag);
|
||||
}
|
||||
}
|
||||
void SceneflagManager::setSceneflagGlobal(u16 sceneIdx, u16 flag) {
|
||||
u16 slot = getSceneflagSlotGlobal(sceneIdx, flag);
|
||||
u16* pData = FileManager::sInstance->getSceneflags();
|
||||
u16 pCurData = pData[slot];
|
||||
mFlagHelper.setFlag(0, flag % 16, &pCurData, 2);
|
||||
FileManager::sInstance->setSceneflags(&pCurData, slot, 1);
|
||||
if (sceneIdx == mSceneIdx) {
|
||||
u16* pData2 = mSceneflags.getFlagPtrChecked();
|
||||
mFlagHelper.setFlag(getSceneflagSlot(flag), flag % 16, pData2, mSceneflags.mCount);
|
||||
}
|
||||
setShouldCommit(flag);
|
||||
}
|
||||
void SceneflagManager::setTempOrSceneflag(u16 flag) {
|
||||
if (checkUncommittedTempOrSceneflag2(flag) != 1) {
|
||||
u16* pData;
|
||||
if (flag >= 0x80) {
|
||||
u16 tempflag = flag - 0x80;
|
||||
pData = mTempflags.getFlagPtrChecked();
|
||||
mFlagHelper.setFlag(getTempflagSlot(tempflag), tempflag % 16, pData, mTempflags.mCount);
|
||||
} else {
|
||||
pData = mSceneflags.getFlagPtrChecked();
|
||||
mFlagHelper.setFlag(getSceneflagSlot(flag), flag % 16, pData, mSceneflags.mCount);
|
||||
}
|
||||
setShouldCommit(flag);
|
||||
}
|
||||
}
|
||||
void SceneflagManager::unsetZoneflag(u16 roomId, u16 flag) {
|
||||
if (checkUncommittedZoneflag2(roomId, flag) != 0 && flag != 0xFF) {
|
||||
u16* pData;
|
||||
u16 zoneflag = flag - 0xC0;
|
||||
pData = mZoneflags.getFlagPtrChecked();
|
||||
u16 slot = getZoneflagSlot(roomId, zoneflag);
|
||||
mFlagHelper.unsetFlag(slot, zoneflag % 16, pData, mZoneflags.mCount);
|
||||
setShouldCommit(flag);
|
||||
}
|
||||
}
|
||||
void SceneflagManager::unsetFlag(u16 roomId, u16 flag) {
|
||||
if (isZoneFlag(flag)) {
|
||||
unsetZoneflag(roomId, flag);
|
||||
} else {
|
||||
unsetTempOrSceneflag(flag);
|
||||
}
|
||||
}
|
||||
void SceneflagManager::unsetSceneflagGlobal(u16 sceneIdx, u16 flag) {
|
||||
u16 slot = getSceneflagSlotGlobal(sceneIdx, flag);
|
||||
u16* pData = FileManager::sInstance->getSceneflags();
|
||||
u16 pCurData = pData[slot];
|
||||
mFlagHelper.unsetFlag(0, flag % 16, &pCurData, 2);
|
||||
FileManager::sInstance->setSceneflags(&pCurData, slot, 1);
|
||||
if (sceneIdx == mSceneIdx) {
|
||||
u16* pData2 = mSceneflags.getFlagPtrChecked();
|
||||
mFlagHelper.unsetFlag(getSceneflagSlot(flag), flag % 16, pData2, mSceneflags.mCount);
|
||||
}
|
||||
setShouldCommit(flag);
|
||||
}
|
||||
void SceneflagManager::unsetTempOrSceneflag(u16 flag) {
|
||||
if (checkUncommittedTempOrSceneflag2(flag) != 0) {
|
||||
u16* pData;
|
||||
if (flag >= 0x80) {
|
||||
u16 tempflag = flag - 0x80;
|
||||
pData = mTempflags.getFlagPtrChecked();
|
||||
mFlagHelper.unsetFlag(getTempflagSlot(tempflag), tempflag % 16, pData, mTempflags.mCount);
|
||||
} else {
|
||||
pData = mSceneflags.getFlagPtrChecked();
|
||||
mFlagHelper.unsetFlag(getSceneflagSlot(flag), flag % 16, pData, mSceneflags.mCount);
|
||||
}
|
||||
setShouldCommit(flag);
|
||||
}
|
||||
}
|
||||
s32 SceneflagManager::doCommit() {
|
||||
if (mSceneIdx == 0xFFFF) {
|
||||
return 0;
|
||||
} else if (mShouldCommit) {
|
||||
FileManager::getInstance()->setSceneflags(mSceneflags.getFlagPtrUnchecked(), mSceneIdx * 8, 8);
|
||||
FileManager::getInstance()->setTempflags(mTempflags.getFlagPtrUnchecked(), 0, mTempflags.mCount);
|
||||
FileManager::getInstance()->setZoneflags(mZoneflags.getFlagPtrUnchecked(), 0, mZoneflags.mCount);
|
||||
mShouldCommit = false;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user