Match and link CScriptMailbox and strtold

This commit is contained in:
Phillip Stephens 2024-11-01 19:17:45 -07:00
parent 9dafdadac7
commit 0b74ded7ba
11 changed files with 574 additions and 9 deletions

View File

@ -15235,8 +15235,8 @@ GetTransformMinusOffset__17CPoseAsTransformsCFRC6CSegId = .text:0x80368F7C; // t
GetRotation__17CPoseAsTransformsCFRC6CSegId = .text:0x80368F9C; // type:function size:0x20 scope:global
Insert__17CPoseAsTransformsFRC6CSegIdRC9CMatrix3fRC9CVector3f = .text:0x80368FBC; // type:function size:0x74 scope:global
__ct__17CPoseAsTransformsFUc = .text:0x80369030; // type:function size:0x130 scope:global
Insert__58TSegIdMapVariableSize<Q217CPoseAsTransforms12CElementType>FRC6CSegIdRCQ217CPoseAsTransforms12CElementType = .text:0x80369160; // type:function size:0xAC scope:global
Clear__58TSegIdMapVariableSize<Q217CPoseAsTransforms12CElementType>Fv = .text:0x8036920C; // type:function size:0x44 scope:global
Insert__58TSegIdMapVariableSize<Q217CPoseAsTransforms12CElementType>FRC6CSegIdRCQ217CPoseAsTransforms12CElementType = .text:0x80369160; // type:function size:0xAC scope:weak
Clear__58TSegIdMapVariableSize<Q217CPoseAsTransforms12CElementType>Fv = .text:0x8036920C; // type:function size:0x44 scope:weak
CreateRumbleHandle__12CRumbleVoiceFUs = .text:0x80369250; // type:function size:0x4C scope:global
OwnsSustained__12CRumbleVoiceCFs = .text:0x8036929C; // type:function size:0x38 scope:global
GetIntensity__12CRumbleVoiceCFv = .text:0x803692D4; // type:function size:0x4C scope:global

View File

@ -466,7 +466,7 @@ config.libs = [
Object(Matching, "MetroidPrime/Weapons/CPowerBeam.cpp"),
Object(NonMatching, "MetroidPrime/Weapons/CWaveBeam.cpp"),
Object(NonMatching, "MetroidPrime/Weapons/CIceBeam.cpp"),
Object(NonMatching, "MetroidPrime/CScriptMailbox.cpp"),
Object(Matching, "MetroidPrime/CScriptMailbox.cpp"),
Object(Matching, "MetroidPrime/ScriptObjects/CScriptRelay.cpp"),
Object(NonMatching, "MetroidPrime/ScriptObjects/CScriptSpawnPoint.cpp"),
Object(NonMatching, "MetroidPrime/ScriptObjects/CScriptRandomRelay.cpp"),
@ -1228,7 +1228,7 @@ config.libs = [
Object(Matching, "Runtime/sscanf.c"),
Object(Matching, "Runtime/string.c"),
Object(Matching, "Runtime/float.c"),
Object(NonMatching, "Runtime/strtold.c"),
Object(Matching, "Runtime/strtold.c"),
Object(Matching, "Runtime/uart_console_io.c"),
Object(Matching, "Runtime/wchar_io.c"),
Object(Matching, "Runtime/e_acos.c"),

View File

@ -3,8 +3,7 @@
#include "types.h"
#include "MetroidPrime/TGameTypes.hpp"
#include "Kyoto/Animation/CSegId.hpp"
#include "Kyoto/Math/CTransform4f.hpp"
#include "rstl/reserved_vector.hpp"
@ -12,6 +11,10 @@
class CPoseAsTransforms {
public:
class CElementType {
};
const CMatrix3f& GetRotation(const CSegId& id) const;
private:
CSegId x0_nextId;

View File

@ -46,7 +46,7 @@ public:
explicit CRelay(CInputStream& in);
const TEditorId& GetRelayId() const { return x0_relay; }
const TEditorId& GetTargetId() const { return x4_target; }
ushort GetMessage() const { return x8_msg; }
const ushort& GetMessage() const { return x8_msg; }
bool GetActive() const { return xa_active; }
static rstl::vector< CRelay > ReadMemoryRelays(CInputStream& in); // name?

View File

@ -11,12 +11,16 @@ extern "C" {
#define FLT_MIN 1.175494351e-38f
#define DBL_DIG 6
#define DBL_MIN 5.8774717e-39
#define DBL_MAX (* (double *) __double_max)
#define DBL_MIN (*(double*)__double_min)
#define DBL_MAX (*(double*)__double_max)
#define DBL_EPSILON 1.1920929e-07
#define DBL_MANT_DIG 53
#define LDBL_MAX (*(long double*)__extended_max)
#define LDBL_EPSILON (*(long double*)__extended_epsilon)
#define LDBL_MIN (*(long double*)__extended_min)
#ifdef __cplusplus
}
#endif

View File

@ -13,6 +13,8 @@
#endif
#define SHRT_MAX 0x7fff
#define SHRT_MIN (~SHRT_MAX)
#define USHRT_MAX 0xffffU
#define INT_MAX 0x7fffffff

View File

@ -32,6 +32,7 @@ struct lconv {
char int_n_sign_posn;
};
extern struct lconv __lconv;
#ifdef __cplusplus
}
#endif

View File

@ -56,6 +56,10 @@ extern _INT32 __float_huge[];
extern _INT32 __float_nan[];
extern _INT32 __double_huge[];
extern _INT32 __extended_huge[];
extern _INT32 __extended_min[];
extern _INT32 __extended_max[];
extern _INT32 __extended_epsilon[];
extern _INT32 __double_min[];
extern _INT32 __double_max[];
#define HUGE_VAL (*(double*)__double_huge)
@ -217,6 +221,7 @@ static inline double scalbn(double x, int n) { return ldexp(x, n); }
static inline float scalbnf(float x, int n) { return (float)ldexpf(x, n); }
double nextafter(double, double);
#ifdef __cplusplus
}
#endif

View File

@ -128,6 +128,8 @@ size_t fwrite(const void*, size_t memb_size, size_t num_memb, FILE*);
int fseek(FILE* file, long offset, int mode);
size_t __fwrite(const void*, size_t, size_t, FILE*);
int __StringRead(void* isc, int ch, int Action);
#ifdef __cplusplus
}
#endif

View File

@ -56,6 +56,7 @@ bool CPlayer::CPlayerStuckTracker::IsPlayerStuck() {
max1 = *_getElementBoundsCheck(x148_, 0);
CAABox box1(min1, max1);
CAABox box(*_getElementBoundsCheck(x148_, 0), *_getElementBoundsCheck(x148_, 0));
return true;
}
void CPlayer::CPlayerStuckTracker::ResetStats() {

547
src/Runtime/strtold.c Normal file
View File

@ -0,0 +1,547 @@
#include "ansi_fp.h"
#include <limits.h>
#include <locale.h>
#include <math.h>
#include <stdio.h>
#include <float.h>
#include <errno.h>
#include <ctype.h>
enum scan_states {
start = 0x0001,
sig_start = 0x0002,
leading_sig_zeroes = 0x0004,
int_digit_loop = 0x0008,
frac_start = 0x0010,
frac_digit_loop = 0x0020,
sig_end = 0x0040,
exp_start = 0x0080,
leading_exp_digit = 0x0100,
leading_exp_zeroes = 0x0200,
exp_digit_loop = 0x0400,
finished = 0x0800,
failure = 0x1000,
nan_state = 0x2000,
infin_state = 0x4000,
hex_state = 0x8000
};
enum hex_scan_states {
not_hex = 0x0000,
hex_start = 0x0001,
hex_leading_sig_zeroes = 0x0002,
hex_int_digit_loop = 0x0004,
hex_frac_digit_loop = 0x0008,
hex_sig_end = 0x0010,
hex_exp_start = 0x0020,
hex_leading_exp_digit = 0x0040,
hex_leading_exp_zeroes = 0x0080,
hex_exp_digit_loop = 0x0100
};
#define MAX_SIG_DIG 20
#define FINAL_STATE(scan_state) (scan_state & (finished | failure))
#define SUCCESS(scan_state) \
(scan_state & (leading_sig_zeroes | int_digit_loop | frac_digit_loop | leading_exp_zeroes | \
exp_digit_loop | finished))
#define FETCH() (count++, (*ReadProc)(ReadProcArg, 0, __GetChar))
#define UNFETCH(c) (*ReadProc)(ReadProcArg, c, __UngetChar)
long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg,
int* chars_scanned, int* overflow) {
int scan_state = start;
int hex_scan_state = not_hex;
int count = 0;
int spaces = 0;
int c;
decimal d = {0, 0, 0, {0, ""}};
int sig_negative = 0;
int exp_negative = 0;
long exp_value = 0;
int exp_adjust = 0;
long double result;
int sign_detected = 0;
unsigned char* chptr = (unsigned char*)&result;
unsigned char uch, uch1;
int ui;
int chindex;
int NibbleIndex;
int expsign = 0;
int exp_digits = 0;
int intdigits = 0;
int RadixPointFound = 0;
short exponent = 0;
int dot;
dot = *(unsigned char*)__lconv.decimal_point;
*overflow = 0;
c = FETCH();
while (count <= max_width && c != EOF && !FINAL_STATE(scan_state)) {
switch (scan_state) {
case start:
if (isspace(c)) {
c = FETCH();
count--;
spaces++;
break;
}
switch (toupper(c)) {
case '-':
sig_negative = 1;
case '+':
c = FETCH();
sign_detected = 1;
break;
case 'I':
c = FETCH();
scan_state = infin_state;
break;
case 'N':
c = FETCH();
scan_state = nan_state;
break;
default:
scan_state = sig_start;
break;
}
break;
case infin_state: {
int i = 1;
char model[] = "INFINITY";
while ((i < 8) && (toupper(c) == model[i])) {
i++;
c = FETCH();
}
if ((i == 3) || (i == 8)) {
if (sig_negative)
result = -INFINITY;
else
result = INFINITY;
*chars_scanned = spaces + i + sign_detected;
return (result);
} else
scan_state = failure;
break;
}
case nan_state: {
int i = 1, j = 0;
char model[] = "NAN(";
char nan_arg[32] = "";
while ((i < 4) && (toupper(c) == model[i])) {
i++;
c = FETCH();
}
if ((i == 3) || (i == 4)) {
if (i == 4) {
while ((j < 32) && (isdigit(c) || isalpha(c))) {
nan_arg[j++] = c;
c = FETCH();
}
if (c != ')') {
scan_state = failure;
break;
} else
j++;
}
nan_arg[j] = '\0';
if (sig_negative)
result = -NAN;
else
result = NAN;
*chars_scanned = spaces + i + j + sign_detected;
return (result);
} else
scan_state = failure;
break;
}
case sig_start:
if (c == dot) {
scan_state = frac_start;
c = FETCH();
break;
}
if (!isdigit(c)) {
scan_state = failure;
break;
}
if (c == '0') {
c = FETCH();
if (toupper(c) == 'X') {
scan_state = hex_state;
hex_scan_state = hex_start;
} else
scan_state = leading_sig_zeroes;
break;
}
scan_state = int_digit_loop;
break;
case leading_sig_zeroes:
if (c == '0') {
c = FETCH();
break;
}
scan_state = int_digit_loop;
break;
case int_digit_loop:
if (!isdigit(c)) {
if (c == dot) {
scan_state = frac_digit_loop;
c = FETCH();
} else
scan_state = sig_end;
break;
}
if (d.sig.length < MAX_SIG_DIG)
d.sig.text[d.sig.length++] = c;
else
exp_adjust++;
c = FETCH();
break;
case frac_start:
if (!isdigit(c)) {
scan_state = failure;
break;
}
scan_state = frac_digit_loop;
break;
case frac_digit_loop:
if (!isdigit(c)) {
scan_state = sig_end;
break;
}
if (d.sig.length < MAX_SIG_DIG)
{
if (c != '0' || d.sig.length)
d.sig.text[d.sig.length++] = c;
exp_adjust--;
}
c = FETCH();
break;
case sig_end:
if (toupper(c) == 'E') {
scan_state = exp_start;
c = FETCH();
break;
}
scan_state = finished;
break;
case exp_start:
if (c == '+')
c = FETCH();
else if (c == '-') {
c = FETCH();
exp_negative = 1;
}
scan_state = leading_exp_digit;
break;
case leading_exp_digit:
if (!isdigit(c)) {
scan_state = failure;
break;
}
if (c == '0') {
scan_state = leading_exp_zeroes;
c = FETCH();
break;
}
scan_state = exp_digit_loop;
break;
case leading_exp_zeroes:
if (c == '0') {
c = FETCH();
break;
}
scan_state = exp_digit_loop;
break;
case exp_digit_loop:
if (!isdigit(c)) {
scan_state = finished;
break;
}
exp_value = exp_value * 10 + (c - '0');
if (exp_value > SHRT_MAX)
*overflow = 1;
c = FETCH();
break;
case hex_state: {
switch (hex_scan_state) {
case hex_start:
for (chindex = 0; chindex < 8; chindex++)
*(chptr + chindex) = '\0';
NibbleIndex = 2;
hex_scan_state = hex_leading_sig_zeroes;
c = FETCH();
break;
case hex_leading_sig_zeroes:
if (c == '0') {
c = FETCH();
break;
}
hex_scan_state = hex_int_digit_loop;
break;
case hex_int_digit_loop:
if (!isxdigit(c)) {
if (c == dot) {
hex_scan_state = hex_frac_digit_loop;
c = FETCH();
} else
hex_scan_state = hex_sig_end;
break;
}
if (NibbleIndex < 17) {
intdigits++;
uch = *(chptr + NibbleIndex / 2);
ui = toupper(c);
if (ui >= 'A')
ui = ui - 'A' + 10;
else
ui -= '0';
uch1 = ui;
if ((NibbleIndex % 2) != 0)
uch |= uch1;
else
uch |= uch1 << 4;
*(chptr + NibbleIndex++ / 2) = uch;
c = FETCH();
} else
c = FETCH();
break;
case hex_frac_digit_loop:
if (!isxdigit(c)) {
hex_scan_state = hex_sig_end;
break;
}
if (NibbleIndex < 17) {
uch = *(chptr + NibbleIndex / 2);
ui = toupper(c);
if (ui >= 'A')
ui = ui - 'A' + 10;
else
ui -= '0';
uch1 = ui;
if ((NibbleIndex % 2) != 0)
uch |= uch1;
else
uch |= uch1 << 4;
*(chptr + NibbleIndex++ / 2) = uch;
c = FETCH();
} else
c = FETCH();
break;
case hex_sig_end:
if (toupper(c) == 'P') {
hex_scan_state = hex_exp_start;
exp_digits++;
c = FETCH();
} else
scan_state = finished;
break;
case hex_exp_start:
exp_digits++;
if (c == '-')
expsign = 1;
else if (c != '+') {
c = UNFETCH(c);
exp_digits--;
}
hex_scan_state = hex_leading_exp_digit;
c = FETCH();
break;
case hex_leading_exp_digit:
if (!isdigit(c)) {
scan_state = failure;
break;
}
if (c == '0') {
exp_digits++;
hex_scan_state = hex_leading_exp_zeroes;
c = FETCH();
break;
}
hex_scan_state = hex_exp_digit_loop;
break;
case hex_exp_digit_loop:
if (!isdigit(c)) {
scan_state = finished;
break;
}
exponent = exponent * 10 + (c - '0');
if (exp_value > SHRT_MAX)
*overflow = 1;
exp_digits++;
c = FETCH();
break;
}
} break;
}
}
if (!SUCCESS(scan_state)) {
count = 0;
*chars_scanned = 0;
} else {
count--;
*chars_scanned = count + spaces;
}
UNFETCH(c);
if (hex_scan_state == not_hex) {
if (exp_negative)
exp_value = -exp_value;
{
int n = d.sig.length;
unsigned char* p = &d.sig.text[n];
while (n-- && *--p == '0')
exp_adjust++;
d.sig.length = n + 1;
if (d.sig.length == 0)
d.sig.text[d.sig.length++] = '0';
}
exp_value += exp_adjust;
if (exp_value < SHRT_MIN || exp_value > SHRT_MAX)
*overflow = 1;
if (*overflow) {
if (exp_negative) {
return 0.0;
} else {
return sig_negative ? -HUGE_VAL : HUGE_VAL;
}
}
d.exp = exp_value;
result = __dec2num(&d);
if (result != 0.0 && result < LDBL_MIN) {
*overflow = 1;
} else if (result > LDBL_MAX) {
*overflow = 1;
result = HUGE_VAL;
}
if (sig_negative && SUCCESS(scan_state))
result = -result;
return (result);
} else {
unsigned long long * uptr = (unsigned long long *)&result;
if (result) {
if (expsign) {
exponent = -exponent;
}
while ((*(short*)(&result) & 0x00f0) != 0x0010) {
*uptr >>= 1;
exponent++;
}
exponent += 4 * (intdigits - 1);
*(short*)&result &= 0x000f;
*(short*)(&result) |= ((exponent + 1023) << 4);
*chars_scanned = spaces + sign_detected + NibbleIndex + 1 + exp_digits;
if (result != 0.0 && result < LDBL_MIN) {
*overflow = 1;
result = 0.0;
} else if (result > LDBL_MAX) {
*overflow = 1;
result = HUGE_VAL;
}
if (sig_negative) {
*(short*)(&result) |= 0x8000;
}
} else {
result = 0.0;
}
return result;
}
}
long double strtold(const char* nptr, char** endptr) {
long double value, abs_value;
int count, overflow;
__InStrCtrl isc;
isc.NextChar = (char*)nptr;
isc.NullCharDetected = 0;
value = __strtold(INT_MAX, &__StringRead, (void*)&isc, &count, &overflow);
if (endptr)
*endptr = (char*)nptr + count;
abs_value = fabs(value);
if (overflow || (value != 0.0 && (abs_value < DBL_MIN || abs_value > DBL_MAX)))
errno = ERANGE;
return value;
}
double strtod(const char* str, char** end) {
long double value, abs_value;
int count, overflow;
__InStrCtrl isc;
isc.NextChar = (char*)str;
isc.NullCharDetected = 0;
value = __strtold(INT_MAX, &__StringRead, (void*)&isc, &count, &overflow);
if (end)
*end = (char*)str + count;
abs_value = fabs(value);
if (overflow || (value != 0.0 && (abs_value < DBL_MIN || abs_value > DBL_MAX)))
errno = ERANGE;
return (value);
}
double atof(const char* str) { return (strtod(str, NULL)); }