summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorengineer124 <engineer124engineer124@gmail.com>2021-11-17 16:22:01 +1100
committerengineer124 <engineer124engineer124@gmail.com>2021-11-17 16:22:01 +1100
commitc3c999764e52be55058fb2ddc8dfeac7d2a660c6 (patch)
tree22f7bbb03ba23f95956f99a9b3779fe15311b66a /src/code
parentcf7009b45c591d64926efc71240b1324c973385d (diff)
parent7134e81898d548266b8c45b389cf6a17b12a5105 (diff)
Merge branch 'master' into voice
Diffstat (limited to 'src/code')
-rw-r--r--src/code/code_800CB000.c3
-rw-r--r--src/code/sched.c6
-rw-r--r--src/code/sys_initial_check.c115
-rw-r--r--src/code/z_actor.c4
-rw-r--r--src/code/z_bg_collect.c12
-rw-r--r--src/code/z_bg_item.c146
6 files changed, 212 insertions, 74 deletions
diff --git a/src/code/code_800CB000.c b/src/code/code_800CB000.c
deleted file mode 100644
index 7642d35c4..000000000
--- a/src/code/code_800CB000.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "global.h"
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_800CB000/func_800CB000.s")
diff --git a/src/code/sched.c b/src/code/sched.c
index ecd984b05..927a48f66 100644
--- a/src/code/sched.c
+++ b/src/code/sched.c
@@ -225,7 +225,7 @@ s32 Sched_TaskCheckFramebuffers(SchedContext* sched, OSScTask* task) {
void* nextFB = osViGetNextFramebuffer();
void* curFB = osViGetCurrentFramebuffer();
- if (task == NULL || sched->pendingSwapBuf1 != NULL || (curFB == task->framebuffer->fb1 && curFB != nextFB)) {
+ if (task == NULL || sched->pendingSwapBuf1 != NULL || (curFB == TASK_FRAMEBUFFER(task)->fb1 && curFB != nextFB)) {
return 0;
}
return 1;
@@ -257,7 +257,7 @@ s32 Sched_Schedule(SchedContext* sched, OSScTask** spTask, OSScTask** dpTask, s3
}
}
} else if (ret == (OS_SC_SP | OS_SC_DP)) {
- if (gfxTask->framebuffer == NULL || Sched_TaskCheckFramebuffers(sched, gfxTask)) {
+ if (TASK_FRAMEBUFFER(gfxTask) == NULL || Sched_TaskCheckFramebuffers(sched, gfxTask)) {
*spTask = *dpTask = gfxTask;
ret &= ~(OS_SC_SP | OS_SC_DP);
sched->gfxListHead = sched->gfxListHead->next;
@@ -271,7 +271,7 @@ s32 Sched_Schedule(SchedContext* sched, OSScTask** spTask, OSScTask** dpTask, s3
}
void Sched_TaskUpdateFramebuffer(SchedContext* sched, OSScTask* task) {
- sched->pendingSwapBuf1 = task->framebuffer;
+ sched->pendingSwapBuf1 = TASK_FRAMEBUFFER(task);
if (sched->curBuf != NULL && sched->curBuf->updateRate2 > 0) {
return;
diff --git a/src/code/sys_initial_check.c b/src/code/sys_initial_check.c
index 7b0a26cc8..84871255b 100644
--- a/src/code/sys_initial_check.c
+++ b/src/code/sys_initial_check.c
@@ -1,17 +1,116 @@
+/**
+ * File: sys_initial_check.c
+ * Description: Functions for checking for the presence of the Expansion Pak and the correct TV type (PAL/NTSC/MPAL),
+ * and functions for printing error messages directly to screen if not found or incorrect.
+ *
+ * These checks are some of the first functions run in Main, before even setting up the system heap, and any image files
+ * are DMA'd directly to fixed RAM addresses.
+ */
#include "global.h"
+#include "misc/locerrmsg/locerrmsg.h"
+#include "misc/memerrmsg/memerrmsg.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_WriteRGBA16Pixel.s")
+#define SIZEOF_LOCERRMSG (sizeof(gNotDesignedForSystemErrorTex))
+#define SIZEOF_MEMERRMSG (sizeof(gExpansionPakNotInstalledErrorTex) + sizeof(gSeeInstructionBookletErrorTex))
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_WriteI4Pixel.s")
+// Address with enough room after to load either of the error message image files before the fault screen buffer at the
+// end of RDRAM
+#define CHECK_ERRMSG_STATIC_SEGMENT (u8*)(FAULT_FB_ADDRESS - MAX(SIZEOF_LOCERRMSG, SIZEOF_MEMERRMSG))
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_DrawI4Texture.s")
+void Check_WriteRGBA16Pixel(u16* buffer, u32 x, u32 y, u32 value) {
+ if (value & RGBA16_PIXEL_OPAQUE) {
+ (&buffer[x])[y * SCREEN_WIDTH] = value;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_ClearRGBA16.s")
+void Check_WriteI4Pixel(u16* buffer, u32 x, u32 y, u32 value) {
+ Check_WriteRGBA16Pixel(buffer, x, y, value * GPACK_RGBA5551(16, 16, 16, 0) + GPACK_RGBA5551(12, 12, 12, 1));
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_DrawExpansionPakErrorMessage.s")
+/**
+ * x and y are the coordinates of the bottom-left corner.
+ */
+void Check_DrawI4Texture(u16* buffer, s32 x, s32 y, s32 width, s32 height, u8* texture) {
+ s32 v;
+ s32 u;
+ u8 pixelPair;
+ u8* pixelPairPtr = texture;
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_DrawRegionLockErrorMessage.s")
+ // I4 textures are bitpacked 2 pixels per byte, so this writes a pair of pixels in each iteration using bitmasking.
+ for (v = 0; v < height; v++) {
+ for (u = 0; u < width; u += 2, pixelPairPtr++) {
+ pixelPair = *pixelPairPtr;
+ Check_WriteI4Pixel(buffer, x + u, y + v, pixelPair >> 4);
+ pixelPair = *pixelPairPtr;
+ Check_WriteI4Pixel(buffer, x + u + 1, y + v, pixelPair & 0xF);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_ExpansionPak.s")
+void Check_ClearRGBA16(u16* buffer) {
+ u32 x;
+ u32 y;
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_RegionIsSupported.s")
+ for (y = 0; y < SCREEN_HEIGHT; y++) {
+ for (x = 0; x < SCREEN_WIDTH; x++) {
+ Check_WriteRGBA16Pixel(buffer, x, y, 1);
+ }
+ }
+}
+
+/**
+ * Draw error message textures directly to a screen buffer at the end of normal RDRAM
+ */
+void Check_DrawExpansionPakErrorMessage(void) {
+ DmaMgr_SendRequest0(CHECK_ERRMSG_STATIC_SEGMENT, SEGMENT_ROM_START(memerrmsg), SEGMENT_SIZE(memerrmsg));
+ Check_ClearRGBA16((u16*)FAULT_FB_ADDRESS);
+ Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 71, 128, 37, CHECK_ERRMSG_STATIC_SEGMENT);
+ Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 127, 128, 37,
+ CHECK_ERRMSG_STATIC_SEGMENT + sizeof(gExpansionPakNotInstalledErrorTex));
+ osWritebackDCacheAll();
+ osViSwapBuffer((u16*)FAULT_FB_ADDRESS);
+ osViBlack(false);
+}
+
+/**
+ * Draw error message texture directly to a screen buffer at the end of normal RDRAM
+ */
+void Check_DrawRegionLockErrorMessage(void) {
+ DmaMgr_SendRequest0(CHECK_ERRMSG_STATIC_SEGMENT, SEGMENT_ROM_START(locerrmsg), SEGMENT_SIZE(locerrmsg));
+ Check_ClearRGBA16((u16*)FAULT_FB_ADDRESS);
+ Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 56, 112, 208, 16, CHECK_ERRMSG_STATIC_SEGMENT);
+ osWritebackDCacheAll();
+ osViSwapBuffer((u16*)FAULT_FB_ADDRESS);
+ osViBlack(false);
+}
+
+/**
+ * If Expansion pak is not installed, display error message until console is turned off
+ */
+void Check_ExpansionPak(void) {
+ // Expansion pak installed
+ if (osMemSize >= 0x800000) {
+ return;
+ }
+
+ Check_DrawExpansionPakErrorMessage();
+ osDestroyThread(NULL);
+ while (true) {}
+}
+
+/**
+ * If region is not NTSC or MPAL, display error message until console is turned off
+ */
+void Check_RegionIsSupported(void) {
+ s32 regionSupported = false;
+
+ if ((osTvType == OS_TV_NTSC) || (osTvType == OS_TV_MPAL)) {
+ regionSupported = true;
+ }
+
+ if (!regionSupported) {
+ Check_DrawRegionLockErrorMessage();
+ osDestroyThread(NULL);
+ while (true) {}
+ }
+}
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 03a362fc6..42f67987a 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -509,8 +509,8 @@ f32 Actor_YDistance(Actor* actor1, Actor* actor2) {
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B72E0.s")
void func_800B72F8(DynaPolyActor* dpactor, f32 a1, s16 a2) {
- dpactor->unk150 = a2;
- dpactor->unk148 += a1;
+ dpactor->yRotation = a2;
+ dpactor->pushForce += a1;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_IsLinkFacingActor.s")
diff --git a/src/code/z_bg_collect.c b/src/code/z_bg_collect.c
index 29c4cf7da..706c4b80a 100644
--- a/src/code/z_bg_collect.c
+++ b/src/code/z_bg_collect.c
@@ -61,13 +61,13 @@ void BgCheck2_AttachToMesh(CollisionContext* colCtx, Actor* actor, s32 index) {
meshActor = BgCheck_GetActorOfMesh(colCtx, index);
if (meshActor != NULL) {
- func_800CAE88(meshActor);
+ DynaPolyActor_SetRidingFallingState(meshActor);
if ((actor->flags & 0x4000000) == 0x4000000) {
- func_800CAF24(meshActor);
+ DynaPolyActor_SetSwitchPressedState(meshActor);
}
if ((actor->flags & 0x20000) == 0x20000) {
- func_800CAF38(meshActor);
+ DynaPolyActor_SetHeavySwitchPressedState(meshActor);
}
}
}
@@ -80,7 +80,7 @@ u32 BgCheck2_UpdateActorAttachedToMesh(CollisionContext* colCtx, s32 index, Acto
return 0;
}
- if (((colCtx->dyna.bgActorFlags[index] & 2) != 0) || ((colCtx->dyna.bgActorFlags[index] & 1) == 0)) {
+ if (colCtx->dyna.bgActorFlags[index] & 2 || !(colCtx->dyna.bgActorFlags[index] & 1)) {
return 0;
}
@@ -90,12 +90,12 @@ u32 BgCheck2_UpdateActorAttachedToMesh(CollisionContext* colCtx, s32 index, Acto
return 0;
}
- if ((meshActor->unk154 & 1) != 0) {
+ if (meshActor->flags & 1) {
BgCheck2_UpdateActorPosition(colCtx, index, actor);
wasUpdated = 1;
}
- if ((meshActor->unk154 & 2) != 0) {
+ if (meshActor->flags & 2) {
BgCheck2_UpdateActorYRotation(colCtx, index, actor);
wasUpdated = 1;
}
diff --git a/src/code/z_bg_item.c b/src/code/z_bg_item.c
index 77cc014b4..92a300e43 100644
--- a/src/code/z_bg_item.c
+++ b/src/code/z_bg_item.c
@@ -1,99 +1,141 @@
#include "global.h"
-void BcCheck3_BgActorInit(DynaPolyActor* actor, UNK_TYPE4 param_2) {
- actor->bgId = -1;
- actor->unk148 = 0;
- actor->unk14C = 0;
- actor->unk154 = param_2;
- actor->unk_158 = 0;
+#define DYNAPOLY_STATE_NONE 0
+#define DYNAPOLY_STATE_RIDING_FALLING (1 << 0)
+#define DYNAPOLY_STATE_RIDING_MOVING (1 << 1)
+#define DYNAPOLY_STATE_RIDING_ROTATING (1 << 2)
+#define DYNAPOLY_STATE_SWITCH_PRESSED (1 << 3)
+#define DYNAPOLY_STATE_HEAVY_SWITCH_PRESSED (1 << 4)
+
+void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 flags) {
+ dynaActor->bgId = -1;
+ dynaActor->pushForce = 0.0f;
+ dynaActor->unk14C = 0.0f;
+ dynaActor->flags = flags;
+ dynaActor->stateFlags = DYNAPOLY_STATE_NONE;
}
-void BgCheck3_LoadMesh(GlobalContext* globalCtx, DynaPolyActor* actor, CollisionHeader* meshHeader) {
- CollisionHeader* header;
+void DynaPolyActor_LoadMesh(GlobalContext* globalCtx, DynaPolyActor* dynaActor, CollisionHeader* meshHeader) {
+ CollisionHeader* header = NULL;
- header = NULL;
BgCheck_RelocateMeshHeader(meshHeader, &header);
- actor->bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, actor, header);
+ dynaActor->bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, dynaActor, header);
}
-void BgCheck3_ResetFlags(DynaPolyActor* actor) {
- actor->unk_158 = 0;
+void DynaPolyActor_ResetState(DynaPolyActor* dynaActor) {
+ dynaActor->stateFlags = DYNAPOLY_STATE_NONE;
}
-void func_800CAE88(DynaPolyActor* actor) {
- actor->unk_158 |= 1;
+void DynaPolyActor_SetRidingFallingState(DynaPolyActor* dynaActor) {
+ dynaActor->stateFlags |= DYNAPOLY_STATE_RIDING_FALLING;
}
-void func_800CAE9C(DynaPolyActor* actor) {
- actor->unk_158 |= 2;
+void DynaPolyActor_SetRidingMovingState(DynaPolyActor* dynaActor) {
+ dynaActor->stateFlags |= DYNAPOLY_STATE_RIDING_MOVING;
}
-void func_800CAEB0(CollisionContext* colCtx, s32 index) {
- DynaPolyActor* actor;
+void DynaPolyActor_SetRidingMovingStateByIndex(CollisionContext* colCtx, s32 index) {
+ DynaPolyActor* dynaActor = BgCheck_GetActorOfMesh(colCtx, index);
- actor = BgCheck_GetActorOfMesh(colCtx, index);
- if (actor != (DynaPolyActor*)0x0) {
- func_800CAE9C(actor);
+ if (dynaActor != NULL) {
+ DynaPolyActor_SetRidingMovingState(dynaActor);
}
}
-void func_800CAEE0(DynaPolyActor* actor) {
- actor->unk_158 |= 4;
+void DynaPolyActor_SetRidingRotatingState(DynaPolyActor* dynaActor) {
+ dynaActor->stateFlags |= DYNAPOLY_STATE_RIDING_ROTATING;
}
-void func_800CAEF4(CollisionContext* colCtx, s32 index) {
- DynaPolyActor* actor;
+void DynaPolyActor_SetRidingRotatingStateByIndex(CollisionContext* colCtx, s32 index) {
+ DynaPolyActor* dynaActor = BgCheck_GetActorOfMesh(colCtx, index);
- actor = BgCheck_GetActorOfMesh(colCtx, index);
- if (actor != (DynaPolyActor*)0x0) {
- func_800CAEE0(actor);
+ if (dynaActor != NULL) {
+ DynaPolyActor_SetRidingRotatingState(dynaActor);
}
}
-void func_800CAF24(DynaPolyActor* actor) {
- actor->unk_158 |= 8;
+void DynaPolyActor_SetSwitchPressedState(DynaPolyActor* dynaActor) {
+ dynaActor->stateFlags |= DYNAPOLY_STATE_SWITCH_PRESSED;
}
-void func_800CAF38(DynaPolyActor* actor) {
- actor->unk_158 |= 0x10;
+void DynaPolyActor_SetHeavySwitchPressedState(DynaPolyActor* dynaActor) {
+ dynaActor->stateFlags |= DYNAPOLY_STATE_HEAVY_SWITCH_PRESSED;
}
-s32 func_800CAF4C(DynaPolyActor* actor) {
- if (actor->unk_158 & 1) {
- return 1;
+s32 DynaPolyActor_IsInRidingFallingState(DynaPolyActor* dynaActor) {
+ if (dynaActor->stateFlags & DYNAPOLY_STATE_RIDING_FALLING) {
+ return true;
} else {
- return 0;
+ return false;
}
}
-s32 func_800CAF70(DynaPolyActor* actor) {
- if (actor->unk_158 & 2) {
- return 1;
+s32 DynaPolyActor_IsInRidingMovingState(DynaPolyActor* dynaActor) {
+ if (dynaActor->stateFlags & DYNAPOLY_STATE_RIDING_MOVING) {
+ return true;
} else {
- return 0;
+ return false;
}
}
-s32 func_800CAF94(DynaPolyActor* actor) {
- if (actor->unk_158 & 4) {
- return 1;
+s32 DynaPolyActor_IsInRidingRotatingState(DynaPolyActor* dynaActor) {
+ if (dynaActor->stateFlags & DYNAPOLY_STATE_RIDING_ROTATING) {
+ return true;
} else {
- return 0;
+ return false;
}
}
-s32 func_800CAFB8(DynaPolyActor* actor) {
- if (actor->unk_158 & 8) {
- return 1;
+s32 DynaPolyActor_IsInSwitchPressedState(DynaPolyActor* dynaActor) {
+ if (dynaActor->stateFlags & DYNAPOLY_STATE_SWITCH_PRESSED) {
+ return true;
} else {
- return 0;
+ return false;
}
}
-s32 func_800CAFDC(DynaPolyActor* actor) {
- if (actor->unk_158 & 0x10) {
- return 1;
+s32 DynaPolyActor_IsInHeavySwitchPressedState(DynaPolyActor* dynaActor) {
+ if (dynaActor->stateFlags & DYNAPOLY_STATE_HEAVY_SWITCH_PRESSED) {
+ return true;
} else {
- return 0;
+ return false;
}
}
+
+s32 DynaPolyActor_ValidateMove(GlobalContext* globalCtx, DynaPolyActor* dynaActor, s16 startRadius, s16 endRadius,
+ s16 startHeight) {
+ Vec3f startPos;
+ Vec3f endPos;
+ Vec3f intersectionPos;
+ f32 sin = Math_SinS(dynaActor->yRotation);
+ f32 cos = Math_CosS(dynaActor->yRotation);
+ s32 bgId;
+ CollisionPoly* poly;
+ f32 adjustedStartRadius;
+ f32 adjustedEndRadius;
+ f32 sign = (0.0f <= dynaActor->pushForce) ? 1.0f : -1.0f;
+
+ adjustedStartRadius = (f32)startRadius - 0.1f;
+ startPos.x = dynaActor->actor.world.pos.x + (adjustedStartRadius * cos);
+ startPos.y = dynaActor->actor.world.pos.y + startHeight;
+ startPos.z = dynaActor->actor.world.pos.z - (adjustedStartRadius * sin);
+
+ adjustedEndRadius = (f32)endRadius - 0.1f;
+ endPos.x = sign * adjustedEndRadius * sin + startPos.x;
+ endPos.y = startPos.y;
+ endPos.z = sign * adjustedEndRadius * cos + startPos.z;
+
+ if (func_800C56E0(&globalCtx->colCtx, &startPos, &endPos, &intersectionPos, &poly, true, false, false, true, &bgId,
+ &dynaActor->actor, 0.0f)) {
+ return false;
+ }
+ startPos.x = (dynaActor->actor.world.pos.x * 2.0f) - startPos.x;
+ startPos.z = (dynaActor->actor.world.pos.z * 2.0f) - startPos.z;
+ endPos.x = sign * adjustedEndRadius * sin + startPos.x;
+ endPos.z = sign * adjustedEndRadius * cos + startPos.z;
+ if (func_800C56E0(&globalCtx->colCtx, &startPos, &endPos, &intersectionPos, &poly, true, false, false, true, &bgId,
+ &dynaActor->actor, 0.0f)) {
+ return false;
+ }
+ return true;
+}