pmd-red/src/code_8002774.c
2025-04-10 21:01:22 -07:00

515 lines
12 KiB
C

#include "global.h"
#include "globaldata.h"
#include "code_8002774.h"
#include "constants/direction.h"
#include "structs/str_position.h"
#include "other_random.h"
#define UNK_STRUCT_ARR_COUNT 4
struct S
{
u8 x0[UNK_STRUCT_ARR_COUNT];
};
const u8 sUnknown_8002774[] = {0, 0, 0, 0, 0, 0, 0, 0};
const PixelPos gVectorDirections[NUM_DIRECTIONS] = {
{0, 1}, // N
{1, 1}, // NE
{1, 0}, // E
{1, -1}, // SE
{0, -1}, // S
{-1, -1}, // SW
{-1, 0}, // W
{-1, 1}, // NW
};
static s8 VecDirection4Radial(PixelPos *pixelPos);
u16 sub_8002774(struct S s)
{
return ((s.x0[2] & 0xF8) << 7) | ((s.x0[1] & 0xF8) << 2) | ((s.x0[0] & 0xF8) >> 3);
}
struct S sub_80027A0(u16 a0)
{
struct S ret;
ret.x0[0] = (a0 & 0x1F) << 3 | ((a0 & 1) ? 7 : 0);
ret.x0[1] = (a0 & 0x3E0) >> 2 | ((a0 & 0x20) ? 7 : 0);
ret.x0[2] = (a0 & 0x7C00) >> 7 | ((a0 & 0x400) ? 7 : 0);
ret.x0[3] = 0;
return ret;
}
UNUSED static void sub_8002804(struct S *r0, s32 r1, struct S *r2)
{
s32 i;
for (i = 0; i < UNK_STRUCT_ARR_COUNT; i++) {
r0->x0[i] = (r1 * r2->x0[i]) / 256;
}
}
UNUSED static void sub_800282C(struct S *dst, s32 a1, struct S *a2, struct S *a3)
{
s32 i, j;
float spFloats[4];
float floatsMul[4];
float f0 = 1.0f / a1;
for (i = 0; i < 4; i++) {
s8 asSigned = (s8) a2->x0[i];
float f = (float)(asSigned);
if (asSigned < 0) {
f += 256.0f;
}
spFloats[i] = f;
floatsMul[i] = (float)(a3->x0[i] - a2->x0[i]) * f0;
}
*dst++ = *a2;
for (i = 1; i < a1 - 1; dst++, i++) {
for (j = 0; j < 4; j++) {
dst->x0[j] = (unsigned int)((spFloats[j] += floatsMul[j]));
}
}
*dst = *a3;
}
// TODO: File split here
// arm9.bin::02010314
void sub_800290C(PixelPos *param_1, s32 param_2)
{
if (param_1->x > param_2)
param_1->x = param_2;
else if (param_1->x < -param_2)
param_1->x = -param_2;
if (param_1->y > param_2)
param_1->y = param_2;
else if(param_1->y < -param_2)
param_1->y = -param_2;
}
// arm9.bin::020102B8
void sub_8002934(PixelPos *param_1, PixelPos *param_2, PixelPos *param_3, s32 param_4, s32 param_5)
{
s32 r9 = (param_4 + param_5);
param_1->x = (param_4 * param_2->x + param_5 * param_3->x) / r9;
param_1->y = (param_4 * param_2->y + param_5 * param_3->y) / r9;
}
// TODO: File split here
static inline s8 sub_8002984_sub(s32 direction1, s32 rand, s32 add, s32 multi)
{
return (s8)(((direction1 + add) + OtherRandInt(rand) * multi) % NUM_DIRECTIONS);
}
// arm9.bin::020109F4
s32 sub_8002984(s32 _direction1, u32 caseID)
{
s32 direction1;
direction1 = (s8)_direction1;
switch((u8)caseID) {
case 1:
if (direction1 >= 0) {
direction1 += 7;
direction1 &= DIRECTION_MASK;
}
break;
case 2:
if (direction1 >= 0) {
direction1 += 1;
direction1 &= DIRECTION_MASK;
}
break;
case 3:
if (direction1 >= 0) {
direction1 += 6;
direction1 &= DIRECTION_MASK;
}
break;
case 4:
if (direction1 >= 0) {
direction1 += 2;
direction1 &= DIRECTION_MASK;
}
break;
case 5:
if (direction1 >= 0) {
direction1 += 4;
direction1 &= DIRECTION_MASK;
}
break;
case 6:
if ((direction1 & 1) != 0) {
direction1 = sub_8002984_sub(direction1, 2, 7, 2);
}
else
{
direction1 = sub_8002984_sub(direction1, 3, 6, 2);
}
break;
case 7:
direction1 = sub_8002984_sub(direction1, 3, 7, 1);
break;
case 8:
direction1 = (s8)(OtherRandInt(NUM_DIRECTIONS) & 0xfe);
break;
case 9:
direction1 = (s8)OtherRandInt(NUM_DIRECTIONS);
break;
default:
break;
}
return direction1;
}
// arm9.bin::020108EC
s32 sub_8002A70(s32 _direction1, s32 _direction2, s32 _caseId)
{
s32 direction1 = (s8)(_direction1);
s32 direction2 = (s8)(_direction2);
s32 caseId = (u8)(_caseId);
if (direction1 == direction2)
return direction1;
switch (caseId) {
case 1:
if (direction1 >= 0) {
direction1 += 7;
direction1 &= DIRECTION_MASK;
}
break;
case 2:
if (direction1 >= 0) {
direction1 += 1;
direction1 &= DIRECTION_MASK;
}
break;
case 3:
if (direction1 >= 0) {
direction1 += 6;
direction1 &= DIRECTION_MASK;
}
break;
case 4:
if (direction1 >= 0) {
direction1 += 2;
direction1 &= DIRECTION_MASK;
}
break;
case 11:
direction1 = sub_8002B04(direction1, direction2);
// Fallthrough
case 10:
direction1 = sub_8002B04(direction1, direction2);
break;
}
return direction1;
}
// arm9.bin::02010824
s32 sub_8002B04(s32 _direction1, s32 _direction2)
{
s32 direction1 = (s8)(_direction1);
s32 direction2 = (s8)(_direction2);
if (direction2 != -1)
{
s32 newDirection = ((direction2 + NUM_DIRECTIONS) - direction1) % NUM_DIRECTIONS;
if (newDirection != 0) {
if (newDirection < 4)
newDirection = (direction1 + 1) % NUM_DIRECTIONS;
else
newDirection = (direction1 + 7) % NUM_DIRECTIONS;
direction1 = (s8)newDirection;
}
}
return direction1;
}
#if (GAME_VERSION == VERSION_RED)
UNUSED static s32 sub_8002B5C(s32 _direction1, s32 _direction2)
{
s32 newDirection;
s32 direction1;
s32 direction2;
direction1 = (s8)_direction1;
direction2 = (s8)_direction2;
if (direction2 != -1) {
newDirection = ((direction2 + NUM_DIRECTIONS) - direction1) % NUM_DIRECTIONS;
if (newDirection != 0) {
if (newDirection < 4) {
newDirection = (direction1 + 2) % NUM_DIRECTIONS;
}
else {
newDirection = (direction1 + 6) % NUM_DIRECTIONS;
}
direction1 = (s8)(newDirection);
}
}
return direction1 & DIRECTION_MASK_CARDINAL;
}
#endif
// arm9.bin::02010790
PixelPos SetVecFromDirectionSpeed(s8 r1, u32 r2)
{
const PixelPos *vec = &gVectorDirections[r1];
return (PixelPos){ .x = vec->x * r2, .y = vec->y * r2 };
}
UNUSED static s32 VecDirection8Sign(PixelPos *param_1)
{
if (param_1->x < 0) {
if (param_1->y < 0)
return DIRECTION_NORTHWEST;
else if (param_1->y > 0)
return DIRECTION_SOUTHWEST;
else
return DIRECTION_WEST;
}
else if (param_1->x > 0) {
if (param_1->y < 0)
return DIRECTION_NORTHEAST;
else if (param_1->y > 0)
return DIRECTION_SOUTHEAST;
else
return DIRECTION_EAST;
}
else if (param_1->y < 0)
return DIRECTION_NORTH;
else if (param_1->y > 0)
return DIRECTION_SOUTH;
else
return -1;
}
UNUSED static s32 VecDirection4SignYX(PixelPos *param_1)
{
if (param_1->y < 0) {
return DIRECTION_NORTH;
}
else if (param_1->y > 0) {
return DIRECTION_SOUTH;
}
else if (param_1->x < 0) {
return DIRECTION_WEST;
}
else if (param_1->x > 0) {
return DIRECTION_EAST;
}
else {
return -1;
}
}
// arm9.bin::02010680
s8 VecDirection8Radial(PixelPos *pixelPos)
{
PixelPos absPos = {abs(pixelPos->x), abs(pixelPos->y)};
if (pixelPos->x < 0) {
if (pixelPos->y < 0) {
if (absPos.y > absPos.x * 2) {
return DIRECTION_NORTH;
}
if (absPos.x <= absPos.y * 2) {
return DIRECTION_NORTHWEST;
}
return DIRECTION_WEST;
}
if (absPos.y <= absPos.x * 2) {
if (absPos.x > absPos.y * 2) {
return DIRECTION_WEST;
}
return DIRECTION_SOUTHWEST;
}
}
else if (pixelPos->x > 0) {
if (pixelPos->y < 0) {
if (absPos.y > absPos.x * 2) {
return DIRECTION_NORTH;
}
if (absPos.x <= absPos.y * 2) {
return DIRECTION_NORTHEAST;
}
return DIRECTION_EAST;
}
else {
if (absPos.y > absPos.x * 2) {
return DIRECTION_SOUTH;
}
if (absPos.x > absPos.y * 2) {
return DIRECTION_EAST;
}
return DIRECTION_SOUTHEAST;
}
}
else {
if (pixelPos->y < 0) {
return DIRECTION_NORTH;
}
if (pixelPos->y < 1) {
return -1;
}
}
return DIRECTION_SOUTH;
}
// arm9.bin::020105A0
static s8 VecDirection4Radial(PixelPos *pixelPos)
{
PixelPos absPos = {abs(pixelPos->x), abs(pixelPos->y)};
if (pixelPos->x < 0) {
if (pixelPos->y < 0) {
if (absPos.y > absPos.x) {
return DIRECTION_NORTH;
}
return DIRECTION_WEST;
}
if (absPos.y <= absPos.x) {
return DIRECTION_WEST;
}
}
else if (pixelPos->x > 0) {
if (pixelPos->y < 0) {
if (absPos.y > absPos.x) {
return DIRECTION_NORTH;
}
return DIRECTION_EAST;
}
else {
if (absPos.y > absPos.x) {
return DIRECTION_SOUTH;
}
return DIRECTION_EAST;
}
}
else {
if (pixelPos->y < 0) {
return DIRECTION_NORTH;
}
if (pixelPos->y < 1) {
return -1;
}
}
return DIRECTION_SOUTH;
}
// arm9.bin::02010478
s8 SizedDeltaDirection4(const PixelPos *r0, const PixelPos *r1, const PixelPos *r2, const PixelPos *r3)
{
PixelPos stack;
s32 iVar1;
s32 iVar2;
s32 iVar3;
stack.x = r2->x - r0->x;
stack.y = r2->y - r0->y;
if(stack.x >= 0)
{
iVar3 = (stack.x + 1);
iVar3 -= ((r1->x + r3->x) / 2);
stack.x = iVar3;
if(stack.x < 0) stack.x = 0;
}
else
{
iVar1 = (stack.x - 1);
iVar1 += ((r1->x + r3->x) / 2);
stack.x = iVar1;
if(stack.x > 0) stack.x = 0;
}
if(stack.y >= 0)
{
iVar2 = (stack.y + 1);
iVar2 -= ((r1->y + r3->y) / 2);
stack.y = iVar2;
if(stack.y < 0) stack.y = 0;
}
else
{
iVar1 = (stack.y - 1);
iVar1 += ((r1->y + r3->y) / 2);
stack.y = iVar1;
if(stack.y > 0) stack.y = 0;
}
return VecDirection4Radial(&stack);
}
// arm9.bin::02010350
s8 SizedDeltaDirection8(const PixelPos *r0, const PixelPos *r1, const PixelPos *r2, const PixelPos *r3)
{
PixelPos stack;
s32 iVar1;
s32 iVar2;
s32 iVar3;
stack.x = r2->x - r0->x;
stack.y = r2->y - r0->y;
if (stack.x >= 0) {
iVar3 = stack.x + 1;
iVar3 -= (r1->x + r3->x) / 2;
stack.x = iVar3;
if (stack.x < 0)
stack.x = 0;
}
else {
iVar1 = stack.x - 1;
iVar1 += (r1->x + r3->x) / 2;
stack.x = iVar1;
if (stack.x > 0)
stack.x = 0;
}
if (stack.y >= 0) {
iVar2 = stack.y + 1;
iVar2 -= (r1->y + r3->y) / 2;
stack.y = iVar2;
if (stack.y < 0)
stack.y = 0;
}
else {
iVar1 = stack.y - 1;
iVar1 += (r1->y + r3->y) / 2;
stack.y = iVar1;
if (stack.y > 0)
stack.y = 0;
}
return VecDirection8Radial(&stack);
}