Merge branch 'main' into pr/44

This commit is contained in:
elijah-thomas774
2024-05-31 19:33:08 -04:00
38 changed files with 2397 additions and 317 deletions
+7 -17
View File
@@ -320,35 +320,25 @@ const char *DynamicModuleControl::getModuleTypeString() const {
}
DbMapFile::~DbMapFile() {
if (unk_0) {
if (mMapFileHandle != nullptr) {
Unregister();
}
}
namespace nw4r {
namespace db {
// TODO
typedef struct MapFile {
} MapFile;
extern MapFile *MapFile_RegistOnDvd(void *arg, const char *buf, const OSModuleInfo *info);
extern void *MapFile_Unregist(MapFile *);
} // namespace db
} // namespace nw4r
void DbMapFile::RegisterOnDvd(const char *path, const OSModuleInfo *info) {
if (mDvd::IsExistPath(path)) {
unk_0 = (UNKWORD)nw4r::db::MapFile_RegistOnDvd(((int *)this) + 1, path, info);
mMapFileHandle = nw4r::db::MapFile_RegistOnDvd(&mMapFile, path, info);
} else {
unk_0 = 0xffffffff;
mMapFileHandle = (nw4r::db::MapFileHandle)0xffffffff;
}
}
void DbMapFile::Unregister() {
if (unk_0 != 0) {
if (unk_0 != 0xffffffff) {
nw4r::db::MapFile_Unregist((nw4r::db::MapFile *)unk_0);
if (mMapFileHandle != nullptr) {
if ((u32)mMapFileHandle != 0xffffffff) {
nw4r::db::MapFile_Unregist(mMapFileHandle);
}
unk_0 = 0;
mMapFileHandle = nullptr;
}
}
+425 -63
View File
@@ -1,6 +1,12 @@
#include "d/a/d_a_base.h"
// RoomManager* RoomManager::m_Instance;
#include "d/d_player.h"
#include "f/f_list_nd.h"
#include "m/m_vec.h"
#include "toBeSorted/event.h"
#include "toBeSorted/file_manager.h"
#include "toBeSorted/misc_flag_managers.h"
#include "toBeSorted/scgame.h"
#include "toBeSorted/special_item_drop_mgr.h"
// .sdata
u32 dAcBase_c::s_Create_RoomId = -1;
@@ -17,8 +23,15 @@ ObjInfo *dAcBase_c::s_Create_ObjInfo;
u8 dAcBase_c::s_Create_Subtype;
extern "C" ObjInfo *getObjByActorIdAndSubtype_unkNamespace(ProfileName, u8);
extern "C" ObjInfo *getObjByActorName_unkNamespace(char *name);
extern "C" char *getObjectName_8006a730(ObjInfo *);
extern "C" void *soundForActorInitRelated_803889c0(s8, fBase_c *, char *, u8);
extern "C" SoundSource *soundForActorInitRelated_803889c0(s8, fBase_c *, char *, u8);
extern "C" s16 targetAngleY(mVec3_c *, mVec3_c *);
extern "C" s16 targetAngleX(mVec3_c *, mVec3_c *);
extern "C" bool checkCollision(mVec3_c *pos);
extern "C" s8 collisionCheckGetRoom();
extern "C" dRoom *getRoomByIndex(RoomManager *mgr, s8 roomid);
extern "C" bool alsoSetAsCurrentEvent(dAcBase_c *, Event *, void *);
bool dAcBase_c::createHeap() {
return true;
@@ -26,28 +39,30 @@ bool dAcBase_c::createHeap() {
// Doesnt Match Yet
dAcBase_c::dAcBase_c()
: heap_allocator(), obj_info(s_Create_ObjInfo), sound_info_tail(&heap_allocator.mHeap),
sound_info_next(&heap_allocator.mHeap), count(0), obj_sound(nullptr), obj_pos(&position),
params2(s_Create_Params2), obj_id(s_Create_UnkFlags), viewclip_index(s_Create_ViewClipIdx), actor_node(),
: heap_allocator(), obj_info(s_Create_ObjInfo), sound_source(nullptr), sound_list(), obj_pos(&position),
params2(s_Create_Params2), obj_id(s_Create_UnkFlags), viewclip_index(s_Create_ViewClipIdx), actor_node(nullptr),
roomid(s_Create_RoomId), actor_subtype(s_Create_Subtype) {
JStudio_actor = 0;
someStr[0] = 0;
if (s_Create_Position != nullptr) {
// void set(f32 fx, f32 fy, f32 fz) { x = fx; y = fy; z = fz; }
position.set(s_Create_Position->x, s_Create_Position->y, s_Create_Position->z);
// position = *s_Create_Position;
if (s_Create_Position) {
setPostion(*s_Create_Position);
}
if (s_Create_Rotation != 0) {
rotation = *(s_Create_Rotation);
if (s_Create_Rotation) {
SetRotation(*s_Create_Rotation);
}
if (s_Create_Scale != 0) {
setScale(s_Create_Scale->x, s_Create_Scale->y, s_Create_Scale->z);
if (s_Create_Scale) {
SetScale(*s_Create_Scale);
} else {
setScale(1.0, 1.0, 1.0);
scale.set(1.0f, 1.0f, 1.0f);
}
if (s_Create_Parent != 0) {
if (s_Create_Parent != nullptr) {
setActorRef(s_Create_Parent);
}
fProfile::fActorProfile_c *profile = (fProfile::fActorProfile_c *)((*fProfile::sProfileList)[profile_name]);
actor_properties = profile->mActorProperties;
if (obj_info == nullptr) {
@@ -56,7 +71,8 @@ dAcBase_c::dAcBase_c()
someStr[0] = '\0';
}
/* 8002c530 */ dBase_c::~dBase_c() {}
// 8002c530
dBase_c::~dBase_c() {}
dAcBase_c::~dAcBase_c() {}
@@ -75,14 +91,16 @@ void dAcBase_c::setTempCreateParams(mVec3_c *pos, mAng3_c *rot, mVec3_c *scale,
}
// has regswap
void *dAcBase_c::FUN_8002c690() {
SoundSource *dAcBase_c::FUN_8002c690() {
if (obj_info == nullptr) {
return nullptr;
}
s8 unk_val = obj_info->unk_0xA;
s32 unk_val = obj_info->unk_0xA;
if (unk_val == -1) {
return nullptr;
}
char *objName = getObjectName_8006a730(obj_info);
return soundForActorInitRelated_803889c0(unk_val, this, objName, subtype);
}
@@ -96,7 +114,7 @@ int dAcBase_c::initAllocator(int size, char *name, EGG::Heap *heap, int align) {
if (fn_802EE510(&heap_allocator, size, heap, name, 0x20, 0) == 0) {
return 0;
}
obj_sound = FUN_8002c690();
sound_source = FUN_8002c690();
int success = createHeap();
heap_allocator.adjustFrmHeapRestoreCurrent();
return success;
@@ -117,15 +135,19 @@ bool dAcBase_c::addActorToRoom(s32 roomId) {
}
return false;
}
void dAcBase_c::setBit_field_0xE8(s32 shift) {
field_0xe8 |= (1 << shift);
}
int dAcBase_c::actorCreate() {
return SUCCEEDED;
}
int dAcBase_c::actorPostCreate() {
return SUCCEEDED;
}
int dAcBase_c::create() {
if (actor_properties & 0x8000000) {
return actorPostCreate();
@@ -138,6 +160,8 @@ int dAcBase_c::create() {
return success;
}
// 8002c8f0
// loads f2 before f0 instead of f0 then f2
void dAcBase_c::postCreate(fBase_c::MAIN_STATE_e state) {
if (state == SUCCESS) {
pos_copy = position;
@@ -147,8 +171,10 @@ void dAcBase_c::postCreate(fBase_c::MAIN_STATE_e state) {
dBase_c::postCreate(state);
}
// 8002c940
int dAcBase_c::preDelete() {}
// 8002cb10
int dAcBase_c::preExecute() {
if (dBase_c::preExecute() == NOT_READY) {
return NOT_READY;
@@ -161,44 +187,253 @@ int dAcBase_c::preExecute() {
}
return SUCCEEDED;
}
// 8002cc10
int dAcBase_c::execute() {}
int dAcBase_c::actorExecute() {}
int dAcBase_c::actorExecuteInEvent() {}
// 8002cca0
int dAcBase_c::actorExecute() {
return 1;
}
// 8002ccb0
int dAcBase_c::actorExecuteInEvent() {
return actorExecute();
}
// 8002ccc0
void dAcBase_c::postExecute(fBase_c::MAIN_STATE_e state) {}
// 8002ce90
void dAcBase_c::unkVirtFunc_0x5C() {
return;
}
// 8002cea0
void dAcBase_c::unkVirtFunc_0x60() {
return;
}
bool dAcBase_c::restorePosRotFromCopy() {}
u32 dAcBase_c::itemDroppingAndGivingRelated(Vec3f *spawnPos, int subtype) {}
void dAcBase_c::fillUpperParams2Byte() {}
u32 dAcBase_c::getParams2_ignoreLower() {}
void dAcBase_c::setParams2Upper_ignoreLower(u32 val) {}
u8 dAcBase_c::getParams2UpperByte() {}
void dAcBase_c::setParams2UpperByte(u32 val) {}
u32 dAcBase_c::buildParams2(u32 lower, u8 upper) {}
u32 dAcBase_c::getParams2Lower() {}
dAcBase_c *dAcBase_c::findActor(char *objName, dAcBase_c *parent) {}
// searches for actor based on groupType
dAcBase_c *dAcBase_c::searchActor(dAcBase_c &optionalParent) {}
void dAcBase_c::forEachActor(void *, dAcBase_c &) {}
mAng dAcBase_c::getXZAngleToPlayer() {}
bool dAcBase_c::getDistanceToActor(dAcBase_c &actor, f32 distThresh, f32 *outDist) {}
bool dAcBase_c::getDistanceAndAngleToActor(dAcBase_c &actor, f32 distThresh, s16 yAngle, s16 xAngle, f32 *outDist,
s16 *outDiffAngleY, s16 *outDiffAngleX) {}
bool dAcBase_c::isWithinPlayerRadius(f32 radius) {}
bool dAcBase_c::getDistanceAndAngleToPlayer(f32 distThresh, s16 yAngle, s16 xAngle, f32 *outDist, s16 *outDiffAngleY,
s16 *outDiffAngleX) {
// return getDistanceAndAngleToActor(PLAYER, distThresh, yAngle, xAngle, outDist, outDiffAngleY, outDiffAngleX);
// 8002ceb0
// loads f2 before f0 instead of f0 then f2
bool dAcBase_c::restorePosRotFromCopy() {
if (roomid != room_id_copy) {
return 0;
}
position = pos_copy;
rotation = rot_copy;
return 1;
}
f32 dAcBase_c::getDistToPlayer() {}
f32 dAcBase_c::getSquareDistToPlayer() {}
void dAcBase_c::updateRoomId(f32 yOffs) {}
bool dAcBase_c::isRoomFlags_0x6_Set() {}
// 8002cf10
u32 dAcBase_c::itemDroppingAndGivingRelated(mVec3_c *spawnPos, int subtype) {
if (ScGame::currentSpawnInfo.trial == 1) {
return 0;
}
if (spawnPos == nullptr) {
spawnPos = &position;
}
u32 param2Copy = params2;
params2 = param2Copy | 0xFF000000;
// mAng3_c rot = {};
s16 rot = 0;
return SpecialItemDropMgr::giveSpecialDropItem(SpecialItemDropMgr::sInstance, param2Copy >> 0x18, roomid, spawnPos,
subtype, &rot, -1);
}
// 8002cf90
void dAcBase_c::fillUpperParams2Byte() {
params2 |= 0xFF000000;
}
// 8002cfa0
u32 dAcBase_c::getParams2_ignoreLower() {
return params2 | 0xFFFF;
}
// 8002cfb0
void dAcBase_c::setParams2Upper_ignoreLower(u32 val) {
params2 = val | 0xFFFF;
}
// 8002cfc0
u8 dAcBase_c::getParams2UpperByte() {
return params2 >> 0x18;
}
// 8002cfd0
void dAcBase_c::setParams2UpperByte(u32 val) {
params2 = (params2 & 0xFFFFFF) | val << 0x18;
}
// 8002cff0
u32 dAcBase_c::buildParams2(u32 lower, u32 upper) {
return ((upper & 0xFFFF) | 0xFFFF0000) & ((lower << 0x18) | 0xFFFFFF);
}
// 8002d010
u32 dAcBase_c::getParams2Lower() {
return params2 & 0xFFFF;
}
// 8002d020
dAcBase_c *dAcBase_c::findActor(char *objName, dAcBase_c *parent) {
ObjInfo *objInfo = getObjByActorName_unkNamespace(objName);
if (objInfo == nullptr) {
return nullptr;
} else {
do {
parent = (dAcBase_c *)fManager_c::searchBaseByProfName(objInfo->obj_id, parent);
if (parent == nullptr) {
break;
}
} while (parent->actor_subtype != objInfo->subtype);
}
return parent;
}
// searches for actor based on groupType
// 8002d0a0
DECOMP_INLINE dAcBase_c *findActor(dAcBase_c *parent) {
if (!parent) {
return (dAcBase_c *)fManager_c::searchBaseByGroupType(2, nullptr);
}
if (parent->group_type == 2) {
return (dAcBase_c *)fManager_c::searchBaseByGroupType(2, parent);
}
return nullptr;
}
dAcBase_c *dAcBase_c::searchActor(dAcBase_c *parent) {
dAcBase_c *foundActor = ::findActor(parent);
if (foundActor) {
return foundActor;
} else {
return (dAcBase_c *)fManager_c::searchBaseByGroupType(STAGE, parent);
}
}
// 8002d130
void dAcBase_c::forEveryActor(void *func(dAcBase_c *, dAcBase_c *), dAcBase_c *parent) {
dAcBase_c *foundActor = searchActor(nullptr);
while (foundActor != nullptr) {
dAcBase_c *nextActor = (dAcBase_c *)func(foundActor, parent);
foundActor = searchActor(nextActor);
}
}
// 8002d190
mAng dAcBase_c::getXZAngleToPlayer(s16 *angle) {
return targetAngleY(&this->position, &dPlayer::LINK->position);
}
// 8002d1d0
bool dAcBase_c::getDistanceToActor(dAcBase_c *actor, f32 distThresh, f32 *outDist) {
f32 distSquared = 3.402823e+38;
bool isWithinThreshhold = false;
if (actor != nullptr) {
distSquared = PSVECSquareDistance(position, actor->position);
if (distSquared <= distThresh * distThresh) {
isWithinThreshhold = true;
}
}
if (outDist != nullptr) {
*outDist = distSquared <= 0.0f ? 0.0f : nw4r::math::FrSqrt(distSquared) * distSquared;
}
return isWithinThreshhold;
}
s32 doAbs(s16 val) {
return labs(val);
}
// Similar weirdness as the above function. Also, r29->31 are initted in the wrong order?
// 8002d290
bool dAcBase_c::getDistanceAndAngleToActor(dAcBase_c *actor, f32 distThresh, s16 yAngle, s16 xAngle, f32 *outDist,
s16 *outDiffAngleY, s16 *outDiffAngleX) {
f32 distSquared = 3.402823e+38f;
s16 angleToActorY, angleToActorX;
bool isWithinRange = false;
angleToActorY = 0;
angleToActorX = 0;
if (actor != nullptr) {
distSquared = PSVECSquareDistance(position, actor->position);
angleToActorY = targetAngleY(&position, &actor->position);
angleToActorX = targetAngleX(&position, &actor->position);
if ((distSquared <= distThresh * distThresh) && (doAbs(s32(rotation.y - angleToActorY)) <= yAngle) &&
(doAbs(s32(rotation.x - angleToActorX)) <= xAngle)) {
isWithinRange = true;
}
}
if (outDist != nullptr) {
*outDist = distSquared <= 0.0f ? 0.0f : nw4r::math::FrSqrt(distSquared) * distSquared;
}
if (outDiffAngleY != nullptr) {
*outDiffAngleY = angleToActorY;
}
if (outDiffAngleX != nullptr) {
*outDiffAngleX = angleToActorX;
}
return isWithinRange;
}
// 8002d3e0
bool dAcBase_c::isWithinPlayerRadius(f32 radius) {
mVec3_c dist_diff = GetPostionDifference(dPlayer::LINK);
return dist_diff.x * dist_diff.x + dist_diff.z * dist_diff.z < radius * radius;
}
// 8002d440
bool dAcBase_c::getDistanceAndAngleToPlayer(f32 distThresh, s16 yAngle, s16 xAngle, f32 *outDist, s16 *outDiffAngleY,
s16 *outDiffAngleX) {
return getDistanceAndAngleToActor(dPlayer::LINK, distThresh, yAngle, xAngle, outDist, outDiffAngleY, outDiffAngleX);
}
// 8002d470
f32 dAcBase_c::getDistToPlayer() {
return EGG::Math<f32>::sqrt(PSVECSquareDistance(position, dPlayer::LINK->position));
}
// 8002d4a0
f32 dAcBase_c::getSquareDistToPlayer() {
return PSVECSquareDistance(position, dPlayer::LINK->position);
}
// Some weirdness with the float registers being used
// 8002d4b0
void dAcBase_c::updateRoomId(f32 yOffset) {
if (getConnectParent()->profile_name != 701 /* fProfile::PROFILE_NAME_e::ROOM */) {
mVec3_c actorPos(position.x, position.y + yOffset, position.z);
if (checkCollision(&actorPos)) {
roomid = collisionCheckGetRoom();
} else {
roomid = RoomManager::m_Instance->curr_room_id;
}
}
}
// 8002d540
bool dAcBase_c::isRoomFlags_0x6_Set() {
dRoom *room = RoomManager::m_Instance->GetRoomByIndex(roomid);
return (room->flags & 6);
}
// Start of SoundSource stuff
void dAcBase_c::FUN_8002d590() {}
void dAcBase_c::FUN_8002d5b0() {}
void dAcBase_c::playSound() {}
@@ -215,31 +450,158 @@ void dAcBase_c::FUN_8002d7f0() {}
void dAcBase_c::FUN_8002d810() {}
void dAcBase_c::FUN_8002d830() {}
void dAcBase_c::FUN_8002d860() {}
void dAcBase_c::FUN_8002d880() {}
// 8002d880
SoundSource *dAcBase_c::getSoundSource() {
return sound_source;
}
// End of SoundSource stuff
// first param is not dAcBase_c
// 8002d890
void dAcBase_c::FUN_8002d890() {}
// current name is Global__setActorRef
void dAcBase_c::setActorRef(dBase_c *) {}
void dAcBase_c::setActorRef(dBase_c *ref) {
actor_node.link(ref);
}
// May not be only purpose
void dAcBase_c::setUnkFlag() {}
void dAcBase_c::FUN_8002d940() {}
void dAcBase_c::FUN_8002d960() {}
void dAcBase_c::setEnemyDefeatFlag() {
EnemyDefeatManager::sInstance->setFlag(obj_id);
}
// 8002d940
void dAcBase_c::changeLoadedEntitiesWithSet() {
RoomManager::m_Instance->changeLoadedEntities(RoomManager::m_Instance, obj_id, true);
}
// 8002d960
void dAcBase_c::changeLoadedEntitiesNoSet() {
RoomManager::m_Instance->changeLoadedEntities(RoomManager::m_Instance, obj_id, false);
}
// spawns GroupType2 (ACTOR)
dAcBase_c dAcBase_c::createActor(ProfileName actorId, u32 params1, Vec3f *pos, Vec3s *rot, Vec3f *scale, u32 params2,
s32 roomId, dBase_c *ref) {}
// 8002d980
dAcBase_c *dAcBase_c::createActor(ProfileName actorId, u32 actorParams1, mVec3_c *actorPosition, mAng3_c *actorRotation,
mVec3_c *actorScale, u32 actorParams2, s32 actorRoomid, dBase_c *actorRef) {
if (actorPosition == nullptr) {
actorPosition = &position;
}
dAcBase_c dAcBase_c::createActorUnkGroup3(ProfileName actorId, u32 params1, Vec3f *pos, Vec3s *rot, Vec3f *scale,
u32 params2, s32 roomId, dBase_c *ref) {}
if (actorRotation == nullptr) {
actorRotation = &rotation;
}
if (actorScale == nullptr) {
actorScale = &scale;
}
if (actorRoomid == 63) {
actorRoomid = roomid;
}
u32 newParams2 = actorParams2 != 0 ? getParams2_ignoreLower() : -1;
setTempCreateParams(actorPosition, actorRotation, actorScale, actorRoomid, newParams2, (dAcBase_c *)actorRef, 0, -1,
0xFF, nullptr);
dBase_c *room = RoomManager::getRoom(roomid);
return (dAcBase_c *)dBase_c::createBase(actorId, room, actorParams1, ACTOR);
}
// spawns GroupType2 (STAGE)
// 8002da80
dAcBase_c *dAcBase_c::createActorStage(ProfileName actorId, u32 actorParams1, mVec3_c *actorPosition,
mAng3_c *actorRotation, mVec3_c *actorScale, u32 actorParams2, s32 actorRoomid, dBase_c *actorRef) {
if (actorPosition == nullptr) {
actorPosition = &position;
}
if (actorRotation == nullptr) {
actorRotation = &rotation;
}
if (actorScale == nullptr) {
actorScale = &scale;
}
if (actorRoomid == 63) {
actorRoomid = roomid;
}
u32 newParams2 = actorParams2 != 0 ? getParams2_ignoreLower() : -1;
setTempCreateParams(actorPosition, actorRotation, actorScale, actorRoomid, newParams2, (dAcBase_c *)actorRef, 0, -1,
0xFF, nullptr);
dBase_c *room = RoomManager::getRoom(roomid);
return (dAcBase_c *)dBase_c::createBase(actorId, room, actorParams1, STAGE);
}
// 8002db80
void *dAcBase_c::getCurrentEventActor() {}
// 8002db90
void dAcBase_c::unkVirtFunc_0x6C() {}
void dAcBase_c::doInteraction(int) {}
// 8002dba0
void dAcBase_c::doInteraction(s32 param) {
if (param == 4 || param == 5 || param == 12) {
Event event = Event("DefaultTalk", 400, 0x100001, nullptr, nullptr);
alsoSetAsCurrentEvent(this, &event, nullptr);
}
}
// Only called by dPlayer::dig and that function fails to decomp in ghidra?
// 8002dc20
void dAcBase_c::FUN_8002dc20(s16 *, s16 *) {}
void dAcBase_c::incrementKillCounter() {}
void dAcBase_c::FUN_8002dcd0() {}
void dAcBase_c::FUN_8002dd10() {}
void dAcBase_c::FUN_8002dd50() {}
void dAcBase_c::FUN_8002dd90() {}
// 8002dc50
void dAcBase_c::incrementKillCounter() {
dAcObjBase_c *object = (dAcObjBase_c *)this; // Probably wrong
if (group_type == ACTOR && object->unkByteTargetFiRelated == 1) {
int killCounterId = object->targetFiTextId;
if (killCounterId < 91 && (killCounterId & 0x300) == 0) {
FileManager *fileMgr = FileManager::sInstance;
u16 killCount = fileMgr->getEnemyKillCount(killCounterId) + 1;
fileMgr->setEnemyKillCount(killCounterId, killCount);
}
}
}
// 8002dcd0
void dAcBase_c::FUN_8002dcd0() {
fillUpperParams2Byte();
fBase_c::deleteRequest();
incrementKillCounter();
}
// 8002dd10
void dAcBase_c::FUN_8002dd10() {
setEnemyDefeatFlag();
fBase_c::deleteRequest();
incrementKillCounter();
}
// 8002dd50
void dAcBase_c::FUN_8002dd50() {
fillUpperParams2Byte();
FUN_8002dd10();
}
// 8002dd90
void dAcBase_c::FUN_8002dd90() {
fillUpperParams2Byte();
setEnemyDefeatFlag();
fBase_c::deleteRequest();
}
// Some collision related thing
// 8002ddd0
void dAcBase_c::FUN_8002ddd0() {}
void dAcBase_c::FUN_8002de30() {}
// 8002de30
void dAcBase_c::FUN_8002de30() {
FUN_8002ddd0();
}
+3
View File
@@ -0,0 +1,3 @@
#include "d/d_player.h";
dPlayer* dPlayer::LINK;
+2 -9
View File
@@ -3,18 +3,11 @@
#include <egg/core/eggXfbManager.h>
#include <egg/prim/eggAssert.h>
#include <nw4r/db/db_directPrint.h>
#include <nw4r/db/db_mapFile.h>
#include <rvl/OS.h>
#include <rvl/VI.h>
#include <MSL_C/string.h>
namespace nw4r {
namespace db {
// TODO
extern s32 MapFile_QuerySymbol(void *arg, char *buf, u32 buf_size);
} // namespace db
} // namespace nw4r
namespace EGG {
namespace Assert {
@@ -62,7 +55,7 @@ bool sAssertOccurred;
/* 80674c60 */ char buf[260];
/* 8049c100 */ const char *getMapSymbol(void *arg) {
u32 success = nw4r::db::MapFile_QuerySymbol(arg, buf, sizeof(buf));
bool success = nw4r::db::MapFile_QuerySymbol((u32)arg, (u8*)buf, sizeof(buf));
return success ? buf : nullptr;
}
+16
View File
@@ -0,0 +1,16 @@
#include <common.h>
#include <nw4r/db/db_assert.h>
namespace nw4r {
namespace db {
static ConsoleHandle sConsoleHandle = nullptr;
ConsoleHandle Assertion_SetConsole(ConsoleHandle handle) {
ConsoleHandle oldHandle = sConsoleHandle;
sConsoleHandle = handle;
return oldHandle;
}
} // namespace db
} // namespace nw4r
+375
View File
@@ -0,0 +1,375 @@
#include <common.h>
#include <nw4r/db/db_console.h>
#include <nw4r/db/db_directPrint.h>
#include <nw4r/ut/ut_TextWriterBase.h>
#include <rvl/OS.h>
namespace nw4r {
namespace db {
static ConsoleHandle sConsoleList;
static OSMutex sMutex;
static u8 sStrBuf[0x400];
bool sInited;
static ConsoleHandle FindInsertionPosition_(u16 priority) {
ConsoleHandle cursor = sConsoleList;
if (cursor == nullptr || cursor->priority < priority) {
return nullptr;
}
while (cursor->next != nullptr) {
if (cursor->next->priority < priority) {
return cursor;
}
cursor = cursor->next;
}
return cursor;
}
static void Console_Append_(ConsoleHandle console) {
OSLockMutex(&sMutex);
ConsoleHandle cursor = FindInsertionPosition_(console->priority);
if (cursor == nullptr) {
console->next = sConsoleList;
sConsoleList = console;
} else {
console->next = cursor->next;
cursor->next = console;
}
OSUnlockMutex(&sMutex);
}
void RemoveConsoleFromList_(ConsoleHandle console) {
OSLockMutex(&sMutex);
if (sConsoleList == console) {
sConsoleList = console->next;
console->next = nullptr;
} else {
ConsoleHandle cursor = sConsoleList;
while (cursor->next != nullptr) {
if (cursor->next == console) {
cursor->next = console->next;
console->next = nullptr;
goto end;
}
cursor = cursor->next;
}
#line 386
OSError("illegal console handle");
}
end:
OSUnlockMutex(&sMutex);
}
static bool TryLockMutex_(OSMutex *mutex) {
if (OSGetCurrentThread() != nullptr) {
OSLockMutex(&sMutex);
return true;
}
if (mutex->thread == nullptr) {
return true;
}
return false;
}
static void UnlockMutex_(OSMutex *mutex) {
if (OSGetCurrentThread() != nullptr) {
OSUnlockMutex(&sMutex);
}
}
ConsoleHandle Console_Create(void *arg, u16 width, u16 height, u16 viewLines, u16 priority, u16 attr) {
ConsoleHandle console = (ConsoleHandle)arg;
if (!sInited) {
OSInitMutex(&sMutex);
sInited = true;
}
console->textBuf = (u8 *)(console + 1);
console->width = width;
console->height = height;
console->priority = priority;
console->attr = attr;
console->isVisible = false;
console->printTop = 0;
console->printXPos = 0;
console->ringTop = 0;
console->ringTopLineCnt = 0;
console->viewTopLine = 0;
console->viewPosX = 0x1e;
console->viewPosY = 0x32;
console->viewLines = viewLines;
console->writer = nullptr;
if (TryLockMutex_(&sMutex)) {
BOOL intr = OSDisableInterrupts();
console->printTop = 0;
console->printXPos = 0;
console->ringTop = 0;
console->ringTopLineCnt = 0;
console->viewTopLine = 0;
OSRestoreInterrupts(intr);
UnlockMutex_(&sMutex);
}
Console_Append_(console);
return console;
}
ConsoleHandle Console_Destroy(ConsoleHandle console) {
RemoveConsoleFromList_(console);
return console;
}
static u8 *GetTextPtr_(ConsoleHandle console, u16 line, u16 xPos) {
return &console->textBuf[(console->width + 1) * line + xPos];
}
static u16 GetRingUsedLines_(ConsoleHandle console) {
s32 lines = console->printTop - console->ringTop;
if (lines < 0) {
lines += console->height;
}
return lines;
}
static u16 GetActiveLines_(ConsoleHandle console) {
u16 lines = GetRingUsedLines_(console);
if (console->printXPos != 0) {
lines += 1;
}
return lines;
}
static void DoDrawString_(ConsoleHandle console, u32 printLine, const u8 *str, nw4r::ut::TextWriterBase<char> *writer) {
if (writer != nullptr) {
writer->Printf("%s\n", str);
} else {
s32 height = console->viewPosY + printLine * 10;
db::DirectPrint_DrawString(console->viewPosX, height, false, "%s\n", str);
}
}
static void DoDrawConsole_(ConsoleHandle console, nw4r::ut::TextWriterBase<char> *writer) {
// I guess we don't care if locking the mutex fails??
TryLockMutex_(&sMutex);
s32 viewOffset = console->viewTopLine - console->ringTopLineCnt;
u16 line;
u16 printLines = 0;
u16 topLine;
if (viewOffset < 0) {
viewOffset = 0;
} else if (viewOffset > GetActiveLines_(console)) {
goto err;
}
line = console->ringTop + viewOffset;
if (line >= console->height) {
line -= console->height;
}
topLine = console->printTop + ((console->printXPos > 0) ? 1 : 0);
if (topLine == console->height) {
topLine = 0;
}
while (line != topLine) {
DoDrawString_(console, printLines, GetTextPtr_(console, line, 0), writer);
printLines++;
line++;
if (line == console->height) {
if ((console->attr & 2) != 0) {
break;
}
line = 0;
}
if (printLines >= console->viewLines) {
break;
}
}
err:
UnlockMutex_(&sMutex);
}
void Console_DrawDirect(ConsoleHandle console) {
if (DirectPrint_IsActive() && console->isVisible) {
DirectPrint_EraseXfb(console->viewPosX - 6, console->viewPosY - 3, console->width * 6 + 12,
console->viewLines * 10 + 4);
DoDrawConsole_(console, nullptr);
DirectPrint_StoreCache();
}
}
static void TerminateLine_(ConsoleHandle console) {
*GetTextPtr_(console, console->printTop, console->printXPos) = '\0';
}
static u32 GetTabSize_(ConsoleHandle console) {
s32 tab = (console->attr & 12) >> 2;
return 2 << tab;
}
static u32 CodeWidth_(const u8 *p) {
return (*p >= 0x81) ? 2 : 1;
}
static u32 PutChar_(ConsoleHandle console, const u8 *str, u8 *dstPtr) {
u32 codeWidth;
u32 count;
codeWidth = CodeWidth_(str);
if (console->printXPos + codeWidth > console->width) {
return 0;
} else {
console->printXPos += codeWidth;
for (count = codeWidth; count > 0; count--) {
*dstPtr++ = *str++;
}
return codeWidth;
}
}
static u8 *PutTab_(ConsoleHandle console, u8 *dstPtr) {
u32 tabWidth = GetTabSize_(console);
do {
*dstPtr++ = ' ';
console->printXPos++;
if (console->printXPos >= console->width) {
break;
}
} while ((console->printXPos & (tabWidth - 1)) != 0);
return dstPtr;
}
static u8 *SearchEndOfLine_(const u8 *str) {
while (*str != '\n' && *str != '\0') {
str++;
}
return (u8 *)str;
}
static u8 *NextLine_(ConsoleHandle console) {
*GetTextPtr_(console, console->printTop, console->printXPos) = '\0';
console->printXPos = 0;
console->printTop++;
if (console->printTop == console->height && (console->attr & 2) == 0) {
console->printTop = 0;
}
if (console->printTop == console->ringTop) {
console->ringTopLineCnt++;
if (++console->ringTop == console->height) {
console->ringTop = 0;
}
}
return GetTextPtr_(console, console->printTop, 0);
}
static void PrintToBuffer_(ConsoleHandle console, const u8 *str) {
BOOL enabled = OSDisableInterrupts();
u8 *storePtr = GetTextPtr_(console, console->printTop, console->printXPos);
while (*str != '\0') {
if ((console->attr & 2) && console->printTop == console->height) {
break;
}
while (*str != '\0') {
bool newLineFlag = false;
if (*str == '\n') {
str++;
storePtr = NextLine_(console);
break;
} else if (*str == '\t') {
str++;
storePtr = PutTab_(console, storePtr);
} else {
u32 bytes = PutChar_(console, str, storePtr);
if (bytes > 0) {
str += bytes;
storePtr += bytes;
} else {
newLineFlag = true;
}
}
if (console->printXPos >= console->width) {
newLineFlag = true;
}
if (newLineFlag) {
if ((console->attr & 1) != 0) {
str = SearchEndOfLine_(str);
} else {
if (*str == '\n') {
str++;
}
storePtr = NextLine_(console);
}
break;
}
if (*str == '\0') {
TerminateLine_(console);
}
}
}
OSRestoreInterrupts(enabled);
}
static void Console_PrintString_(ConsoleOutputType type, ConsoleHandle console, const u8 *str) {
if ((type & CONSOLE_OUTPUT_TERMINAL) != 0) {
OSReport("%s", str);
}
if ((type & CONSOLE_OUTPUT_DISPLAY) != 0) {
PrintToBuffer_(console, str);
}
}
void Console_VFPrintf(ConsoleOutputType type, ConsoleHandle console, const char *format, va_list vlist) {
if (TryLockMutex_(&sMutex)) {
vsnprintf((char *)sStrBuf, sizeof(sStrBuf), format, vlist);
Console_PrintString_(type, console, sStrBuf);
UnlockMutex_(&sMutex);
}
}
void Console_Printf(ConsoleHandle console, const char *format, ...) {
va_list args;
va_start(args, format);
if (TryLockMutex_(&sMutex)) {
vsnprintf((char *)sStrBuf, sizeof(sStrBuf), format, args);
OSReport("%s", sStrBuf);
PrintToBuffer_(console, sStrBuf);
UnlockMutex_(&sMutex);
}
}
s32 Console_GetTotalLines(ConsoleHandle console) {
s32 count;
BOOL enabled = OSDisableInterrupts();
count = console->ringTopLineCnt + GetActiveLines_(console);
OSRestoreInterrupts(enabled);
return count;
}
} // namespace db
} // namespace nw4r
+492
View File
@@ -0,0 +1,492 @@
#include <MSL_C/string.h>
#include <nw4r/db/db_directPrint.h>
#include <nw4r/db/db_exception.h>
#include <nw4r/db/db_mapFile.h>
#include <rvl/GX.h>
#include <rvl/VI.h>
namespace nw4r {
namespace db {
struct ExceptionStruct {
OSThread thread;
OSMessageQueue queue;
void *frameMemory;
u32 stackAddress;
ConsoleHandle consoleHandle;
const GXRenderModeObj *exceptionRenderObj;
bool (*exceptionCallback)(detail::ConsoleHead *, void *);
void *exceptionCallbackArgs;
u32 MSR_COPY;
u32 FPCSR_COPY;
u16 exceptionDisplayInfo;
};
static OSMessage sMessageBuffer[1];
static struct ExceptionStruct sException;
static u8 sThreadBuffer[0x4000] ALIGN(0x20);
extern "C" u32 lbl_80574960;
const char *CPU_EXP_NAME[] = {
"SYSTEM RESET",
"MACHINE CHECK",
"DSI",
"ISI",
"EXTERNAL INTERRUPT",
"ALIGNMENT",
"PROGRAM",
"FLOATING POINT",
"DECREMENTER",
"SYSTEM CALL",
"TRACE",
"PERFORMACE MONITOR",
"BREAK POINT",
"SYSTEM INTERRUPT",
"THERMAL INTERRUPT",
"PROTECTION",
"FLOATING POINT",
};
void *RunThread_(void *);
// TODO u8 vs u16
void ErrorHandler_(u16, OSContext *, u32, u32);
void Exception_Init() {
memset(&sException, 0, sizeof(struct ExceptionStruct));
sException.exceptionCallback = nullptr;
sException.consoleHandle = nullptr;
sException.exceptionDisplayInfo = 0x21;
sException.frameMemory = nullptr;
sException.exceptionRenderObj = nullptr;
OSCreateThread(&sException.thread, RunThread_, nullptr, sThreadBuffer + 0x4000, 0x4000, 0, 1);
OSInitMessageQueue(&sException.queue, sMessageBuffer, 1);
OSResumeThread(&sException.thread);
OSSetErrorHandler(2, ErrorHandler_);
OSSetErrorHandler(3, ErrorHandler_);
OSSetErrorHandler(5, ErrorHandler_);
OSSetErrorHandler(15, ErrorHandler_);
lbl_80574960 = 0;
OSSetErrorHandler(16, nullptr);
}
extern "C" u32 PPCMfmsr();
extern "C" void PPCMtmsr(u32);
extern "C" void OSFillFPUContext(OSContext *ctx);
extern "C" void fn_803AA2E0(u32, u32, u32, u32);
static void DumpException_(const ExceptionCallbackParam *);
void ErrorHandler_(u16 error, OSContext *ctx, u32 dsisr, u32 dar) {
sException.MSR_COPY = PPCMfmsr();
sException.FPCSR_COPY = ctx->fpscr;
OSFillFPUContext(ctx);
OSSetErrorHandler(error, nullptr);
if (error == 0xf) {
fn_803AA2E0(0, 0, 0, 3);
fn_803AA2E0(1, 0, 0, 3);
fn_803AA2E0(2, 0, 0, 3);
fn_803AA2E0(3, 0, 0, 3);
}
ExceptionCallbackParam param;
param.error = error;
param.ctx = ctx;
param.dsisr = dsisr;
param.dar = dar;
OSSendMessage(&sException.queue, &param, 1);
if (OSGetCurrentThread() == nullptr) {
VISetPreRetraceCallback(nullptr);
VISetPostRetraceCallback(nullptr);
PPCMtmsr(PPCMfmsr() | 2);
DumpException_(&param);
}
while (OSEnableScheduler() > 0) {}
OSYieldThread();
OSDisableScheduler();
}
void *RunThread_(void *) {
OSMessage message;
u32 msr = PPCMfmsr();
PPCMtmsr(msr & ~(0x800 | 0x100));
OSReceiveMessage(&sException.queue, &message, 1);
OSDisableInterrupts();
VISetPreRetraceCallback(nullptr);
VISetPostRetraceCallback(nullptr);
if (sException.consoleHandle != nullptr) {
VISetBlack(false);
VIFlush();
}
DumpException_((const ExceptionCallbackParam *)message);
return nullptr;
}
static void PrintContext_(u16, const OSContext *, u32, u32);
static void WaitTime_(s32 time);
static void Console_SetVisible(ConsoleHandle, bool);
static void Console_SetViewBaseLine(ConsoleHandle, s32);
static u32 Console_GetBufferHeadLine(ConsoleHandle);
static void DrawConsoleEndless_(ConsoleHandle console) {
s32 lineCnt = Console_GetBufferHeadLine(console);
while (true) {
if (lineCnt >= Console_GetTotalLines(console)) {
lineCnt = console->ringTopLineCnt;
}
Console_SetViewBaseLine(sException.consoleHandle, lineCnt);
Console_DrawDirect(console);
WaitTime_(200);
lineCnt++;
}
}
static void DumpException_(const ExceptionCallbackParam *param) {
u16 error = param->error;
OSContext *ctx = param->ctx;
u32 dsisr = param->dsisr;
u32 dar = param->dar;
if (error < 0x11) {
sException.stackAddress = ctx->gprs[1];
}
if (sException.consoleHandle != nullptr) {
sException.frameMemory = detail::DirectPrint_SetupFB(sException.exceptionRenderObj);
}
while (true) {
PrintContext_(error, ctx, dsisr, dar);
if (sException.consoleHandle != nullptr && DirectPrint_IsActive()) {
Console_DrawDirect(sException.consoleHandle);
}
if (sException.exceptionCallback != nullptr) {
u16 info = sException.exceptionDisplayInfo;
do {
if (!(sException.exceptionCallback)(sException.consoleHandle, sException.exceptionCallbackArgs)) {
return;
}
} while (info == sException.exceptionDisplayInfo);
} else if (sException.consoleHandle != nullptr) {
DrawConsoleEndless_(sException.consoleHandle);
} else {
break;
}
}
}
static void Exception_Printf_(const char *format, ...) {
const GXRenderModeObj *obj = sException.exceptionRenderObj;
va_list args;
va_start(args, fmt);
OSVReport(format, args);
va_end(args);
if (sException.consoleHandle != nullptr) {
void *frameBuf = VIGetCurrentFrameBuffer();
DirectPrint_ChangeXfb(frameBuf, obj->fbWidth, obj->xfbHeight);
va_list args;
va_start(args, fmt);
Console_VFPrintf(CONSOLE_OUTPUT_DISPLAY, sException.consoleHandle, format, args);
va_end(args);
}
}
static void ShowStackTrace_(u32);
static void ShowMainInfo_(u16, const OSContext *, u32, u32);
static void ShowGPR_(const OSContext *);
static void ShowSRR0Map_(const OSContext *);
static void ShowGPRMap_(const OSContext *);
static void ShowFloat_(const OSContext *);
static bool ShowMapInfoSubroutine_(u32 address, bool arg);
static void PrintContext_(u16 error, const OSContext *context, u32 dsisr, u32 dar) {
if (error < 0x11) {
Exception_Printf_("******** EXCEPTION OCCURRED! ********\nFrameMemory:%XH\n", sException.frameMemory);
} else {
Exception_Printf_("******** USER HALT ********\nFrameMemory:%XH\n", sException.frameMemory);
}
if (sException.exceptionDisplayInfo & 0x1) {
Exception_Printf_("---MainInfo---\n");
ShowMainInfo_(error, context, dsisr, dar);
}
if (sException.exceptionDisplayInfo & 0x2) {
Exception_Printf_("---EXCEPTION_INFO_GPR---\n");
ShowGPR_(context);
}
if (sException.exceptionDisplayInfo & 0x8) {
Exception_Printf_("---EXCEPTION_INFO_SRR0MAP---\n");
ShowSRR0Map_(context);
}
if (sException.exceptionDisplayInfo & 0x4) {
Exception_Printf_("---EXCEPTION_INFO_GPRMAP---\n");
ShowGPRMap_(context);
}
if (sException.exceptionDisplayInfo & 0x10) {
Exception_Printf_("---EXCEPTION_INFO_FPR---\n");
ShowFloat_(context);
Exception_Printf_(" MSR:%08XH FPSCR:%08XH\n", sException.MSR_COPY, sException.FPCSR_COPY);
}
if (sException.exceptionDisplayInfo & 0x20) {
Exception_Printf_("---EXCEPTION_INFO_TRACE---\n");
ShowStackTrace_(sException.stackAddress);
}
Exception_Printf_("--------------------------------\n");
}
static bool IsValidStackAddr_(u32 stackAddress) {
if (stackAddress == 0 || stackAddress == 0xFFFFFFFF) {
return false;
} else if (OS_MEM_IS_MEM1(stackAddress)) {
if ((stackAddress & 0x0fffffff) >= OSGetPhysicalMem1Size()) {
return false;
}
} else if (OS_MEM_IS_MEM2(stackAddress)) {
if ((stackAddress & 0x0fffffff) >= OSGetPhysicalMem2Size()) {
return false;
}
} else {
return false;
}
return true;
}
static void ShowStackTrace_(u32 stackAddress) {
Exception_Printf_("-------------------------------- TRACE\n");
Exception_Printf_("Stack Address: %08X\n", stackAddress);
Exception_Printf_("LR save\n");
u32 i;
u32 *ptr = (u32 *)stackAddress;
for (i = 0; i < 16; i++) {
if (!IsValidStackAddr_((u32)ptr)) {
break;
}
Exception_Printf_("%08X ", ptr[1]);
u32 fp = ptr[1];
// TODO arg
if (!ShowMapInfoSubroutine_(fp, true)) {
Exception_Printf_("\n");
}
ptr = (u32 *)*ptr;
}
}
void ShowMainInfo_(u16 error, const OSContext *context, u32 dsisr, u32 dar) {
if (error < 0x11) {
Exception_Printf_("CONTEXT:%08XH (%s EXCEPTION)\n", context, CPU_EXP_NAME[error]);
} else {
Exception_Printf_("CONTEXT:%08XH\n", context);
}
/* floating point error */
if (error == 0x10) {
u32 uVar1 = sException.FPCSR_COPY;
uVar1 &= (((uVar1 & 0xf8) << 0x16) | 0x01f80700);
if ((uVar1 & 0x20000000) != 0) {
Exception_Printf_(" FPE: Invalid operation\n");
if ((sException.FPCSR_COPY & 0x1000000) != 0) {
Exception_Printf_(" SNaN\n");
}
if ((sException.FPCSR_COPY & 0x800000) != 0) {
Exception_Printf_(" Infinity - Infinity\n");
}
if ((sException.FPCSR_COPY & 0x400000) != 0) {
Exception_Printf_(" Infinity / Infinity\n");
}
if ((sException.FPCSR_COPY & 0x200000) != 0) {
Exception_Printf_(" 0 / 0\n");
}
if ((sException.FPCSR_COPY & 0x100000) != 0) {
Exception_Printf_(" Infinity * 0\n");
}
if ((sException.FPCSR_COPY & 0x80000) != 0) {
Exception_Printf_(" Invalid compare\n");
}
if ((sException.FPCSR_COPY & 0x400) != 0) {
Exception_Printf_(" Software request\n");
}
if ((sException.FPCSR_COPY & 0x200) != 0) {
Exception_Printf_(" Invalid square root\n");
}
if ((sException.FPCSR_COPY & 0x100) != 0) {
Exception_Printf_(" Invalid integer convert\n");
}
}
if ((uVar1 & 0x10000000) != 0) {
Exception_Printf_(" FPE: Overflow\n");
}
if ((uVar1 & 0x8000000) != 0) {
Exception_Printf_(" FPE: Underflow\n");
}
if ((uVar1 & 0x4000000) != 0) {
Exception_Printf_(" FPE: Zero division\n");
}
if ((uVar1 & 0x2000000) != 0) {
Exception_Printf_(" FPE: Inexact result\n");
}
}
Exception_Printf_("SRR0: %08XH SRR1:%08XH\n", context->srr0, context->srr1);
Exception_Printf_("DSISR: %08XH DAR: %08XH\n", dsisr, dar);
}
void ShowGPR_(const OSContext *ctx) {
Exception_Printf_("-------------------------------- GPR\n");
for (int i = 0; i < 10; i++) {
Exception_Printf_("R%02d:%08XH R%02d:%08XH R%02d:%08XH\n", i, ctx->gprs[i], i + 11, ctx->gprs[i + 11], i + 22,
ctx->gprs[i + 22]);
}
Exception_Printf_("R%02d:%08XH R%02d:%08XH\n", 10, ctx->gprs[10], 21, ctx->gprs[21]);
}
void ShowGPRMap_(const OSContext *ctx) {
bool shownAny = false;
Exception_Printf_("-------------------------------- GPRMAP\n");
for (int i = 0; i <= 31; i++) {
u32 address = ctx->gprs[i];
if ((address < 0x80000000) || (0x82ffffff < address)) {
continue;
}
shownAny = true;
Exception_Printf_("R%02d: %08XH ", i, address);
// TODO arg
if (!ShowMapInfoSubroutine_(address, true)) {
Exception_Printf_(" no information\n");
}
}
if (!shownAny) {
Exception_Printf_(" no register which seem to address.\n");
}
}
void ShowSRR0Map_(const OSContext *ctx) {
Exception_Printf_("-------------------------------- SRR0MAP\n");
u32 address = ctx->srr0;
if (!((address < 0x80000000) || (0x82ffffff < address))) {
Exception_Printf_("SRR0: %08XH ", address);
// TODO arg
if (!ShowMapInfoSubroutine_(address, true)) {
Exception_Printf_(" no information\n");
}
}
}
// 804ca0e4
extern "C" int __fpclassifyf(float val);
static void ShowFloatSub_(s32 reg, f32 val);
void ShowFloat_(const OSContext *ctx) {
Exception_Printf_("-------------------------------- FPR\n");
for (int i = 0; i < 10; i++) {
ShowFloatSub_(i, ctx->fprs[i]);
Exception_Printf_(" ");
ShowFloatSub_(i + 11, ctx->fprs[i + 11]);
Exception_Printf_(" ");
ShowFloatSub_(i + 22, ctx->fprs[i + 22]);
Exception_Printf_("\n");
}
ShowFloatSub_(10, ctx->fprs[10]);
Exception_Printf_(" ");
ShowFloatSub_(21, ctx->fprs[21]);
Exception_Printf_("\n");
}
void ShowFloatSub_(s32 reg, f32 val) {
if (__fpclassifyf(val) == 1) {
Exception_Printf_("F%02d: Nan ", reg);
} else {
if (__fpclassifyf(val) == 2) {
if ((reinterpret_cast<u8 &>(val) & 0x80) != 0) {
Exception_Printf_("F%02d:+Inf ", reg);
} else {
Exception_Printf_("F%02d:-Inf ", reg);
}
} else if (val == 0.0f) {
Exception_Printf_("F%02d: 0.0 ", reg);
} else {
Exception_Printf_("F%02d:%+.3E", reg, val);
}
}
}
static void SetFPException_(u32) {
// TODO
}
bool ShowMapInfoSubroutine_(u32 address, bool arg) {
if ((address < 0x80000000) || (0x82ffffff < address)) {
return false;
} else {
u8 acStack_124[260];
if (nw4r::db::MapFile_QuerySymbol(address, acStack_124, sizeof(acStack_124))) {
Exception_Printf_("%s\n", acStack_124);
return true;
} else {
return false;
}
}
}
ConsoleHandle Exception_SetConsole(ConsoleHandle console, const GXRenderModeObj *renderObj) {
ConsoleHandle old = sException.consoleHandle;
sException.exceptionRenderObj = renderObj;
sException.consoleHandle = console;
return old;
}
ConsoleHandle Exception_GetConsole() {
return sException.consoleHandle;
}
void Exception_SetUserCallback(bool (*callback)(detail::ConsoleHead *, void *), void *args) {
sException.exceptionCallback = callback;
sException.exceptionCallbackArgs = args;
}
u16 Exception_SetDisplayInfo(u16 newInfo) {
u16 old = sException.exceptionDisplayInfo;
sException.exceptionDisplayInfo = newInfo;
return old;
}
static void WaitTime_(s32 time) {
s64 t1 = OSGetTime();
s64 t2;
do {
t2 = OSGetTime();
} while ((t2 - t1) / ((OS_BUS_CLOCK_SPEED / 4) / 1000) < time);
}
/*
void DrawConsoleEndless_(detail::ConsoleHead *) {
// TODO
}
*/
static void Console_SetVisible(detail::ConsoleHead *, bool) {
// TODO
}
static void Console_SetViewBaseLine(detail::ConsoleHead *console, s32 line) {
console->viewTopLine = line;
}
static u32 Console_GetBufferHeadLine(detail::ConsoleHead *console) {
return console->ringTopLineCnt;
}
} // namespace db
} // namespace nw4r
+342
View File
@@ -0,0 +1,342 @@
#include <MSL_C/string.h>
#include <nw4r/db/db_mapFile.h>
#include <rvl/DVD.h>
#include <rvl/OS.h>
namespace nw4r {
namespace db {
static u32 sFileLength;
static MapFile *sMapFileList = nullptr;
static u8 (*GetCharPtr_)(const u8 *) = nullptr;
static u8 sMapBuf[512] ALIGN(32);
static DVDFileInfo sFileInfo;
static s32 sMapBufMaxSize = 0x200;
static u8 *sDvdBuf = sMapBuf;
static s32 sMapBufOffset = -1;
static void MapFile_Append_(MapFile *file) {
if (sMapFileList == nullptr) {
sMapFileList = file;
return;
}
if (file->moduleInfo != nullptr) {
file->next = sMapFileList->next;
sMapFileList->next = file;
} else {
file->next = sMapFileList;
sMapFileList = file;
}
}
/** 80436a50 */
MapFileHandle MapFile_RegistOnDvd(void *buf, const char *path, const OSModuleInfo *info) {
MapFile *file = (MapFile *)buf;
file->mapBuf = nullptr;
file->moduleInfo = info;
file->fileEntry = DVDConvertPathToEntrynum(path);
file->next = nullptr;
MapFile_Append_(file);
return file;
}
/** 80436ae0 */
void MapFile_Unregist(MapFileHandle file) {
if (file == sMapFileList) {
sMapFileList = sMapFileList->next;
return;
}
MapFile *cursor = sMapFileList;
for (; cursor != nullptr; cursor = cursor->next) {
if (cursor->next == file) {
cursor->next = file->next;
return;
}
}
}
/** 80436b30 */
void MapFile_UnregistAll() {
sMapFileList = nullptr;
}
/** 80436b40 */
static u8 GetCharOnMem_(const u8 *arg) {
return *arg;
}
/** 80436b50 */
static u8 GetCharOnDvd_(const u8 *buf) {
s32 address = (u32)buf & 0x7fffffff;
s32 offset = address - sMapBufOffset;
if (address >= sFileLength) {
return 0;
}
if (sMapBufOffset < 0 || offset < 0 || offset >= sMapBufMaxSize) {
sMapBufOffset = ROUND_DOWN(address, 32);
offset = address - sMapBufOffset;
address = sMapBufMaxSize;
if (sMapBufOffset + sMapBufMaxSize >= sFileLength) {
address = ROUND_UP(sFileLength - sMapBufOffset, 32);
}
BOOL enabled = OSEnableInterrupts();
BOOL read = DVDReadAsyncPrio(&sFileInfo, sDvdBuf, address, sMapBufOffset, nullptr, 2);
while (DVDGetCommandBlockStatus(&sFileInfo.block)) {}
OSRestoreInterrupts(enabled);
if (read <= 0) {
return 0;
}
}
return *(sDvdBuf + offset);
}
static u8 *SearchNextLine_(u8 *buf, s32 lines) {
u8 c;
if (buf == nullptr) {
return nullptr;
}
while ((c = (GetCharPtr_)(buf)) != '\0') {
if (c == '\n') {
if (--lines <= 0) {
return buf + 1;
}
}
buf++;
}
return nullptr;
}
static u8 *SearchNextSection_(u8 *buf) {
do {
buf = SearchNextLine_(buf, 1);
if (buf == nullptr) {
return nullptr;
}
} while ((GetCharPtr_)(buf) != '.');
return buf;
}
static u8 *SearchParam_(u8 *lineTop, u32 argNum, u8 splitter) {
bool inArg = false;
u8 *buf = lineTop;
if (buf == nullptr) {
return nullptr;
}
while (true) {
u8 c = (GetCharPtr_)(buf);
if (c == '\0' || c == '\n') {
return 0;
}
if (inArg) {
if (c == splitter) {
inArg = false;
}
} else if (c != splitter) {
if (argNum-- == 0) {
return buf;
}
inArg = true;
}
buf++;
}
}
static u32 XStrToU32_(const u8 *str) {
u32 val = 0;
while (true) {
u32 num;
u8 c = (GetCharPtr_)(str);
if ('0' <= c && c <= '9') {
num = c - '0';
} else if ('a' <= c && c <= 'z') {
num = c - 'a' + 10;
} else if ('A' <= c && c <= 'Z') {
num = c - 'A' + 10;
} else {
return val;
}
if (val >= 0x10000000) {
return 0;
}
val = num + val * 16;
str++;
}
}
static u32 CopySymbol_(const u8 *buf, u8 *str, u32 strLenMax, u8 splitter) {
u32 cnt = 0;
while (true) {
u8 c = (GetCharPtr_)(buf++);
if (c == splitter || c == '\0' || c == '\n') {
*str = '\0';
return cnt;
}
*str++ = c;
if (++cnt >= strLenMax - 1) {
*str = '\0';
return cnt;
}
}
}
bool QuerySymbolToMapFile_(u8 *buf, const OSModuleInfo *moduleInfo, u32 address, u8 *strBuf, u32 strBufSize) {
OSSectionInfo *sectionInfo = nullptr;
u32 sectionCnt;
if (moduleInfo != nullptr) {
sectionInfo = OSGetSectionInfo(moduleInfo);
sectionCnt = moduleInfo->numSections;
}
while (true) {
u32 offset = 0;
buf = SearchNextSection_(buf);
buf = SearchNextLine_(buf, 3);
if (sectionInfo != nullptr) {
offset = ROUND_DOWN(sectionInfo->offset, 2);
if (address < offset || address >= offset + sectionInfo->size) {
goto next;
}
}
while (true) {
u8 *param;
u32 startAddr;
u32 size;
buf = SearchNextLine_(buf, 1);
if (buf == nullptr) {
return false;
}
param = SearchParam_(buf, 1, ' ');
if (param == nullptr) {
goto next;
}
size = XStrToU32_(param);
param = SearchParam_(buf, 2, ' ');
if (param == nullptr) {
goto next;
}
startAddr = XStrToU32_(param);
if (startAddr == 0) {
continue;
}
startAddr += offset;
if (address < startAddr || startAddr + size <= address) {
continue;
}
param = SearchParam_(buf, 5, ' ');
if (param == nullptr) {
strBuf[0] = '\0';
return true;
}
if ((GetCharPtr_)(param) == '.') {
continue;
}
CopySymbol_(param, strBuf, strBufSize, '\t');
return true;
}
next:
if (sectionInfo != nullptr) {
if (--sectionCnt == 0) {
return 0;
}
sectionInfo++;
}
}
}
// No idea, doesn't appear in the DWARF
/** 804370d0 */
bool UnkFunction_(const OSModuleInfo *moduleInfo, u32 address, u8 *strBuf, u32 strBufSize) {
if (moduleInfo == nullptr) {
if (address < (u32)_stack_end) {
snprintf((char *)strBuf, strBufSize, "[%p]", address);
return true;
} else {
return false;
}
} else {
u32 sectionIdx = 0;
OSSectionInfo *sectionInfo = OSGetSectionInfo(moduleInfo);
for (u32 sectionCnt = 0; sectionCnt < moduleInfo->numSections; sectionCnt++) {
u32 offset = ROUND_DOWN(sectionInfo->offset, 2);
if (offset <= address && address < offset + sectionInfo->size) {
snprintf((char *)strBuf, strBufSize, "[%d:%d:%06x]", moduleInfo->id, sectionIdx, address - offset);
return true;
}
sectionInfo++;
sectionIdx++;
}
return false;
}
}
bool QuerySymbolToSingleMapFile_(MapFileHandle pMapFile, u32 address, u8 *strBuf, u32 strBufSize) {
if (pMapFile->mapBuf != nullptr) {
GetCharPtr_ = GetCharOnMem_;
return QuerySymbolToMapFile_(pMapFile->mapBuf, pMapFile->moduleInfo, address, strBuf, strBufSize);
} else if (pMapFile->fileEntry >= 0) {
u8 *buf = (u8 *)0x80000000;
bool ret;
if (!DVDFastOpen(pMapFile->fileEntry, &sFileInfo)) {
goto err;
}
sMapBufOffset = -1;
sFileLength = sFileInfo.size;
GetCharPtr_ = GetCharOnDvd_;
ret = QuerySymbolToMapFile_(buf, pMapFile->moduleInfo, address, strBuf, strBufSize);
DVDClose(&sFileInfo);
return ret;
} else {
return UnkFunction_(pMapFile->moduleInfo, address, strBuf, strBufSize);
}
err:
strBuf[0] = '\0';
return false;
}
bool MapFile_QuerySymbol(u32 address, u8 *strBuf, u32 strBufSize) {
if (sMapFileList == nullptr) {
if (address < (u32)_stack_end) {
snprintf((char *)strBuf, strBufSize, "[%p]", address);
return true;
} else {
u32 offset;
u32 section;
OSModuleInfo *info = OSSearchModule((void *)address, &section, &offset);
if (info) {
snprintf((char *)strBuf, strBufSize, "[%d:%d:%06x]", info->id, section, offset);
return true;
}
return false;
}
} else {
for (MapFile *pMap = sMapFileList; pMap != nullptr; pMap = pMap->next) {
if (QuerySymbolToSingleMapFile_(pMap, address, strBuf, strBufSize)) {
return true;
}
}
return false;
}
}
} // namespace db
} // namespace nw4r
+4 -4
View File
@@ -210,10 +210,10 @@ inline void strnsth(char *dest, const char *src, size_t max_len) {
/* 8000BA70 */ void FileManager::setBeaconPos(u32 beaconArea, u32 beaconNum, mVec3_c *pos) {}
/* 8000BB80 */ mVec3_c *FileManager::getBeaconPos(u32 beaconArea, u32 beaconNum) {}
/* 8000BC70 */ void FileManager::setEnemyKillCount(u32 enemy, u16 killCount) {}
/* 8000BCE0 */ u16 FileManager::getEnemyKillCount(u32 enemy) {}
/* 8000BD60 */ void FileManager::setHitCountFromEnemy(u32 enemy, u16 hitCount) {}
/* 8000BDD0 */ u16 FileManager::getHitCountFromEnemy(u32 enemy) {}
/* 8000BC70 */ void FileManager::setEnemyKillCount(u8 enemy, u16 killCount) {}
/* 8000BCE0 */ u16 FileManager::getEnemyKillCount(u8 enemy) {}
/* 8000BD60 */ void FileManager::setHitCountFromEnemy(u8 enemy, u16 hitCount) {}
/* 8000BDD0 */ u16 FileManager::getHitCountFromEnemy(u8 enemy) {}
/* 8000BE50 */ void FileManager::setLoadRoomT1_FileB(s16 roomId) {}
/* 8000BE80 */ s16 FileManager::getLoadRoomT1_FileB() {}
+1 -71
View File
@@ -1,26 +1,10 @@
#include <common.h>
#include <libc.h>
#include <toBeSorted/misc_flag_managers.h>
#include <toBeSorted/bitwise_flag_helper.h>
#include <toBeSorted/file_manager.h>
#include <toBeSorted/flag_space.h>
class CommittableFlagManager {
public:
bool mNeedsCommit;
virtual void doCommit() = 0;
bool commitIfNecessary();
void setNeedsCommit(bool commit) {
mNeedsCommit = commit;
}
CommittableFlagManager() {
mNeedsCommit = false;
}
CommittableFlagManager(bool commit) {
mNeedsCommit = commit;
}
};
/* 0x800BE7B0 */
bool CommittableFlagManager::commitIfNecessary() {
if (mNeedsCommit) {
@@ -32,31 +16,6 @@ bool CommittableFlagManager::commitIfNecessary() {
}
}
class TBoxFlagManager : public CommittableFlagManager {
public:
FlagSpace mFlagSpace;
u16 mSceneIndex;
BitwiseFlagHelper mFlagHelper;
static u16 sTBoxFlags[2];
static TBoxFlagManager *sInstance;
virtual void doCommit() override;
bool checkUncommittedFlag(u16 flag);
TBoxFlagManager();
virtual ~TBoxFlagManager() {}
void init();
void copyFromSave(s16 sceneIndex);
bool checkFlag(u16 sceneIndex, u16 flag);
virtual u16 getFlagCount() const;
void setFlag(u16 flag);
bool checkUncommittedFlag(u16 sceneIndex, u16 flag);
u16 checkUncommittedFlag2(u16 flag) {
return checkUncommittedFlag(flag);
}
};
TBoxFlagManager *TBoxFlagManager::sInstance = nullptr;
u16 TBoxFlagManager::sTBoxFlags[2] = {};
@@ -108,35 +67,6 @@ void TBoxFlagManager::setFlag(u16 flag) {
}
}
// NOTE: Not actually Enemy Defeat.
// This is a little more than that, it keeps track of live objects based on their id as a whole
class EnemyDefeatManager : public CommittableFlagManager {
public:
FlagSpace mFlagSpace;
BitwiseFlagHelper mFlagHelper;
u16 mSceneIndex;
static u16 sEnemyDefeatFlags[4096];
static EnemyDefeatManager *sInstance;
void clearSavedFlags();
bool checkUncommittedFlag(u16 flag);
u16 checkUncommittedFlag2(u16 flag) {
return checkUncommittedFlag(flag);
}
EnemyDefeatManager();
void init();
void copyFromSave(u16 sceneIndex);
void updateFlagIndex(u16 sceneIndex);
void clearAll();
bool checkIsValidFlag(u16 flag);
bool checkFlag(u16 flag);
virtual ~EnemyDefeatManager() {}
virtual u16 getFlagCount() const;
void setFlag(u16 flag);
};
EnemyDefeatManager *EnemyDefeatManager::sInstance = nullptr;
u16 EnemyDefeatManager::sEnemyDefeatFlags[4096] = {};
+5
View File
@@ -0,0 +1,5 @@
#include "toBeSorted/scgame.h"
SpawnInfo ScGame::currentSpawnInfo = {};
SpawnInfo ScGame::nextSpawnInfo = {};
ScGame* ScGame::sInstance = nullptr;
+114
View File
@@ -0,0 +1,114 @@
#include "m/m_vec.h"
#include "m/m_Angle.h"
#include "d/d_player.h"
#include "toBeSorted/special_item_drop_mgr.h"
SpecialItemDropMgr* SpecialItemDropMgr::sInstance = nullptr;
extern "C" short targetAngleY(mVec3_c *, mVec3_c *);
extern "C" int rndInt(int);
extern "C" void spawnItem1(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
extern "C" void spawnItem2(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
extern "C" void spawnItem3(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
extern "C" void spawnItem4(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
extern "C" void spawnItem5(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
extern "C" void spawnItem6(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
extern "C" void spawnItem7(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
extern "C" void spawnItem8(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
extern "C" void spawnItem9(s16 itemid, u32 roomid, mVec3_c *pos, mAng3_c *rot, u32 param2, u32 unk);
// 800c7b80
SpecialItemDropMgr::SpecialItemDropMgr() {
SpecialItemDropMgr::sInstance = this;
}
// TODO: Convert to enum once work on items has started
int SPECIAL_ITEM_ARRAY[28] = {0, 6, 6, 2, 3, 4, 0x2b, 0x28, 0x29, 7, 8, 0x39, 0, 0, 0x1c, 0xa5, 58, 59, 183, 184, 185, 72, 72, 1, 34, 0, 0, 0};
int RAND_RUPEE_ARRAY[4] = {2, 3, 4, 0};
// 800c7bb0
int fn_800C7BB0(SpecialItemDropMgr *mgr, int specialItemId) {}
// 800c7d00
short fn_800C7D00(SpecialItemDropMgr *mgr, int specialItemId) {}
// 800c7d20
short fn_800C7D20(SpecialItemDropMgr *mgr, int specialItemId) {}
// 800c7d40
int giveSpecialDropItem(SpecialItemDropMgr *mgr, int specialItemId, int roomid, mVec3_c *pos, int subtype, s16 *rot, s32 unused) {}
// 800c7ef0
// Very unmatching. Just here as a starting point
bool spawnSpecialDropItem(SpecialItemDropMgr *mgr, int specialItemId, int roomid, mVec3_c *pos, int subtype, s16 *rot) {
u32 unk = fn_800C7BB0(mgr, specialItemId);
if (unk == 0) {
return false;
}
s8 itemCount = 1;
if (unk == 2) {
itemCount = 3;
} else if (unk == 12) {
itemCount = 10;
} else if (unk == 13) {
itemCount = 5;
} else if (unk == 22) {
itemCount = 2;
}
s16 currentRot;
s16 tempOther;
u16 itemid = SPECIAL_ITEM_ARRAY[unk];
mAng3_c itemRot = {0, 0, 0};
if (subtype == 2 || subtype == 6) {
currentRot = *rot;
tempOther = -0xe39;
} else {
currentRot = targetAngleY(&(dPlayer::LINK->position), pos);
tempOther = -0x8000;
currentRot += 0x4000;
}
s16 angleDecrement = tempOther / itemCount;
tempOther = angleDecrement / 2;
currentRot += tempOther;
tempOther /= 2;
for (s8 currentItemIndex = 0; currentItemIndex < itemCount; currentItemIndex++) {
s16 out;
SpecialItemDropMgr::fn_800C81D0(out, tempOther, -tempOther);
itemRot.y = currentRot + out;
if (unk < 15) {
itemid = RAND_RUPEE_ARRAY[rndInt(3)];
spawnItem1(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
} else if (subtype == 2) {
spawnItem2(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
} else {
if (subtype == 1) {
spawnItem3(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
} else if (subtype == 4) {
spawnItem4(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
} else if (subtype == 3) {
spawnItem5(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
} else if (subtype == 5) {
spawnItem6(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
} else if (subtype == 6) {
spawnItem7(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
} else if (subtype == 7) {
spawnItem8(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
} else {
spawnItem9(itemid, roomid, pos, &itemRot, 0xFFFFFFFF, 0);
}
}
currentRot -= angleDecrement;
}
return true;
}
// 800c81d0
void fn_800C81D0(s16, s16, s16) {};
// 800c8270
SpecialItemDropMgr::~SpecialItemDropMgr() {}