//
// Generated by dtk
// Translation Unit: c_lib.cpp
//

#include "SSystem/SComponent/c_lib.h"
#include "MSL_C/string.h"
#include "SSystem/SComponent/c_math.h"
#include "dolphin/mtx/mtxvec.h"


/* 802528A4-802528C4       .text cLib_memCpy__FPvPCvUl */
void cLib_memCpy(void* dst, const void* src, unsigned long size) {
    memcpy(dst, src, size);
}

/* 802528C4-802528E4       .text cLib_memSet__FPviUl */
void cLib_memSet(void* ptr, int value, unsigned long size) {
    memset(ptr, value, size);
}

/* 802528E4-802529A4       .text cLib_addCalc__FPfffff */
f32 cLib_addCalc(f32* pValue, f32 target, f32 scale, f32 maxStep, f32 minStep) {
    if (*pValue != target) {
        f32 step = scale * (target - *pValue);
        if (step >= minStep || step <= -minStep) {
            if (step > maxStep) {
                step = maxStep;
            }
            if (step < -maxStep) {
                step = -maxStep;
            }
            *pValue += step;
        } else {
            if (step > 0) {
                if (step < minStep) {
                    *pValue += minStep;
                    if (*pValue > target) {
                        *pValue = target;
                    }
                }
            } else {
                minStep = -minStep;
                if (step > minStep) {
                    *pValue += minStep;
                    if (*pValue < target) {
                        *pValue = target;
                    }
                }
            }
        }
    }
    return fabsf(target - *pValue);
}

/* 802529A4-802529E8       .text cLib_addCalc2__FPffff */
void cLib_addCalc2(f32* pValue, f32 target, f32 scale, f32 maxStep) {
    if (*pValue != target) {
        f32 step = scale * (target - *pValue);
        if (step > maxStep) {
            step = maxStep;
        } else if (step < -maxStep) {
            step = -maxStep;
        }
        *pValue += step;
    }
}

/* 802529E8-80252A20       .text cLib_addCalc0__FPfff */
void cLib_addCalc0(f32* pValue, f32 scale, f32 maxStep) {
    f32 step = *pValue * scale;
    if (step > maxStep) {
        step = maxStep;
    } else if (step < -maxStep) {
        step = -maxStep;
    }
    *pValue -= step;
}

/* 80252A20-80252C5C       .text cLib_addCalcPos__FP4cXyzRC4cXyzfff */
f32 cLib_addCalcPos(cXyz* pValue, cXyz const& target, f32 scale, f32 maxStep, f32 minStep) {
    if (*pValue != target) {
        cXyz diff = (*pValue - target);
        f32 step = diff.abs();
        if (step < minStep) {
            *pValue = target;
        } else {
            step *= scale;
            diff *= scale;
            if (!cLib_IsZero(step)) {
                if (step > maxStep) {
                    diff *= (maxStep / step);
                } else if (step < minStep) {
                    diff *= (minStep / step);
                }
                *pValue -= diff;
            } else {
                *pValue = target;
            }
        }
    }
    return pValue->abs(target);
}

/* 80252C5C-80252EE0       .text cLib_addCalcPosXZ__FP4cXyzRC4cXyzfff */
f32 cLib_addCalcPosXZ(cXyz* pValue, cXyz const& target, f32 scale, f32 maxStep, f32 minStep) {
    if (pValue->x != target.x || pValue->z != target.z) {
        cXyz diff = (*pValue - target);
        f32 step = diff.absXZ();
        if (step < minStep) {
            pValue->x = target.x;
            pValue->z = target.z;
        } else {
            step *= scale;
            diff *= scale;
            if (!cLib_IsZero(step)) {
                if (step > maxStep) {
                    diff *= (maxStep / step);
                } else if (step < minStep) {
                    diff *= (minStep / step);
                }
                pValue->x -= diff.x;
                pValue->z -= diff.z;
            } else {
                pValue->x = target.x;
                pValue->z = target.z;
            }
        }
    }
    return (*pValue - target).absXZ();
}

/* 80252EE0-80253038       .text cLib_addCalcPos2__FP4cXyzRC4cXyzff */
void cLib_addCalcPos2(cXyz* pValue, cXyz const& target, f32 scale, f32 maxStep) {
    if (*pValue != target) {
        cXyz diff = (*pValue - target) * scale;
        if (diff.abs() > maxStep) {
            diff = diff.normZP();
            diff *= maxStep;
        }
        *pValue -= diff;
    }
}

/* 80253038-802531A8       .text cLib_addCalcPosXZ2__FP4cXyzRC4cXyzff */
void cLib_addCalcPosXZ2(cXyz* pValue, cXyz const& target, f32 scale, f32 maxStep) {
    if (pValue->x != target.x || pValue->z != target.z) {
        cXyz diff = (*pValue - target) * scale;
        f32 step = diff.absXZ();
        if (!cLib_IsZero(step)) {
            if (step > maxStep) {
                diff *= (maxStep / step);
            }
            pValue->x -= diff.x;
            pValue->z -= diff.z;
        }
    }
}

/* 802531A8-80253270       .text cLib_addCalcAngleS__FPsssss */
s16 cLib_addCalcAngleS(s16* pValue, s16 target, s16 scale, s16 maxStep, s16 minStep) {
    s16 diff = target - *pValue;
    if (*pValue != target) {
        s16 step = (diff) / scale;
        if (step > minStep || step < -minStep) {
            if (step > maxStep) {
                step = maxStep;
            }
            if (step < -maxStep) {
                step = -maxStep;
            }
            *pValue += step;
        } else {
            if (0 <= diff) {
                *pValue += minStep;
                diff = target - *pValue;
                if (0 >= diff) {
                    *pValue = target;
                }
            } else {
                *pValue -= minStep;
                diff = target - *pValue;
                if (0 <= diff) {
                    *pValue = target;
                }
            }
        }
    }
    return target - *pValue;
}

/* 80253270-802532C4       .text cLib_addCalcAngleS2__FPssss */
void cLib_addCalcAngleS2(s16* pValue, s16 target, s16 scale, s16 maxStep) {
    s16 diff = target - *pValue;
    s16 step = diff / scale;
    if (step > maxStep) {
        *pValue += maxStep;
    } else if (step < -maxStep) {
        *pValue -= maxStep;
    } else {
        *pValue += step;
    }
}

/* 802532C4-8025335C       .text cLib_addCalcAngleL__FPlllll */
s32 cLib_addCalcAngleL(s32* pValue, s32 target, s32 scale, s32 maxStep, s32 minStep) {
    s32 diff = target - *pValue;
    if (*pValue != target) {
        scale = (diff) / scale;
        if (scale > minStep || scale < -minStep) {
            if (scale > maxStep) {
                scale = maxStep;
            }
            if (scale < -maxStep) {
                scale = -maxStep;
            }
            *pValue += scale;
        } else {
            if (0 <= diff) {
                *pValue += minStep;
                if (0 >= target - *pValue) {
                    *pValue = target;
                }
            } else {
                *pValue -= minStep;
                if (0 <= target - *pValue) {
                    *pValue = target;
                }
            }
        }
    }
    return diff;
}

/* 8025335C-802533D0       .text cLib_chaseUC__FPUcUcUc */
int cLib_chaseUC(u8* pValue, u8 target, u8 step) {
    if (step) {
        s16 wideValue = *pValue;
        s16 wideTarget = target;
        s16 wideStep;
        if (wideValue > wideTarget) {
            wideStep = -step;
        } else {
            wideStep = step;
        }
        wideValue += wideStep;
        if (wideStep * (wideValue - wideTarget) >= 0) {
            *pValue = target;
            return 1;
        } else {
            *pValue = wideValue;
        }
    } else if (*pValue == target) {
        return 1;
    }
    return 0;
}

/* 802533D0-80253440       .text cLib_chaseS__FPsss */
int cLib_chaseS(s16* pValue, s16 target, s16 step) {
    if (step) {
        if (*pValue > target) {
            step = -step;
        }
        *pValue += step;
        if (step * (*pValue - target) >= 0) {
            *pValue = target;
            return 1;
        }
    } else if (*pValue == target) {
        return 1;
    }
    return 0;
}

/* 80253440-802534AC       .text cLib_chaseF__FPfff */
int cLib_chaseF(f32* pValue, f32 target, f32 step) {
    if (step) {
        if (*pValue > target) {
            step = -step;
        }
        *pValue += step;
        if (step * (*pValue - target) >= 0) {
            *pValue = target;
            return 1;
        }
    } else if (*pValue == target) {
        return 1;
    }
    return 0;
}

/* 802534AC-80253610       .text cLib_chasePos__FP4cXyzRC4cXyzf */
int cLib_chasePos(cXyz* pValue, cXyz const& target, f32 step) {
    if (step) {
        cXyz diff = *pValue - target;
        f32 diffF = diff.abs();
        if (cLib_IsZero(diffF) || diffF <= step) {
            *pValue = target;
            return 1;
        }
        *pValue -= diff * (step / diffF);
    } else if (*pValue == target) {
        return 1;
    }
    return 0;
}

/* 80253610-80253790       .text cLib_chasePosXZ__FP4cXyzRC4cXyzf */
int cLib_chasePosXZ(cXyz* pValue, cXyz const& target, f32 step) {
    cXyz diff = *pValue - target;
    diff.y = 0;
    f32 diffF = diff.absXZ();
    if (step) {
        if (cLib_IsZero(diffF) || diffF <= step) {
            *pValue = target;
            return 1;
        }
        *pValue -= diff * (step / diffF);
    } else if (cLib_IsZero(diffF)) {
        return 1;
    }
    return 0;
}

/* 80253790-80253804       .text cLib_chaseAngleS__FPsss */
int cLib_chaseAngleS(s16* pValue, s16 target, s16 step) {
    if (step) {
        if ((s16)(*pValue - target) > 0) {
            step = -step;
        }
        *pValue += step;
        if (step * (s16)(*pValue - target) >= 0) {
            *pValue = target;
            return 1;
        }
    } else if (*pValue == target) {
        return 1;
    }
    return 0;
}

/* 80253804-8025383C       .text cLib_targetAngleY__FP4cXyzP4cXyz */
s16 cLib_targetAngleY(cXyz* lhs, cXyz* rhs) {
    return cM_atan2s(rhs->x - lhs->x, rhs->z - lhs->z);
}

/* 8025383C-80253908       .text cLib_targetAngleX__FP4cXyzP4cXyz */
s16 cLib_targetAngleX(cXyz* lhs, cXyz* rhs) {
    cXyz delta = (*rhs - *lhs);
    f32 dist = delta.absXZ();
    return cM_atan2s(delta.y, dist);
}

/* 80253908-8025397C       .text cLib_offsetPos__FP4cXyzP4cXyzsP4cXyz */
void cLib_offsetPos(cXyz* pDest, cXyz* pSrc, s16 angle, cXyz* vec) {
    f32 cos = cM_scos(angle);
    f32 sin = cM_ssin(angle);
    pDest->x = pSrc->x + (vec->x * cos + vec->z * sin);
    pDest->y = pSrc->y + vec->y;
    pDest->z = pSrc->z + (vec->z * cos - vec->x * sin);
}

/* 8025397C-802539A4       .text cLib_distanceAngleS__Fss */
s32 cLib_distanceAngleS(s16 x, s16 y) {
    return abs(static_cast<s16>(x - y));
}

Mtx mtx[10];

Mtx* calc_mtx = mtx;

/* 802539A4-802539B4       .text MtxInit__Fv */
void MtxInit() {
    calc_mtx = mtx;
}

/* 802539B4-802539FC       .text MtxTrans__FfffUc */
void MtxTrans(f32 x_trans, f32 y_trans, f32 z_trans, u8 concat) {
    if (concat == 0) {
        MTXTrans(*calc_mtx, x_trans, y_trans, z_trans);
    } else {
        Mtx mtx;
        MTXTrans(mtx, x_trans, y_trans, z_trans);
        MTXConcat(*calc_mtx, mtx, *calc_mtx);
    }
}

/* 802539FC-80253A4C       .text MtxRotX__FfUc */
void MtxRotX(f32 rot, u8 concat) {
    if (concat == 0) {
        MTXRotRad(*calc_mtx, 'X', rot);
    } else {
        Mtx mtx;
        MTXRotRad(mtx, 'X', rot);
        MTXConcat(*calc_mtx, mtx, *calc_mtx);
    }
}

/* 80253A4C-80253A9C       .text MtxRotY__FfUc */
void MtxRotY(f32 rot, u8 concat) {
    if (concat == 0) {
        MTXRotRad(*calc_mtx, 'Y', rot);
    } else {
        Mtx mtx;
        MTXRotRad(mtx, 'Y', rot);
        MTXConcat(*calc_mtx, mtx, *calc_mtx);
    }
}

/* 80253A9C-80253AEC       .text MtxRotZ__FfUc */
void MtxRotZ(f32 rot, u8 concat) {
    if (concat == 0) {
        MTXRotRad(*calc_mtx, 'Z', rot);
    } else {
        Mtx mtx;
        MTXRotRad(mtx, 'Z', rot);
        MTXConcat(*calc_mtx, mtx, *calc_mtx);
    }
}

/* 80253AEC-80253B34       .text MtxScale__FfffUc */
void MtxScale(f32 x_trans, f32 y_trans, f32 z_trans, u8 concat) {
    if (concat == 0) {
        MTXScale(*calc_mtx, x_trans, y_trans, z_trans);
    } else {
        Mtx mtx;
        MTXScale(mtx, x_trans, y_trans, z_trans);
        MTXConcat(*calc_mtx, mtx, *calc_mtx);
    }
}

/* 80253B34-80253B64       .text MtxPosition__FP4cXyzP4cXyz */
void MtxPosition(cXyz* src, cXyz* dest) {
    MTXMultVec(*calc_mtx, src, dest);
}

/* 80253B64-80253BA0       .text MtxPush__Fv */
void MtxPush() {
    Mtx mtx;
    MTXCopy(*calc_mtx, mtx);
    calc_mtx++;
    MTXCopy(mtx, *calc_mtx);
}

/* 80253BA0-80253BB0       .text MtxPull__Fv */
Mtx* MtxPull() {
    return calc_mtx--;
}
