2020-06-02 12:44:34 -04:00
|
|
|
#include <PR/ultratypes.h>
|
2019-08-25 00:46:40 -04:00
|
|
|
|
2020-06-02 12:44:34 -04:00
|
|
|
#include "behavior_data.h"
|
|
|
|
#include "debug.h"
|
2019-08-25 00:46:40 -04:00
|
|
|
#include "engine/behavior_script.h"
|
|
|
|
#include "engine/surface_collision.h"
|
2020-04-03 14:57:26 -04:00
|
|
|
#include "game_init.h"
|
2019-08-25 00:46:40 -04:00
|
|
|
#include "main.h"
|
2020-06-02 12:44:34 -04:00
|
|
|
#include "object_constants.h"
|
|
|
|
#include "object_fields.h"
|
|
|
|
#include "object_helpers.h"
|
2019-08-25 00:46:40 -04:00
|
|
|
#include "object_list_processor.h"
|
2020-06-02 12:44:34 -04:00
|
|
|
#include "print.h"
|
|
|
|
#include "sm64.h"
|
|
|
|
#include "types.h"
|
2019-08-25 00:46:40 -04:00
|
|
|
|
|
|
|
#define DEBUG_INFO_NOFLAGS (0 << 0)
|
|
|
|
#define DEBUG_INFO_FLAG_DPRINT (1 << 0)
|
|
|
|
#define DEBUG_INFO_FLAG_LSELECT (1 << 1)
|
|
|
|
#define DEBUG_INFO_FLAG_ALL 0xFF
|
|
|
|
|
|
|
|
s16 gDebugPrintState1[6]; // prints top-down?
|
|
|
|
s16 gDebugPrintState2[6]; // prints bottom-up?
|
|
|
|
|
|
|
|
enum DebugPrintStateInfo {
|
|
|
|
DEBUG_PSTATE_DISABLED,
|
|
|
|
DEBUG_PSTATE_X_CURSOR,
|
|
|
|
DEBUG_PSTATE_Y_CURSOR,
|
|
|
|
DEBUG_PSTATE_MIN_Y_CURSOR,
|
|
|
|
DEBUG_PSTATE_MAX_X_CURSOR,
|
|
|
|
DEBUG_PSTATE_LINE_Y_OFFSET
|
|
|
|
};
|
|
|
|
|
|
|
|
// DEBUG_SYS_EFFECTINFO
|
|
|
|
const char *sDebugEffectStringInfo[] = {
|
|
|
|
" a0 %d", " a1 %d", " a2 %d", " a3 %d", " a4 %d", " a5 %d", " a6 %d", " a7 %d",
|
|
|
|
"A" // cursor
|
|
|
|
};
|
|
|
|
|
|
|
|
// DEBUG_SYS_ENEMYINFO
|
|
|
|
const char *sDebugEnemyStringInfo[] = {
|
|
|
|
" b0 %d", " b1 %d", " b2 %d", " b3 %d", " b4 %d", " b5 %d", " b6 %d", " b7 %d",
|
|
|
|
"B" // cursor
|
|
|
|
};
|
|
|
|
|
|
|
|
s32 sDebugInfoDPadMask = 0;
|
|
|
|
s32 sDebugInfoDPadUpdID = 0;
|
|
|
|
s8 sDebugLvSelectCheckFlag = FALSE;
|
|
|
|
|
|
|
|
#define DEBUG_PAGE_MIN DEBUG_PAGE_OBJECTINFO
|
|
|
|
#define DEBUG_PAGE_MAX DEBUG_PAGE_ENEMYINFO
|
|
|
|
|
|
|
|
s8 sDebugPage = DEBUG_PAGE_MIN;
|
|
|
|
s8 sNoExtraDebug = FALSE;
|
|
|
|
s8 sDebugStringArrPrinted = FALSE;
|
|
|
|
s8 sDebugSysCursor = 0;
|
|
|
|
s8 sDebugInfoButtonSeqID = 0;
|
|
|
|
s16 sDebugInfoButtonSeq[] = { U_CBUTTONS, L_CBUTTONS, D_CBUTTONS, R_CBUTTONS, -1 };
|
|
|
|
|
|
|
|
// most likely present in an ifdef DEBUG build. TODO: check DD version?
|
2020-03-01 22:42:52 -05:00
|
|
|
void stub_debug_1(void) {
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
2020-03-01 22:42:52 -05:00
|
|
|
void stub_debug_2(void) {
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
2020-03-01 22:42:52 -05:00
|
|
|
void stub_debug_3(void) {
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
2020-03-01 22:42:52 -05:00
|
|
|
void stub_debug_4(void) {
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These 2 functions are called from the object list processor in regards to cycle
|
|
|
|
* counts. They likely have stubbed out code that calculated the clock count and
|
|
|
|
* its difference for consecutive calls.
|
|
|
|
*/
|
|
|
|
s64 get_current_clock(void) {
|
2019-11-03 14:36:27 -05:00
|
|
|
s64 wtf = 0;
|
2019-08-25 00:46:40 -04:00
|
|
|
|
|
|
|
return wtf;
|
|
|
|
}
|
|
|
|
|
|
|
|
s64 get_clock_difference(UNUSED s64 arg0) {
|
2019-11-03 14:36:27 -05:00
|
|
|
s64 wtf = 0;
|
2019-08-25 00:46:40 -04:00
|
|
|
|
|
|
|
return wtf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the print state info given a pointer to a print state and the relevent
|
|
|
|
* information. Note the reset of the printing boolean. For all intenses and
|
|
|
|
* purposes this creates/formats a new print state.
|
|
|
|
*/
|
|
|
|
void set_print_state_info(s16 *printState, s16 xCursor, s16 yCursor, s16 minYCursor, s16 maxXCursor,
|
|
|
|
s16 lineYOffset) {
|
|
|
|
printState[DEBUG_PSTATE_DISABLED] = FALSE;
|
|
|
|
printState[DEBUG_PSTATE_X_CURSOR] = xCursor;
|
|
|
|
printState[DEBUG_PSTATE_Y_CURSOR] = yCursor;
|
|
|
|
printState[DEBUG_PSTATE_MIN_Y_CURSOR] = minYCursor;
|
|
|
|
printState[DEBUG_PSTATE_MAX_X_CURSOR] = maxXCursor;
|
|
|
|
printState[DEBUG_PSTATE_LINE_Y_OFFSET] = lineYOffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Take a print state array, string, and the number to print, and use its information to print
|
|
|
|
* the next entry in the list. If the current print state array is too far down the list, this
|
|
|
|
* will print "DPRINT OVER" instead, signaling that the print state overflowed.
|
|
|
|
*/
|
|
|
|
void print_text_array_info(s16 *printState, const char *str, s32 number) {
|
|
|
|
if (!printState[DEBUG_PSTATE_DISABLED]) {
|
|
|
|
if ((printState[DEBUG_PSTATE_Y_CURSOR] < printState[DEBUG_PSTATE_MIN_Y_CURSOR])
|
|
|
|
|| (printState[DEBUG_PSTATE_MAX_X_CURSOR] < printState[DEBUG_PSTATE_Y_CURSOR])) {
|
|
|
|
print_text(printState[DEBUG_PSTATE_X_CURSOR], printState[DEBUG_PSTATE_Y_CURSOR],
|
|
|
|
"DPRINT OVER");
|
|
|
|
printState[DEBUG_PSTATE_DISABLED] += 1; // why not just = TRUE...
|
|
|
|
} else {
|
|
|
|
print_text_fmt_int(printState[DEBUG_PSTATE_X_CURSOR], printState[DEBUG_PSTATE_Y_CURSOR],
|
|
|
|
str, number);
|
|
|
|
printState[DEBUG_PSTATE_Y_CURSOR] += printState[DEBUG_PSTATE_LINE_Y_OFFSET];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_text_array_x_y(s32 xOffset, s32 yOffset) {
|
|
|
|
s16 *printState = gDebugPrintState1;
|
|
|
|
|
|
|
|
printState[DEBUG_PSTATE_X_CURSOR] += xOffset;
|
|
|
|
printState[DEBUG_PSTATE_Y_CURSOR] =
|
|
|
|
yOffset * printState[DEBUG_PSTATE_LINE_Y_OFFSET] + printState[DEBUG_PSTATE_Y_CURSOR];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These series of dprint functions print methods depending on the context of the
|
|
|
|
* current debug mode as well as the printer array (down to up vs up to down).
|
|
|
|
*/
|
|
|
|
void print_debug_bottom_up(const char *str, s32 number) {
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gDebugInfoFlags & DEBUG_INFO_FLAG_DPRINT) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_text_array_info(gDebugPrintState2, str, number);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_debug_top_down_objectinfo(const char *str, s32 number) {
|
2019-09-01 15:50:50 -04:00
|
|
|
if ((gDebugInfoFlags & DEBUG_INFO_FLAG_DPRINT) && sDebugPage == DEBUG_PAGE_OBJECTINFO) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_text_array_info(gDebugPrintState1, str, number);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_debug_top_down_mapinfo(const char *str, s32 number) {
|
2019-09-01 15:50:50 -04:00
|
|
|
if (sNoExtraDebug) { // how come this is the only instance of the sNoExtraDebug check?
|
2019-08-25 00:46:40 -04:00
|
|
|
return;
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gDebugInfoFlags & DEBUG_INFO_FLAG_DPRINT) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_text_array_info(gDebugPrintState1, str, number);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void print_debug_top_down_normal(const char *str, s32 number) {
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gDebugInfoFlags & DEBUG_INFO_FLAG_DPRINT) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_text_array_info(gDebugPrintState1, str, number);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef VERSION_EU
|
|
|
|
void print_mapinfo(void) {
|
|
|
|
struct Surface *pfloor;
|
|
|
|
f32 bgY;
|
|
|
|
f32 water;
|
|
|
|
s32 area;
|
|
|
|
s32 angY;
|
|
|
|
|
|
|
|
angY = gCurrentObject->oMoveAngleYaw / 182.044000;
|
|
|
|
area = ((s32) gCurrentObject->oPosX + 0x2000) / 1024
|
|
|
|
+ ((s32) gCurrentObject->oPosZ + 0x2000) / 1024 * 16;
|
|
|
|
|
|
|
|
bgY = find_floor(gCurrentObject->oPosX, gCurrentObject->oPosY, gCurrentObject->oPosZ, &pfloor);
|
|
|
|
water = find_water_level(gCurrentObject->oPosX, gCurrentObject->oPosZ);
|
|
|
|
|
|
|
|
print_debug_top_down_normal("mapinfo", 0);
|
|
|
|
print_debug_top_down_mapinfo("area %x", area);
|
|
|
|
print_debug_top_down_mapinfo("wx %d", gCurrentObject->oPosX);
|
|
|
|
//! Fat finger: programmer hit tab instead of space. Japanese
|
|
|
|
// thumb shift keyboards had the tab key next to the spacebar,
|
|
|
|
// so this was likely the reason.
|
|
|
|
print_debug_top_down_mapinfo("wy\t %d", gCurrentObject->oPosY);
|
|
|
|
print_debug_top_down_mapinfo("wz %d", gCurrentObject->oPosZ);
|
|
|
|
print_debug_top_down_mapinfo("bgY %d", bgY);
|
|
|
|
print_debug_top_down_mapinfo("angY %d", angY);
|
|
|
|
|
|
|
|
if (pfloor) // not null
|
|
|
|
{
|
|
|
|
print_debug_top_down_mapinfo("bgcode %d", pfloor->type);
|
|
|
|
print_debug_top_down_mapinfo("bgstatus %d", pfloor->flags);
|
|
|
|
print_debug_top_down_mapinfo("bgarea %d", pfloor->room);
|
|
|
|
}
|
|
|
|
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gCurrentObject->oPosY < water) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_mapinfo("water %d", water);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
void print_mapinfo(void) {
|
|
|
|
// EU mostly stubbed this function out.
|
|
|
|
struct Surface *pfloor;
|
|
|
|
UNUSED f32 bgY;
|
|
|
|
UNUSED f32 water;
|
2020-02-03 00:51:26 -05:00
|
|
|
UNUSED s32 area;
|
2019-08-25 00:46:40 -04:00
|
|
|
// s32 angY;
|
|
|
|
//
|
|
|
|
// angY = gCurrentObject->oMoveAngleYaw / 182.044000;
|
|
|
|
// area = ((s32)gCurrentObject->oPosX + 0x2000) / 1024
|
|
|
|
// + ((s32)gCurrentObject->oPosZ + 0x2000) / 1024 * 16;
|
|
|
|
//
|
|
|
|
bgY = find_floor(gCurrentObject->oPosX, gCurrentObject->oPosY, gCurrentObject->oPosZ, &pfloor);
|
|
|
|
water = find_water_level(gCurrentObject->oPosX, gCurrentObject->oPosZ);
|
|
|
|
|
|
|
|
print_debug_top_down_normal("mapinfo", 0);
|
|
|
|
// print_debug_top_down_mapinfo("area %x", area);
|
|
|
|
// print_debug_top_down_mapinfo("wx %d", gCurrentObject->oPosX);
|
|
|
|
// print_debug_top_down_mapinfo("wy\t %d", gCurrentObject->oPosY);
|
|
|
|
// print_debug_top_down_mapinfo("wz %d", gCurrentObject->oPosZ);
|
|
|
|
// print_debug_top_down_mapinfo("bgY %d", bgY);
|
|
|
|
// print_debug_top_down_mapinfo("angY %d", angY);
|
|
|
|
//
|
|
|
|
// if(pfloor) // not null
|
|
|
|
//{
|
|
|
|
// print_debug_top_down_mapinfo("bgcode %d", pfloor->type);
|
|
|
|
// print_debug_top_down_mapinfo("bgstatus %d", pfloor->flags);
|
|
|
|
// print_debug_top_down_mapinfo("bgarea %d", pfloor->room);
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
// if(gCurrentObject->oPosY < water)
|
|
|
|
// print_debug_top_down_mapinfo("water %d", water);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void print_checkinfo(void) {
|
|
|
|
print_debug_top_down_normal("checkinfo", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_surfaceinfo(void) {
|
|
|
|
debug_surface_list_info(gMarioObject->oPosX, gMarioObject->oPosZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_stageinfo(void) {
|
|
|
|
print_debug_top_down_normal("stageinfo", 0);
|
|
|
|
print_debug_top_down_normal("stage param %d", gTTCSpeedSetting);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Common printer function for effectinfo and enemyinfo. This function
|
|
|
|
* also prints the cursor functionality intended to be used with modifying
|
|
|
|
* gDebugInfo to set enemy/effect behaviors.
|
|
|
|
*/
|
|
|
|
void print_string_array_info(const char **strArr) {
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
if (sDebugStringArrPrinted == FALSE) {
|
|
|
|
sDebugStringArrPrinted += 1; // again, why not = TRUE...
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
// sDebugPage is assumed to be 4 or 5 here.
|
|
|
|
print_debug_top_down_mapinfo(strArr[i], gDebugInfo[sDebugPage][i]);
|
|
|
|
}
|
|
|
|
// modify the cursor position so the cursor prints at the correct location.
|
|
|
|
// this is equivalent to (sDebugSysCursor - 8)
|
|
|
|
set_text_array_x_y(0, -1 - (u32)(7 - sDebugSysCursor));
|
|
|
|
print_debug_top_down_mapinfo(strArr[8], 0); // print the cursor
|
|
|
|
set_text_array_x_y(0, 7 - sDebugSysCursor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_effectinfo(void) {
|
|
|
|
print_debug_top_down_normal("effectinfo", 0);
|
|
|
|
print_string_array_info(sDebugEffectStringInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_enemyinfo(void) {
|
|
|
|
print_debug_top_down_normal("enemyinfo", 0);
|
|
|
|
print_string_array_info(sDebugEnemyStringInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
void update_debug_dpadmask(void) {
|
|
|
|
s32 dPadMask = gPlayer1Controller->buttonDown & (U_JPAD | D_JPAD | L_JPAD | R_JPAD);
|
|
|
|
|
|
|
|
if (!dPadMask) {
|
|
|
|
sDebugInfoDPadUpdID = 0;
|
|
|
|
sDebugInfoDPadMask = 0;
|
|
|
|
} else {
|
|
|
|
// to prevent stuttering of mask updates, the first time is updated 6
|
|
|
|
// frames from start, and then every 2 frames when held down.
|
|
|
|
if (sDebugInfoDPadUpdID == 0) {
|
|
|
|
sDebugInfoDPadMask = dPadMask;
|
|
|
|
} else if (sDebugInfoDPadUpdID == 6) {
|
|
|
|
sDebugInfoDPadMask = dPadMask;
|
|
|
|
} else {
|
|
|
|
sDebugInfoDPadMask = 0;
|
|
|
|
}
|
|
|
|
sDebugInfoDPadUpdID += 1;
|
|
|
|
if (sDebugInfoDPadUpdID >= 8) {
|
|
|
|
sDebugInfoDPadUpdID = 6; // rapidly set to 6 from 8 as long as dPadMask is being set.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void debug_unknown_level_select_check(void) {
|
|
|
|
if (!sDebugLvSelectCheckFlag) {
|
|
|
|
sDebugLvSelectCheckFlag += 1; // again, just do = TRUE...
|
|
|
|
|
2019-09-01 15:50:50 -04:00
|
|
|
if (!gDebugLevelSelect) {
|
2019-08-25 00:46:40 -04:00
|
|
|
gDebugInfoFlags = DEBUG_INFO_NOFLAGS;
|
2019-09-01 15:50:50 -04:00
|
|
|
} else {
|
2019-08-25 00:46:40 -04:00
|
|
|
gDebugInfoFlags = DEBUG_INFO_FLAG_LSELECT;
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
|
|
|
|
gNumCalls.floor = 0;
|
|
|
|
gNumCalls.ceil = 0;
|
|
|
|
gNumCalls.wall = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset_debug_objectinfo(void) {
|
|
|
|
gNumFindFloorMisses = 0;
|
|
|
|
gUnknownWallCount = 0;
|
|
|
|
gObjectCounter = 0;
|
|
|
|
sDebugStringArrPrinted = FALSE;
|
|
|
|
D_8035FEE2 = 0;
|
|
|
|
D_8035FEE4 = 0;
|
|
|
|
|
|
|
|
set_print_state_info(gDebugPrintState1, 20, 185, 40, 200, -15);
|
|
|
|
set_print_state_info(gDebugPrintState2, 180, 30, 0, 150, 15);
|
|
|
|
update_debug_dpadmask();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function checks for a button sequence (C Up, C Left, C Down,
|
|
|
|
* C Right) and then toggles the debug flags from FF to 2; 2 is unused,
|
|
|
|
* despite so this has no effect, being called. (unused)
|
|
|
|
*/
|
|
|
|
static void check_debug_button_seq(void) {
|
|
|
|
s16 *buttonArr;
|
|
|
|
s16 cButtonMask;
|
|
|
|
|
|
|
|
buttonArr = sDebugInfoButtonSeq;
|
|
|
|
|
2019-09-01 15:50:50 -04:00
|
|
|
if (!(gPlayer1Controller->buttonDown & L_TRIG)) {
|
2019-08-25 00:46:40 -04:00
|
|
|
sDebugInfoButtonSeqID = 0;
|
2019-09-01 15:50:50 -04:00
|
|
|
} else {
|
2019-08-25 00:46:40 -04:00
|
|
|
if ((s16)(cButtonMask = (gPlayer1Controller->buttonPressed & C_BUTTONS))) {
|
|
|
|
if (buttonArr[sDebugInfoButtonSeqID] == cButtonMask) {
|
|
|
|
sDebugInfoButtonSeqID += 1;
|
|
|
|
if (buttonArr[sDebugInfoButtonSeqID] == -1) {
|
|
|
|
if (gDebugInfoFlags == DEBUG_INFO_FLAG_ALL) {
|
|
|
|
gDebugInfoFlags = DEBUG_INFO_FLAG_LSELECT;
|
|
|
|
} else {
|
|
|
|
gDebugInfoFlags = DEBUG_INFO_FLAG_ALL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
sDebugInfoButtonSeqID = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Poll the debug info flags and controller for appropriate presses that
|
|
|
|
* control sDebugPage's range. (unused)
|
|
|
|
*/
|
|
|
|
static void try_change_debug_page(void) {
|
|
|
|
if (gDebugInfoFlags & DEBUG_INFO_FLAG_DPRINT) {
|
|
|
|
if ((gPlayer1Controller->buttonPressed & L_JPAD)
|
|
|
|
&& (gPlayer1Controller->buttonDown & (L_TRIG | R_TRIG))) {
|
|
|
|
sDebugPage += 1;
|
|
|
|
}
|
|
|
|
if ((gPlayer1Controller->buttonPressed & R_JPAD)
|
|
|
|
&& (gPlayer1Controller->buttonDown & (L_TRIG | R_TRIG))) {
|
|
|
|
sDebugPage -= 1;
|
|
|
|
}
|
|
|
|
if (sDebugPage >= (DEBUG_PAGE_MAX + 1)) {
|
|
|
|
sDebugPage = DEBUG_PAGE_MIN;
|
|
|
|
}
|
|
|
|
if (sDebugPage < DEBUG_PAGE_MIN) {
|
|
|
|
sDebugPage = DEBUG_PAGE_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use the controller to modify gDebugInfo and the sys cursor while
|
|
|
|
* using the DPad. L/R DPad modifies gDebugInfo while U/D modifies
|
|
|
|
* sDebugSysCursor. This is used to adjust enemy and effect behaviors
|
|
|
|
* on the fly. (unused)
|
|
|
|
*/
|
2020-04-03 14:57:26 -04:00
|
|
|
#ifndef VERSION_SH
|
|
|
|
static
|
|
|
|
#endif
|
|
|
|
void try_modify_debug_controls(void) {
|
2019-08-25 00:46:40 -04:00
|
|
|
s32 sp4;
|
|
|
|
|
|
|
|
if (gPlayer1Controller->buttonPressed & Z_TRIG) {
|
|
|
|
sNoExtraDebug ^= 1;
|
|
|
|
}
|
|
|
|
if (!(gPlayer1Controller->buttonDown & (L_TRIG | R_TRIG)) && sNoExtraDebug == FALSE) {
|
|
|
|
sp4 = 1;
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gPlayer1Controller->buttonDown & B_BUTTON) {
|
2019-08-25 00:46:40 -04:00
|
|
|
sp4 = 100;
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
|
|
|
|
if (sDebugInfoDPadMask & U_JPAD) {
|
|
|
|
sDebugSysCursor -= 1;
|
2019-09-01 15:50:50 -04:00
|
|
|
if (sDebugSysCursor < 0) {
|
2019-08-25 00:46:40 -04:00
|
|
|
sDebugSysCursor = 0;
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sDebugInfoDPadMask & D_JPAD) {
|
|
|
|
sDebugSysCursor += 1;
|
2019-09-01 15:50:50 -04:00
|
|
|
if (sDebugSysCursor >= 8) {
|
2019-08-25 00:46:40 -04:00
|
|
|
sDebugSysCursor = 7;
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sDebugInfoDPadMask & L_JPAD) {
|
|
|
|
// we allow the player while in this mode to modify the debug controls. This is
|
|
|
|
// so the playtester can adjust enemy behavior and parameters on the fly, since
|
|
|
|
// various behaviors try to update their behaviors from gDebugInfo[4] and [5].
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gPlayer1Controller->buttonDown & A_BUTTON) {
|
2019-08-25 00:46:40 -04:00
|
|
|
gDebugInfo[sDebugPage][sDebugSysCursor] =
|
|
|
|
gDebugInfoOverwrite[sDebugPage][sDebugSysCursor];
|
2019-09-01 15:50:50 -04:00
|
|
|
} else {
|
2019-08-25 00:46:40 -04:00
|
|
|
gDebugInfo[sDebugPage][sDebugSysCursor] = gDebugInfo[sDebugPage][sDebugSysCursor] - sp4;
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sDebugInfoDPadMask & R_JPAD) {
|
|
|
|
gDebugInfo[sDebugPage][sDebugSysCursor] = gDebugInfo[sDebugPage][sDebugSysCursor] + sp4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// possibly a removed debug control (TODO: check DD)
|
2020-03-01 22:42:52 -05:00
|
|
|
void stub_debug_5(void) {
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If Mario's object exists, this function tries to print available object debug
|
|
|
|
* information depending on the debug sys ID. Additional information (updated obj
|
|
|
|
* count, floor misses, and an unknown wall counter) is also printed.
|
|
|
|
*/
|
|
|
|
void try_print_debug_mario_object_info(void) {
|
|
|
|
if (gMarioObject != NULL) {
|
|
|
|
switch (sDebugPage) {
|
|
|
|
case DEBUG_PAGE_CHECKSURFACEINFO:
|
|
|
|
print_surfaceinfo();
|
|
|
|
break;
|
|
|
|
case DEBUG_PAGE_EFFECTINFO:
|
|
|
|
print_effectinfo();
|
|
|
|
break;
|
|
|
|
case DEBUG_PAGE_ENEMYINFO:
|
|
|
|
print_enemyinfo();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
print_debug_top_down_mapinfo("obj %d", gObjectCounter);
|
|
|
|
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gNumFindFloorMisses) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_bottom_up("NULLBG %d", gNumFindFloorMisses);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gUnknownWallCount) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_bottom_up("WALL %d", gUnknownWallCount);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Similar to above, but with level information. (checkinfo, mapinfo,
|
|
|
|
* stageinfo)
|
|
|
|
*/
|
|
|
|
void try_print_debug_mario_level_info(void) {
|
|
|
|
switch (sDebugPage) {
|
|
|
|
case DEBUG_PAGE_OBJECTINFO:
|
|
|
|
break; // no info list is printed for obj info.
|
|
|
|
case DEBUG_PAGE_CHECKSURFACEINFO:
|
|
|
|
print_checkinfo();
|
|
|
|
break;
|
|
|
|
case DEBUG_PAGE_MAPINFO:
|
|
|
|
print_mapinfo();
|
|
|
|
break;
|
|
|
|
case DEBUG_PAGE_STAGEINFO:
|
|
|
|
print_stageinfo();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* One of the only remaining debug controls activatable from the
|
|
|
|
* debug control array. This function lets you spawn 1 of 3
|
|
|
|
* objects: A koopa shell, a jumping box, and an underwater koopa
|
|
|
|
* shell. This can be reactivated by turning on modifying
|
|
|
|
* debug controls with try_modify_debug_controls and setting
|
|
|
|
* [5][7] (b7 in the string array) to 1 to enable debug spawn.
|
|
|
|
*/
|
|
|
|
void try_do_mario_debug_object_spawn(void) {
|
|
|
|
UNUSED s32 unused;
|
|
|
|
|
|
|
|
if (sDebugPage == DEBUG_PAGE_STAGEINFO && gDebugInfo[DEBUG_PAGE_ENEMYINFO][7] == 1) {
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gPlayer1Controller->buttonPressed & R_JPAD) {
|
2019-08-25 00:46:40 -04:00
|
|
|
spawn_object_relative(0, 0, 100, 200, gCurrentObject, MODEL_KOOPA_SHELL, bhvKoopaShell);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gPlayer1Controller->buttonPressed & L_JPAD) {
|
2019-08-25 00:46:40 -04:00
|
|
|
spawn_object_relative(0, 0, 100, 200, gCurrentObject, MODEL_BREAKABLE_BOX_SMALL,
|
|
|
|
bhvJumpingBox);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gPlayer1Controller->buttonPressed & D_JPAD) {
|
2019-08-25 00:46:40 -04:00
|
|
|
spawn_object_relative(0, 0, 100, 200, gCurrentObject, MODEL_KOOPA_SHELL,
|
|
|
|
bhvKoopaShellUnderwater);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: figure out what this is
|
2020-04-03 14:57:26 -04:00
|
|
|
#ifndef VERSION_SH
|
|
|
|
static
|
|
|
|
#endif
|
|
|
|
void debug_print_obj_move_flags(void) {
|
|
|
|
#ifndef VERSION_EU // TODO: Is there a better way to diff this? static EU doesn't seem to work.
|
2019-09-01 15:50:50 -04:00
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_LANDED) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("BOUND %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_ON_GROUND) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("TOUCH %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_LEFT_GROUND) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("TAKEOFF %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_ENTERED_WATER) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("DIVE %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_AT_WATER_SURFACE) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("S WATER %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_UNDERWATER_OFF_GROUND) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("U WATER %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_UNDERWATER_ON_GROUND) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("B WATER %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_IN_AIR) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("SKY %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
|
|
|
if (gCurrentObject->oMoveFlags & OBJ_MOVE_8) {
|
2019-08-25 00:46:40 -04:00
|
|
|
print_debug_top_down_objectinfo("OUT SCOPE %x", gCurrentObject->oMoveFlags);
|
2019-09-01 15:50:50 -04:00
|
|
|
}
|
2020-02-03 00:51:26 -05:00
|
|
|
#endif
|
2019-08-25 00:46:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// unused, what is this?
|
2020-03-01 22:42:52 -05:00
|
|
|
void debug_enemy_unknown(s16 *enemyArr) {
|
2019-08-25 00:46:40 -04:00
|
|
|
// copy b1-b4 over to an unknown s16 array
|
|
|
|
enemyArr[4] = gDebugInfo[DEBUG_PAGE_ENEMYINFO][1];
|
|
|
|
enemyArr[5] = gDebugInfo[DEBUG_PAGE_ENEMYINFO][2];
|
|
|
|
enemyArr[6] = gDebugInfo[DEBUG_PAGE_ENEMYINFO][3];
|
|
|
|
enemyArr[7] = gDebugInfo[DEBUG_PAGE_ENEMYINFO][4];
|
|
|
|
}
|