mirror of
https://github.com/zeldaret/tp
synced 2026-05-23 06:54:28 -04:00
Add missing TUs for Wii/Shield retail (+ filename cleanup) (#3072)
* Fix GCN_mem_alloc.c filename capitalization * Fix up TRK file names in Wii/Shield splits * Add string_TRK * Add cc_gdev * Add Shield-only wstring TUs * Implement NdevExi2A * Add missing JSystem TUs (more are still missing from ShieldD) * Clean up includes
This commit is contained in:
@@ -26,14 +26,6 @@ J3DMtxBuffer* J3DMtxCalc::mMtxBuffer;
|
||||
|
||||
J3DJoint* J3DMtxCalc::mJoint;
|
||||
|
||||
inline s32 checkScaleOne(const Vec& param_0) {
|
||||
if (param_0.x == 1.0f && param_0.y == 1.0f && param_0.z == 1.0f) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void J3DMtxCalcCalcTransformBasic::calcTransform(J3DTransformInfo const& transInfo) {
|
||||
J3DJoint* joint = J3DMtxCalc::getJoint();
|
||||
J3DMtxBuffer* mtxBuf = J3DMtxCalc::getMtxBuffer();
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/J3DU/J3DUFur.h"
|
||||
|
||||
#include "JSystem/J3DGraphAnimator/J3DModel.h"
|
||||
#include "JSystem/J3DGraphBase/J3DMaterial.h"
|
||||
#include "JSystem/J3DGraphBase/J3DVertex.h"
|
||||
|
||||
static void dummy() {
|
||||
J3DShape* shape;
|
||||
J3DMaterial* material = shape->getMaterial();
|
||||
J3DJoint* joint = material->getJoint();
|
||||
|
||||
J3DVertexBuffer* vtxBuf;
|
||||
vtxBuf->swapTransformedVtxPos();
|
||||
J3DVertexData* vtxData = vtxBuf->getVertexData();
|
||||
vtxBuf->getTransformedVtxPos(0);
|
||||
vtxBuf->getCurrentVtxNrm();
|
||||
vtxBuf->setCurrentVtxPos(NULL);
|
||||
|
||||
J3DModel* model;
|
||||
model->getVertexBuffer();
|
||||
|
||||
J3DModelData* modelData;
|
||||
vtxData->getNrmNum();
|
||||
modelData->getNrmNum();
|
||||
vtxData->getVtxNum();
|
||||
modelData->getVtxNum();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/J3DU/J3DUMotion.h"
|
||||
|
||||
#include "JSystem/J3DGraphAnimator/J3DJoint.h"
|
||||
#include "JSystem/J3DGraphLoader/J3DModelLoader.h"
|
||||
#include "JSystem/JMath/JMath.h"
|
||||
|
||||
static void dummy() {
|
||||
J3DMtxCalcJ3DSysInitSoftimage* img;
|
||||
Vec* vec;
|
||||
Mtx mtx;
|
||||
img->init(*vec, mtx);
|
||||
checkScaleOne(*vec);
|
||||
J3DMtxCalc::getMtxBuffer();
|
||||
JMAFastReciprocal(0.0f);
|
||||
JMath::fastReciprocal(0.0f);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/J3DU/J3DUShadow.h"
|
||||
|
||||
#include "JSystem/JGeometry.h"
|
||||
#include "JSystem/JMath/JMath.h"
|
||||
#include "JSystem/JUtility/JUTTexture.h"
|
||||
|
||||
void dummy() {
|
||||
JMAAbs(0.0f);
|
||||
JMathInlineVEC::C_VECDotProduct(NULL, NULL);
|
||||
JGeometry::TVec3<f32>* vec;
|
||||
vec->dot(*vec);
|
||||
vec->length();
|
||||
|
||||
JUTTexture* tex;
|
||||
tex->getCaptureFlag();
|
||||
tex->getFormat();
|
||||
JMath::fastSqrt<f32>(0.0f);
|
||||
JUTTexture tex2;
|
||||
tex2.setCaptureFlag(false);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JAudio2/JAUAudience.h"
|
||||
|
||||
// NONMATCHING
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JAudio2/JAUSoundObject.h"
|
||||
|
||||
#include "JSystem/JGeometry.h"
|
||||
|
||||
static void dummy() {
|
||||
JGeometry::TVec3<f32>* vec_1;
|
||||
JGeometry::TVec3<f32>* vec_2;
|
||||
*vec_1 = *vec_2;
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
#include "NdevExi2A/DebuggerDriver.h"
|
||||
|
||||
#include "NdevExi2A/exi2.h"
|
||||
#include <dolphin/exi.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
static s32 __DBRecvDataSize;
|
||||
static u32 __DBRecvMail;
|
||||
|
||||
static u8 EXIInputFlag;
|
||||
|
||||
static MtrCallback __DBDbgCallback;
|
||||
static MtrCallback __DBMtrCallback;
|
||||
|
||||
static u8 SendCount = 0x80;
|
||||
|
||||
#define IS_TRUE(x) ((x) != FALSE)
|
||||
#define IS_FALSE(x) !IS_TRUE(x)
|
||||
#define ROUND_UP(x, align) (((x) + (align)-1) & (-(align)))
|
||||
|
||||
void __DBMtrHandler(s32 param_0, OSContext* ctx) {
|
||||
EXIInputFlag = 1;
|
||||
if (__DBMtrCallback != (void*)NULL) {
|
||||
__DBMtrCallback(0, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void __DBIntrHandler(s16 param_0, OSContext* ctx) {
|
||||
*__PIRegs = 0x1000;
|
||||
if (__DBDbgCallback != NULL) {
|
||||
__DBDbgCallback(param_0, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void __DBCheckMailBox(void) {
|
||||
u8 sp08;
|
||||
u32 mail;
|
||||
sp08 = __DBReadUSB_CSR();
|
||||
if (!(sp08 & 0x8)) {
|
||||
__DBReadMailbox(&mail);
|
||||
|
||||
if (ODEMUIsValidMail(mail)) {
|
||||
__DBRecvMail = mail;
|
||||
__DBRecvDataSize = ODEMUGetSize(mail);
|
||||
EXIInputFlag = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u8 __DBReadUSB_CSR() {
|
||||
u8 result;
|
||||
__DBEXIReadReg(0x34000000, &result, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DBInitComm(u8** a, MtrCallback callback) {
|
||||
BOOL interrupts = OSDisableInterrupts();
|
||||
|
||||
//pEXIInputFlag = &EXIInputFlag;
|
||||
*a = &EXIInputFlag;
|
||||
__DBMtrCallback = callback;
|
||||
__DBEXIInit();
|
||||
|
||||
OSRestoreInterrupts(interrupts);
|
||||
}
|
||||
|
||||
void DBInitInterrupts(void) {
|
||||
__OSMaskInterrupts(0x18000);
|
||||
__OSMaskInterrupts(0x40);
|
||||
__DBDbgCallback = &__DBMtrHandler;
|
||||
__OSSetInterruptHandler(0x19, __DBIntrHandler);
|
||||
__OSUnmaskInterrupts(0x40);
|
||||
}
|
||||
|
||||
u32 DBQueryData(void) {
|
||||
BOOL interrupts;
|
||||
EXIInputFlag = 0;
|
||||
if (__DBRecvDataSize == 0) {
|
||||
interrupts = OSDisableInterrupts();
|
||||
__DBCheckMailBox();
|
||||
OSRestoreInterrupts(interrupts);
|
||||
}
|
||||
return __DBRecvDataSize;
|
||||
}
|
||||
|
||||
BOOL DBRead(u32* buffer, s32 count) {
|
||||
u32 v;
|
||||
u32 interrupts = OSDisableInterrupts();
|
||||
v = ODEMUGetPc2NngcOffset(__DBRecvMail) + 0x1000;
|
||||
|
||||
__DBRead(v, buffer, ROUND_UP(count, 4));
|
||||
|
||||
__DBRecvDataSize = 0;
|
||||
EXIInputFlag = 0;
|
||||
|
||||
OSRestoreInterrupts(interrupts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL DBWrite(void* src, u32 size) {
|
||||
BOOL interrupts;
|
||||
u32 v;
|
||||
u32 mail;
|
||||
|
||||
interrupts = OSDisableInterrupts();
|
||||
|
||||
__DBWaitForSendMail();
|
||||
|
||||
SendCount++;
|
||||
v = (SendCount & 0x1) ? 0x800 : 0;
|
||||
|
||||
while (!__DBWrite(v, src, ROUND_UP(size, 4)))
|
||||
;
|
||||
|
||||
__DBWaitForSendMail();
|
||||
|
||||
mail = ODEMUGenMailData(SendCount, size);
|
||||
while (!__DBWriteMailbox(mail))
|
||||
;
|
||||
|
||||
__DBWaitForSendMail();
|
||||
|
||||
OSRestoreInterrupts(interrupts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __DBWaitForSendMail() {
|
||||
u8 busyFlag;
|
||||
do {
|
||||
busyFlag = __DBReadUSB_CSR();
|
||||
} while (busyFlag & 0x4);
|
||||
}
|
||||
|
||||
void DBOpen(void) {}
|
||||
|
||||
void DBClose(void) {}
|
||||
|
||||
static u32 ODEMUGetSize(u32 mail) {
|
||||
return mail & 0x1FFF;
|
||||
}
|
||||
|
||||
BOOL ODEMUIsValidMail(u32 mail) {
|
||||
return (mail & 0x1F000000) == 0x1F000000;
|
||||
}
|
||||
|
||||
u32 ODEMUGetPc2NngcOffset(u32 v) {
|
||||
return ODEMUGetPage(v) & 0x1 ? 0x800 : 0;
|
||||
}
|
||||
|
||||
u32 ODEMUGetPage(u32 v) {
|
||||
return (v & 0xFF0000) >> 16;
|
||||
}
|
||||
|
||||
u32 ODEMUGenMailData(u32 v, u32 size) {
|
||||
return (0x1f000000 | ((v << 16) & 0xFF0000)) | (size & 0x1FFF);
|
||||
}
|
||||
|
||||
void __DBReadMailbox(u32* out) {
|
||||
__DBEXIReadReg(0x34000200, out, 4);
|
||||
}
|
||||
|
||||
BOOL __DBRead(u32 param_0, void* dst, u32 count) {
|
||||
return __DBEXIReadRam(((param_0 + 0xD10000) << 6) & 0x3FFFFF00, dst, count);
|
||||
}
|
||||
|
||||
BOOL __DBWriteMailbox(u32 val) {
|
||||
return __DBEXIWriteReg(0xB4000100, &val, 0x4);
|
||||
}
|
||||
|
||||
BOOL __DBWrite(u32 param_0, void* dst, u32 count) {
|
||||
return __DBEXIWriteRam((((param_0 + 0xD10000) << 6) & 0x3FFFFF00) | 0x80000000, dst, count);
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
#include "NdevExi2A/exi2.h"
|
||||
|
||||
#include <revolution/os.h>
|
||||
|
||||
#define IS_TRUE(x) ((x) != FALSE)
|
||||
#define IS_FALSE(x) !IS_TRUE(x)
|
||||
#define ROUND_UP(x, align) (((x) + (align)-1) & (-(align)))
|
||||
|
||||
BOOL __EXI2Select() {
|
||||
u32 regs = __EXIRegs[10];
|
||||
regs &= 0x405;
|
||||
regs |= 0xC0;
|
||||
__EXIRegs[10] = regs;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL __EXI2Deselect() {
|
||||
u32 regs = __EXIRegs[10];
|
||||
__EXIRegs[10] = regs & 0x405;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL __EXI2Sync() {
|
||||
while (__EXIRegs[13] & 0x1) {
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL __EXI2Imm(u32* param_0, int width, int param_2) {
|
||||
int i1; // r31
|
||||
int i2; // r30
|
||||
u32 var_r29;
|
||||
u8* var_r28;
|
||||
u32 var_r25;
|
||||
|
||||
if (param_2 != 0) {
|
||||
var_r29 = 0;
|
||||
for (i1 = 0; i1 < width; i1++) {
|
||||
var_r29 |= ((u8*)param_0)[i1] << ((3 - i1) << 3);
|
||||
}
|
||||
__EXIRegs[14] = var_r29;
|
||||
}
|
||||
|
||||
__EXIRegs[13] = 0x1 | (param_2 << 2) | ((width - 1) << 4);
|
||||
__EXI2Sync();
|
||||
|
||||
if (param_2 == 0) {
|
||||
var_r28 = (u8*)param_0;
|
||||
var_r25 = __EXIRegs[14];
|
||||
for (i2 = 0; i2 < width; i2++) {
|
||||
*var_r28 = var_r25 >> ((3 - i2) << 3);
|
||||
var_r28++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void __DBEXIInit() {
|
||||
u8 sp08;
|
||||
|
||||
__OSMaskInterrupts(0x18000);
|
||||
|
||||
while ((__EXIRegs[13] & 0x1) == 0x1) {
|
||||
};
|
||||
|
||||
__EXIRegs[10] = 0;
|
||||
sp08 = 0xD4;
|
||||
__DBEXIWriteReg(0xB4000000, &sp08, 1);
|
||||
}
|
||||
|
||||
BOOL __DBEXIReadReg(u32 param_0, void* dst, u32 param_2) {
|
||||
int is_failed = FALSE;
|
||||
u32 val = 0;
|
||||
|
||||
is_failed |= IS_FALSE(__EXI2Select());
|
||||
is_failed |= IS_FALSE(__EXI2Imm(¶m_0, 4, 1));
|
||||
is_failed |= IS_FALSE(__EXI2Sync());
|
||||
is_failed |= IS_FALSE(__EXI2Imm(&val, 4, 0));
|
||||
is_failed |= IS_FALSE(__EXI2Sync());
|
||||
is_failed |= IS_FALSE(__EXI2Deselect());
|
||||
|
||||
switch (param_2) {
|
||||
case 1:
|
||||
*(u8*)dst = val >> 24;
|
||||
break;
|
||||
case 2:
|
||||
*(u16*)dst = (val >> 24) | ((val >> 8) & 0xff00);
|
||||
break;
|
||||
default:
|
||||
*(u32*)dst = __EXISwap32(val);
|
||||
break;
|
||||
}
|
||||
return IS_FALSE(is_failed);
|
||||
}
|
||||
|
||||
BOOL __DBEXIWriteReg(u32 param_0, void* src, u32 width) {
|
||||
int is_failed = FALSE;
|
||||
u32 val;
|
||||
|
||||
switch (width) {
|
||||
case 1:
|
||||
val = (*(u8*)src & 0xFF) << 24;
|
||||
break;
|
||||
case 2:
|
||||
val = ((*(u16*)src & 0xFF) << 24) | ((*(u16*)src & 0xff00) << 8);
|
||||
break;
|
||||
default:
|
||||
val = __EXISwap32(*(u32*)src);
|
||||
break;
|
||||
}
|
||||
|
||||
is_failed |= IS_FALSE(__EXI2Select());
|
||||
is_failed |= IS_FALSE(__EXI2Imm(¶m_0, 4, 1));
|
||||
is_failed |= IS_FALSE(__EXI2Sync());
|
||||
is_failed |= IS_FALSE(__EXI2Imm(&val, 4, 1));
|
||||
is_failed |= IS_FALSE(__EXI2Sync());
|
||||
is_failed |= IS_FALSE(__EXI2Deselect());
|
||||
|
||||
return IS_FALSE(is_failed);
|
||||
}
|
||||
|
||||
BOOL __DBEXIReadRam(u32 param_0, void* dst, int count) {
|
||||
int is_failed = FALSE;
|
||||
u32 cur_val;
|
||||
u32* cursor = (u32*)dst;
|
||||
|
||||
is_failed |= IS_FALSE(__EXI2Select());
|
||||
is_failed |= IS_FALSE(__EXI2Imm(¶m_0, 4, 1));
|
||||
is_failed |= IS_FALSE(__EXI2Sync());
|
||||
|
||||
while (count > 0) {
|
||||
is_failed |= IS_FALSE(__EXI2Imm(&cur_val, 4, 0));
|
||||
is_failed |= IS_FALSE(__EXI2Sync());
|
||||
*cursor++ = cur_val;
|
||||
count -= 4;
|
||||
}
|
||||
|
||||
is_failed |= IS_FALSE(__EXI2Deselect());
|
||||
|
||||
return IS_FALSE(is_failed);
|
||||
}
|
||||
|
||||
BOOL __DBEXIWriteRam(u32 param_0, void* src, int count) {
|
||||
int is_failed = FALSE;
|
||||
u32 cur_val;
|
||||
u32* cursor = (u32*)src;
|
||||
|
||||
is_failed |= IS_FALSE(__EXI2Select());
|
||||
is_failed |= IS_FALSE(__EXI2Imm(¶m_0, 4, 1));
|
||||
is_failed |= IS_FALSE(__EXI2Sync());
|
||||
|
||||
while (count > 0) {
|
||||
cur_val = *cursor++;
|
||||
is_failed |= IS_FALSE(__EXI2Imm(&cur_val, 4, 1));
|
||||
is_failed |= IS_FALSE(__EXI2Sync());
|
||||
count -= 4;
|
||||
}
|
||||
|
||||
is_failed |= IS_FALSE(__EXI2Deselect());
|
||||
|
||||
return IS_FALSE(is_failed);
|
||||
}
|
||||
|
||||
u32 __EXISwap32(u32 v) {
|
||||
return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);
|
||||
}
|
||||
@@ -9,9 +9,15 @@ extern "C" {
|
||||
|
||||
size_t wcstombs(char* dst, const wchar_t* src, size_t n);
|
||||
|
||||
int mbtowc(wchar_t* pwc, const char* s, size_t n);
|
||||
int mbstowcs(wchar_t* param_0, const char* param_1, int param_2);
|
||||
|
||||
int __mbtowc_noconv(wchar_t*, const char*, size_t);
|
||||
int __wctomb_noconv(char*, wchar_t);
|
||||
|
||||
int mbsrtowcs_s(size_t* retval, wchar_t* dst, unsigned int dstsz, const char** param_4, size_t len,
|
||||
int param_6);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,7 +12,7 @@ int fprintf(FILE* stream, const char* format, ...);
|
||||
int printf(const char* format, ...);
|
||||
int sprintf(char* s, const char* format, ...);
|
||||
int snprintf(char* s, size_t n, const char* format, ...);
|
||||
int vsnprintf(char* s, size_t n, const char* format, va_list arg);
|
||||
int vsnprintf(char* s, size_t n, const char* fmt, va_list args);
|
||||
int vsprintf(char* s, const char* format, va_list arg);
|
||||
int vprintf(const char* format, va_list arg);
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef _MSL_COMMON_WCSTOUL_H
|
||||
#define _MSL_COMMON_WCSTOUL_H
|
||||
|
||||
#include <wstring.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
size_t wcstoul(wchar_t* param_1, wchar_t** param_2, int param_3);
|
||||
|
||||
size_t wcstol(wchar_t* param_1, wchar_t** param_2, int param_3);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MSL_COMMON_WCSTOUL_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef _MSL_COMMON_WMEM_H
|
||||
#define _MSL_COMMON_WMEM_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void wmemcpy(wchar_t* dst, const wchar_t* src, size_t n);
|
||||
|
||||
const wchar_t* wmemchr(const wchar_t* str, wchar_t needle, int max_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MSL_COMMON_WMEM_H */
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef _MSL_COMMON_WPRINTF_H
|
||||
#define _MSL_COMMON_WPRINTF_H
|
||||
|
||||
#include <wstring.h>
|
||||
#include <cstddef>
|
||||
#include <cstdarg>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int swprintf(wchar_t *dst, size_t maxlen, const wchar_t *fmt, ...);
|
||||
|
||||
int vsnwprintf_s(wchar_t* str, size_t n, const wchar_t* fmt, va_list args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MSL_COMMON_WPRINTF_H */
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _MSL_COMMON_WSCANF_H
|
||||
#define _MSL_COMMON_WSCANF_H
|
||||
|
||||
#include <wstring.h>
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
wchar_t* WCharStr;
|
||||
size_t MaxCharCount;
|
||||
size_t CharsWritten;
|
||||
} __OutStrCtrl;
|
||||
|
||||
wchar_t __wStringRead(wString* src, wchar_t param_1, wchar_t param_2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MSL_COMMON_WSCANF_H */
|
||||
@@ -7,6 +7,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct wString {
|
||||
wchar_t* buffer;
|
||||
size_t field_0x4;
|
||||
size_t field_0x8;
|
||||
} wString;
|
||||
|
||||
size_t wcslen(const wchar_t*);
|
||||
wchar_t* wcscpy(wchar_t*, const wchar_t*);
|
||||
wchar_t* wcsncpy(wchar_t*, const wchar_t*, size_t);
|
||||
|
||||
@@ -2,8 +2,124 @@
|
||||
#include <cstring>
|
||||
#include <locale>
|
||||
|
||||
#include "errno.h"
|
||||
#include "global.h"
|
||||
|
||||
extern void __msl_runtime_constraint_violation_s(const char* msg, void* ptr, int error);
|
||||
|
||||
static unsigned int is_utf8_complete(const char* buf, unsigned int len) {
|
||||
char start_byte;
|
||||
int checked_cnt;
|
||||
int conts;
|
||||
int rem_conts;
|
||||
|
||||
if (len == 0) {
|
||||
return -1;
|
||||
}
|
||||
start_byte = buf[0];
|
||||
if (start_byte == 0) {
|
||||
return 0;
|
||||
}
|
||||
if ((start_byte & 0x80) == 0) {
|
||||
return 1;
|
||||
}
|
||||
if ((start_byte & 0xe0) == 0xc0) {
|
||||
conts = 1;
|
||||
} else if ((start_byte & 0xf0) == 0xe0) {
|
||||
conts = 2;
|
||||
} else if ((start_byte & 0xf8) == 0xf0) {
|
||||
conts = 3;
|
||||
} else if ((start_byte & 0xfc) == 0xf8) {
|
||||
conts = 4;
|
||||
} else if ((start_byte & 0xfe) == 0xfc) {
|
||||
conts = 5;
|
||||
} else {
|
||||
return 0xffffffff;
|
||||
}
|
||||
checked_cnt = 0;
|
||||
for (rem_conts = conts; rem_conts > 0; rem_conts--) {
|
||||
if ((buf[checked_cnt + 1] & 0xc0) != 0x80) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
checked_cnt++;
|
||||
}
|
||||
if (len >= checked_cnt + 1U) {
|
||||
return conts + 1;
|
||||
}
|
||||
return 0xfffffffe;
|
||||
}
|
||||
|
||||
static int __utf8_to_unicode(wchar_t* dst, const char* src, unsigned int len) {
|
||||
short byte_cnt;
|
||||
int remaining;
|
||||
int codepoint;
|
||||
|
||||
codepoint = 0;
|
||||
if (src == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
byte_cnt = is_utf8_complete(src, len);
|
||||
if (byte_cnt < 0) {
|
||||
return -1;
|
||||
}
|
||||
switch (byte_cnt) {
|
||||
case 6:
|
||||
codepoint = *src & ((1 << 2) - 1);
|
||||
break;
|
||||
case 5:
|
||||
codepoint = *src & ((1 << 3) - 1);
|
||||
break;
|
||||
case 4:
|
||||
codepoint = *src & ((1 << 4) - 1);
|
||||
break;
|
||||
case 3:
|
||||
codepoint = *src & ((1 << 5) - 1);
|
||||
break;
|
||||
case 2:
|
||||
codepoint = *src & ((1 << 6) - 1);
|
||||
break;
|
||||
case 1:
|
||||
codepoint = *src;
|
||||
break;
|
||||
}
|
||||
|
||||
for (remaining = byte_cnt - 1; remaining > 0; remaining--) {
|
||||
codepoint <<= 6;
|
||||
codepoint |= *++src & 0x7f;
|
||||
}
|
||||
|
||||
if (codepoint == 0) {
|
||||
remaining = 0;
|
||||
} else if (codepoint < 0 || codepoint < 0x80) {
|
||||
remaining = 1;
|
||||
} else if (codepoint < 0x800) {
|
||||
remaining = 2;
|
||||
} else if (codepoint < 0x10000) {
|
||||
remaining = 3;
|
||||
} else if (codepoint < 0x200000) {
|
||||
remaining = 4;
|
||||
} else if (codepoint < 0x4000000) {
|
||||
remaining = 5;
|
||||
} else {
|
||||
remaining = 6;
|
||||
}
|
||||
|
||||
if (remaining != byte_cnt) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dst != NULL) {
|
||||
*dst = codepoint;
|
||||
}
|
||||
|
||||
return byte_cnt;
|
||||
}
|
||||
|
||||
#if !PLATFORM_GCN
|
||||
int mbtowc(wchar_t* pwc, const char* s, size_t n) {
|
||||
return _current_locale.ctype_cmpt_ptr->decode_mb(pwc, s, n);
|
||||
@@ -67,6 +183,32 @@ int __wctomb_noconv(char* s, wchar_t wchar) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mbstowcs(wchar_t* param_0, const char* param_1, int param_2) {
|
||||
unsigned int i;
|
||||
int decoded_cnt;
|
||||
int remaining = strlen(param_1);
|
||||
if (param_0 != NULL) {
|
||||
for (i = 0; i < param_2; i++) {
|
||||
if (param_1[0] != '\0') {
|
||||
decoded_cnt =
|
||||
_current_locale.ctype_cmpt_ptr->decode_mb(param_0++, param_1, remaining);
|
||||
if (decoded_cnt > 0) {
|
||||
param_1 += decoded_cnt;
|
||||
remaining -= decoded_cnt;
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
param_0[0] = L'\0';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int wctomb(char* s, wchar_t wchar) {
|
||||
#if PLATFORM_GCN
|
||||
return (unicode_to_UTF8(s, wchar));
|
||||
@@ -101,3 +243,67 @@ size_t wcstombs(char* s, const wchar_t* pwcs, size_t n) {
|
||||
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
int mbsrtowcs_s(size_t* retval, wchar_t* dst, unsigned int dstsz, const char** param_4,
|
||||
size_t len, int param_6) {
|
||||
wchar_t* var_r27;
|
||||
const char* var_r24;
|
||||
unsigned int var_r25;
|
||||
int var_r26;
|
||||
wchar_t sp08[4];
|
||||
|
||||
if (retval == NULL || param_4 == NULL || *param_4 == NULL || param_6 == 0 ||
|
||||
(dst != NULL && (len > 0x7fffffff || dstsz > 0x7fffffff || dstsz < len)))
|
||||
{
|
||||
__msl_runtime_constraint_violation_s(NULL, NULL, 0x22);
|
||||
if (retval != NULL) {
|
||||
*retval = 0xffffffff;
|
||||
}
|
||||
return 0x22;
|
||||
}
|
||||
|
||||
var_r24 = *param_4;
|
||||
var_r26 = strlen(var_r24);
|
||||
for (var_r25 = 0; var_r25 < len; var_r25++) {
|
||||
if (*var_r24 != '\0') {
|
||||
int var_r3_1;
|
||||
|
||||
if (dst == NULL) {
|
||||
var_r27 = sp08;
|
||||
} else {
|
||||
var_r27 = dst++;
|
||||
}
|
||||
|
||||
if (var_r24 != NULL) {
|
||||
var_r3_1 = is_utf8_complete(var_r24, var_r26);
|
||||
if (var_r3_1 < 0xfffffffe) {
|
||||
if (var_r27 != NULL) {
|
||||
var_r3_1 = __utf8_to_unicode(var_r27, var_r24, var_r26);
|
||||
} else if (var_r3_1 == 0xffffffff) {
|
||||
errno = 0x58;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (var_r27 != NULL) {
|
||||
*var_r27 = L'\0';
|
||||
}
|
||||
var_r3_1 = 0;
|
||||
}
|
||||
|
||||
if (var_r3_1 <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
var_r24 += var_r3_1;
|
||||
var_r26 -= var_r3_1;
|
||||
} else {
|
||||
if (dst != NULL) {
|
||||
*dst = 0;
|
||||
*param_4 = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*retval = var_r25;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1550,7 +1550,7 @@ int vprintf(const char* format, va_list arg) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vsnprintf(char* s, size_t n, const char* format, va_list arg) {
|
||||
int vsnprintf(char* s, size_t n, const char* fmt, va_list args) {
|
||||
int end;
|
||||
__OutStrCtrl osc;
|
||||
osc.CharStr = s;
|
||||
@@ -1558,9 +1558,9 @@ int vsnprintf(char* s, size_t n, const char* format, va_list arg) {
|
||||
osc.CharsWritten = 0;
|
||||
|
||||
#if PLATFORM_GCN
|
||||
end = __pformatter(&__StringWrite, &osc, format, arg);
|
||||
end = __pformatter(&__StringWrite, &osc, fmt, args);
|
||||
#else
|
||||
end = __pformatter(&__StringWrite, &osc, format, arg, 0);
|
||||
end = __pformatter(&__StringWrite, &osc, fmt, args, 0);
|
||||
#endif
|
||||
|
||||
if (s) {
|
||||
|
||||
@@ -72,7 +72,7 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int
|
||||
scan_state = need_digit;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case leading_zero:
|
||||
if (c == 'X' || c == 'x') {
|
||||
base = 16;
|
||||
scan_state = need_digit;
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
#include <wcstoul.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <wctype_api.h>
|
||||
#include <wscanf.h>
|
||||
#include <climits>
|
||||
#include <locale>
|
||||
|
||||
enum scan_states {
|
||||
start = 0x01,
|
||||
check_for_zero = 0x02,
|
||||
leading_zero = 0x04,
|
||||
need_digit = 0x08,
|
||||
digit_loop = 0x10,
|
||||
finished = 0x20,
|
||||
failure = 0x40
|
||||
};
|
||||
|
||||
#define final_state(scan_state) (scan_state & (finished | failure))
|
||||
#define success(scan_state) (scan_state & (leading_zero | digit_loop | finished))
|
||||
#define fetch() (count++, (*read_proc)(read_proc_arg, 0, 0))
|
||||
|
||||
static size_t __wcstoul(int base, int max_width,
|
||||
wchar_t (*read_proc)(wString* src, wchar_t param_1, wchar_t param_2),
|
||||
void* read_proc_arg, int* chars_scanned, int* negative, int* overflow) {
|
||||
int scan_state;
|
||||
int count;
|
||||
int spaces;
|
||||
unsigned int value;
|
||||
unsigned int value_max;
|
||||
wchar_t c;
|
||||
|
||||
count = 0;
|
||||
scan_state = 1;
|
||||
spaces = 0;
|
||||
value = 0;
|
||||
value_max = 0;
|
||||
|
||||
*negative = *overflow = 0;
|
||||
|
||||
if (base < 0 || base == 1 || base > 36 || max_width < 1) {
|
||||
scan_state = failure;
|
||||
} else {
|
||||
c = fetch();
|
||||
}
|
||||
|
||||
if (base != 0) {
|
||||
value_max = ULONG_MAX / base;
|
||||
}
|
||||
|
||||
// NOTE: c is uninitialized if the parameter validation above fails. In practice, this doesn't
|
||||
// matter because the third condition will always fail in this scenario anyway.
|
||||
while (count <= max_width && c != -1 && !final_state(scan_state)) {
|
||||
switch (scan_state) {
|
||||
case start:
|
||||
if (c >= 0x100 ?
|
||||
0 :
|
||||
_current_locale.ctype_cmpt_ptr->wctype_map_ptr[c] & wctype_space) {
|
||||
c = read_proc(read_proc_arg, 0, 0);
|
||||
spaces++;
|
||||
} else {
|
||||
if (c == L'+') {
|
||||
c = fetch();
|
||||
} else if (c == L'-') {
|
||||
c = fetch();
|
||||
*negative = 1;
|
||||
}
|
||||
scan_state = check_for_zero;
|
||||
}
|
||||
break;
|
||||
case check_for_zero:
|
||||
if ((base == 0 || base == 16) && c == L'0') {
|
||||
scan_state = leading_zero;
|
||||
c = fetch();
|
||||
} else {
|
||||
scan_state = need_digit;
|
||||
}
|
||||
break;
|
||||
case leading_zero:
|
||||
if (c == L'X' || c == L'x') {
|
||||
base = 16;
|
||||
scan_state = need_digit;
|
||||
c = fetch();
|
||||
} else {
|
||||
if (base == 0) {
|
||||
base = 8;
|
||||
}
|
||||
scan_state = digit_loop;
|
||||
}
|
||||
break;
|
||||
case need_digit:
|
||||
case digit_loop:
|
||||
if (base == 0) {
|
||||
base = 10;
|
||||
}
|
||||
|
||||
if (value_max == 0) {
|
||||
value_max = ULONG_MAX / base;
|
||||
}
|
||||
|
||||
if (c >= 0x100 ? 0 : _current_locale.ctype_cmpt_ptr->wctype_map_ptr[c] & wctype_digit) {
|
||||
c -= L'0';
|
||||
if (c >= base) {
|
||||
if (scan_state == digit_loop) {
|
||||
scan_state = finished;
|
||||
} else {
|
||||
scan_state = failure;
|
||||
}
|
||||
c += L'0';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
int temp;
|
||||
if (!(c >= 0x100 ?
|
||||
0 :
|
||||
_current_locale.ctype_cmpt_ptr->wctype_map_ptr[c] & wctype_alpha)) {
|
||||
goto label;
|
||||
}
|
||||
|
||||
temp = 1;
|
||||
if (c <= 0xFF) {
|
||||
temp = 0;
|
||||
}
|
||||
if ((temp ? c :
|
||||
_current_locale.ctype_cmpt_ptr->upper_map_ptr[c]) -
|
||||
0x37 >=
|
||||
base) {
|
||||
label:
|
||||
if (scan_state == digit_loop) {
|
||||
scan_state = finished;
|
||||
} else {
|
||||
scan_state = failure;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
c = (wchar_t)(c >= 0x100 ?
|
||||
c :
|
||||
_current_locale.ctype_cmpt_ptr->wupper_map_ptr[c]) -
|
||||
0x37;
|
||||
}
|
||||
}
|
||||
|
||||
if (value > value_max) {
|
||||
*overflow = 1;
|
||||
}
|
||||
|
||||
value *= base;
|
||||
if (c > ULONG_MAX - value) {
|
||||
*overflow = 1;
|
||||
}
|
||||
|
||||
scan_state = digit_loop;
|
||||
value += c;
|
||||
c = fetch();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success(scan_state)) {
|
||||
value = 0;
|
||||
*chars_scanned = 0;
|
||||
} else {
|
||||
*chars_scanned = count + spaces - 1;
|
||||
}
|
||||
|
||||
read_proc(read_proc_arg, c, 1);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
size_t wcstoul(wchar_t* param_1, wchar_t** param_2, int param_3) {
|
||||
wString sp18;
|
||||
size_t retval;
|
||||
int sp10[2]; // not sure if this should be an array, but the stack doesn't match otherwise
|
||||
int sp0C;
|
||||
int sp08;
|
||||
sp18.buffer = param_1;
|
||||
sp18.field_0x4 = 0;
|
||||
|
||||
retval = __wcstoul(param_3, 0x7fffffff, __wStringRead, &sp18, sp10, &sp0C, &sp08);
|
||||
|
||||
if (param_2 != NULL) {
|
||||
*param_2 = param_1 + sp10[0];
|
||||
}
|
||||
|
||||
if (sp08 != 0) {
|
||||
errno = 0x22;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sp0C != 0) {
|
||||
return -retval;
|
||||
} else {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
size_t wcstol(wchar_t* param_1, wchar_t** param_2, int param_3) {
|
||||
size_t retval;
|
||||
wString sp18;
|
||||
int sp10[2]; // not sure if this should be an array, but the stack doesn't match otherwise
|
||||
int sp0C;
|
||||
int sp08;
|
||||
sp18.buffer = param_1;
|
||||
sp18.field_0x4 = 0;
|
||||
|
||||
retval = __wcstoul(param_3, 0x7fffffff, __wStringRead, &sp18, sp10, &sp0C, &sp08);
|
||||
|
||||
if (param_2 != NULL) {
|
||||
*param_2 = param_1 + sp10[0];
|
||||
}
|
||||
|
||||
if (sp08 != 0 || (sp0C == 0 && retval > 0x7fffffff) || (sp0C != 0 && retval > 0x80000000)) {
|
||||
errno = 0x22;
|
||||
return sp0C != 0 ? 0x80000000 : 0x7fffffff;
|
||||
}
|
||||
|
||||
if (sp0C != 0) {
|
||||
return -retval;
|
||||
} else {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <wmem.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
void wmemcpy(wchar_t* dst, const wchar_t* src, size_t n) {
|
||||
memcpy(dst, src, n * 2);
|
||||
}
|
||||
|
||||
const wchar_t* wmemchr(const wchar_t* str, wchar_t needle, int max_len) {
|
||||
int i;
|
||||
for (i = 0; i != max_len; i++) {
|
||||
if (*str == needle) {
|
||||
return str;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
#include <wscanf.h>
|
||||
#include <wstring.h>
|
||||
|
||||
wchar_t __wStringRead(wString* src, wchar_t param_1, wchar_t param_2) {
|
||||
switch (param_2) {
|
||||
case 0:
|
||||
param_2 = *src->buffer;
|
||||
if (param_2 == 0) {
|
||||
src->field_0x4 = 1;
|
||||
return 0xFFFF;
|
||||
} else {
|
||||
src->buffer++;
|
||||
return param_2;
|
||||
}
|
||||
case 1:
|
||||
if (src->field_0x4 == 0) {
|
||||
src->buffer--;
|
||||
} else {
|
||||
src->field_0x4 = 0;
|
||||
}
|
||||
return param_1;
|
||||
case 2:
|
||||
return src->field_0x4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/string_TRK.h"
|
||||
|
||||
int TRK_strlen(const char *str) {
|
||||
// NONMATCHING for Wii - for some reason Wii uses cmplwi instead of cmpwi
|
||||
int n = -1;
|
||||
do {
|
||||
n++;
|
||||
} while (((unsigned char*)str)[n] != '\0');
|
||||
return n;
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "TRK_MINNOW_DOLPHIN/utils/common/CircleBuffer.h"
|
||||
#include "odemuexi2/DebuggerDriver.h"
|
||||
|
||||
#define GDEV_BUF_SIZE (0x500)
|
||||
|
||||
static CircleBuffer gRecvCB;
|
||||
static u8 gRecvBuf[GDEV_BUF_SIZE];
|
||||
static BOOL gIsInitialized;
|
||||
|
||||
int gdev_cc_initinterrupts() {
|
||||
DBInitInterrupts();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdev_cc_peek() {
|
||||
u8 buf[GDEV_BUF_SIZE];
|
||||
int len;
|
||||
|
||||
if ((len = DBQueryData()) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (DBRead((u32*)buf, len) == 0) {
|
||||
CircleBufferWriteBytes(&gRecvCB, buf, len);
|
||||
} else {
|
||||
return 0xFFFFD8E7;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int gdev_cc_post_stop() {
|
||||
DBOpen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdev_cc_pre_continue() {
|
||||
DBClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdev_cc_write(unsigned char* src, int size) {
|
||||
if (!gIsInitialized) {
|
||||
return 0xFFFFD8EF;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
u32 written_cnt = DBWrite(src, size);
|
||||
if (written_cnt == 0) {
|
||||
break;
|
||||
}
|
||||
src += written_cnt;
|
||||
size -= written_cnt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdev_cc_read(u8* buf, u32 len) {
|
||||
u8 buf_local[GDEV_BUF_SIZE];
|
||||
int rv = 0;
|
||||
int var_r29;
|
||||
|
||||
if (!gIsInitialized) {
|
||||
return 0xFFFFD8EF;
|
||||
}
|
||||
|
||||
while (CBGetBytesAvailableForRead(&gRecvCB) < len) {
|
||||
rv = 0;
|
||||
if ((var_r29 = DBQueryData()) == 0) {
|
||||
continue;
|
||||
}
|
||||
rv = DBRead((u32*)buf_local, len);
|
||||
if (rv == 0) {
|
||||
CircleBufferWriteBytes(&gRecvCB, buf_local, var_r29);
|
||||
}
|
||||
}
|
||||
if (rv == 0) {
|
||||
CircleBufferReadBytes(&gRecvCB, buf, len);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
int gdev_cc_close() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdev_cc_open() {
|
||||
if (gIsInitialized) {
|
||||
return 0xFFFFD8EB;
|
||||
}
|
||||
|
||||
gIsInitialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdev_cc_shutdown() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gdev_cc_initialize(u8** a, MTRCallbackType b) {
|
||||
DBInitComm(a, b);
|
||||
CircleBufferInitialize(&gRecvCB, gRecvBuf, sizeof(gRecvBuf));
|
||||
return 0;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "odemuexi2/DebuggerDriver.h"
|
||||
|
||||
#include <dolphin/exi.h>
|
||||
#include <dolphin/os.h>
|
||||
|
||||
typedef void (*MTRCallbackType)(int);
|
||||
|
||||
static MTRCallbackType MTRCallback;
|
||||
|
||||
static void (*DBGCallback)(u32, OSContext*);
|
||||
|
||||
Reference in New Issue
Block a user