Reorganizaton of main (#199)

* reorganize main

* more names

* libc
This commit is contained in:
petrie911
2024-04-03 09:30:50 -05:00
committed by GitHub
parent 5f2b690a2b
commit ac41c180a9
73 changed files with 653 additions and 641 deletions
+335
View File
@@ -0,0 +1,335 @@
#include "sys.h"
#include "PR/os_internal.h"
FaultMgr gFaultMgr;
u8 sFaultCharIndex[0x80] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x29, 0xFF, 0xFF, 0xFF, 0x2B,
0xFF, 0xFF, 0x25, 0x26, 0xFF, 0x2A, 0xFF, 0x27, 0x2C, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
s32 sFaultCharPixelFlags[0x40] = {
0x70871C30, 0x8988A250, 0x88808290, 0x88831C90, 0x888402F8, 0x88882210, 0x71CF9C10, 0xF9CF9C70,
0x8228A288, 0xF200A288, 0x0BC11C78, 0x0A222208, 0x8A222288, 0x71C21C70, 0x23C738F8, 0x5228A480,
0x8A282280, 0x8BC822F0, 0xFA282280, 0x8A28A480, 0x8BC738F8, 0xF9C89C08, 0x82288808, 0x82088808,
0xF2EF8808, 0x82288888, 0x82288888, 0x81C89C70, 0x8A08A270, 0x920DA288, 0xA20AB288, 0xC20AAA88,
0xA208A688, 0x9208A288, 0x8BE8A270, 0xF1CF1CF8, 0x8A28A220, 0x8A28A020, 0xF22F1C20, 0x82AA0220,
0x82492220, 0x81A89C20, 0x8A28A288, 0x8A28A288, 0x8A289488, 0x8A2A8850, 0x894A9420, 0x894AA220,
0x70852220, 0xF8011000, 0x08020800, 0x10840400, 0x20040470, 0x40840400, 0x80020800, 0xF8011000,
0x70800000, 0x88822200, 0x08820400, 0x108F8800, 0x20821000, 0x00022200, 0x20800020, 0x00000000,
};
const char* sFaultCauses[18] = {
"Interrupt",
"TLB modification",
"TLB exception on load",
"TLB exception on store",
"Address error on load",
"Address error on store",
"Bus error on inst.",
"Bus error on data",
"System call exception",
"Breakpoint exception",
"Reserved instruction",
"Coprocessor unusable",
"Arithmetic overflow",
"Trap exception",
"Virtual coherency on inst.",
"Floating point exception",
"Watchpoint exception",
"Virtual coherency on data",
};
const char* sFloatExceptions[6] = {
"Unimplemented operation", "Invalid operation", "Division by zero", "Overflow", "Underflow", "Inexact operation",
};
void func_800073C0(s32 arg0, s32 arg1, s32 arg2, s32 arg3) {
u16* var_v0;
s32 i;
s32 j;
var_v0 = gFaultMgr.width * arg1 + gFaultMgr.fb->data + arg0;
for (i = 0; i < arg3; i++) {
for (j = 0; j < arg2; j++, var_v0++) {
*var_v0 = ((*var_v0 & 0xE738) >> 2) | 1;
}
var_v0 += gFaultMgr.width - arg2;
}
}
void func_800074AC(s32 arg0, s32 arg1, s32 arg2) {
s32* var_v0;
u16* var_v1;
s32 i;
s32 j;
var_v0 = &sFaultCharPixelFlags[(arg2 / 5) * 7];
var_v1 = gFaultMgr.width * arg1 + gFaultMgr.fb->data + arg0;
for (i = 0; i < 7; i++) {
u32 temp_t1 = 0x80000000 >> ((arg2 % 5) * 6);
u32 temp_a3 = *var_v0++;
for (j = 0; j < 6; j++) {
if (temp_t1 & temp_a3) {
*var_v1 = -1;
} else {
*var_v1 = 1;
}
var_v1++;
temp_t1 >>= 1;
}
var_v1 += gFaultMgr.width - 6;
}
}
void* func_80007604(void* arg0, const char* arg1, size_t arg2) {
return (char*) memcpy(arg0, arg1, arg2) + arg2;
}
void func_8000762C(s32 arg0, s32 arg1, const char* fmt, ...) {
u8* var_s0;
s32 i;
u8 sp40[0x100];
s32 temp_a2;
va_list args;
va_start(args, fmt);
for (i = 0; i < 0x100; i++) {
sp40[i] = 0;
}
if (_Printf((outfun*) func_80007604, sp40, fmt, args) <= 0) {
return;
}
for (var_s0 = sp40; *var_s0 != 0; var_s0++) {
temp_a2 = sFaultCharIndex[*var_s0 & 0x7F];
if (temp_a2 != 0xFF) {
func_800074AC(arg0, arg1, temp_a2);
}
arg0 += 6;
label:; // fake, probably
}
va_end(args);
}
void func_8000770C(s32 time) {
u64 time64 = MSEC_TO_CYCLES(time);
osSetTime(0);
while (osGetTime() < time64) {
;
}
}
void func_800077F8(s32 arg0, s32 arg1, s32 arg2, f32* arg3) {
u32 temp_v0 = *(u32*) arg3;
s32 temp_v1 = ((temp_v0 & 0x7F800000) >> 0x17) - 0x7F;
if (((-0x7F < temp_v1) && (temp_v1 < 0x80)) || (temp_v0 == 0)) {
func_8000762C(arg0, arg1, "F%02d:%.3e", arg2, *arg3);
} else {
func_8000762C(arg0, arg1, "F%02d:---------", arg2);
}
}
void func_80007880(u32 arg0) {
s32 var_v0;
u32 var_v1 = 0x20000;
func_8000762C(0x1E, 0xA0, "FPCSR:%08XH", arg0);
for (var_v0 = 0; var_v0 < 6; var_v0++, var_v1 >>= 1) {
if (arg0 & var_v1) {
func_8000762C(0x84, 0xA0, "(%s)", sFloatExceptions[var_v0]);
return;
}
}
}
#define CAUSE_INDEX(cause) ((cause >> CAUSE_EXCSHIFT) & (CAUSE_EXCMASK >> CAUSE_EXCSHIFT))
void func_80007910(OSThread* thread) {
__OSThreadContext* context = &thread->context;
s16 var_s0 = CAUSE_INDEX(context->cause);
if (var_s0 == CAUSE_INDEX(EXC_WATCH)) {
var_s0 = 16;
}
if (var_s0 == CAUSE_INDEX(EXC_VCED)) {
var_s0 = 17;
}
func_8000770C(3000);
func_800073C0(15, 15, 290, 210);
func_8000762C(30, 40, "THREAD:%d (%s)", thread->id, sFaultCauses[var_s0]);
func_8000762C(30, 50, "PC:%08XH SR:%08XH\tVA:%08XH", context->pc, context->sr, context->badvaddr);
osWritebackDCacheAll();
func_8000762C(30, 60, "AT:%08XH V0:%08XH\tV1:%08XH", (s32) context->at, (s32) context->v0, (s32) context->v1);
func_8000762C(30, 70, "A0:%08XH A1:%08XH\tA2:%08XH", (s32) context->a0, (s32) context->a1, (s32) context->a2);
func_8000762C(30, 80, "A3:%08XH T0:%08XH\tT1:%08XH", (s32) context->a3, (s32) context->t0, (s32) context->t1);
func_8000762C(30, 90, "T2:%08XH T3:%08XH\tT4:%08XH", (s32) context->t2, (s32) context->t3, (s32) context->t4);
func_8000762C(30, 100, "T5:%08XH T6:%08XH\tT7:%08XH", (s32) context->t5, (s32) context->t6, (s32) context->t7);
func_8000762C(30, 110, "S0:%08XH S1:%08XH\tS2:%08XH", (s32) context->s0, (s32) context->s1, (s32) context->s2);
func_8000762C(30, 120, "S3:%08XH S4:%08XH\tS5:%08XH", (s32) context->s3, (s32) context->s4, (s32) context->s5);
func_8000762C(30, 130, "S6:%08XH S7:%08XH\tT8:%08XH", (s32) context->s6, (s32) context->s7, (s32) context->t8);
func_8000762C(30, 140, "T9:%08XH GP:%08XH\tSP:%08XH", (s32) context->t9, (s32) context->gp, (s32) context->sp);
func_8000762C(30, 150, "S8:%08XH RA:%08XH", (s32) context->s8, (s32) context->ra);
func_80007880(context->fpcsr);
osWritebackDCacheAll();
func_800077F8(30, 170, 0, &context->fp0.f.f_even);
func_800077F8(120, 170, 2, &context->fp2.f.f_even);
func_800077F8(210, 170, 4, &context->fp4.f.f_even);
func_800077F8(30, 180, 6, &context->fp6.f.f_even);
func_800077F8(120, 180, 8, &context->fp8.f.f_even);
func_800077F8(210, 180, 10, &context->fp10.f.f_even);
func_800077F8(30, 190, 12, &context->fp12.f.f_even);
func_800077F8(120, 190, 14, &context->fp14.f.f_even);
func_800077F8(210, 190, 16, &context->fp16.f.f_even);
func_800077F8(30, 200, 18, &context->fp18.f.f_even);
func_800077F8(120, 200, 20, &context->fp20.f.f_even);
func_800077F8(210, 200, 22, &context->fp22.f.f_even);
func_800077F8(30, 210, 24, &context->fp24.f.f_even);
func_800077F8(120, 210, 26, &context->fp26.f.f_even);
func_800077F8(210, 210, 28, &context->fp28.f.f_even);
func_800077F8(30, 220, 30, &context->fp30.f.f_even);
osWritebackDCacheAll();
osViBlack(0);
osViRepeatLine(0);
osViSwapBuffer(gFaultMgr.fb);
}
OSThread* func_80007CEC(void) {
OSThread* var_v1;
var_v1 = __osGetActiveQueue();
while (var_v1->priority != -1) {
if ((var_v1->priority > 0) && (var_v1->priority < 0x7F) && (var_v1->flags & 3)) {
return var_v1;
}
var_v1 = var_v1->tlnext;
}
return NULL;
}
void Fault_ThreadEntry(void* arg0) {
OSMesg sp44;
OSThread* sp40;
s32 var_s2;
s32 var_s5;
u32 var_s0;
sp44 = NULL;
var_s5 = 0;
var_s0 = 0;
var_s2 = 0;
osSetEventMesg(OS_EVENT_CPU_BREAK, &gFaultMgr.msgQueue, (OSMesg) FAULT_MESG_BREAK);
osSetEventMesg(OS_EVENT_FAULT, &gFaultMgr.msgQueue, (OSMesg) FAULT_MESG_FAULT);
sp40 = NULL;
while (sp40 == NULL) {
osRecvMesg(&gFaultMgr.msgQueue, &sp44, OS_MESG_BLOCK);
sp40 = func_80007CEC();
}
func_8000762C(300, 10, "-");
gControllerPlugged[0] = 1;
while (var_s5 == 0) {
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_PRI_NORMAL);
osRecvMesg(&gControllerMsgQueue, NULL, OS_MESG_BLOCK);
Controller_UpdateInput();
switch (var_s0) {
case 0:
if (gControllerHold[0].button == (R_TRIG | D_CBUTTONS | L_CBUTTONS)) {
var_s0++;
var_s2 = 4000;
}
break;
case 1:
case 2:
case 7:
if (gControllerHold[0].button & R_TRIG) {
if (gControllerPress[0].button == A_BUTTON) {
var_s0++;
var_s2 = 3000;
} else if (gControllerPress[0].button != 0) {
var_s0 = 0;
}
}
break;
case 3:
case 4:
case 8:
if (gControllerHold[0].button & R_TRIG) {
if (gControllerPress[0].button == B_BUTTON) {
var_s0++;
var_s2 = 3000;
} else if (gControllerPress[0].button != 0) {
var_s0 = 0;
}
}
break;
case 5:
case 6:
case 9:
case 10:
case 11:
case 12:
case 13:
if (gControllerHold[0].button & R_TRIG) {
if (gControllerPress[0].button == L_CBUTTONS) {
var_s0++;
var_s2 = 3000;
} else if (gControllerPress[0].button != 0) {
var_s0 = 0;
}
}
break;
case 14:
if (gControllerHold[0].button & R_TRIG) {
if (gControllerPress[0].button == START_BUTTON) {
var_s0++;
var_s2 = 3000;
} else if (gControllerPress[0].button != 0) {
var_s0 = 0;
}
}
break;
case 15:
var_s5 = 1;
break;
}
if (var_s2 != 0) {
var_s2 -= 1;
} else {
var_s0 = 0;
}
}
func_80007910(sp40);
while (1) {
;
}
}
void func_80007FE4(FrameBuffer* arg0, u16 arg1, u16 arg2) {
gFaultMgr.fb = arg0;
gFaultMgr.width = arg1;
gFaultMgr.height = arg2;
}
void Fault_Init(void) {
gFaultMgr.fb = (FrameBuffer*) (PHYS_TO_K0(osMemSize) - sizeof(FrameBuffer));
gFaultMgr.width = SCREEN_WIDTH;
gFaultMgr.height = SCREEN_HEIGHT;
osCreateMesgQueue(&gFaultMgr.msgQueue, &gFaultMgr.msg, 1);
osCreateThread(&gFaultMgr.thread, THREAD_ID_FAULT, Fault_ThreadEntry, 0, gFaultMgr.stack + sizeof(gFaultMgr.stack),
127);
osStartThread(&gFaultMgr.thread);
}
+149
View File
@@ -0,0 +1,149 @@
#include "sys.h"
OSContPad gControllerHold[4];
OSContPad gControllerPress[4];
u8 gControllerPlugged[4];
u32 gControllerLock;
u8 gControllerRumble[4];
OSContPad sNextController[4]; //
OSContPad sPrevController[4]; //
OSContStatus sControllerStatus[4]; //
OSPfs sControllerMotor[4]; //
void Controller_AddDeadZone(s32 contrNum) {
s32 temp_v0 = gControllerHold[contrNum].stick_x;
s32 temp_a2 = gControllerHold[contrNum].stick_y;
s32 var_a0;
s32 var_v0;
if ((temp_v0 >= -16) && (temp_v0 <= 16)) {
var_a0 = 0;
} else if (temp_v0 > 16) {
var_a0 = temp_v0 - 16;
} else {
var_a0 = temp_v0 + 16;
}
if ((temp_a2 >= -16) && (temp_a2 <= 16)) {
var_v0 = 0;
} else if (temp_a2 > 16) {
var_v0 = temp_a2 - 16;
} else {
var_v0 = temp_a2 + 16;
}
if (var_a0 > 60) {
var_a0 = 60;
}
if (var_a0 < -60) {
var_a0 = -60;
}
if (var_v0 > 60) {
var_v0 = 60;
}
if (var_v0 < -60) {
var_v0 = -60;
}
gControllerPress[contrNum].stick_x = var_a0;
gControllerPress[contrNum].stick_y = var_v0;
}
void Controller_Init(void) {
u8 sp1F;
s32 i;
osContInit(&gSerialEventQueue, &sp1F, sControllerStatus);
for (i = 0; i < 4; i++) {
gControllerPlugged[i] = (sp1F >> i) & 1;
gControllerRumble[i] = 0;
}
}
void Controller_UpdateInput(void) {
s32 i;
for (i = 0; i < 4; i++) {
if (gControllerPlugged[i] == 1 && sNextController[i].errno == 0) {
sPrevController[i] = gControllerHold[i];
gControllerHold[i] = sNextController[i];
gControllerPress[i].button =
(gControllerHold[i].button ^ sPrevController[i].button) & gControllerHold[i].button;
Controller_AddDeadZone(i);
} else {
gControllerHold[i].button = gControllerHold[i].stick_x = gControllerHold[i].stick_y =
gControllerHold[i].errno = gControllerPress[i].button = gControllerPress[i].stick_x =
gControllerPress[i].stick_y = gControllerPress[i].errno = 0;
}
}
}
void Controller_ReadData(void) {
s32 i;
if (gControllerLock != 0) {
gControllerLock--;
for (i = 0; i < 4; i++) {
sNextController[i].button = sNextController[i].stick_x = sNextController[i].stick_y =
sNextController[i].errno = 0;
}
} else {
osContStartReadData(&gSerialEventQueue);
osRecvMesg(&gSerialEventQueue, NULL, OS_MESG_BLOCK);
osContGetReadData(sNextController);
}
osSendMesg(&gControllerMsgQueue, (OSMesg) SI_CONT_READ_DONE, OS_MESG_PRI_NORMAL);
}
void Save_ReadData(void) {
if ((gStartNMI == 0) && (Save_ReadEeprom(&gSaveIOBuffer) == 0)) {
osSendMesg(&gSaveMsgQueue, (OSMesg) SI_SAVE_SUCCESS, OS_MESG_PRI_NORMAL);
return;
}
osSendMesg(&gSaveMsgQueue, (OSMesg) SI_SAVE_FAILED, OS_MESG_PRI_NORMAL);
}
void Save_WriteData(void) {
if ((gStartNMI == 0) && (Save_WriteEeprom(&gSaveIOBuffer) == 0)) {
osSendMesg(&gSaveMsgQueue, (OSMesg) SI_SAVE_SUCCESS, OS_MESG_PRI_NORMAL);
return;
}
osSendMesg(&gSaveMsgQueue, (OSMesg) SI_SAVE_FAILED, OS_MESG_PRI_NORMAL);
}
void Controller_Rumble(void) {
s32 i;
osContStartQuery(&gSerialEventQueue);
osRecvMesg(&gSerialEventQueue, NULL, OS_MESG_BLOCK);
osContGetQuery(sControllerStatus);
for (i = 0; i < 4; i++) {
if ((gControllerPlugged[i] != 0) && (sControllerStatus[i].errno == 0)) {
if (sControllerStatus[i].status & 1) {
if (gControllerRumble[i] == 0) {
if (osMotorInit(&gSerialEventQueue, &sControllerMotor[i], i)) {
gControllerRumble[i] = 0;
} else {
gControllerRumble[i] = 1;
}
}
if (gControllerRumble[i] == 1) {
if (D_80137E84[i] != 0) {
if (osMotorStart(&sControllerMotor[i])) {
gControllerRumble[i] = 0;
}
} else {
if (osMotorStop(&sControllerMotor[i])) {
gControllerRumble[i] = 0;
}
}
}
} else {
gControllerRumble[i] = 0;
}
}
}
for (i = 0; i < 4; i++) {
D_80137E84[i] = 0;
}
}
+143
View File
@@ -0,0 +1,143 @@
#include "sys.h"
s32 Lib_vsPrintf(char* dst, const char* fmt, va_list args) {
return vsprintf(dst, fmt, args);
}
void Lib_vTable(s32 index, void (**table)(s32, s32), s32 arg0, s32 arg1) {
void (*func)(s32, s32) = table[index];
func(arg0, arg1);
}
void Lib_SwapBuffers(u8* buf1, u8* buf2, s32 len) {
s32 i;
u8 temp;
for (i = 0; i < len; i++) {
temp = buf2[i];
buf2[i] = buf1[i];
buf1[i] = temp;
}
}
void Lib_QuickSort(u8* first, u32 length, u32 size, CompareFunc cFunc) {
u32 splitIdx;
u8* last;
u8* right;
u8* left;
while (1) {
last = first + (length - 1) * size;
if (length == 2) {
if (cFunc(first, last) > 0) {
Lib_SwapBuffers(first, last, size);
}
return;
}
if (size && size && size) {} //! FAKE: must be here with at least 3 && operands.
left = first;
right = last - size;
while (1) {
while (cFunc(left, last) < 0) {
left += size;
}
while ((cFunc(right, last) >= 0) && (left < right)) {
right -= size;
}
if (left >= right) {
break;
}
Lib_SwapBuffers(left, right, size);
left += size;
right -= size;
}
Lib_SwapBuffers(last, left, size);
splitIdx = (left - first) / size;
if (length / 2 < splitIdx) {
if ((length - splitIdx) > 2) {
Lib_QuickSort(left + size, length - splitIdx - 1, size, cFunc);
}
if (splitIdx < 2) {
return;
}
left = first;
length = splitIdx;
} else {
if (splitIdx >= 2) {
Lib_QuickSort(first, splitIdx, size, cFunc);
}
if ((length - splitIdx) <= 2) {
return;
}
first = left + size;
length -= splitIdx + 1;
}
}
}
void Lib_Perspective(Gfx** dList) {
u16 norm;
guPerspective(gGfxMtx, &norm, D_game_80161A3C, (f32) SCREEN_WIDTH / SCREEN_HEIGHT, D_game_80161A40, D_game_80161A44,
1.0f);
gSPPerspNormalize((*dList)++, norm);
gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
guLookAt(gGfxMtx, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -12800.0f, 0.0f, 1.0f, 0.0f);
gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
Matrix_Copy(gGfxMatrix, &gIdentityMatrix);
}
void Lib_Ortho(Gfx** dList) {
guOrtho(gGfxMtx, -160.0f, 160.0f, -120.0f, 120.0f, D_game_80161A40, D_game_80161A44, 1.0f);
gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
guLookAt(gGfxMtx, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -12800.0f, 0.0f, 1.0f, 0.0f);
gSPMatrix((*dList)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
Matrix_Copy(gGfxMatrix, &gIdentityMatrix);
}
void Lib_DmaRead(void* src, void* dst, ptrdiff_t size) {
osInvalICache(dst, size);
osInvalDCache(dst, size);
while (size > 0x100) {
osPiStartDma(&gDmaIOMsg, 0, 0, (uintptr_t) src, dst, 0x100, &gDmaMsgQueue);
size -= 0x100;
src = (void*) ((uintptr_t) src + 0x100);
dst = (void*) ((uintptr_t) dst + 0x100);
osRecvMesg(&gDmaMsgQueue, NULL, OS_MESG_BLOCK);
}
if (size != 0) {
osPiStartDma(&gDmaIOMsg, 0, 0, (uintptr_t) src, dst, size, &gDmaMsgQueue);
osRecvMesg(&gDmaMsgQueue, NULL, OS_MESG_BLOCK);
}
}
void Lib_FillScreen(u8 setFill) {
s32 i;
gFillScreenColor |= 1;
if (setFill == true) {
if (gFillScreen == false) {
if (gFillScreenColor == 1) {
osViBlack(1);
} else {
for (i = 0; i < 3 * SCREEN_WIDTH; i++) {
gFillBuffer[i] = gFillScreenColor;
}
osWritebackDCacheAll();
osViSwapBuffer(&gFillBuffer[SCREEN_WIDTH]);
osViRepeatLine(1);
}
gFillScreen = true;
}
} else if (gFillScreen == true) {
osViRepeatLine(0);
osViBlack(0);
gFillScreen = false;
}
}
+84
View File
@@ -0,0 +1,84 @@
#include "sys.h"
void Lights_AddLight(Gfx** dList) {
gSPNumLights((*dList)++, 7);
gSPLight((*dList)++, &gLight->l[0], 1);
gSPLight((*dList)++, &gLight->l[1], 2);
gSPLight((*dList)++, &gLight->l[2], 3);
gSPLight((*dList)++, &gLight->l[3], 4);
gSPLight((*dList)++, &gLight->l[4], 5);
gSPLight((*dList)++, &gLight->l[5], 6);
gSPLight((*dList)++, &gLight->l[6], 7);
gSPLight((*dList)++, &gLight->a, 8);
gLight++;
}
void Lights_SetOneLight(Gfx** dList, s32 dirX, s32 dirY, s32 dirZ, s32 colR, s32 colG, s32 colB, s32 ambR, s32 ambG,
s32 ambB) {
s32 i;
for (i = 0; i < 4; i++) {
gLight->l[i].l.dir[0] = dirX;
gLight->l[i].l.dir[1] = dirY;
gLight->l[i].l.dir[2] = dirZ;
gLight->l[i].l.col[0] = colR;
gLight->l[i].l.col[1] = colG;
gLight->l[i].l.col[2] = colB;
gLight->l[i].l.colc[0] = colR;
gLight->l[i].l.colc[1] = colG;
gLight->l[i].l.colc[2] = colB;
}
for (i = 4; i < 7; i++) {
gLight->l[i].l.dir[0] = dirX;
gLight->l[i].l.dir[1] = dirY;
gLight->l[i].l.dir[2] = dirZ;
gLight->l[i].l.col[0] = 0;
gLight->l[i].l.col[1] = 0;
gLight->l[i].l.col[2] = 0;
gLight->l[i].l.colc[0] = 0;
gLight->l[i].l.colc[1] = 0;
gLight->l[i].l.colc[2] = 0;
}
gLight->a.l.col[0] = ambR;
gLight->a.l.col[1] = ambG;
gLight->a.l.col[2] = ambB;
gLight->a.l.colc[0] = ambR;
gLight->a.l.colc[1] = ambG;
gLight->a.l.colc[2] = ambB;
Lights_AddLight(dList);
}
void Lights_SetTwoLights(Gfx** dList, s32 dir1x, s32 dir1y, s32 dir1z, s32 dir2x, s32 dir2y, s32 dir2z, s32 col1r,
s32 col1g, s32 col1b, s32 col2r, s32 col2g, s32 col2b, s32 ambR, s32 ambG, s32 ambB) {
s32 i;
for (i = 0; i < 4; i++) {
gLight->l[i].l.dir[0] = dir1x;
gLight->l[i].l.dir[1] = dir1y;
gLight->l[i].l.dir[2] = dir1z;
gLight->l[i].l.col[0] = col1r;
gLight->l[i].l.col[1] = col1g;
gLight->l[i].l.col[2] = col1b;
gLight->l[i].l.colc[0] = col1r;
gLight->l[i].l.colc[1] = col1g;
gLight->l[i].l.colc[2] = col1b;
}
for (i = 4; i < 7; i++) {
gLight->l[i].l.dir[0] = dir2x;
gLight->l[i].l.dir[1] = dir2y;
gLight->l[i].l.dir[2] = dir2z;
gLight->l[i].l.col[0] = col2r;
gLight->l[i].l.col[1] = col2g;
gLight->l[i].l.col[2] = col2b;
gLight->l[i].l.colc[0] = col2r;
gLight->l[i].l.colc[1] = col2g;
gLight->l[i].l.colc[2] = col2b;
}
gLight->a.l.col[0] = ambR;
gLight->a.l.col[1] = ambG;
gLight->a.l.col[2] = ambB;
gLight->a.l.colc[0] = ambR;
gLight->a.l.colc[1] = ambG;
gLight->a.l.colc[2] = ambB;
Lights_AddLight(dList);
}
+493
View File
@@ -0,0 +1,493 @@
#include "sys.h"
void AudioLoad_Init(void);
SPTask* AudioThread_CreateTask(void);
void Audio_InitSounds(void);
void Audio_Update(void);
s32 sGammaMode = 1;
SPTask* gCurrentTask;
SPTask* sAudioTasks[1];
SPTask* sGfxTasks[2];
SPTask* sNewAudioTasks[1];
SPTask* sNewGfxTasks[2];
u32 gSegments[16]; // 800E1FD0
OSMesgQueue gPiMgrCmdQueue; // 800E2010
OSMesg sPiMgrCmdBuff[50]; // 800E2028
OSMesgQueue gDmaMsgQueue;
void* sDmaMsgBuff[1];
OSIoMesg gDmaIOMsg;
OSMesgQueue gSerialEventQueue;
void* sSerialEventBuff[1];
OSMesgQueue gMainThreadMsgQueue;
void* sMainThreadMsgBuff[32];
OSMesgQueue gTaskMsgQueue;
void* sTaskMsgBuff[16];
OSMesgQueue gAudioVImsgQueue;
void* sAudioVImsgBuff[1];
OSMesgQueue gAudioTaskMsgQueue;
void* sAudioTaskMsgBuff[1];
OSMesgQueue gGfxVImsgQueue;
void* sGfxVImsgBuff[4];
OSMesgQueue gGfxTaskMsgQueue;
void* sGfxTaskMsgBuff[2];
OSMesgQueue gSerialThreadMsgQueue;
void* sSerialThreadMsgBuff[8];
OSMesgQueue gControllerMsgQueue;
void* sControllerMsgBuff[1];
OSMesgQueue gSaveMsgQueue;
void* sSaveMsgBuff[1];
OSMesgQueue gTimerTaskMsgQueue;
void* sTimerTaskMsgBuff[16];
OSMesgQueue gTimerWaitMsgQueue;
void* sTimerWaitMsgBuff[1];
GfxPool gGfxPools[2];
GfxPool* gGfxPool;
SPTask* gGfxTask;
Vp* gViewport;
Mtx* gGfxMtx;
Gfx* gUnkDisp1;
Gfx* gMasterDisp;
Gfx* gUnkDisp2;
Lightsn* gLight;
FrameBuffer* gFrameBuffer;
u16* gTextureRender;
u8 D_80137E78;
u32 gSysFrameCount;
u8 gStartNMI;
u8 gStopTasks;
u8 D_80137E84[4];
u16 gFillScreenColor;
u16 gFillScreen;
u8 gUnusedStack[0x1000];
OSThread sIdleThread; // 80138E90
u8 sIdleThreadStack[0x1000]; // 801390A0
OSThread gMainThread; // 8013A040
u8 sMainThreadStack[0x1000]; // 8013A1F0
OSThread gAudioThread; // 8013B1F0
u8 gAudioThreadStack[0x1000]; // 800DDAA0
OSThread gGraphicsThread; // 800DEAA0
u8 gGraphicsThreadStack[0x1000]; // 800DEC50
OSThread gTimerThread; // 800DFC50
u8 gTimerThreadStack[0x1000]; // 800DFE00
OSThread gSerialThread; // 800E0E00
u8 gSerialThreadStack[0x1000]; // 800E0FB0
void Main_Initialize(void) {
u8 i;
D_80137E78 = 0;
gSysFrameCount = 0;
gStartNMI = false;
gStopTasks = false;
gFillScreenColor = 0;
gFillScreen = false;
gCurrentTask = NULL;
for (i = 0; i < ARRAY_COUNT(sAudioTasks); i += 1) {
sAudioTasks[i] = NULL;
}
for (i = 0; i < ARRAY_COUNT(sGfxTasks); i += 1) {
sGfxTasks[i] = NULL;
}
for (i = 0; i < ARRAY_COUNT(sNewAudioTasks); i += 1) {
sNewAudioTasks[i] = NULL;
}
for (i = 0; i < ARRAY_COUNT(sNewGfxTasks); i += 1) {
sNewGfxTasks[i] = NULL;
}
}
void Audio_ThreadEntry(void* arg0) {
SPTask* task;
AudioLoad_Init();
Audio_InitSounds();
task = AudioThread_CreateTask();
if (task != NULL) {
task->msgQueue = &gAudioTaskMsgQueue;
task->msg = (OSMesg) TASK_MESG_1;
osWritebackDCacheAll();
osSendMesg(&gTaskMsgQueue, task, OS_MESG_PRI_NORMAL);
}
while (1) {
task = AudioThread_CreateTask();
if (task != NULL) {
task->msgQueue = &gAudioTaskMsgQueue;
task->msg = (OSMesg) TASK_MESG_1;
osWritebackDCacheAll();
}
osRecvMesg(&gAudioTaskMsgQueue, NULL, OS_MESG_NOBLOCK);
if (task != NULL) {
osSendMesg(&gTaskMsgQueue, task, OS_MESG_PRI_NORMAL);
}
osRecvMesg(&gAudioVImsgQueue, NULL, OS_MESG_BLOCK);
}
}
void Graphics_SetTask(void) {
gGfxTask->msgQueue = &gGfxTaskMsgQueue;
gGfxTask->msg = (OSMesg) TASK_MESG_2;
gGfxTask->task.t.type = M_GFXTASK;
gGfxTask->task.t.flags = 0;
gGfxTask->task.t.ucode_boot = rspbootTextStart;
gGfxTask->task.t.ucode_boot_size = (uintptr_t) rspbootTextEnd - (uintptr_t) rspbootTextStart;
gGfxTask->task.t.ucode = gspF3DEX_fifoTextStart;
gGfxTask->task.t.ucode_size = SP_UCODE_SIZE;
gGfxTask->task.t.ucode_data = (u64*) &gspF3DEX_fifoDataStart;
gGfxTask->task.t.ucode_data_size = SP_UCODE_DATA_SIZE;
gGfxTask->task.t.dram_stack = gDramStack;
gGfxTask->task.t.dram_stack_size = SP_DRAM_STACK_SIZE8;
gGfxTask->task.t.output_buff = (u64*) gTaskOutputBuffer;
gGfxTask->task.t.output_buff_size = (u64*) gAudioHeap;
gGfxTask->task.t.data_ptr = (u64*) gGfxPool->masterDL;
gGfxTask->task.t.data_size = (gMasterDisp - gGfxPool->masterDL) * sizeof(Gfx);
gGfxTask->task.t.yield_data_ptr = (u64*) &gOSYieldData;
gGfxTask->task.t.yield_data_size = OS_YIELD_DATA_SIZE;
osWritebackDCacheAll();
osSendMesg(&gTaskMsgQueue, gGfxTask, OS_MESG_PRI_NORMAL);
}
void Graphics_InitializeTask(u32 frameCount) {
gGfxPool = &gGfxPools[frameCount % 2];
gGfxTask = &gGfxPool->task;
gViewport = gGfxPool->viewports;
gGfxMtx = gGfxPool->mtx;
gUnkDisp1 = gGfxPool->unkDL1;
gMasterDisp = gGfxPool->masterDL;
gUnkDisp2 = gGfxPool->unkDL2;
gLight = gGfxPool->lights;
gFrameBuffer = &gFrameBuffers[frameCount % 3];
gTextureRender = &gTextureRenderBuffer[0];
gGfxMatrix = &sGfxMatrixStack[0];
gCalcMatrix = &sCalcMatrixStack[0];
D_80178710 = &D_80178580[0];
}
void Main_SetVIMode(void) {
if ((gControllerHold[0].button & D_JPAD) && (gControllerHold[1].button & D_JPAD) &&
(gControllerHold[2].button & D_JPAD) && (gControllerHold[3].button & L_TRIG) &&
(gControllerHold[3].button & R_TRIG) && (gControllerHold[3].button & Z_TRIG)) {
sGammaMode = 1 - sGammaMode;
}
switch (osTvType) {
case OS_TV_PAL:
osViSetMode(&osViModePalLan1);
break;
case OS_TV_MPAL:
osViSetMode(&osViModeMpalLan1);
break;
default:
case OS_TV_NTSC:
osViSetMode(&osViModeNtscLan1);
break;
}
if (sGammaMode != 0) {
osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_DIVOT_OFF | OS_VI_GAMMA_ON | OS_VI_GAMMA_DITHER_ON);
} else {
osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_DIVOT_OFF | OS_VI_GAMMA_OFF | OS_VI_GAMMA_DITHER_OFF);
}
}
void SerialInterface_ThreadEntry(void* arg0) {
OSMesg sp34;
Controller_Init();
while (1) {
osRecvMesg(&gSerialThreadMsgQueue, &sp34, OS_MESG_BLOCK);
switch ((s32) sp34) {
case SI_READ_CONTROLLER:
Controller_ReadData();
break;
case SI_READ_SAVE:
Save_ReadData();
break;
case SI_WRITE_SAVE:
Save_WriteData();
break;
case SI_RUMBLE:
Controller_Rumble();
break;
}
}
}
void Timer_ThreadEntry(void* arg0) {
void* sp24;
while (1) {
osRecvMesg(&gTimerTaskMsgQueue, &sp24, OS_MESG_BLOCK);
Timer_CompleteTask(sp24);
}
}
void Graphics_ThreadEntry(void* arg0) {
u8 i;
u8 var_v1;
u8 var_v2;
Game_Initialize();
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_PRI_NORMAL);
Graphics_InitializeTask(gSysFrameCount);
{
gSPSegment(gUnkDisp1++, 0, 0);
gSPDisplayList(gMasterDisp++, gGfxPool->unkDL1);
Game_Update();
gSPEndDisplayList(gUnkDisp1++);
gSPEndDisplayList(gUnkDisp2++);
gSPDisplayList(gMasterDisp++, gGfxPool->unkDL2);
gDPFullSync(gMasterDisp++);
gSPEndDisplayList(gMasterDisp++);
}
Graphics_SetTask();
while (1) {
gSysFrameCount++;
Graphics_InitializeTask(gSysFrameCount);
osRecvMesg(&gControllerMsgQueue, NULL, OS_MESG_BLOCK);
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_RUMBLE, OS_MESG_PRI_NORMAL);
Controller_UpdateInput();
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_PRI_NORMAL);
if (gControllerPress[3].button & U_JPAD) {
Main_SetVIMode();
}
{
gSPSegment(gUnkDisp1++, 0, 0);
gSPDisplayList(gMasterDisp++, gGfxPool->unkDL1);
Game_Update();
if (gStartNMI == 1) {
Graphics_NMIWipe();
}
gSPEndDisplayList(gUnkDisp1++);
gSPEndDisplayList(gUnkDisp2++);
gSPDisplayList(gMasterDisp++, gGfxPool->unkDL2);
gDPFullSync(gMasterDisp++);
gSPEndDisplayList(gMasterDisp++);
}
osRecvMesg(&gGfxTaskMsgQueue, NULL, OS_MESG_BLOCK);
Graphics_SetTask();
if (gFillScreen == 0) {
osViSwapBuffer(&gFrameBuffers[(gSysFrameCount - 1) % 3]);
}
func_80007FE4(&gFrameBuffers[(gSysFrameCount - 1) % 3], SCREEN_WIDTH, 16);
var_v1 = MIN(D_80137E78, 4);
var_v2 = MAX(var_v1, gGfxVImsgQueue.validCount + 1);
for (i = 0; i < var_v2; i += 1) { // Can't be ++
osRecvMesg(&gGfxVImsgQueue, NULL, OS_MESG_BLOCK);
}
Audio_Update();
}
}
void Main_InitMesgQueues(void) {
osCreateMesgQueue(&gDmaMsgQueue, sDmaMsgBuff, ARRAY_COUNT(sDmaMsgBuff));
osCreateMesgQueue(&gTaskMsgQueue, sTaskMsgBuff, ARRAY_COUNT(sTaskMsgBuff));
osCreateMesgQueue(&gAudioVImsgQueue, sAudioVImsgBuff, ARRAY_COUNT(sAudioVImsgBuff));
osCreateMesgQueue(&gAudioTaskMsgQueue, sAudioTaskMsgBuff, ARRAY_COUNT(sAudioTaskMsgBuff));
osCreateMesgQueue(&gGfxVImsgQueue, sGfxVImsgBuff, ARRAY_COUNT(sGfxVImsgBuff));
osCreateMesgQueue(&gGfxTaskMsgQueue, sGfxTaskMsgBuff, ARRAY_COUNT(sGfxTaskMsgBuff));
osCreateMesgQueue(&gSerialEventQueue, sSerialEventBuff, ARRAY_COUNT(sSerialEventBuff));
osSetEventMesg(OS_EVENT_SI, &gSerialEventQueue, NULL);
osCreateMesgQueue(&gMainThreadMsgQueue, sMainThreadMsgBuff, ARRAY_COUNT(sMainThreadMsgBuff));
osViSetEvent(&gMainThreadMsgQueue, (OSMesg) EVENT_MESG_VI, 1);
osSetEventMesg(OS_EVENT_SP, &gMainThreadMsgQueue, (OSMesg) EVENT_MESG_SP);
osSetEventMesg(OS_EVENT_DP, &gMainThreadMsgQueue, (OSMesg) EVENT_MESG_DP);
osSetEventMesg(OS_EVENT_PRENMI, &gMainThreadMsgQueue, (OSMesg) EVENT_MESG_PRENMI);
osCreateMesgQueue(&gTimerTaskMsgQueue, sTimerTaskMsgBuff, ARRAY_COUNT(sTimerTaskMsgBuff));
osCreateMesgQueue(&gTimerWaitMsgQueue, sTimerWaitMsgBuff, ARRAY_COUNT(sTimerWaitMsgBuff));
osCreateMesgQueue(&gSerialThreadMsgQueue, sSerialThreadMsgBuff, ARRAY_COUNT(sSerialThreadMsgBuff));
osCreateMesgQueue(&gControllerMsgQueue, sControllerMsgBuff, ARRAY_COUNT(sControllerMsgBuff));
osCreateMesgQueue(&gSaveMsgQueue, sSaveMsgBuff, ARRAY_COUNT(sSaveMsgBuff));
}
void Main_HandleRDP(void) {
SPTask** var_v1 = sGfxTasks;
u8 i;
if ((*var_v1)->msgQueue != NULL) {
osSendMesg((*var_v1)->msgQueue, (*var_v1)->msg, OS_MESG_PRI_NORMAL);
}
(*var_v1)->state = SPTASK_STATE_FINISHED_DP;
for (i = 0; i < ARRAY_COUNT(sGfxTasks) - 1; i += 1, var_v1++) {
*var_v1 = *(var_v1 + 1);
}
*var_v1 = NULL;
}
void Main_HandleRSP(void) {
SPTask* task = gCurrentTask;
gCurrentTask = NULL;
if (task->state == SPTASK_STATE_INTERRUPTED) {
if (osSpTaskYielded(&task->task) == 0) {
task->state = SPTASK_STATE_FINISHED;
}
} else {
task->state = SPTASK_STATE_FINISHED;
if (task->task.t.type == M_AUDTASK) {
if (task->msgQueue != NULL) {
osSendMesg(task->msgQueue, task->msg, OS_MESG_PRI_NORMAL);
}
sAudioTasks[0] = NULL;
}
}
}
void Main_GetNewTasks(void) {
u8 i;
SPTask** var_a0;
SPTask** var_a1;
SPTask** var_s0_2;
SPTask** var_s1_2;
OSMesg sp40;
SPTask* sp3C;
var_s0_2 = sNewAudioTasks;
var_s1_2 = sNewGfxTasks;
for (i = 0; i < ARRAY_COUNT(sNewAudioTasks); i += 1) {
*(var_s0_2++) = NULL;
}
for (i = 0; i < ARRAY_COUNT(sNewGfxTasks); i += 1) {
*(var_s1_2++) = NULL;
}
var_s0_2 = sNewAudioTasks;
var_s1_2 = sNewGfxTasks;
while (osRecvMesg(&gTaskMsgQueue, &sp40, OS_MESG_NOBLOCK) != MSG_QUEUE_EMPTY) {
sp3C = (SPTask*) sp40;
sp3C->state = SPTASK_STATE_NOT_STARTED;
switch (sp3C->task.t.type) {
case M_AUDTASK:
*(var_s0_2++) = sp3C;
break;
case M_GFXTASK:
*(var_s1_2++) = sp3C;
break;
}
}
var_s0_2 = sNewAudioTasks;
var_s1_2 = sNewGfxTasks;
var_a0 = sAudioTasks;
var_a1 = sGfxTasks;
for (i = 0; i < ARRAY_COUNT(sAudioTasks); i += 1, var_a0++) {
if (*var_a0 == NULL) {
break;
}
}
for (i; i < ARRAY_COUNT(sAudioTasks); i += 1) {
*(var_a0++) = *(var_s0_2++);
}
for (i = 0; i < ARRAY_COUNT(sGfxTasks); i += 1, var_a1++) {
if (*var_a1 == NULL) {
break;
}
}
for (i; i < ARRAY_COUNT(sGfxTasks); i += 1) {
*(var_a1++) = *(var_s1_2++);
}
}
void Main_StartNextTask(void) {
if (sAudioTasks[0] != NULL) {
if (gCurrentTask != NULL) {
if (gCurrentTask->task.t.type == M_GFXTASK) {
gCurrentTask->state = SPTASK_STATE_INTERRUPTED;
osSpTaskYield();
}
} else {
gCurrentTask = sAudioTasks[0];
osSpTaskLoad(&gCurrentTask->task);
osSpTaskStartGo(&gCurrentTask->task);
gCurrentTask->state = SPTASK_STATE_RUNNING;
}
} else if ((gCurrentTask == NULL) && (sGfxTasks[0] != NULL) && (sGfxTasks[0]->state != SPTASK_STATE_FINISHED)) {
gCurrentTask = sGfxTasks[0];
osDpSetStatus(DPC_CLR_TMEM_CTR | DPC_CLR_PIPE_CTR | DPC_CLR_CMD_CTR | DPC_CLR_CLOCK_CTR);
osSpTaskLoad(&gCurrentTask->task);
osSpTaskStartGo(&gCurrentTask->task);
gCurrentTask->state = SPTASK_STATE_RUNNING;
}
}
void Main_ThreadEntry(void* arg0) {
OSMesg ogMsg;
u8 mesg;
osCreateThread(&gAudioThread, THREAD_ID_AUDIO, Audio_ThreadEntry, arg0,
gAudioThreadStack + sizeof(gAudioThreadStack), 80);
osStartThread(&gAudioThread);
osCreateThread(&gGraphicsThread, THREAD_ID_GRAPHICS, Graphics_ThreadEntry, arg0,
gGraphicsThreadStack + sizeof(gGraphicsThreadStack), 40);
osStartThread(&gGraphicsThread);
osCreateThread(&gTimerThread, THREAD_ID_TIMER, Timer_ThreadEntry, arg0,
gTimerThreadStack + sizeof(gTimerThreadStack), 60);
osStartThread(&gTimerThread);
osCreateThread(&gSerialThread, THREAD_ID_SERIAL, SerialInterface_ThreadEntry, arg0,
gSerialThreadStack + sizeof(gSerialThreadStack), 20);
osStartThread(&gSerialThread);
Main_InitMesgQueues();
while (true) {
osRecvMesg(&gMainThreadMsgQueue, &ogMsg, OS_MESG_BLOCK);
mesg = (u32) ogMsg;
switch (mesg) {
case EVENT_MESG_VI:
osSendMesg(&gAudioVImsgQueue, (OSMesg) EVENT_MESG_VI, OS_MESG_PRI_NORMAL);
osSendMesg(&gGfxVImsgQueue, (OSMesg) EVENT_MESG_VI, OS_MESG_PRI_NORMAL);
Main_GetNewTasks();
break;
case EVENT_MESG_SP:
Main_HandleRSP();
break;
case EVENT_MESG_DP:
Main_HandleRDP();
break;
case EVENT_MESG_PRENMI:
gStartNMI = 1;
break;
}
if (gStopTasks == 0) {
Main_StartNextTask();
}
}
}
void Idle_ThreadEntry(void* arg0) {
osCreateViManager(OS_PRIORITY_VIMGR);
Main_SetVIMode();
Lib_FillScreen(1);
osCreatePiManager(OS_PRIORITY_PIMGR, &gPiMgrCmdQueue, sPiMgrCmdBuff, ARRAY_COUNT(sPiMgrCmdBuff));
osCreateThread(&gMainThread, THREAD_ID_MAIN, &Main_ThreadEntry, arg0, sMainThreadStack + sizeof(sMainThreadStack),
100);
osStartThread(&gMainThread);
Fault_Init();
osSetThreadPri(NULL, OS_PRIORITY_IDLE);
loop_1:
goto loop_1;
}
void bootproc(void) {
RdRam_CheckIPL3();
osInitialize();
Main_Initialize();
osCreateThread(&sIdleThread, THREAD_ID_IDLE, &Idle_ThreadEntry, NULL, sIdleThreadStack + sizeof(sIdleThreadStack),
255);
osStartThread(&sIdleThread);
}
+185
View File
@@ -0,0 +1,185 @@
#include "sys.h"
s32 sSeededRandSeed3;
s32 sRandSeed1;
s32 sRandSeed2;
s32 sRandSeed3;
s32 sSeededRandSeed1;
s32 sSeededRandSeed2;
f32 Math_ModF(f32 value, f32 mod) {
return value - ((s32) (value / mod) * mod);
}
void Rand_Init(void) {
sRandSeed1 = (s32) osGetTime() % 30000;
sRandSeed2 = (s32) osGetTime() % 30000;
sRandSeed3 = (s32) osGetTime() % 30000;
}
f32 Rand_ZeroOne(void) {
sRandSeed1 = (sRandSeed1 * 171) % 30269;
sRandSeed2 = (sRandSeed2 * 172) % 30307;
sRandSeed3 = (sRandSeed3 * 170) % 30323;
return fabsf(Math_ModF((sRandSeed1 / 30269.0f) + (sRandSeed2 / 30307.0f) + (sRandSeed3 / 30323.0f), 1.0f));
}
void Rand_SetSeed(s32 seed1, s32 seed2, s32 seed3) {
sSeededRandSeed1 = seed1;
sSeededRandSeed2 = seed2;
sSeededRandSeed3 = seed3;
}
f32 Rand_ZeroOneSeeded(void) {
sSeededRandSeed1 = (sSeededRandSeed1 * 171) % 30269;
sSeededRandSeed2 = (sSeededRandSeed2 * 172) % 30307;
sSeededRandSeed3 = (sSeededRandSeed3 * 170) % 30323;
return fabsf(
Math_ModF((sSeededRandSeed1 / 30269.0f) + (sSeededRandSeed2 / 30307.0f) + (sSeededRandSeed3 / 30323.0f), 1.0f));
}
f32 Math_Atan2F(f32 y, f32 x) {
if ((y == 0.0f) && (x == 0.0f)) {
return 0.0f;
}
if (x == 0.0f) {
if (y < 0.0f) {
return -M_PI / 2.0f;
} else {
return M_PI / 2.0f;
}
}
if (x < 0.0f) {
if (y < 0.0f) {
return -(M_PI - Math_FAtanF(fabs(y / x)));
} else {
return M_PI - Math_FAtanF(fabs(y / x));
}
} else {
return Math_FAtanF(y / x);
}
}
f32 Math_Atan2F_XY(f32 x, f32 y) {
if ((x == 0.0f) && (y == 0.0f)) {
return 0.0f;
}
if (x == 0.0f) {
if (y < 0.0f) {
return -M_PI / 2.0f;
} else {
return M_PI / 2.0f;
}
}
if (y == 0.0f) {
if (x > 0.0f) {
return 0.0f;
} else {
return M_PI;
}
}
if (x < 0.0f) {
if (y < 0.0f) {
return -(M_PI - Math_FAtanF(fabs(x / y)));
} else {
return M_PI - Math_FAtanF(fabs(x / y));
}
} else {
return Math_FAtanF(x / y);
}
}
f32 Math_Atan2F_XYAlt(f32 x, f32 y) {
if ((x == 0.0f) && (y == 0.0f)) {
return 0.0f;
}
if (x == 0.0f) {
if (y < 0.0f) {
return -M_PI / 2.0f;
}
return M_PI / 2.0f;
}
if (y == 0.0f) {
return 0.0f;
}
return -Math_FAtanF(x / y);
}
f32 Math_FactorialF(f32 n) {
f32 out = 1.0f;
s32 i;
for (i = (s32) n; i > 1; i--) {
out *= i;
}
return out;
}
f32 D_800C45E0[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600 };
f32 Math_Factorial(s32 n) {
f32 out;
s32 i;
if (n > 12) {
out = 1.0f;
for (i = n; i > 1; i--) {
out *= i;
}
} else {
out = D_800C45E0[n];
}
return out;
}
f32 Math_PowF(f32 base, s32 exp) {
f32 out = 1.0f;
while (exp > 0) {
exp--;
out *= base;
}
return out;
}
void Math_MinMax(s32* min, s32* max, s32 val1, s32 val2, s32 val3) {
if (val1 < val2) {
if (val2 < val3) {
*min = val1;
*max = val3;
return;
}
*max = val2;
if (val1 < val3) {
*min = val1;
return;
}
*min = val3;
return;
}
if (val1 < val3) {
*min = val2;
*max = val3;
return;
}
*max = val1;
if (val2 < val3) {
*min = val2;
return;
}
*min = val3;
}
+513
View File
@@ -0,0 +1,513 @@
#include "sys.h"
Mtx gIdentityMtx = { {
{
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 },
},
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
} };
Matrix gIdentityMatrix = { {
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
} };
Matrix* gGfxMatrix;
Matrix sGfxMatrixStack[0x20];
Matrix* gCalcMatrix;
Matrix sCalcMatrixStack[0x20];
// Copies src Matrix into dst
void Matrix_Copy(Matrix* dst, Matrix* src) {
s32 i;
for (i = 0; i < 4; i++) {
dst->m[i][0] = src->m[i][0];
dst->m[i][1] = src->m[i][1];
dst->m[i][2] = src->m[i][2];
dst->m[i][3] = src->m[i][3];
}
}
// Makes a copy of the stack's current matrix and puts it on the top of the stack
void Matrix_Push(Matrix** mtxStack) {
Matrix_Copy(*mtxStack + 1, *mtxStack);
*mtxStack += 1;
}
// Removes the top matrix of the stack
void Matrix_Pop(Matrix** mtxStack) {
*mtxStack -= 1;
}
// Copies tf into mtx (MTXMODE_NEW) or applies it to mtx (MTXMODE_APPLY)
void Matrix_Mult(Matrix* mtx, Matrix* tf, u8 mode) {
f32 rx;
f32 ry;
f32 rz;
f32 rw;
s32 i0;
s32 i1;
s32 i2;
s32 i3;
if (mode == 1) {
rx = mtx->m[0][0];
ry = mtx->m[1][0];
rz = mtx->m[2][0];
rw = mtx->m[3][0];
for (i0 = 0; i0 < 4; i0++) {
mtx->m[i0][0] = (rx * tf->m[i0][0]) + (ry * tf->m[i0][1]) + (rz * tf->m[i0][2]) + (rw * tf->m[i0][3]);
}
rx = mtx->m[0][1];
ry = mtx->m[1][1];
rz = mtx->m[2][1];
rw = mtx->m[3][1];
for (i1 = 0; i1 < 4; i1++) {
mtx->m[i1][1] = (rx * tf->m[i1][0]) + (ry * tf->m[i1][1]) + (rz * tf->m[i1][2]) + (rw * tf->m[i1][3]);
}
rx = mtx->m[0][2];
ry = mtx->m[1][2];
rz = mtx->m[2][2];
rw = mtx->m[3][2];
for (i2 = 0; i2 < 4; i2++) {
mtx->m[i2][2] = (rx * tf->m[i2][0]) + (ry * tf->m[i2][1]) + (rz * tf->m[i2][2]) + (rw * tf->m[i2][3]);
}
rx = mtx->m[0][3];
ry = mtx->m[1][3];
rz = mtx->m[2][3];
rw = mtx->m[3][3];
for (i3 = 0; i3 < 4; i3++) {
mtx->m[i3][3] = (rx * tf->m[i3][0]) + (ry * tf->m[i3][1]) + (rz * tf->m[i3][2]) + (rw * tf->m[i3][3]);
}
} else {
Matrix_Copy(mtx, tf);
}
}
// Creates a translation matrix in mtx (MTXMODE_NEW) or applies one to mtx (MTXMODE_APPLY)
void Matrix_Translate(Matrix* mtx, f32 x, f32 y, f32 z, u8 mode) {
f32 rx;
f32 ry;
s32 i;
if (mode == 1) {
for (i = 0; i < 4; i++) {
rx = mtx->m[0][i];
ry = mtx->m[1][i];
mtx->m[3][i] += (rx * x) + (ry * y) + (mtx->m[2][i] * z);
}
} else {
mtx->m[3][0] = x;
mtx->m[3][1] = y;
mtx->m[3][2] = z;
mtx->m[0][1] = mtx->m[0][2] = mtx->m[0][3] = mtx->m[1][0] = mtx->m[1][2] = mtx->m[1][3] = mtx->m[2][0] =
mtx->m[2][1] = mtx->m[2][3] = 0.0f;
mtx->m[0][0] = mtx->m[1][1] = mtx->m[2][2] = mtx->m[3][3] = 1.0f;
}
}
// Creates a scale matrix in mtx (MTXMODE_NEW) or applies one to mtx (MTXMODE_APPLY)
void Matrix_Scale(Matrix* mtx, f32 xScale, f32 yScale, f32 zScale, u8 mode) {
f32 rx;
f32 ry;
s32 i;
if (mode == 1) {
for (i = 0; i < 4; i++) {
rx = mtx->m[0][i];
ry = mtx->m[1][i];
mtx->m[0][i] = rx * xScale;
mtx->m[1][i] = ry * yScale;
mtx->m[2][i] *= zScale;
}
} else {
mtx->m[0][0] = xScale;
mtx->m[1][1] = yScale;
mtx->m[2][2] = zScale;
mtx->m[0][1] = mtx->m[0][2] = mtx->m[0][3] = mtx->m[1][0] = mtx->m[1][2] = mtx->m[1][3] = mtx->m[2][0] =
mtx->m[2][1] = mtx->m[2][3] = mtx->m[3][0] = mtx->m[3][1] = mtx->m[3][2] = 0.0f;
mtx->m[3][3] = 1.0f;
}
}
// Creates rotation matrix about the X axis in mtx (MTXMODE_NEW) or applies one to mtx (MTXMODE_APPLY)
void Matrix_RotateX(Matrix* mtx, f32 angle, u8 mode) {
f32 cs;
f32 sn;
f32 ry;
f32 rz;
s32 i;
sn = __sinf(angle);
cs = __cosf(angle);
if (mode == 1) {
for (i = 0; i < 4; i++) {
ry = mtx->m[1][i];
rz = mtx->m[2][i];
mtx->m[1][i] = (ry * cs) + (rz * sn);
mtx->m[2][i] = (rz * cs) - (ry * sn);
}
} else {
mtx->m[1][1] = mtx->m[2][2] = cs;
mtx->m[1][2] = sn;
mtx->m[2][1] = -sn;
mtx->m[0][0] = mtx->m[3][3] = 1.0f;
mtx->m[0][1] = mtx->m[0][2] = mtx->m[0][3] = mtx->m[1][0] = mtx->m[1][3] = mtx->m[2][0] = mtx->m[2][3] =
mtx->m[3][0] = mtx->m[3][1] = mtx->m[3][2] = 0.0f;
}
}
// Creates rotation matrix about the Y axis in mtx (MTXMODE_NEW) or applies one to mtx (MTXMODE_APPLY)
void Matrix_RotateY(Matrix* mtx, f32 angle, u8 mode) {
f32 cs;
f32 sn;
f32 rx;
f32 rz;
s32 i;
sn = __sinf(angle);
cs = __cosf(angle);
if (mode == 1) {
for (i = 0; i < 4; i++) {
rx = mtx->m[0][i];
rz = mtx->m[2][i];
mtx->m[0][i] = (rx * cs) - (rz * sn);
mtx->m[2][i] = (rx * sn) + (rz * cs);
}
} else {
mtx->m[0][0] = mtx->m[2][2] = cs;
mtx->m[0][2] = -sn;
mtx->m[2][0] = sn;
mtx->m[1][1] = mtx->m[3][3] = 1.0f;
mtx->m[0][1] = mtx->m[0][3] = mtx->m[1][0] = mtx->m[1][2] = mtx->m[1][3] = mtx->m[2][1] = mtx->m[2][3] =
mtx->m[3][0] = mtx->m[3][1] = mtx->m[3][2] = 0.0f;
}
}
// Creates rotation matrix about the Z axis in mtx (MTXMODE_NEW) or applies one to mtx (MTXMODE_APPLY)
void Matrix_RotateZ(Matrix* mtx, f32 angle, u8 mode) {
f32 cs;
f32 sn;
f32 rx;
f32 ry;
s32 i;
sn = __sinf(angle);
cs = __cosf(angle);
if (mode == 1) {
for (i = 0; i < 4; i++) {
rx = mtx->m[0][i];
ry = mtx->m[1][i];
mtx->m[0][i] = (rx * cs) + (ry * sn);
mtx->m[1][i] = (ry * cs) - (rx * sn);
}
} else {
mtx->m[0][0] = mtx->m[1][1] = cs;
mtx->m[0][1] = sn;
mtx->m[1][0] = -sn;
mtx->m[2][2] = mtx->m[3][3] = 1.0f;
mtx->m[0][2] = mtx->m[0][3] = mtx->m[1][2] = mtx->m[1][3] = mtx->m[2][0] = mtx->m[2][1] = mtx->m[2][3] =
mtx->m[3][0] = mtx->m[3][1] = mtx->m[3][2] = 0.0f;
}
}
// Creates rotation matrix about a given vector axis in mtx (MTXMODE_NEW) or applies one to mtx (MTXMODE_APPLY).
// The vector specifying the axis does not need to be a unit vector.
void Matrix_RotateAxis(Matrix* mtx, f32 angle, f32 axisX, f32 axisY, f32 axisZ, u8 mode) {
f32 rx;
f32 ry;
f32 rz;
f32 norm;
f32 cxx;
f32 cyx;
f32 czx;
f32 cxy;
f32 cyy;
f32 czy;
f32 cxz;
f32 cyz;
f32 czz;
f32 xx;
f32 yy;
f32 zz;
f32 xy;
f32 yz;
f32 xz;
f32 sinA;
f32 cosA;
norm = sqrtf((axisX * axisX) + (axisY * axisY) + (axisZ * axisZ));
if (norm != 0.0) {
axisX /= norm;
axisY /= norm;
axisZ /= norm;
sinA = __sinf(angle);
cosA = __cosf(angle);
xx = axisX * axisX;
yy = axisY * axisY;
zz = axisZ * axisZ;
xy = axisX * axisY;
yz = axisY * axisZ;
xz = axisX * axisZ;
if (mode == 1) {
cxx = (1.0f - xx) * cosA + xx;
cyx = (1.0f - cosA) * xy + axisZ * sinA;
czx = (1.0f - cosA) * xz - axisY * sinA;
cxy = (1.0f - cosA) * xy - axisZ * sinA;
cyy = (1.0f - yy) * cosA + yy;
czy = (1.0f - cosA) * yz + axisX * sinA;
cxz = (1.0f - cosA) * xz + axisY * sinA;
cyz = (1.0f - cosA) * yz - axisX * sinA;
czz = (1.0f - zz) * cosA + zz;
// loop doesn't seem to work here.
rx = mtx->m[0][0];
ry = mtx->m[0][1];
rz = mtx->m[0][2];
mtx->m[0][0] = (rx * cxx) + (ry * cxy) + (rz * cxz);
mtx->m[0][1] = (rx * cyx) + (ry * cyy) + (rz * cyz);
mtx->m[0][2] = (rx * czx) + (ry * czy) + (rz * czz);
rx = mtx->m[1][0];
ry = mtx->m[1][1];
rz = mtx->m[1][2];
mtx->m[1][0] = (rx * cxx) + (ry * cxy) + (rz * cxz);
mtx->m[1][1] = (rx * cyx) + (ry * cyy) + (rz * cyz);
mtx->m[1][2] = (rx * czx) + (ry * czy) + (rz * czz);
rx = mtx->m[2][0];
ry = mtx->m[2][1];
rz = mtx->m[2][2];
mtx->m[2][0] = (rx * cxx) + (ry * cxy) + (rz * cxz);
mtx->m[2][1] = (rx * cyx) + (ry * cyy) + (rz * cyz);
mtx->m[2][2] = (rx * czx) + (ry * czy) + (rz * czz);
} else {
mtx->m[0][0] = (1.0f - xx) * cosA + xx;
mtx->m[0][1] = (1.0f - cosA) * xy + axisZ * sinA;
mtx->m[0][2] = (1.0f - cosA) * xz - axisY * sinA;
mtx->m[0][3] = 0.0f;
mtx->m[1][0] = (1.0f - cosA) * xy - axisZ * sinA;
mtx->m[1][1] = (1.0f - yy) * cosA + yy;
mtx->m[1][2] = (1.0f - cosA) * yz + axisX * sinA;
mtx->m[1][3] = 0.0f;
mtx->m[2][0] = (1.0f - cosA) * xz + axisY * sinA;
mtx->m[2][1] = (1.0f - cosA) * yz - axisX * sinA;
mtx->m[2][2] = (1.0f - zz) * cosA + zz;
mtx->m[2][3] = 0.0f;
mtx->m[3][0] = mtx->m[3][1] = mtx->m[3][2] = 0.0f;
mtx->m[3][3] = 1.0f;
}
}
}
// Converts the current Gfx matrix to a Mtx
void Matrix_ToMtx(Mtx* dest) {
s32 intVal;
u16(*iPart)[4] = dest->u.i;
u16(*fPart)[4] = dest->u.f;
Matrix* src = gGfxMatrix;
intVal = src->m[0][0] * 0x10000;
iPart[0][0] = intVal >> 0x10;
fPart[0][0] = intVal % 0x10000U;
intVal = src->m[0][1] * 0x10000;
iPart[0][1] = intVal >> 0x10;
fPart[0][1] = intVal % 0x10000U;
intVal = src->m[0][2] * 0x10000;
iPart[0][2] = intVal >> 0x10;
fPart[0][2] = intVal % 0x10000U;
intVal = src->m[0][3] * 0x10000;
iPart[0][3] = intVal >> 0x10;
fPart[0][3] = intVal % 0x10000U;
intVal = src->m[1][0] * 0x10000;
iPart[1][0] = intVal >> 0x10;
fPart[1][0] = intVal % 0x10000U;
intVal = src->m[1][1] * 0x10000;
iPart[1][1] = intVal >> 0x10;
fPart[1][1] = intVal % 0x10000U;
intVal = src->m[1][2] * 0x10000;
iPart[1][2] = intVal >> 0x10;
fPart[1][2] = intVal % 0x10000U;
intVal = src->m[1][3] * 0x10000;
iPart[1][3] = intVal >> 0x10;
fPart[1][3] = intVal % 0x10000U;
intVal = src->m[2][0] * 0x10000;
iPart[2][0] = intVal >> 0x10;
fPart[2][0] = intVal % 0x10000U;
intVal = src->m[2][1] * 0x10000;
iPart[2][1] = intVal >> 0x10;
fPart[2][1] = intVal % 0x10000U;
intVal = src->m[2][2] * 0x10000;
iPart[2][2] = intVal >> 0x10;
fPart[2][2] = intVal % 0x10000U;
intVal = src->m[2][3] * 0x10000;
iPart[2][3] = intVal >> 0x10;
fPart[2][3] = intVal % 0x10000U;
intVal = src->m[3][0] * 0x10000;
iPart[3][0] = intVal >> 0x10;
fPart[3][0] = intVal % 0x10000U;
intVal = src->m[3][1] * 0x10000;
iPart[3][1] = intVal >> 0x10;
fPart[3][1] = intVal % 0x10000U;
intVal = src->m[3][2] * 0x10000;
iPart[3][2] = intVal >> 0x10;
fPart[3][2] = intVal % 0x10000U;
intVal = src->m[3][3] * 0x10000;
iPart[3][3] = intVal >> 0x10;
fPart[3][3] = intVal % 0x10000U;
}
// Converts the Mtx src to a Matrix, putting the result in dest
void Matrix_FromMtx(Mtx* src, Matrix* dest) {
dest->m[0][0] = ((src->u.i[0][0] << 0x10) | src->u.f[0][0]) * (1.0f / 0x10000);
dest->m[0][1] = ((src->u.i[0][1] << 0x10) | src->u.f[0][1]) * (1.0f / 0x10000);
dest->m[0][2] = ((src->u.i[0][2] << 0x10) | src->u.f[0][2]) * (1.0f / 0x10000);
dest->m[0][3] = ((src->u.i[0][3] << 0x10) | src->u.f[0][3]) * (1.0f / 0x10000);
dest->m[1][0] = ((src->u.i[1][0] << 0x10) | src->u.f[1][0]) * (1.0f / 0x10000);
dest->m[1][1] = ((src->u.i[1][1] << 0x10) | src->u.f[1][1]) * (1.0f / 0x10000);
dest->m[1][2] = ((src->u.i[1][2] << 0x10) | src->u.f[1][2]) * (1.0f / 0x10000);
dest->m[1][3] = ((src->u.i[1][3] << 0x10) | src->u.f[1][3]) * (1.0f / 0x10000);
dest->m[2][0] = ((src->u.i[2][0] << 0x10) | src->u.f[2][0]) * (1.0f / 0x10000);
dest->m[2][1] = ((src->u.i[2][1] << 0x10) | src->u.f[2][1]) * (1.0f / 0x10000);
dest->m[2][2] = ((src->u.i[2][2] << 0x10) | src->u.f[2][2]) * (1.0f / 0x10000);
dest->m[2][3] = ((src->u.i[2][3] << 0x10) | src->u.f[2][3]) * (1.0f / 0x10000);
dest->m[3][0] = ((src->u.i[3][0] << 0x10) | src->u.f[3][0]) * (1.0f / 0x10000);
dest->m[3][1] = ((src->u.i[3][1] << 0x10) | src->u.f[3][1]) * (1.0f / 0x10000);
dest->m[3][2] = ((src->u.i[3][2] << 0x10) | src->u.f[3][2]) * (1.0f / 0x10000);
dest->m[3][3] = ((src->u.i[3][3] << 0x10) | src->u.f[3][3]) * (1.0f / 0x10000);
}
// Applies the transform matrix mtx to the vector src, putting the result in dest
void Matrix_MultVec3f(Matrix* mtx, Vec3f* src, Vec3f* dest) {
dest->x = (mtx->m[0][0] * src->x) + (mtx->m[1][0] * src->y) + (mtx->m[2][0] * src->z) + mtx->m[3][0];
dest->y = (mtx->m[0][1] * src->x) + (mtx->m[1][1] * src->y) + (mtx->m[2][1] * src->z) + mtx->m[3][1];
dest->z = (mtx->m[0][2] * src->x) + (mtx->m[1][2] * src->y) + (mtx->m[2][2] * src->z) + mtx->m[3][2];
}
// Applies the linear part of the transformation matrix mtx to the vector src, ignoring any translation that mtx might
// have. Puts the result in dest.
void Matrix_MultVec3fNoTranslate(Matrix* mtx, Vec3f* src, Vec3f* dest) {
dest->x = (mtx->m[0][0] * src->x) + (mtx->m[1][0] * src->y) + (mtx->m[2][0] * src->z);
dest->y = (mtx->m[0][1] * src->x) + (mtx->m[1][1] * src->y) + (mtx->m[2][1] * src->z);
dest->z = (mtx->m[0][2] * src->x) + (mtx->m[1][2] * src->y) + (mtx->m[2][2] * src->z);
}
// Expresses the rotational part of the transform mtx as Tait-Bryan angles, in the yaw-pitch-roll (intrinsic YXZ)
// convention used in worldspace calculations
void Matrix_GetYRPAngles(Matrix* mtx, Vec3f* rot) {
Matrix invYP;
Vec3f origin = { 0.0f, 0.0f, 0.0f };
Vec3f originP;
Vec3f zHat = { 0.0f, 0.0f, 1.0f };
Vec3f zHatP;
Vec3f xHat = { 1.0f, 0.0f, 0.0f };
Vec3f xHatP;
Matrix_MultVec3fNoTranslate(mtx, &origin, &originP);
Matrix_MultVec3fNoTranslate(mtx, &zHat, &zHatP);
Matrix_MultVec3fNoTranslate(mtx, &xHat, &xHatP);
zHatP.x -= originP.x;
zHatP.y -= originP.y;
zHatP.z -= originP.z;
xHatP.x -= originP.x;
xHatP.y -= originP.y;
xHatP.z -= originP.z;
rot->y = Math_Atan2F(zHatP.x, zHatP.z);
rot->x = -Math_Atan2F(zHatP.y, sqrtf(SQ(zHatP.x) + SQ(zHatP.z)));
Matrix_RotateX(&invYP, -rot->x, 0);
Matrix_RotateY(&invYP, -rot->y, 1);
Matrix_MultVec3fNoTranslate(&invYP, &xHatP, &xHat);
rot->x *= M_RTOD;
rot->y *= M_RTOD;
rot->z = Math_Atan2F(xHat.y, xHat.x) * M_RTOD;
}
// Expresses the rotational part of the transform mtx as Tait-Bryan angles, in the extrinsic XYZ convention used in
// modelspace calculations
void Matrix_GetXYZAngles(Matrix* mtx, Vec3f* rot) {
Matrix invYZ;
Vec3f origin = { 0.0f, 0.0f, 0.0f };
Vec3f originP;
Vec3f xHat = { 1.0f, 0.0f, 0.0f };
Vec3f xHatP;
Vec3f yHat = { 0.0f, 1.0f, 0.0f };
Vec3f yHatP;
Matrix_MultVec3fNoTranslate(mtx, &origin, &originP);
Matrix_MultVec3fNoTranslate(mtx, &xHat, &xHatP);
Matrix_MultVec3fNoTranslate(mtx, &yHat, &yHatP);
xHatP.x -= originP.x;
xHatP.y -= originP.y;
xHatP.z -= originP.z;
yHatP.x -= originP.x;
yHatP.y -= originP.y;
yHatP.z -= originP.z;
rot->z = Math_Atan2F(xHatP.y, xHatP.x);
rot->y = -Math_Atan2F(xHatP.z, sqrtf(SQ(xHatP.x) + SQ(xHatP.y)));
Matrix_RotateY(&invYZ, -rot->y, 0);
Matrix_RotateZ(&invYZ, -rot->z, 1);
Matrix_MultVec3fNoTranslate(&invYZ, &yHatP, &yHat);
rot->x = Math_Atan2F(yHat.z, yHat.y) * M_RTOD;
rot->y *= M_RTOD;
rot->z *= M_RTOD;
}
// Creates a look-at matrix from Eye, At, and Up in mtx (MTXMODE_NEW) or applies one to mtx (MTXMODE_APPLY).
// A look-at matrix is a rotation-translation matrix that maps y to Up, z to (At - Eye), and translates to Eye
void Matrix_LookAt(Matrix* mtx, f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f32 xUp, f32 yUp, f32 zUp,
u8 mode) {
Matrix lookAt;
guLookAtF(lookAt.m, xEye, yEye, zEye, xAt, yAt, zAt, xUp, yUp, zUp);
Matrix_Mult(mtx, &lookAt, mode);
}
// Converts the current Gfx matrix to a Mtx and sets it to the display list
void Matrix_SetGfxMtx(Gfx** gfx) {
Matrix_ToMtx(gGfxMtx);
gSPMatrix((*gfx)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
}
+15
View File
@@ -0,0 +1,15 @@
#include "sys.h"
s32 sMemoryBuffer[0x2200];
s32* sMemoryPtr;
void Memory_FreeAll(void) {
sMemoryPtr = sMemoryBuffer;
}
void* Memory_Allocate(s32 size) {
void* addr = sMemoryPtr;
sMemoryPtr = (void*) (((size + 0xF) & ~0xF) + (uintptr_t) sMemoryPtr);
return addr;
}
+65
View File
@@ -0,0 +1,65 @@
#include "sys.h"
SaveFile gSaveIOBuffer;
SaveFile sPrevSaveData;
s32 Save_ReadBlock(s32 arg0, u8* arg1) {
if (osEepromRead(&gSerialEventQueue, arg0, arg1)) {
(void) "EEPROM インターフェース回路反応なし (READ)\n";
return -1;
}
(void) "EEPROM READ %02X: %02X %02X %02X %02X %02X %02X %02X %02X\n";
return 0;
}
s32 Save_WriteBlock(s32 arg0, u8* arg1) {
if (osEepromWrite(&gSerialEventQueue, arg0, arg1)) {
(void) "EEPROM インターフェース回路反応なし (WRITE)\n";
return -1;
}
Timer_Wait(MSEC_TO_CYCLES(15));
(void) "EEPROM WRITE %02X: %02X %02X %02X %02X %02X %02X %02X %02X\n";
return 0;
}
s32 Save_WriteEeprom(SaveFile* arg0) {
s32 var_a2;
s32 i;
s32 j;
if (osEepromProbe(&gSerialEventQueue) != 1) {
(void) "EEPROM が ありません\n";
return -1;
}
for (i = 0; i < EEPROM_MAXBLOCKS; i++) {
var_a2 = 0;
for (j = 0; j < EEPROM_BLOCK_SIZE; j++) {
if (((char*) &sPrevSaveData)[EEPROM_BLOCK_SIZE * i + j] != ((char*) arg0)[EEPROM_BLOCK_SIZE * i + j]) {
((char*) &sPrevSaveData)[EEPROM_BLOCK_SIZE * i + j] = ((char*) arg0)[EEPROM_BLOCK_SIZE * i + j];
var_a2 = 1;
}
}
if ((var_a2 == 1) && Save_WriteBlock(i, &((char*) arg0)[EEPROM_BLOCK_SIZE * i])) {
return -1;
}
}
return 0;
}
s32 Save_ReadEeprom(SaveFile* arg0) {
s32 i;
if (osEepromProbe(&gSerialEventQueue) != 1) {
(void) "EEPROM が ありません\n";
return -1;
}
for (i = 0; i < EEPROM_MAXBLOCKS; i++) {
if (Save_ReadBlock(i, &((char*) arg0)[EEPROM_BLOCK_SIZE * i]) != 0) {
return -1;
}
}
sPrevSaveData = *arg0;
return 0;
}
+50
View File
@@ -0,0 +1,50 @@
#include "sys.h"
TimerTask sTimerTasks[0x10];
TimerTask* Timer_AllocateTask(void) {
s32 i;
for (i = 0; i < 0x10; i++) {
if (!sTimerTasks[i].active) {
return &sTimerTasks[i];
}
}
return NULL;
}
s32 Timer_CreateTask(u64 time, TimerAction action, s32* address, s32 value) {
TimerTask* task = Timer_AllocateTask();
if (task == NULL) {
return -1;
}
task->active = true;
task->action = action;
task->address = address;
task->value = value;
return osSetTimer(&task->timer, time, 0, &gTimerTaskMsgQueue, task);
}
void Timer_Increment(s32* address, s32 value) {
*address += value;
}
void Timer_SetValue(s32* address, s32 value) {
*address = value;
}
void Timer_CompleteTask(TimerTask* task) {
if (task->action != NULL) {
task->action(task->address, task->value);
}
task->active = false;
}
void Timer_Wait(u64 time) {
OSTimer timer;
OSMesg dummy;
osSetTimer(&timer, time, 0, &gTimerWaitMsgQueue, NULL);
osRecvMesg(&gTimerWaitMsgQueue, &dummy, OS_MESG_BLOCK);
}