d_kankyo_data and d_kankyo work (#158)

* Copy over progress

* Comment other d_kankyo_data dat section stuff

* Compiling

* Progress

* Progress

* Close

* Match

* Clean

* Change loop

* Clean

* Clean

* Before attempt clean

* Work on dKy_F_SP121Check, not compiling

* Adjust comparisons

* Adjust headers

* Close

* Matching

* Remove

* Comments

* Fix u8 pointer

* Comment

* Adjust

* Comment stage names

* Rename member

* Decomp dKy_darkworld_spot_check

* Decomp dKy_darkworld_Area_set

* Adjust

* Comments, small adjust

* Add phase1 base txt

* Working through d_s_play phase_1

* Finish function outline

* Comments

* Add darkLv enum

* Rename enum

* Refactor

* Comment

* Documentation

* Move out notes

* Comments

* Adjust

* Rename structs

* Comments

* Minor adjust

* Comment

* Adjust and Comments

* Adjust

* Adjust

* Comment

* Clean

* Add back addresses

* Adjust comment

* Adjust comments

* Comments

* Comment

* Adjust for clang-format-10

* Edit getName

* Fix fog table

* Make l_field_data use placeholder struct

* Make l_envr_default use placeholder struct

* Make l_vr_box_data use placeholder struct

* Make l_pselect_default use placeholder struct
This commit is contained in:
icogn 2021-12-02 16:43:22 -06:00 committed by GitHub
parent bc428f7f65
commit f6f7e7ce38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 588 additions and 1005 deletions

View File

@ -157,7 +157,7 @@ public:
void setMaxOxygen(int max) { mMaxOxygen = max; }
u8 getDoStatus() { return mDoStatus; }
u8 getRStatus() { return mRStatus; }
char* getStartStageName() { return mStartStage.getName(); }
const char* getStartStageName() { return mStartStage.getName(); }
s8 getStartStageRoomNo() { return mStartStage.getRoomNo(); }
s8 getStartStageLayer() { return mStartStage.getLayer(); }
u8 isHeapLockFlag() { return mHeapLockFlag; }
@ -173,6 +173,8 @@ public:
dAttention_c& getAttention() { return mAttention; }
JKRArchive* getMsgDtArchive(int idx) { return mMsgDtArchive[idx]; }
s16 getStartStagePoint() { return mStartStage.getPoint(); }
s8 getStartStageDarkArea() { return mStartStage.getDarkArea(); }
void setStartStageDarkArea(s8 darkArea) { mStartStage.setDarkArea(darkArea); }
void* getPlayerPtr(int ptrIdx) { return mPlayerPtr[ptrIdx]; }
JKRArchive* getMain2DArchive() { return mMain2DArchive; }
J2DGrafContext* getCurrentGrafPort() { return mCurrentGrafPort; }
@ -741,7 +743,7 @@ inline u32 dComIfGp_getNowVibration() {
return g_dComIfG_gameInfo.play.getNowVibration();
}
inline char* dComIfGp_getStartStageName() {
inline const char* dComIfGp_getStartStageName() {
return g_dComIfG_gameInfo.play.getStartStageName();
}
@ -757,6 +759,10 @@ inline s8 dComIfGp_roomControl_getStayNo() {
return dStage_roomControl_c::getStayNo();
}
inline void dComIfGp_setStartStage(dStage_startStage_c* pStartStage) {
g_dComIfG_gameInfo.play.setStartStage(pStartStage);
}
inline s8 dComIfGp_getStartStageRoomNo() {
return g_dComIfG_gameInfo.play.getStartStageRoomNo();
}
@ -765,6 +771,14 @@ inline s8 dComIfGp_getStartStageLayer() {
return g_dComIfG_gameInfo.play.getStartStageLayer();
}
inline s8 dComIfGp_getStartStageDarkArea() {
return g_dComIfG_gameInfo.play.getStartStageDarkArea();
}
inline void dComIfGp_setStartStageDarkArea(s8 darkArea) {
g_dComIfG_gameInfo.play.setStartStageDarkArea(darkArea);
}
inline roomRead_class* dComIfGp_getStageRoom() {
return g_dComIfG_gameInfo.play.getStage().getRoom();
}

View File

@ -548,13 +548,16 @@ private:
class dStage_startStage_c {
public:
void set(const char*, s8, s16, s8);
inline char* getName() { return mStage; }
s8 getLayer() { return mLayer; }
const char* getName() const { return mName; }
s16 getPoint() const { return mPoint; }
s8 getRoomNo() const { return mRoomNo; }
s16 getPoint() { return mPoint; }
s8 getLayer() const { return mLayer; }
void setLayer(s8 layer) { mLayer = layer; }
s8 getDarkArea() const { return mDarkArea; }
void setDarkArea(s8 darkArea) { mDarkArea = darkArea; }
private:
/* 0x0 */ char mStage[8];
/* 0x0 */ char mName[8];
/* 0x8 */ s16 mPoint;
/* 0xA */ s8 mRoomNo;
/* 0xB */ s8 mLayer;

View File

@ -3,4 +3,49 @@
#include "dolphin/types.h"
// Invented name; Used as u8 `darkLv` in dKyd_darkworldTblEntry.
enum dKyd_DARKLV {
FARON = 0,
ELDIN = 1,
LANAYRU = 2,
TEST = 5, // Only used with nonexistent test stages
UNCLEARABLE = 6, // Default. Palace of Twilight stages use this
ALWAYS_DARK = 8, // Unused. Forces Twilight
};
// Invented name
struct dKyd_darkworldTblEntry {
char* stageName;
u8 darkLv;
}; // Size: 0x8
// Invented name; adjust as needed in the future.
// Notes (needs more investigation):
// startTime and endTime are in the range 0 to 360, which is the same as the current time of day.
// l_time_attribute and l_time_attribute_boss are arrays of `dKyd_lightSchedjule` with their times
// set up such that the current time of day will fall in the range of one dKyd_lightSchedjule. For
// example, if the current time is 110.0f (7:20 AM), then the dKyd_lightSchedjule {105.0f, 135.0f,
// 1, 2} would be selected. If the time was 105.0f, we would use light 1. If the time was 135.0f, we
// would use light 2. Since 110.0f is closer to 105.0f than 135.0f, we get a blend of lights 1 and 2
// which is mostly 1. Blending the lights over time is how we get a smooth day-night transition.
struct dKyd_lightSchejule {
float startTime;
float endTime;
u8 startTimeLight;
u8 endTimeLight;
}; // Size: 0xC
void* dKyd_dmpalet_getp();
void* dKyd_dmpselect_getp();
void* dKyd_dmenvr_getp();
void* dKyd_dmvrbox_getp();
dKyd_lightSchejule* dKyd_schejule_getp();
dKyd_lightSchejule* dKyd_schejule_boss_getp();
void dKyd_xfog_table_set(u8);
void* dKyd_maple_col_getp();
dKyd_darkworldTblEntry* dKyd_darkworld_tbl_getp();
void* dKyd_light_size_tbl_getp();
void* dKyd_light_tw_size_tbl_getp();
void* dKyd_BloomInf_tbl_getp(int);
#endif /* D_KANKYO_D_KANKYO_DATA_H */

View File

@ -1205,7 +1205,7 @@ int dComIfG_play_c::getLayerNo(int param_0) {
}
int layer = dComIfGp_getStartStageLayer();
char* stage = dComIfGp_getStartStageName();
const char* stage = dComIfGp_getStartStageName();
return getLayerNo_common(stage, roomNo, layer);
}

View File

@ -2588,7 +2588,7 @@ u8 check_itemno(int i_itemId) {
if (g_dComIfG_gameInfo.play.getLayerNo(0) == 0xD ||
g_dComIfG_gameInfo.play.getLayerNo(0) == 0xE) {
char* tmp = dComIfGp_getStartStageName();
const char* tmp = dComIfGp_getStartStageName();
// D_MN08: Palace of Twilight
if (strncmp(tmp, "D_MN08", 6)) {
return GREEN_RUPEE;

View File

@ -73,7 +73,7 @@ SECTION_DEAD static char const* const pad_80394F3D = "\0\0";
// matching but need gameinfo setup
#ifdef NONMATCHING
bool dKyeff_c::execute() {
char* stageName = dComIfGp_getStartStageName();
const char* stageName = dComIfGp_getStartStageName();
int strcmp_result = strcmp(stageName, "Name"); // strcmp(stageName,"Name");
if (strcmp_result != 0) {
dKyw_wether_move();

View File

@ -546,8 +546,8 @@ static asm int dStage_RoomKeepDoorInit(dStage_dt_c* param_0, void* param_1, int
#pragma pop
#endif
void dStage_startStage_c::set(const char* i_Stage, s8 i_RoomNo, s16 i_Point, s8 i_Layer) {
strcpy(mStage, i_Stage);
void dStage_startStage_c::set(const char* i_Name, s8 i_RoomNo, s16 i_Point, s8 i_Layer) {
strcpy(mName, i_Name);
mRoomNo = i_RoomNo;
mPoint = i_Point;
mLayer = i_Layer;

View File

@ -5,6 +5,7 @@
#include "d/kankyo/d_kankyo.h"
#include "d/com/d_com_inf_game.h"
#include "d/kankyo/d_kankyo_data.h"
#include "dol2asm.h"
#include "dolphin/types.h"
@ -389,6 +390,12 @@ extern "C" u8 mAudioMgrPtr__10Z2AudioMgr[4 + 4 /* padding */];
// Declarations:
//
// TODO: Temporarily putting here. There is said to be some issues in `d_com_inf_game.h` which need
// to be sorted out before we can correctly use this function from there.
inline BOOL dComIfGs_isEventBit(u16 id) {
return g_dComIfG_gameInfo.info.getSavedata().getEvent().isEventBit(id);
}
/* 8019C388-8019C3A4 196CC8 001C+00 2/2 0/0 0/0 .text dKy_WolfPowerup_AmbCol__FP11_GXColorS10 */
#pragma push
#pragma optimization_level 0
@ -3183,52 +3190,166 @@ asm void dKy_darkworld_check() {
}
#pragma pop
/* ############################################################################################## */
/* 80394C6C-80394C6C 0212CC 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */
#pragma push
#pragma force_active on
SECTION_DEAD static char const* const stringBase_80394ED5 = "F_SP108";
#pragma pop
/**
* @brief Returns the following info about a room: (1) if the room must not be in twilight and (2)
* which darkLv the room belongs to (Faron, Eldin, etc.).
*
* @param stageName stage name
* @param roomNo room number
* @param out_darkLv byte pointer to write darkLv to, or NULL
* @param tblIndex index in darkworld table for the stageName
* @return int Returns -1 if the given room must not be loaded in twilight, else returns 0 or 1. A
* return of 1 means darkLv should be read from out_darkLv and 0 means it should be read from the
* darkworld table.
*/
/* 801AC5BC-801AC70C 1A6EFC 0150+00 3/3 0/0 0/0 .text dKy_F_SP121Check__FPCciPUci */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
static asm void dKy_F_SP121Check(char const* param_0, int param_1, u8* param_2, int param_3) {
nofralloc
#include "asm/d/kankyo/d_kankyo/dKy_F_SP121Check__FPCciPUci.s"
}
#pragma pop
static int dKy_F_SP121Check(char const* stageName, int roomNo, u8* out_darkLv, int tblIndex) {
dKyd_darkworldTblEntry* darkworldTbl = dKyd_darkworld_tbl_getp();
int result = 0;
if (out_darkLv != NULL) {
*out_darkLv = UNCLEARABLE;
}
// Stage is Hyrule Field
if (!strcmp(stageName, "F_SP121")) {
// Room is one of:
// - Eldin Field (0)
// - Kakariko Gorge (3)
// - Eldin Field / Kakariko Gorge Path North (5) and South (4)
// - Faron Field / Kakariko Gorge Path North (2)
// - Outside Hidden Village (7)
if (roomNo == 0 || (2 <= roomNo && roomNo <= 5) || roomNo == 7) {
if (out_darkLv != NULL) {
*out_darkLv = ELDIN;
}
result = 1;
}
// Room is one of:
// - Lanayru Field (10)
// - Great Bridge of Hylia (13)
// - Lanayru Field / Great Bridge of Hylia Path North (11) and South (12)
// - Faron Field / Great Bridge of Hylia Path North (14)
// - Lanayru Field / Outside Hidden Village Path (9)
else if (roomNo >= 9 && roomNo <= 14) {
if (out_darkLv != NULL) {
*out_darkLv = LANAYRU;
}
result = 1;
}
// Room is one of:
// - Faron Field (6)
// - Faron Field / Kakariko Gorge Path South (1)
// - Faron Field / Great Bridge of Hylia Path South (15)
else {
result = -1;
}
}
// Faron Spring; No twilight during Rusl cutscene at very beginning of game.
else if (!strcmp(stageName, "F_SP108") && roomNo == 1 && dComIfGp_getStartStageLayer() == 13) {
result = -1;
}
// Prevent twilight if stage depends on Faron Twilight cleared status (Faron Woods, Coro's
// Lantern Shop, Faron Woods Cave) but haven't finished Ordon Day 2.
if (darkworldTbl[tblIndex].darkLv == FARON && !dComIfGs_isEventBit(0x4510)) {
result = -1;
}
return result;
}
/**
* @brief Returns TRUE if (1) the room is one which can be loaded in twilight, (2) there is nothing
* currently preventing it from being loaded in twilight, and (3) the player has not cleared the
* relevant dark level (Faron Twilight, etc.). Otherwise returns FALSE.
*
* @param stageName stage name
* @param roomNo room number
* @return BOOL Returns TRUE if the room can be loaded as twilight and the player has not already
* cleared it, else FALSE.
*/
/* 801AC70C-801AC7E0 1A704C 00D4+00 0/0 2/2 0/0 .text dKy_darkworld_stage_check__FPCci */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm BOOL dKy_darkworld_stage_check(char const* param_0, int param_1) {
nofralloc
#include "asm/d/kankyo/d_kankyo/dKy_darkworld_stage_check__FPCci.s"
}
#pragma pop
BOOL dKy_darkworld_stage_check(char const* stageName, int roomNo) {
dKyd_darkworldTblEntry* darkworldTbl = dKyd_darkworld_tbl_getp();
BOOL result = FALSE;
u8 darkLv[1];
/* 801AC7E0-801AC870 1A7120 0090+00 0/0 1/1 0/0 .text dKy_darkworld_spot_check__FPCci */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void dKy_darkworld_spot_check(char const* param_0, int param_1) {
nofralloc
#include "asm/d/kankyo/d_kankyo/dKy_darkworld_spot_check__FPCci.s"
for (int i = 0; i < 34; i++) {
if (!strcmp(stageName, darkworldTbl[i].stageName)) {
if (darkworldTbl[i].darkLv != ALWAYS_DARK) {
int fsp121CheckResult = dKy_F_SP121Check(stageName, roomNo, darkLv, i);
if (fsp121CheckResult >= 0) {
if (fsp121CheckResult == 0) {
*darkLv = darkworldTbl[i].darkLv;
}
if (!dComIfGs_isDarkClearLV(*darkLv)) {
result = TRUE;
}
break;
}
} else {
// ALWAYS_DARK is used to force twilight (likely for testing). This will
// never normally run since it is not present in l_darkworld_tbl.
result = TRUE;
break;
}
}
}
return result;
}
/**
* @brief Returns TRUE if a given room would be loaded in twilight. This function always behaves as
* if the player has not cleared any twilights.
*
* For example, Eldin Field will always return TRUE. Faron Woods on the other hand might return TRUE
* or FALSE depending on whether or not the player has completed Ordon Day 2.
*
* @param stageName stage name
* @param roomNo room number
* @return BOOL Returns TRUE if a given room would be loaded in twilight. This function always
* behaves as if the player has not cleared any twilights.
*/
/* 801AC7E0-801AC870 1A7120 0090+00 0/0 1/1 0/0 .text dKy_darkworld_spot_check__FPCci */
BOOL dKy_darkworld_spot_check(char const* stageName, int roomNo) {
dKyd_darkworldTblEntry* darkworldTblPtr = dKyd_darkworld_tbl_getp();
BOOL result = FALSE;
for (int i = 0; i < 34; i++) {
if (!strcmp(stageName, darkworldTblPtr->stageName) &&
dKy_F_SP121Check(stageName, roomNo, NULL, i) >= 0) {
result = TRUE;
break;
}
darkworldTblPtr++;
}
return result;
}
#pragma pop
/* 801AC870-801AC918 1A71B0 00A8+00 0/0 1/1 0/0 .text dKy_darkworld_Area_set__FPCci */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void dKy_darkworld_Area_set(char const* param_0, int param_1) {
nofralloc
#include "asm/d/kankyo/d_kankyo/dKy_darkworld_Area_set__FPCci.s"
void dKy_darkworld_Area_set(char const* stageName, int roomNo) {
dKyd_darkworldTblEntry* darkworldTblPtr = dKyd_darkworld_tbl_getp();
u8 darkLv[1];
for (int i = 0; i < 34; i++) {
if (!strcmp(stageName, darkworldTblPtr[i].stageName)) {
int fsp121CheckResult = dKy_F_SP121Check(stageName, roomNo, darkLv, i);
if (fsp121CheckResult >= 0) {
if (fsp121CheckResult == 0) {
*darkLv = darkworldTblPtr[i].darkLv;
}
dComIfGp_setStartStageDarkArea(*darkLv);
break;
}
}
}
}
#pragma pop
/* ############################################################################################## */
/* 80453E00-80453E04 002400 0004+00 1/1 0/0 0/0 .sdata2 @10483 */

File diff suppressed because it is too large Load Diff