Starship/src/main/fox_std_lib.c
petrie911 97f544c557
Improved match for fox_ti, add custom gbi macro, some cleanup (#178)
* splits

* torch

* torch again

* headers

* merges

* format

* matches

* commit

* colpoly

* SY
2024-03-27 17:06:28 -03:00

1225 lines
51 KiB
C

#include "global.h"
char D_801619A0[100];
#include "assets/ast_font.h"
char* Graphics_ClearPrintBuffer(char* buf, s32 fill, s32 len) {
s32 i;
char* ptr = buf;
for (i = len; i > 0; i--) {
*ptr++ = fill;
}
return buf;
}
s32 Graphics_Printf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
Graphics_ClearPrintBuffer(D_801619A0, 0, 100);
Lib_vsPrintf(D_801619A0, fmt, args);
va_end(args);
return 0;
}
void Texture_Scroll(void* texture, s32 width, s32 height, u8 mode) {
u16* temp_t0 = SEGMENTED_TO_VIRTUAL(texture);
u16 temp_a3;
s32 var_a0;
s32 var_t4;
switch (mode) {
case 0:
for (var_a0 = 0; var_a0 < width; var_a0++) {
temp_a3 = temp_t0[var_a0];
for (var_t4 = 1; var_t4 < height; var_t4++) {
temp_t0[(var_t4 - 1) * width + var_a0] = temp_t0[(var_t4) *width + var_a0];
}
temp_t0[(height - 1) * width + var_a0] = temp_a3;
}
break;
case 1:
for (var_a0 = 0; var_a0 < width; var_a0++) {
temp_a3 = temp_t0[(height - 1) * width + var_a0];
for (var_t4 = height - 2; var_t4 >= 0; var_t4--) {
temp_t0[(var_t4 + 1) * width + var_a0] = temp_t0[(var_t4) *width + var_a0];
}
temp_t0[var_a0] = temp_a3;
}
break;
case 2:
for (var_t4 = 0; var_t4 < height; var_t4++) {
temp_a3 = temp_t0[var_t4 * width + width - 1];
for (var_a0 = width - 2; var_a0 >= 0; var_a0--) {
temp_t0[var_t4 * width + var_a0 + 1] = temp_t0[var_t4 * width + var_a0];
}
temp_t0[var_t4 * width] = temp_a3;
}
break;
case 3:
for (var_t4 = 0; var_t4 < height; var_t4++) {
temp_a3 = temp_t0[var_t4 * width];
for (var_a0 = 1; var_a0 < width; var_a0++) {
temp_t0[var_t4 * width + var_a0 - 1] = temp_t0[var_t4 * width + var_a0];
}
temp_t0[var_t4 * width + width - 1] = temp_a3;
}
break;
}
}
void Texture_Mottle(void* dst, void* src, u8 mode) {
s32 var_v1;
s32 var_s3;
u8* var_s0_2;
u8* var_s4_2;
s32 temp_ft3;
dst = SEGMENTED_TO_VIRTUAL(dst);
src = SEGMENTED_TO_VIRTUAL(src);
switch (mode) {
case 2:
for (var_s3 = 0; var_s3 < 32 * 32; var_s3 += 32) {
temp_ft3 = 3.0f * __sinf((s32) (((var_s3 / 32) + (gGameFrameCount / 4)) % 32U) * (2 * M_PI / 32));
for (var_v1 = 0; var_v1 < 32; var_v1++) {
((u16*) dst)[var_s3 + (temp_ft3 + var_v1) % 0x20U] = ((u16*) src)[var_s3 + var_v1];
}
}
break;
case 3:
for (var_s3 = 0; var_s3 < 22 * 64; var_s3 += 64) {
temp_ft3 = __sinf((s32) (((var_s3 / 64) + (gGameFrameCount / 4)) % 32U) * (2 * M_PI / 8));
for (var_v1 = 0; var_v1 < 64; var_v1++) {
((u16*) dst)[var_s3 + (temp_ft3 + var_v1) % 64U] = ((u16*) src)[var_s3 + var_v1];
}
}
break;
case 1:
for (var_s3 = 0; var_s3 < 16 * 16; var_s3 += 16) {
temp_ft3 = 2.0f * __sinf((s32) (((var_s3 / 16) + (gGameFrameCount / 2)) % 16U) * (2 * M_PI / 16));
for (var_v1 = 0; var_v1 < 16; var_v1++) {
((u16*) dst)[var_s3 + (temp_ft3 + var_v1) % 16U] = ((u16*) src)[var_s3 + var_v1];
}
}
break;
case 0:
for (var_s3 = 0; var_s3 < 32 * 32; var_s3 += 32) {
temp_ft3 = 2.0f * __sinf((s32) (((var_s3 / 32) + (gGameFrameCount / 2)) % 32U) * (2 * M_PI / 32));
for (var_v1 = 0; var_v1 < 32; var_v1++) {
((u16*) dst)[var_s3 + (temp_ft3 + var_v1) % 32U] = ((u16*) src)[var_s3 + var_v1];
}
}
break;
case 5:
var_s0_2 = (u8*) dst;
var_s4_2 = (u8*) src;
for (var_s3 = 0; var_s3 < 64 * 64; var_s3 += 64) {
temp_ft3 = 4.0f * __sinf((s32) (((var_s3 / 64) + (gGameFrameCount / 4)) % 32U) * (2 * M_PI / 32));
for (var_v1 = 0; var_v1 < 64; var_v1++) {
var_s0_2[var_s3 + (temp_ft3 + var_v1) % 64U] = var_s4_2[var_s3 + var_v1];
}
}
}
}
s32 Animation_GetLimbIndex(Limb* limb, Limb** skeleton) {
s32 i = 1;
for (i = 1; *skeleton != NULL; i++, skeleton++) {
if (*skeleton == limb) {
return i;
}
}
return 0;
}
void Animation_DrawLimb(s32 mode, Limb* limb, Limb** skeleton, Vec3f* jointTable, OverrideLimbDraw overrideLimbDraw,
PostLimbDraw postLimbDraw, void* data) {
bool override;
s32 limbIndex;
Gfx* dList;
Vec3f trans;
Vec3f rot;
Vec3f pos;
Vec3f origin = { 0.0f, 0.0f, 0.0f };
Matrix_Push(&gCalcMatrix);
limbIndex = Animation_GetLimbIndex(limb, skeleton);
limb = SEGMENTED_TO_VIRTUAL(limb);
rot = jointTable[limbIndex];
trans.x = limb->trans.x;
trans.y = limb->trans.y;
trans.z = limb->trans.z;
dList = limb->dList;
Matrix_Push(&gGfxMatrix);
if (overrideLimbDraw == NULL) {
override = false;
} else {
override = overrideLimbDraw(limbIndex - 1, &dList, &trans, &rot, data);
}
if (!override) {
Matrix_Translate(gCalcMatrix, trans.x, trans.y, trans.z, 1);
Matrix_RotateZ(gCalcMatrix, rot.z * M_DTOR, 1);
Matrix_RotateY(gCalcMatrix, rot.y * M_DTOR, 1);
Matrix_RotateX(gCalcMatrix, rot.x * M_DTOR, 1);
if (dList != NULL) {
if (mode >= 2) {
Matrix_MultVec3f(gCalcMatrix, &origin, &pos);
if (mode != 5) {
func_8005F670(&pos);
}
}
Matrix_Mult(gGfxMatrix, gCalcMatrix, 1);
Matrix_SetGfxMtx(&gMasterDisp);
gSPDisplayList(gMasterDisp++, dList);
}
}
if (postLimbDraw != NULL) {
postLimbDraw(limbIndex - 1, &rot, data);
}
Matrix_Pop(&gGfxMatrix);
if (limb->child != NULL) {
Animation_DrawLimb(mode, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, data);
}
Matrix_Pop(&gCalcMatrix);
if (limb->sibling != NULL) {
Animation_DrawLimb(mode, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, data);
}
}
void Animation_DrawSkeleton(s32 mode, Limb** skeletonSegment, Vec3f* jointTable, OverrideLimbDraw overrideLimbDraw,
PostLimbDraw postLimbDraw, void* data, Matrix* transform) {
bool override;
Limb** skeleton;
Limb* rootLimb;
s32 rootIndex;
Gfx* dList;
Vec3f baseTrans;
Vec3f baseRot;
Matrix_Push(&gCalcMatrix);
Matrix_Copy(gCalcMatrix, transform);
skeleton = SEGMENTED_TO_VIRTUAL(skeletonSegment);
rootLimb = SEGMENTED_TO_VIRTUAL(skeleton[0]);
rootIndex = Animation_GetLimbIndex(skeleton[0], skeleton);
baseRot = jointTable[rootIndex];
if (mode & 1) {
baseTrans.x = rootLimb->trans.x;
baseTrans.y = rootLimb->trans.y;
baseTrans.z = rootLimb->trans.z;
} else {
baseTrans.x = jointTable[0].x;
baseTrans.y = jointTable[0].y;
baseTrans.z = jointTable[0].z;
}
dList = rootLimb->dList;
Matrix_Push(&gGfxMatrix);
if (overrideLimbDraw == NULL) {
override = 0;
} else {
override = overrideLimbDraw(rootIndex - 1, &dList, &baseTrans, &baseRot, data);
}
if (override == 0) {
Matrix_Translate(gCalcMatrix, baseTrans.x, baseTrans.y, baseTrans.z, 1);
Matrix_RotateZ(gCalcMatrix, baseRot.z * M_DTOR, 1);
Matrix_RotateY(gCalcMatrix, baseRot.y * M_DTOR, 1);
Matrix_RotateX(gCalcMatrix, baseRot.x * M_DTOR, 1);
if (dList != NULL) {
Matrix_Mult(gGfxMatrix, gCalcMatrix, 1);
Matrix_SetGfxMtx(&gMasterDisp);
gSPDisplayList(gMasterDisp++, dList);
}
}
if (postLimbDraw != NULL) {
postLimbDraw(rootIndex - 1, &baseRot, data);
}
Matrix_Pop(&gGfxMatrix);
if (rootLimb->child != NULL) {
Animation_DrawLimb(mode, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, data);
}
Matrix_Pop(&gCalcMatrix);
if (mode >= 2) {
Matrix_Mult(gGfxMatrix, gCalcMatrix, 1);
}
}
s16 Animation_GetFrameData(Animation* animationSegmemt, s32 frame, Vec3f* frameTable) {
Animation* animation = SEGMENTED_TO_VIRTUAL(animationSegmemt);
u16 var4 = animation->limbCount;
JointKey* key = SEGMENTED_TO_VIRTUAL(animation->jointKey);
u16* frameData = SEGMENTED_TO_VIRTUAL(animation->frameData);
s32 i;
s32 temp;
temp = (frame < key->xLen) ? frameData[key->x + frame] : frameData[key->x];
frameTable->x = (s16) temp;
temp = (frame < key->yLen) ? frameData[key->y + frame] : frameData[key->y];
frameTable->y = (s16) temp;
temp = (frame < key->zLen) ? frameData[key->z + frame] : frameData[key->z];
frameTable->z = (s16) temp;
frameTable++, key++;
for (i = 1; i <= var4; i++, key++, frameTable++) {
temp = (frame < key->xLen) ? frameData[key->x + frame] : frameData[key->x];
frameTable->x = temp * 360.0f / 65536.0f;
temp = (frame < key->yLen) ? frameData[key->y + frame] : frameData[key->y];
frameTable->y = temp * 360.0f / 65536.0f;
temp = (frame < key->zLen) ? frameData[key->z + frame] : frameData[key->z];
frameTable->z = temp * 360.0f / 65536.0f;
}
return var4 + 1;
}
s32 Animation_GetFrameCount(Animation* animationSegment) {
Animation* animation = SEGMENTED_TO_VIRTUAL(animationSegment);
return animation->frameCount;
}
void Animation_FindBoundingBox(Gfx* dList, s32 len, Vec3f* min, Vec3f* max, s32* vtxFound, s32* vtxCount,
Vtx** vtxList) {
s64* sp44 = SEGMENTED_TO_VIRTUAL(dList);
s64* var_s0;
for (var_s0 = sp44; (s32) (*var_s0 >> 0x38) != G_ENDDL && var_s0 - sp44 < len; var_s0++) {
switch ((s32) (*var_s0 >> 0x38)) {
case G_DL:
Animation_FindBoundingBox(*var_s0 & 0xFFFFFFFF, (*var_s0 >> 0x20) & 0xFFFF, min, max, vtxFound,
vtxCount, vtxList);
break;
case G_VTX:
*vtxList = SEGMENTED_TO_VIRTUAL(*var_s0 & 0xFFFFFFFF);
*vtxCount = (*var_s0 >> 0x30) & 0xF;
break;
case G_TRI1:
if (!*vtxFound) {
*vtxFound = 1;
max->x = min->x = (*vtxList)[*var_s0 & 0xFF].v.ob[0];
max->y = min->y = (*vtxList)[*var_s0 & 0xFF].v.ob[1];
max->z = min->z = (*vtxList)[*var_s0 & 0xFF].v.ob[2];
} else {
min->x = MIN(min->x, (*vtxList)[*var_s0 & 0xFF].v.ob[0]);
min->y = MIN(min->y, (*vtxList)[*var_s0 & 0xFF].v.ob[1]);
min->z = MIN(min->z, (*vtxList)[*var_s0 & 0xFF].v.ob[2]);
max->x = MAX(max->x, (*vtxList)[*var_s0 & 0xFF].v.ob[0]);
max->y = MAX(max->y, (*vtxList)[*var_s0 & 0xFF].v.ob[1]);
max->z = MAX(max->z, (*vtxList)[*var_s0 & 0xFF].v.ob[2]);
}
min->x = MIN(min->x, (*vtxList)[(*var_s0 >> 8) & 0xFF].v.ob[0]);
min->y = MIN(min->y, (*vtxList)[(*var_s0 >> 8) & 0xFF].v.ob[1]);
min->z = MIN(min->z, (*vtxList)[(*var_s0 >> 8) & 0xFF].v.ob[2]);
max->x = MAX(max->x, (*vtxList)[(*var_s0 >> 8) & 0xFF].v.ob[0]);
max->y = MAX(max->y, (*vtxList)[(*var_s0 >> 8) & 0xFF].v.ob[1]);
max->z = MAX(max->z, (*vtxList)[(*var_s0 >> 8) & 0xFF].v.ob[2]);
min->x = MIN(min->x, (*vtxList)[(*var_s0 >> 0x10) & 0xFF].v.ob[0]);
min->y = MIN(min->y, (*vtxList)[(*var_s0 >> 0x10) & 0xFF].v.ob[1]);
min->z = MIN(min->z, (*vtxList)[(*var_s0 >> 0x10) & 0xFF].v.ob[2]);
max->x = MAX(max->x, (*vtxList)[(*var_s0 >> 0x10) & 0xFF].v.ob[0]);
max->y = MAX(max->y, (*vtxList)[(*var_s0 >> 0x10) & 0xFF].v.ob[1]);
max->z = MAX(max->z, (*vtxList)[(*var_s0 >> 0x10) & 0xFF].v.ob[2]);
break;
}
}
}
void Animation_GetDListBoundingBox(Gfx* dList, s32 len, Vec3f* min, Vec3f* max) {
s32 vtxFound = false;
s32 vtxCount;
Vtx* vtxList;
Animation_FindBoundingBox(dList, len, min, max, &vtxFound, &vtxCount, &vtxList);
}
void Animation_GetSkeletonBoundingBox(Limb** skeletonSegment, Animation* animationSegment, s32 frame, Vec3f* min,
Vec3f* max) {
JointKey* key;
u16* frameData;
Animation* animation;
Limb* limb;
u16 var_t6;
s32 vtxFound;
s32 vtxCount;
Vtx* vtxList;
Vec3f boundBox[8];
Vec3f boundBoxRot[8];
s32 i;
Limb** skeleton = (Limb**) SEGMENTED_TO_VIRTUAL(skeletonSegment);
limb = (Limb*) SEGMENTED_TO_VIRTUAL(skeleton[0]);
animation = (Animation*) SEGMENTED_TO_VIRTUAL(animationSegment);
key = (JointKey*) SEGMENTED_TO_VIRTUAL(animation->jointKey);
frameData = (u16*) SEGMENTED_TO_VIRTUAL(animation->frameData);
if (frame < (s16) key[1].zLen) {
var_t6 = frameData[(s16) key[1].z + frame];
} else {
var_t6 = frameData[(s16) key[1].z];
}
Matrix_RotateZ(gGfxMatrix, (((s32) var_t6 * 360.0f) / 65536.0f) * M_DTOR, 0);
if (frame < (s16) key[1].yLen) {
var_t6 = frameData[(s16) key[1].y + frame];
} else {
var_t6 = frameData[(s16) key[1].y];
}
Matrix_RotateY(gGfxMatrix, (((s32) var_t6 * 360.0f) / 65536.0f) * M_DTOR, 1);
if (frame < (s16) key[1].xLen) {
var_t6 = frameData[(s16) key[1].x + frame];
} else {
var_t6 = frameData[(s16) key[1].x];
}
Matrix_RotateX(gGfxMatrix, (((s32) var_t6 * 360.0f) / 65536.0f) * M_DTOR, 1);
vtxFound = false;
if (limb->dList != NULL) {
Animation_FindBoundingBox(limb->dList, 0x2000, min, max, &vtxFound, &vtxCount, &vtxList);
if (vtxFound) {
boundBox[0].x = boundBox[3].x = boundBox[4].x = boundBox[7].x = min->x;
boundBox[0].y = boundBox[1].y = boundBox[4].y = boundBox[5].y = max->y;
boundBox[0].z = boundBox[1].z = boundBox[2].z = boundBox[3].z = max->z;
boundBox[1].x = boundBox[2].x = boundBox[5].x = boundBox[6].x = max->x;
boundBox[2].y = boundBox[3].y = boundBox[6].y = boundBox[7].y = min->y;
boundBox[4].z = boundBox[5].z = boundBox[6].z = boundBox[7].z = min->z;
for (i = 0; i < 8; i++) {
// Matrix_MultVec3f(gGfxMatrix, boundBox[i], boundBoxRot[i]); should logically go here
}
*min = *max = boundBoxRot[0];
for (i = 1; i < 8; i++) {
min->x = MIN(min->x, boundBoxRot[i].x);
max->x = MAX(max->x, boundBoxRot[i].x);
min->y = MIN(min->y, boundBoxRot[i].y);
max->y = MAX(max->y, boundBoxRot[i].y);
min->z = MIN(min->z, boundBoxRot[i].z);
max->z = MAX(max->z, boundBoxRot[i].z);
}
}
}
}
f32 Math_SmoothStepToF(f32* value, f32 target, f32 scale, f32 maxStep, f32 minStep) {
f32 step = target - *value;
if (step != 0.0f) {
step *= scale;
if ((step >= minStep) || (-minStep >= step)) {
if (step > maxStep) {
step = maxStep;
} else if (step < -maxStep) {
step = -maxStep;
}
*value += step;
} else if (step < minStep) { // bug? should check sign, not size.
step = minStep;
*value += step;
if (*value > target) {
*value = target;
}
} else if (step > -minStep) {
step = -minStep;
*value += step;
if (*value < target) {
*value = target;
}
}
}
return step;
}
f32 Math_SmoothStepToAngle(f32* angle, f32 target, f32 scale, f32 maxStep, f32 minStep) {
f32 var_fv1 = target - *angle;
if (var_fv1 != 0.0f) {
if (var_fv1 > 180.0f) {
var_fv1 -= 360.0f;
} else if (var_fv1 < -180.0f) {
var_fv1 += 360.0f;
}
var_fv1 *= scale;
if ((var_fv1 >= minStep) || (-minStep >= var_fv1)) {
if (var_fv1 > maxStep) {
var_fv1 = maxStep;
} else if (var_fv1 < -maxStep) {
var_fv1 = -maxStep;
}
*angle += var_fv1;
} else if (var_fv1 < minStep) { // bug? should check sign, not size.
var_fv1 = minStep;
*angle += minStep;
if (*angle > target) {
*angle = target;
}
} else if (var_fv1 > -minStep) {
var_fv1 = -minStep;
*angle += var_fv1;
if (*angle < target) {
*angle = target;
}
}
}
if (*angle >= 360.0f) {
*angle -= 360.0f;
} else if (*angle < 0.0f) {
*angle += 360.0f;
}
return var_fv1;
}
void Math_SmoothStepToVec3fArray(Vec3f* src, Vec3f* dst, s32 mode, s32 count, f32 scale, f32 maxStep, f32 minStep) {
Vec3f* srcTemp;
Vec3f* dstTemp;
s32 i;
switch (mode) {
case 0:
for (i = 0; i < count; i++) {
dst[i].x = src[i].x;
dst[i].y = src[i].y;
dst[i].z = src[i].z;
}
break;
case 1:
dstTemp = dst;
srcTemp = src;
Math_SmoothStepToF(&dstTemp->x, srcTemp->x, scale, maxStep, minStep);
Math_SmoothStepToF(&dstTemp->y, srcTemp->y, scale, maxStep, minStep);
Math_SmoothStepToF(&dstTemp->z, srcTemp->z, scale, maxStep, minStep);
dstTemp++;
srcTemp++;
for (i = 1; i < count; i++, dstTemp++, srcTemp++) {
Math_SmoothStepToAngle(&dstTemp->x, srcTemp->x, scale, maxStep, minStep);
Math_SmoothStepToAngle(&dstTemp->y, srcTemp->y, scale, maxStep, minStep);
Math_SmoothStepToAngle(&dstTemp->z, srcTemp->z, scale, maxStep, minStep);
}
break;
default:
break;
}
}
s32 Math_PursueVec3f(Vec3f* pos, Vec3f* target, Vec3f* rot, f32 stepSize, f32 scaleTurn, f32 maxTurn, f32 dist) {
Vec3f diff;
f32 targetRotX;
f32 targetRotY;
Vec3f localStep = { 0.0f, 0.0f, 0.0f };
Vec3f worldStep;
Matrix worldTransform;
diff.x = target->x - pos->x;
diff.y = target->y - pos->y;
diff.z = target->z - pos->z;
targetRotY = Math_RadToDeg(Math_Atan2F(diff.x, diff.z));
targetRotX = Math_RadToDeg(-Math_Atan2F(diff.y, sqrtf(SQ(diff.x) + SQ(diff.z))));
Math_SmoothStepToAngle(&rot->y, targetRotY, scaleTurn, maxTurn, 0.0f);
Math_SmoothStepToAngle(&rot->x, targetRotX, scaleTurn, maxTurn, 0.0f);
Matrix_RotateY(&worldTransform, rot->y * M_DTOR, 0);
Matrix_RotateX(&worldTransform, rot->x * M_DTOR, 1);
localStep.z = stepSize;
Matrix_MultVec3fNoTranslate(&worldTransform, &localStep, &worldStep);
pos->x += worldStep.x;
pos->y += worldStep.y;
pos->z += worldStep.z;
diff.x = target->x - pos->x;
diff.y = target->y - pos->y;
diff.z = target->z - pos->z;
return (VEC3F_MAG(&diff)) < dist;
}
void TextureRect_4bCI(Gfx** gfxPtr, void* texture, void* palette, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTLUT_pal16((*gfxPtr)++, 0, palette);
gDPLoadTextureBlock_4b((*gfxPtr)++, texture, G_IM_FMT_CI, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, 0, 0, (s32) (1.0f / xScale * 1024.0f),
(s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_4bCI_Flip(Gfx** gfxPtr, void* texture, void* palette, u32 width, u32 height, f32 xPos, f32 yPos,
f32 xScale, f32 yScale) {
gDPLoadTLUT_pal16((*gfxPtr)++, 0, palette);
gDPLoadTextureBlock_4b((*gfxPtr)++, texture, G_IM_FMT_CI, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangleFlip((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f),
(s32) ((xPos + width * xScale) * 4.0f), (s32) ((yPos + height * yScale) * 4.0f),
G_TX_RENDERTILE, 0, 0, (s32) (1.0f / xScale * 1024.0f), (s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_4bCI_MirX(Gfx** gfxPtr, void* texture, void* palette, u32 width, u32 height, f32 xPos, f32 yPos,
f32 xScale, f32 yScale) {
gDPLoadTLUT_pal16((*gfxPtr)++, 0, palette);
gDPLoadTextureBlock_4b((*gfxPtr)++, texture, G_IM_FMT_CI, width, height, 0, G_TX_MIRROR | G_TX_WRAP,
G_TX_MIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, (width - 1) * 32, 0,
(u16) (s32) (-1.0f / xScale * 1024.0f), (s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_4bCI_MirY(Gfx** gfxPtr, void* texture, void* palette, u32 width, u32 height, f32 xPos, f32 yPos,
f32 xScale, f32 yScale) {
gDPLoadTLUT_pal16((*gfxPtr)++, 0, palette);
gDPLoadTextureBlock_4b((*gfxPtr)++, texture, G_IM_FMT_CI, width, height, 0, G_TX_MIRROR | G_TX_WRAP,
G_TX_MIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, 0, (height - 1) * 32,
(s32) (1.0f / xScale * 1024.0f), (u16) (s32) (-1.0f / yScale * 1024.0f));
}
void TextureRect_8bCI(Gfx** gfxPtr, void* texture, void* palette, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTLUT_pal256((*gfxPtr)++, palette);
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_CI, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, 0, 0, (s32) (1.0f / xScale * 1024.0f),
(s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_16bRGBA(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), 0, 0, 0, (s32) (1.0f / xScale * 1024.0f),
(s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_16bRGBA_MirX(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, (width - 1) * 32, 0,
(u16) (s32) (-1.0f / xScale * 1024.0f), (s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_8bIA(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale, f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), 0, 0, 0, (s32) (1.0f / xScale * 1024.0f),
(s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_8bIA_FilpMirX(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangleFlip((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f),
(s32) ((xPos + height * xScale) * 4.0f), (s32) ((yPos + width * yScale) * 4.0f),
G_TX_RENDERTILE, (width - 1) * 32, 0, (u16) (s32) (-1.0f / yScale * 1024.0f),
(s32) (1.0f / xScale * 1024.0f));
}
void TextureRect_8bIA_FilpMirY(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangleFlip((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f),
(s32) ((xPos + height * xScale) * 4.0f), (s32) ((yPos + width * yScale) * 4.0f),
G_TX_RENDERTILE, 0, (height - 1) * 32, (s32) (1.0f / yScale * 1024.0f),
(u16) (s32) (-1.0f / xScale * 1024.0f));
}
void TextureRect_8bIA_MirX(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, (width - 1) * 32, 0,
(u16) (s32) (-1.0f / xScale * 1024.0f), (s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_8bIA_MirY(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, 0, (height - 1) * 32,
(s32) (1.0f / xScale * 1024.0f), (u16) (s32) (-1.0f / yScale * 1024.0f));
}
void TextureRect_16bIA(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale, f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_16b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, 0, 0, (s32) (1.0f / xScale * 1024.0f),
(s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_16bIA_MirX(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_16b, width, height, 0, G_TX_MIRROR | G_TX_WRAP,
G_TX_MIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, (width - 1) * 32, 0,
(u16) (s32) (-1.0f / xScale * 1024.0f), (s32) (1.0f / yScale * 1024.0f));
}
void TextureRect_16bIA_MirY(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_16b, width, height, 0, G_TX_MIRROR | G_TX_WRAP,
G_TX_MIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, 0, (height - 1) * 32,
(s32) (1.0f / xScale * 1024.0f), (u16) (s32) (-1.0f / yScale * 1024.0f));
}
void TextureRect_16bIA_MirXY(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_IA, G_IM_SIZ_16b, width, height, 0, G_TX_MIRROR | G_TX_WRAP,
G_TX_MIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, (width - 1) * 32, (height - 1) * 32,
(u16) (s32) (-1.0f / xScale * 1024.0f), (u16) (s32) (-1.0f / yScale * 1024.0f));
}
void TextureRect_32bRGBA(Gfx** gfxPtr, void* texture, u32 width, u32 height, f32 xPos, f32 yPos, f32 xScale,
f32 yScale) {
gDPLoadTextureBlock((*gfxPtr)++, texture, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, height, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle((*gfxPtr)++, (s32) (xPos * 4.0f), (s32) (yPos * 4.0f), (s32) ((xPos + width * xScale) * 4.0f),
(s32) ((yPos + height * yScale) * 4.0f), G_TX_RENDERTILE, 0, 0, (s32) (1.0f / xScale * 1024.0f),
(s32) (1.0f / yScale * 1024.0f));
}
void Graphics_FillRectangle(Gfx** gfxPtr, s32 ulx, s32 uly, s32 lrx, s32 lry, u8 r, u8 g, u8 b, u8 a) {
if (a != 0) {
gDPPipeSync((*gfxPtr)++);
gDPSetPrimColor((*gfxPtr)++, 0x00, 0x00, r, g, b, a);
gDPSetColorDither((*gfxPtr)++, G_CD_NOISE);
gDPSetAlphaDither((*gfxPtr)++, G_AD_NOISE);
gDPSetCycleType((*gfxPtr)++, G_CYC_1CYCLE);
gDPSetCombineMode((*gfxPtr)++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
gDPSetRenderMode((*gfxPtr)++, G_RM_CLD_SURF, G_RM_CLD_SURF2);
gDPFillRectangle((*gfxPtr)++, ulx, uly, lrx, lry);
}
}
void Math_Vec3fFromAngles(Vec3f* step, f32 xRot, f32 yRot, f32 stepsize) {
Vec3f sp1C;
Matrix_RotateY(gCalcMatrix, yRot * M_DTOR, 0);
Matrix_RotateX(gCalcMatrix, xRot * M_DTOR, 1);
sp1C.x = sp1C.y = 0.0f;
sp1C.z = stepsize;
Matrix_MultVec3fNoTranslate(gCalcMatrix, &sp1C, step);
}
f32 Math_RadToDeg(f32 rAngle) {
rAngle *= M_RTOD;
while (rAngle < 0.0f) {
rAngle += 360.0f;
}
return rAngle;
}
u16* Graphics_SetupTextureRender(Gfx** gfxPtr, u8 width, u8 height) {
u16* texture;
u16 norm;
width += 0xF;
width &= 0x70;
texture = gTextureRender;
gTextureRender = gTextureRender + width * height;
gDPPipeSync((*gfxPtr)++);
gDPSetCycleType((*gfxPtr)++, G_CYC_FILL);
gDPSetRenderMode((*gfxPtr)++, G_RM_NOOP, G_RM_NOOP2);
gViewport->vp.vscale[0] = width * 2;
gViewport->vp.vscale[1] = height * 2;
gViewport->vp.vscale[2] = G_MAXZ / 2;
gViewport->vp.vscale[3] = 0;
gViewport->vp.vtrans[0] = width * 2;
gViewport->vp.vtrans[1] = height * 2;
gViewport->vp.vtrans[2] = G_MAXZ / 2;
gViewport->vp.vtrans[3] = 0;
gSPViewport((*gfxPtr)++, gViewport++);
gDPSetScissor((*gfxPtr)++, G_SC_NON_INTERLACE, 0, 0, width, height);
gDPSetDepthImage((*gfxPtr)++, &gZBuffer);
gDPSetColorImage((*gfxPtr)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, &gZBuffer);
gDPSetFillColor((*gfxPtr)++, FILL_COLOR(GPACK_ZDZ(G_MAXFBZ, 0)));
gDPFillRectangle((*gfxPtr)++, 0, 0, width - 1, height - 1);
gDPPipeSync((*gfxPtr)++);
gDPSetDepthSource((*gfxPtr)++, G_ZS_PIXEL);
gDPSetColorImage((*gfxPtr)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, texture);
gDPSetColorDither((*gfxPtr)++, G_CD_DISABLE);
gDPSetFillColor((*gfxPtr)++, 0);
gDPSetFillColor((*gfxPtr)++, FILL_COLOR(gBgColor | 1));
gDPFillRectangle((*gfxPtr)++, 0, 0, width - 1, height - 1);
gDPPipeSync((*gfxPtr)++);
guPerspective(gGfxMtx, &norm, D_80161A3C, (f32) width / height, 10.0f, 12800.0f, 1.0f);
gSPPerspNormalize((*gfxPtr)++, norm);
gSPMatrix((*gfxPtr)++, 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((*gfxPtr)++, gGfxMtx++, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
Matrix_Copy(gGfxMatrix, &gIdentityMatrix);
return texture;
}
void Graphics_DisplayHUDNumber(s32 xPos, s32 yPos, s32 number) {
u8* hudNumberTex[] = { D_1010660, D_10106B0, D_1010700, D_1010750, D_10107A0,
D_10107F0, D_1010840, D_1010890, D_10108E0, D_1010930 };
u16* hudNumberPal[] = { D_10106A0, D_10106F0, D_1010740, D_1010790, D_10107E0,
D_1010830, D_1010880, D_10108D0, D_1010920, D_1010970 };
s32 place;
s32 startNumber = false;
number %= 10000000;
place = 1000000;
for (place = 1000000; place != 1; place /= 10) {
if ((number / place != 0) || (startNumber == true)) {
TextureRect_4bCI(&gMasterDisp, hudNumberTex[number / place], hudNumberPal[number / place], 16, 8, xPos,
yPos, 1.0f, 1.0f);
startNumber = true;
xPos += 9;
number %= place;
}
}
TextureRect_4bCI(&gMasterDisp, hudNumberTex[number / place], hudNumberPal[number / place], 16, 8, xPos, yPos, 1.0f,
1.0f);
}
u8* sSmallNumberTex[] = { D_5000000, D_5000080, D_5000100, D_5000180, D_5000200,
D_5000280, D_5000300, D_5000380, D_5000400, D_5000480 };
void Graphics_DisplaySmallNumber(s32 xPos, s32 yPos, s32 number) {
s32 place;
s32 startNumber = false;
number %= 10000000;
place = 1000000;
for (place = 1000000; place != 1; place /= 10) {
if ((number / place != 0) || (startNumber == true)) {
TextureRect_8bIA(&gMasterDisp, sSmallNumberTex[number / place], 16, 8, xPos, yPos, 1.0f, 1.0f);
startNumber = true;
xPos += 9;
number %= place;
}
}
TextureRect_8bIA(&gMasterDisp, sSmallNumberTex[number / place], 16, 8, xPos, yPos, 1.0f, 1.0f);
}
char sSmallChars[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ!:-.0123456789";
char sLargeChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ. 0123456789st-";
u8 sLargeCharWidths[] = { 15, 14, 14, 13, 13, 13, 14, 14, 5, 12, 14, 12, 16, 14, 15, 13, 16, 14, 13, 13, 13,
16, 17, 17, 16, 13, 5, 16, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 10, 9, 14, 0 };
void* sLargeCharTex[] = {
D_5008020, D_5008110, D_5008200, D_50082F0, D_50083E0, D_50084D0, D_50085C0, D_50086B0, D_50087A0,
D_5008890, D_5008980, D_5008A70, D_5008B60, D_5008C50, D_5008D40, D_5008E30, D_5008F20, D_5009010,
D_5009100, D_50091F0, D_50092E0, D_50093D0, D_50094C0, D_50096A0, D_5009880, D_5009A60, D_5009DB0,
NULL, D_5009F60, D_500A050, D_500A140, D_500A230, D_500A320, D_500A410, D_500A500, D_500A5F0,
D_500A6E0, D_500A7D0, D_5009B50, D_5009C40, D_5009970,
};
void* sLargeNumberTex[] = {
D_5009F60, D_500A050, D_500A140, D_500A230, D_500A320, D_500A410, D_500A500, D_500A5F0, D_500A6E0, D_500A7D0,
};
void* sSmallCharTex[] = { NULL, D_50070C0, D_5007100, D_5007180, D_50071C0, D_5007200, D_5007510,
D_5007550, D_5007590, D_50075D0, D_5007610, D_5007650, D_5007F60, D_5007FA0,
D_5007FE0, D_5009D30, D_5009D70, D_5009EA0, D_5009EE0, D_5009F20, D_500B380,
D_500B440, D_500B480, D_500B4C0, D_500B500, D_500B540, D_500B5C0, D_5007140,
D_500B400, D_500B580, D_500B3C0, D_5000000, D_5000080, D_5000100, D_5000180,
D_5000200, D_5000280, D_5000300, D_5000380, D_5000400, D_5000480 };
void Graphics_DisplayLargeText(s32 xPos, s32 yPos, f32 xScale, f32 yScale, char* text) {
u32 charIndex;
f32 xPosCurrent = xPos;
s32 pad4C;
s32 width;
s32 startPrint = false;
while (text[0] != 0) {
charIndex = 0;
while ((charIndex < ARRAY_COUNT(sLargeChars)) && sLargeChars[charIndex] != text[0]) {
charIndex++;
}
if (sLargeChars[charIndex] == text[0]) {
if ((startPrint == true) && (text[-1] == 'Y') && (text[0] == 'A')) {
xPosCurrent -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'A')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'O')) {
xPosCurrent -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'T') && (text[0] == 'A')) {
xPosCurrent -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'Y')) {
xPosCurrent -= 4.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'I')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'O')) {
xPosCurrent -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'J')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'W') && (text[0] == 'A')) {
xPosCurrent -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'Y') && (text[0] == 'O')) {
xPosCurrent -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'T')) {
xPosCurrent -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'W')) {
xPosCurrent -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'O') && (text[0] == 'T')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'G')) {
xPosCurrent -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'O') && (text[0] == 'Y')) {
xPosCurrent -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'J')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'T') && (text[0] == 'O')) {
xPosCurrent -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'U')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'S')) {
xPosCurrent -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'R') && (text[0] == 'O')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'Y')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'N') && (text[0] == 'J')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'E')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'S') && (text[0] == 't')) {
xPosCurrent -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'X') && (text[0] == 'X')) {
xPosCurrent -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'O') && (text[0] == 'X')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'W') && (text[0] == 'W')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'X') && (text[0] == 'W')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'W') && (text[0] == 'X')) {
xPosCurrent -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'H') && (text[0] == 'O')) {
xPosCurrent += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'J') && (text[0] == 'I')) {
xPosCurrent += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'I') && (text[0] == 'N')) {
xPosCurrent += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'I') && (text[0] == 'M')) {
xPosCurrent += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'I') && (text[0] == 'D')) {
xPosCurrent += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'U') && (text[0] == 'K')) {
xPosCurrent += 1.0f;
}
if (sLargeCharTex[charIndex] != NULL) {
width = 16;
if ((text[0] == 'W') || (text[0] == 'X')) {
width = 32;
}
TextureRect_8bIA(&gMasterDisp, sLargeCharTex[charIndex], width, 15, xPosCurrent, yPos, xScale, yScale);
}
startPrint = true;
xPosCurrent += (sLargeCharWidths[charIndex] * xScale) + 2.0f;
}
text++;
}
}
s32 Graphics_GetLargeTextWidth(char* text) {
s32 startPrint = false;
s32 xPos = 0;
u32 charIndex;
while (text[0] != 0) {
charIndex = 0;
while ((charIndex < ARRAY_COUNT(sLargeChars)) && sLargeChars[charIndex] != text[0]) {
charIndex++;
}
if (sLargeChars[charIndex] == text[0]) {
if ((startPrint == true) && (text[-1] == 'Y') && (text[0] == 'A')) {
xPos -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'A')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'O')) {
xPos -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'T') && (text[0] == 'A')) {
xPos -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'Y')) {
xPos -= 4.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'I')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'O')) {
xPos -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'J')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'W') && (text[0] == 'A')) {
xPos -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'Y') && (text[0] == 'O')) {
xPos -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'T')) {
xPos -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'W')) {
xPos -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'O') && (text[0] == 'T')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'G')) {
xPos -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'O') && (text[0] == 'Y')) {
xPos -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'J')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'T') && (text[0] == 'O')) {
xPos -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'U')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'A') && (text[0] == 'S')) {
xPos -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'R') && (text[0] == 'O')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'Y')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'N') && (text[0] == 'J')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'K') && (text[0] == 'E')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'S') && (text[0] == 't')) {
xPos -= 2.0f;
}
if ((startPrint == true) && (text[-1] == 'X') && (text[0] == 'X')) {
xPos -= 3.0f;
}
if ((startPrint == true) && (text[-1] == 'O') && (text[0] == 'X')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'W') && (text[0] == 'W')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'X') && (text[0] == 'W')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'W') && (text[0] == 'X')) {
xPos -= 1.0f;
}
if ((startPrint == true) && (text[-1] == 'H') && (text[0] == 'O')) {
xPos += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'J') && (text[0] == 'I')) {
xPos += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'I') && (text[0] == 'N')) {
xPos += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'I') && (text[0] == 'M')) {
xPos += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'I') && (text[0] == 'D')) {
xPos += 1.0f;
}
if ((startPrint == true) && (text[-1] == 'U') && (text[0] == 'K')) {
xPos += 1.0f;
}
startPrint = true;
xPos += sLargeCharWidths[charIndex] + 2.0f;
}
text++;
}
return xPos;
}
void Graphics_DisplayLargeNumber(s32 xPos, s32 yPos, s32 number) {
s32 place;
s32 startNumber = false;
number %= 10000000;
place = 1000000;
for (place = 1000000; place != 1; place /= 10) {
if ((number / place != 0) || (startNumber == true)) {
TextureRect_8bIA(&gMasterDisp, sLargeNumberTex[number / place], 16, 15, xPos, yPos, 1.0f, 1.0f);
startNumber = true;
xPos += 13;
number %= place;
}
}
TextureRect_8bIA(&gMasterDisp, sLargeNumberTex[number / place], 16, 15, xPos, yPos, 1.0f, 1.0f);
}
void Graphics_DisplaySmallText(s32 xPos, s32 yPos, f32 xScale, f32 yScale, char* text) {
u32 var_t0;
f32 xPosCurrent = xPos;
s32 width;
while (text[0] != 0) {
var_t0 = 0;
while ((var_t0 < ARRAY_COUNT(sSmallChars)) && sSmallChars[var_t0] != text[0]) {
var_t0++;
}
if (sSmallChars[var_t0] == text[0]) {
if (sSmallCharTex[var_t0] != NULL) {
width = 8;
if (var_t0 > 30) {
width = 16;
}
TextureRect_8bIA(&gMasterDisp, sSmallCharTex[var_t0], width, 8, xPosCurrent, yPos, xScale, yScale);
if (1) {}
}
switch (text[0]) {
case '!':
case ':':
case 'I':
xPosCurrent += 4.0f * xScale;
break;
case '-':
xPosCurrent += 6.0f * xScale;
break;
default:
if (var_t0 > 29) {
xPosCurrent += 9.0f * xScale;
} else {
xPosCurrent += 8.0f * xScale;
}
}
}
text++;
}
}
s32 Graphics_GetSmallTextWidth(char* text) {
u32 charIndex;
s32 xPos = 0;
while (text[0] != 0) {
charIndex = 0;
while ((charIndex < ARRAY_COUNT(sSmallChars)) && sSmallChars[charIndex] != text[0]) {
charIndex++;
}
if (sSmallChars[charIndex] == text[0]) {
switch (text[0]) {
case '!':
case ':':
case 'I':
xPos += 4.0f;
break;
case '-':
xPos += 6.0f;
break;
default:
if (charIndex > 29) {
xPos += 9.0f;
} else {
xPos += 8.0f;
}
}
}
text++;
}
return xPos;
}
void func_800A1540(s32 arg0, s32 arg1, s32 arg2, s32 arg3) {
}
// 20 kinds of fake. Try to improve it here: https://decomp.me/scratch/NMQZB
void Texture_BlendRGBA16(f32 weight, u16 size, u16* src1, u16* src2, u16* dst) {
s32 i;
u16* var_a1 = SEGMENTED_TO_VIRTUAL(src1);
u16* var_a2 = SEGMENTED_TO_VIRTUAL(src2);
u16* var_a3 = SEGMENTED_TO_VIRTUAL(dst);
u16 temp1;
u16 temp2;
u16 temp3;
f32 r1;
f32 g1;
f32 b1;
s32 a1;
f32 r2;
f32 g2;
f32 b2;
s32 a2;
f32 red;
f32 grn;
f32 blu;
g2 = RGBA16_GRN(temp2); // mega fake
for (i = 0; i < size; i++) {
temp1 = var_a1[i];
r1 = RGBA16_RED(temp1);
g1 = RGBA16_GRN(temp1);
b1 = RGBA16_BLU(temp1);
temp1 = temp1 & 1; // fake?
if (1) {} // fake?
temp2 = var_a2[i];
r2 = RGBA16_RED(temp2);
g2 = RGBA16_GRN(temp2);
b2 = RGBA16_BLU(temp2);
a2 = temp2 & 1;
red = (r2 - r1) * weight / 100.0f + r1;
grn = (g2 - g1) * weight / 100.0f + g1;
blu = (b2 - b1) * weight / 100.0f + b1;
var_a3[i] = ((u16) (red * 2048.0f) & 0xF800) | ((u16) (grn * 64.0f) & 0x7C0) | ((u16) (blu * 2.0f) & 0x3E) |
(temp1 | a2 & 1);
}
}