mm/src/code/z_lib.c

737 lines
16 KiB
C

#include "global.h"
void* Lib_MemCpy(void* dest, void* src, size_t size) {
bcopy(src, dest, size);
return dest;
}
void* Lib_MemSet(void* buffer, s32 value, size_t size) {
u8* v0;
s32 i;
if (value == 0) {
bzero(buffer, (u32)size);
return buffer;
}
for (v0 = (u8*)buffer, i = size; i > 0; i--) {
*v0++ = value;
}
return buffer;
}
f32 Math_CosS(s16 angle) {
return coss(angle) * SHT_MINV;
}
f32 Math_SinS(s16 angle) {
return sins(angle) * SHT_MINV;
}
s32 Math_StepToIImpl(s32 start, s32 target, s32 step) {
s32 ret;
if (target >= start) {
ret = start + step;
if (target >= ret) {
return ret;
}
} else {
ret = start - step;
if (ret >= target) {
return ret;
}
}
return target;
}
void Math_StepToIGet(s32* pValue, s32 target, s32 step) {
*pValue = Math_StepToIImpl(*pValue, target, step);
}
s32 Math_StepToI(s32* pValue, s32 target, s32 step) {
Math_StepToIGet(pValue, target, step);
return target == *pValue;
}
s32 Math_ScaledStepToS(s16* pValue, s16 target, s16 step) {
f32 f0;
if (step != 0) {
f0 = gFramerateDivisorHalf;
if ((s16)(*pValue - target) > 0) {
step = -step;
}
*pValue += (s16)(step * f0);
if (((s16)(*pValue - target) * step) >= 0) {
*pValue = target;
return true;
}
} else if (target == *pValue) {
return true;
}
return false;
}
s32 Math_StepToS(s16* pValue, s16 target, s16 step) {
if (step != 0) {
if (target < *pValue) {
step = -step;
}
*pValue += step;
if (((*pValue - target) * step) >= 0) {
*pValue = target;
return true;
}
} else if (target == *pValue) {
return true;
}
return false;
}
s32 Math_StepToC(s8* pValue, s8 target, s8 step) {
if (step != 0) {
if (target < *pValue) {
step = -step;
}
*pValue += step;
if (((*pValue - target) * step) >= 0) {
*pValue = target;
return true;
}
} else if (target == *pValue) {
return true;
}
return false;
}
s32 Math_StepToF(f32* pValue, f32 target, f32 step) {
if (step != 0.0f) {
if (target < *pValue) {
step = -step;
}
*pValue += step;
if (((*pValue - target) * step) >= 0) {
*pValue = target;
return true;
}
} else if (target == *pValue) {
return true;
}
return false;
}
s32 Math_StepUntilAngleS(s16* pValue, s16 target, s16 step) {
s16 orig = *pValue;
*pValue += step;
if (((s16)(*pValue - target) * (s16)(orig - target)) <= 0) {
*pValue = target;
return true;
}
return false;
}
s32 Math_StepToAngleS(s16* pValue, s16 target, s16 step) {
s32 diff = target - *pValue;
if (diff < 0) {
step = -step;
}
if (diff > INT16_MAX) {
step = -step;
diff = -UINT16_MAX - -diff;
} else if (diff <= INT16_MIN) {
diff += UINT16_MAX;
step = -step;
}
if (step != 0) {
*pValue += step;
if ((diff * step) <= 0) {
*pValue = target;
return true;
}
} else if (target == *pValue) {
return true;
}
return false;
}
s32 Math_AsymStepToS(s16* pValue, s16 target, s16 incrStep, s16 decrStep) {
s16 step = ((target - *pValue) >= 0) ? incrStep : decrStep;
if (step != 0) {
if (target < *pValue) {
step = -step;
}
*pValue += step;
if (((*pValue - target) * step) >= 0) {
*pValue = target;
return true;
}
} else if (target == *pValue) {
return true;
}
return false;
}
s32 Math_StepUntilF(f32* pValue, f32 limit, f32 step) {
f32 orig = *pValue;
*pValue += step;
if (((*pValue - limit) * (orig - limit)) <= 0) {
*pValue = limit;
return true;
}
return false;
}
s32 Math_AsymStepToF(f32* pValue, f32 target, f32 incrStep, f32 decrStep) {
f32 step = (target >= *pValue) ? incrStep : decrStep;
if (step != 0) {
if (target < *pValue) {
step = -step;
}
*pValue += step;
if (((*pValue - target) * step) >= 0) {
*pValue = target;
return true;
}
} else if (target == *pValue) {
return true;
}
return false;
}
void func_800FF3A0(f32* distOut, s16* angleOut, Input* input) {
f32 x = input->rel.stick_x;
f32 y = input->rel.stick_y;
f32 dist;
dist = sqrtf(SQ(x) + SQ(y));
*distOut = (60.0f < dist) ? 60.0f : dist;
if (dist > 0.0f) {
x = input->cur.stick_x;
y = input->cur.stick_y;
*angleOut = Math_Atan2S_XY(y, -x);
} else {
*angleOut = 0;
}
}
s16 Rand_S16Offset(s16 base, s16 range) {
return (s16)(Rand_ZeroOne() * range) + base;
}
s16 Rand_S16OffsetStride(s16 base, s16 stride, s16 range) {
return (s16)(Rand_ZeroOne() * range) * stride + base;
}
void Math_Vec3f_Copy(Vec3f* dest, Vec3f* src) {
f32 x = src->x;
f32 y = src->y;
f32 z = src->z;
dest->x = x;
dest->y = y;
dest->z = z;
}
void Math_Vec3s_Copy(Vec3s* dest, Vec3s* src) {
s16 x = src->x;
s16 y = src->y;
s16 z = src->z;
dest->x = x;
dest->y = y;
dest->z = z;
}
void Math_Vec3s_ToVec3f(Vec3f* dest, Vec3s* src) {
f32 x = src->x;
f32 y = src->y;
f32 z = src->z;
dest->x = x;
dest->y = y;
dest->z = z;
}
void Math_Vec3f_ToVec3s(Vec3s* dest, Vec3f* src) {
f32 x = src->x;
f32 y = src->y;
f32 z = src->z;
dest->x = x;
dest->y = y;
dest->z = z;
}
void Math_Vec3f_Sum(Vec3f* l, Vec3f* r, Vec3f* dest) {
dest->x = l->x + r->x;
dest->y = l->y + r->y;
dest->z = l->z + r->z;
}
void Math_Vec3f_Diff(Vec3f* l, Vec3f* r, Vec3f* dest) {
dest->x = l->x - r->x;
dest->y = l->y - r->y;
dest->z = l->z - r->z;
}
void Math_Vec3s_DiffToVec3f(Vec3f* dest, Vec3s* l, Vec3s* r) {
dest->x = l->x - r->x;
dest->y = l->y - r->y;
dest->z = l->z - r->z;
}
void Math_Vec3f_Scale(Vec3f* vec, f32 scale) {
vec->x *= scale;
vec->y *= scale;
vec->z *= scale;
}
void Math_Vec3f_ScaleAndStore(Vec3f* vec, f32 scale, Vec3f* dest) {
dest->x = vec->x * scale;
dest->y = vec->y * scale;
dest->z = vec->z * scale;
}
void Math_Vec3f_Lerp(Vec3f* a, Vec3f* b, f32 t, Vec3f* dest) {
dest->x = (b->x - a->x) * t + a->x;
dest->y = (b->y - a->y) * t + a->y;
dest->z = (b->z - a->z) * t + a->z;
}
void Math_Vec3f_SumScaled(Vec3f* a, Vec3f* b, f32 scale, Vec3f* dest) {
dest->x = b->x * scale + a->x;
dest->y = b->y * scale + a->y;
dest->z = b->z * scale + a->z;
}
void Math_Vec3f_AddRand(Vec3f* orig, f32 scale, Vec3f* dest) {
dest->x = Rand_CenteredFloat(scale) + orig->x;
dest->y = Rand_CenteredFloat(scale) + orig->y;
dest->z = Rand_CenteredFloat(scale) + orig->z;
}
void Math_Vec3f_DistXYZAndStoreNormDiff(Vec3f* a, Vec3f* b, f32 scale, Vec3f* dest) {
f32 diff = Math_Vec3f_DistXYZAndStoreDiff(a, b, dest);
f32 normScale;
if (diff == 0) {
return;
}
normScale = scale / diff;
dest->x *= normScale;
dest->y *= normScale;
dest->z *= normScale;
}
f32 Math_Vec3f_DistXYZ(Vec3f* a, Vec3f* b) {
Vec3f diff;
Math_Vec3f_Diff(b, a, &diff);
return sqrtf(SQXYZ(diff));
}
f32 Math_Vec3f_DistXYZAndStoreDiff(Vec3f* a, Vec3f* b, Vec3f* dest) {
Math_Vec3f_Diff(b, a, dest);
return sqrtf(SQ(dest->x) + SQ(dest->y) + SQ(dest->z));
}
f32 Math_Vec3f_DistXZ(Vec3f* a, Vec3f* b) {
f32 dx = b->x - a->x;
f32 dz = b->z - a->z;
return sqrtf(SQ(dx) + SQ(dz));
}
f32 Math_Vec3f_DistXZAndStore(Vec3f* a, Vec3f* b, f32* dx, f32* dz) {
*dx = b->x - a->x;
*dz = b->z - a->z;
return sqrtf(SQ(*dx) + SQ(*dz));
}
f32 Math_Vec3f_StepToXZ(Vec3f* start, Vec3f* target, f32 speed) {
f32 sp24;
f32 sp20;
f32 f0 = Math_Vec3f_DistXZAndStore(target, start, &sp24, &sp20);
f32 f2 = f0 - speed;
if (speed > f0) {
f2 = 0.0f;
}
if (f2 == 0.0f) {
f0 = 0.0f;
} else {
f0 = f2 / f0;
}
start->x = target->x + sp24 * f0;
start->z = target->z + sp20 * f0;
return f2;
}
f32 Math_Vec3f_DiffY(Vec3f* a, Vec3f* b) {
return b->y - a->y;
}
s16 Math_Vec3f_Yaw(Vec3f* a, Vec3f* b) {
f32 f14 = b->x - a->x;
f32 f12 = b->z - a->z;
return Math_Atan2S_XY(f12, f14);
}
s16 Math_Vec3f_Pitch(Vec3f* a, Vec3f* b) {
return Math_Atan2S_XY(Math_Vec3f_DistXZ(a, b), a->y - b->y);
}
void IChain_Apply_u8(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_s8(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_u16(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_s16(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_u32(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_s32(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_f32(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_f32div1000(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_Vec3f(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_Vec3fdiv1000(u8* ptr, InitChainEntry* ichain);
void IChain_Apply_Vec3s(u8* ptr, InitChainEntry* ichain);
void (*sInitChainHandlers[])(u8* ptr, InitChainEntry* ichain) = {
IChain_Apply_u8, IChain_Apply_s8, IChain_Apply_u16, IChain_Apply_s16,
IChain_Apply_u32, IChain_Apply_s32, IChain_Apply_f32, IChain_Apply_f32div1000,
IChain_Apply_Vec3f, IChain_Apply_Vec3fdiv1000, IChain_Apply_Vec3s,
};
void Actor_ProcessInitChain(Actor* actor, InitChainEntry* ichain) {
do {
sInitChainHandlers[ichain->type]((u8*)actor, ichain);
} while ((ichain++)->cont);
}
void IChain_Apply_u8(u8* ptr, InitChainEntry* ichain) {
*(u8*)(ptr + ichain->offset) = (u8)(ichain->value);
}
void IChain_Apply_s8(u8* ptr, InitChainEntry* ichain) {
*(u8*)(ptr + ichain->offset) = (u8)(ichain->value);
}
void IChain_Apply_u16(u8* ptr, InitChainEntry* ichain) {
*(u16*)(ptr + ichain->offset) = (u16)(ichain->value);
}
void IChain_Apply_s16(u8* ptr, InitChainEntry* ichain) {
*(u16*)(ptr + ichain->offset) = (u16)(ichain->value);
}
void IChain_Apply_u32(u8* ptr, InitChainEntry* ichain) {
*(u32*)(ptr + ichain->offset) = (u32)(ichain->value);
}
void IChain_Apply_s32(u8* ptr, InitChainEntry* ichain) {
*(u32*)(ptr + ichain->offset) = (u32)(ichain->value);
}
void IChain_Apply_f32(u8* ptr, InitChainEntry* ichain) {
*(f32*)(ptr + ichain->offset) = (f32)(ichain->value);
}
void IChain_Apply_f32div1000(u8* ptr, InitChainEntry* ichain) {
*(f32*)(ptr + ichain->offset) = (f32)(ichain->value) / 1000;
}
void IChain_Apply_Vec3f(u8* ptr, InitChainEntry* ichain) {
Vec3f* v0 = (Vec3f*)(ptr + ichain->offset);
f32 f0 = (f32)(ichain->value);
v0->z = f0;
v0->y = f0;
v0->x = f0;
}
void IChain_Apply_Vec3fdiv1000(u8* ptr, InitChainEntry* ichain) {
Vec3f* v0 = (Vec3f*)(ptr + ichain->offset);
f32 f0 = (f32)(ichain->value) / 1000;
v0->z = f0;
v0->y = f0;
v0->x = f0;
}
void IChain_Apply_Vec3s(u8* ptr, InitChainEntry* ichain) {
Vec3s* v0 = (Vec3s*)(ptr + ichain->offset);
s16 v1 = (s16)(ichain->value);
v0->z = v1;
v0->y = v1;
v0->x = v1;
}
f32 Math_SmoothStepToF(f32* pValue, f32 target, f32 fraction, f32 step, f32 minStep) {
f32 stepSize;
if (*pValue != target) {
stepSize = (target - *pValue) * fraction;
if ((stepSize >= minStep) || (stepSize <= -minStep)) {
if (stepSize > step) {
stepSize = step;
}
if (stepSize < -step) {
stepSize = -step;
}
*pValue += stepSize;
} else {
if (stepSize > 0) {
if (stepSize < minStep) {
*pValue += minStep;
if (target < *pValue) {
*pValue = target;
}
}
} else {
if (-minStep < stepSize) {
*pValue += -minStep;
if (*pValue < target) {
*pValue = target;
}
}
}
}
}
return fabsf(target - *pValue);
}
void Math_ApproachF(f32* pValue, f32 target, f32 scale, f32 maxStep) {
f32 f2;
if (*pValue != target) {
f2 = (target - *pValue) * scale;
if (f2 > maxStep) {
f2 = maxStep;
} else if (f2 < -maxStep) {
f2 = -maxStep;
}
*pValue += f2;
}
}
void Math_ApproachZeroF(f32* pValue, f32 scale, f32 maxStep) {
f32 f0 = *pValue * scale;
if (maxStep < f0) {
f0 = maxStep;
} else if (f0 < -maxStep) {
f0 = -maxStep;
}
*pValue = *pValue - f0;
}
s16 Math_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step, s16 minStep) {
s16 stepSize = 0;
s16 diff = target - *pValue;
if (*pValue != target) {
stepSize = diff / scale;
if ((stepSize > minStep) || (stepSize < -minStep)) {
if (stepSize > step) {
stepSize = step;
}
if (stepSize < -step) {
stepSize = -step;
}
*pValue += stepSize;
} else {
if (diff >= 0) {
*pValue += minStep;
if ((s16)(target - *pValue) <= 0) {
*pValue = target;
}
} else {
*pValue -= minStep;
if ((s16)(target - *pValue) >= 0) {
*pValue = target;
}
}
}
}
return diff;
}
void Math_ApproachS(s16* pValue, s16 target, s16 scale, s16 maxStep) {
s16 diff = target - *pValue;
diff /= scale;
if (diff > maxStep) {
*pValue += maxStep;
return;
}
if (diff < -maxStep) {
*pValue -= maxStep;
return;
}
*pValue += diff;
}
void Color_RGBA8_Copy(Color_RGBA8* dst, Color_RGBA8* src) {
dst->r = src->r;
dst->g = src->g;
dst->b = src->b;
dst->a = src->a;
}
void func_801000A4(u16 sfxId) {
play_sound(sfxId);
}
void func_801000CC(u16 sfxId) {
func_8019F128(sfxId);
}
void Lib_PlaySfxAtPos(Vec3f* pos, u16 sfxId) {
Audio_PlaySfxAtPos(pos, sfxId);
}
void Lib_Vec3f_TranslateAndRotateY(Vec3f* translation, s16 rotAngle, Vec3f* src, Vec3f* dst) {
f32 cos;
f32 sin;
cos = Math_CosS(rotAngle);
sin = Math_SinS(rotAngle);
dst->x = translation->x + (src->x * cos + src->z * sin);
dst->y = translation->y + src->y;
dst->z = translation->z + (src->z * cos - src->x * sin);
}
void Lib_LerpRGB(Color_RGB8* a, Color_RGB8* b, f32 t, Color_RGB8* dst) {
f32 aF;
aF = a->r;
dst->r = aF + (b->r - aF) * t;
aF = a->g;
dst->g = aF + (b->g - aF) * t;
aF = a->b;
dst->b = aF + (b->b - aF) * t;
}
f32 Math_Vec3f_StepTo(Vec3f* start, Vec3f* target, f32 speed) {
Vec3f diff;
f32 f2;
f32 f0;
Math_Vec3f_Diff(target, start, &diff);
f0 = Math3D_Vec3fMagnitude(&diff);
if (speed < f0) {
f2 = speed / f0;
f0 = f0 - speed;
start->x = start->x + f2 * diff.x;
start->y = start->y + f2 * diff.y;
start->z = start->z + f2 * diff.z;
} else {
Math_Vec3f_Copy(start, target);
f0 = 0.0f;
}
return f0;
}
void Lib_Nop801004FC(void) {
}
void* Lib_SegmentedToVirtual(void* ptr) {
return SEGMENTED_TO_VIRTUAL(ptr);
}
void* Lib_SegmentedToVirtualNull(void* ptr) {
if (((uintptr_t)ptr >> 28) == 0) {
return ptr;
} else {
return SEGMENTED_TO_VIRTUAL(ptr);
}
}
/*
* Converts a 32-bit virtual address (0x80XXXXXX) to a 24-bit physical address (0xXXXXXX). The NULL case accounts for
* the NULL virtual address being 0x00000000 and not 0x80000000. Used by transition overlays, which store their
* addresses in 24-bit fields.
*/
void* Lib_VirtualToPhysical(void* ptr) {
if (ptr == NULL) {
return NULL;
} else {
return (void*)VIRTUAL_TO_PHYSICAL(ptr);
}
}
/*
* Converts a 24-bit physical address (0xXXXXXX) to a 32-bit virtual address (0x80XXXXXX). The NULL case accounts for
* the NULL virtual address being 0x00000000 and not 0x80000000. Used by transition overlays, which store their
* addresses in 24-bit fields.
*/
void* Lib_PhysicalToVirtual(void* ptr) {
if (ptr == NULL) {
return NULL;
} else {
return (void*)PHYSICAL_TO_VIRTUAL(ptr);
}
}