Files
SpaghettiKart/src/debug/debug.c
T
tomas 9d716d921a very cool debug display list (#348)
* added a very cool debug display list ^^ (prints variables to screen)

* Decompiled various functions
2023-08-04 13:04:49 -06:00

252 lines
6.0 KiB
C

#include <ultra64.h>
#include <debug.h>
#include "debug.inc.c"
#include <libc/stdio.h>
#if DVDL
u8 sDisplayListState = OK;
static u32 variable_to_u64(variableWatchAttributes *);
static void round_up_float(u32 *, u8);
static void u64_to_string(variableWatchAttributes *, u32, u8);
static u32 _strlen(const char *);
static void _memcpy(char *, const char *, u32);
void display_dvdl(void) {
u32 variable;
u32 i, vNameLen;
u32 arraySize = sizeof(gMainVariableWatchList) / sizeof(variableWatchAttributes);
s32 text_y_possition = TEXT_Y_POSSITION;
u8 base;
char *vName, *cBuffer;
load_debug_font();
for (i = 0; i < arraySize; i++) {
variableWatchAttributes *currentAttribute = &gMainVariableWatchList[i];
currentAttribute->characterBuffer = currentAttribute->buffer;
cBuffer = currentAttribute->characterBuffer;
vName = currentAttribute->variableName;
variable = variable_to_u64(currentAttribute);
base = 0;
if (currentAttribute->variableFlag & (DISPLAY_FLOAT_AS_TYPE | DISPLAY_FLOAT_WITH_ROUNDING)) {
if (currentAttribute->variableFlag & DISPLAY_FLOAT_NUMBER) {
sDisplayListState = BAD;
} else if (currentAttribute->variableFlag & DISPLAY_FLOAT_WITH_ROUNDING) {
round_up_float(&variable, currentAttribute->variableSize);
}
}
switch (currentAttribute->variableFlag & 0x8F) {
case DISPLAY_FLOAT_NUMBER:
sprintf(cBuffer, "%.3f", *(f32*)&variable);
break;
case DISPLAY_HEXIDECIMAL_NUMBER:
base = HEXIDECIMAL;
break;
case DISPLAY_DECIMAL_NUMBER:
base = DECIMAL;
break;
case DISPLAY_OCTAL_NUMBER:
base = OCTAL;
break;
case DISPLAY_BINARY_NUMBER:
base = BINARY;
break;
default:
sDisplayListState = BAD;
}
if (base) {
u64_to_string(currentAttribute, variable, base);
}
if (sDisplayListState == BAD) {
cBuffer = "NaN";
}
sDisplayListState = OK;
vNameLen = _strlen(vName);
debug_print_str2(TEXT_X_POSSITION, text_y_possition, vName);
debug_print_str2(TEXT_X_POSSITION + (vNameLen * 0x8), text_y_possition, cBuffer);
text_y_possition += 0x8;
}
gSPDisplayList(gDisplayListHead++, D_0D007EB8);
gSPDisplayList(gDisplayListHead++, D_020076E0);
func_80093C98(1);
}
static u32 variable_to_u64(variableWatchAttributes *attribute) {
u32 variable;
switch (attribute->variableSize) {
case sizeof(u8):
variable = *((u8*) attribute->variablePointer);
break;
case sizeof(u16):
variable = *((u16*) attribute->variablePointer);
break;
case sizeof(u32):
case sizeof(u64):
variable = *((u32*) attribute->variablePointer); // no floating point rounding
break;
default:
sDisplayListState = BAD;
}
return variable;
}
static void round_up_float(u32 *variable, u8 variableSize) {
switch (variableSize) {
case sizeof(u64):
case sizeof(u32):
*variable = (u32) (*(f32*) &*variable);
break;
default:
sDisplayListState = BAD;
}
}
static void u64_to_string(variableWatchAttributes *attribute, u32 variable, u8 base) {
s32 signedVariable;
u32 stringDifference, indexesToFillAVariable, stringLengthWithZero;
u32 indexesToFillAByte, upperIndex, remainder;
u32 stringLength, lowerIndex, i;
u8 variableSize;
char *bufferedString;
char swapRegister;
if (sDisplayListState == BAD) {
return;
}
bufferedString = attribute->characterBuffer;
variableSize = attribute->variableSize;
// converts a minus number into it's unsigned equivalent for proper string conversion
if (attribute->variableFlag & DISPLAY_SIGNED_NUMBER) {
switch (variableSize) {
case sizeof(u8):
signedVariable = (s8) variable;
if (signedVariable < 0) {
signedVariable = -signedVariable;
variable = (u8) signedVariable;
*bufferedString = '-';
bufferedString++;
}
break;
case sizeof(u16):
signedVariable = (s16) variable;
if (signedVariable < 0) {
signedVariable = -signedVariable;
variable = (u16) signedVariable;
*bufferedString = '-';
bufferedString++;
}
break;
case sizeof(u32):
case sizeof(u64):
signedVariable = (s32) variable;
if (signedVariable < 0) {
signedVariable = -signedVariable;
variable = (u32) signedVariable;
*bufferedString = '-';
bufferedString++;
}
break;
}
}
stringLength = 0;
// convert u64 into a string but it gets put in reverse
if (base != HEXIDECIMAL) {
do {
stringLength++;
*bufferedString = variable % base + '0';
bufferedString++;
variable /= base;
} while (variable != 0);
} else {
do {
stringLength++;
remainder = variable % 16;
if ((remainder >= 0) && (remainder <= 9)) {
*bufferedString = '0' + remainder;
} else {
*bufferedString = 'A' + (remainder - 10);
}
bufferedString++;
variable /= 16;
} while (variable != 0);
}
bufferedString -= stringLength;
upperIndex = stringLength - 1;
// flip string 4321 --> 1234
for (lowerIndex = 0; lowerIndex < stringLength >> 1; lowerIndex++) {
swapRegister = bufferedString[lowerIndex];
bufferedString[lowerIndex] = bufferedString[upperIndex];
bufferedString[upperIndex] = swapRegister;
upperIndex--;
}
switch (base) {
case BINARY:
indexesToFillAByte = 8;
break;
case OCTAL:
indexesToFillAByte = 3;
break;
case DECIMAL:
bufferedString[stringLength] = '\0';
return;
case HEXIDECIMAL:
indexesToFillAByte = 2;
break;
}
stringLengthWithZero = stringLength - 1;
indexesToFillAVariable = indexesToFillAByte * variableSize;
stringDifference = indexesToFillAVariable - stringLengthWithZero;
// makes space and fills in extra space. u32 FE -> 000000FE
for (i = stringLength; i > 0; i--) {
bufferedString[stringDifference + i - 2] = bufferedString[i - 1];
}
for (i = 0; i < stringDifference - 1; i++) {
bufferedString[i] = '0';
}
bufferedString[indexesToFillAVariable] = '\0';
}
static u32 _strlen(const char *str) {
u32 len;
len = 0;
for (; *str != '\0'; str++) {
len++;
}
return len;
}
// unused but may be useful
static void _memcpy(char *destStr, const char *copyStr, u32 copySize) {
u32 i;
for (i = 0; i < copySize; i++) {
*destStr = *copyStr;
destStr++;
copyStr++;
}
}
#endif