mirror of
https://github.com/HarbourMasters/Starship.git
synced 2025-02-03 08:43:56 +03:00
1248 lines
52 KiB
C
1248 lines
52 KiB
C
#include "global.h"
|
|
#include "assets/ast_font.h"
|
|
|
|
char D_801619A0[100];
|
|
|
|
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(u16* texture, s32 width, s32 height, u8 mode) {
|
|
// LTodo: [HD-Textures] This is broken
|
|
u16* temp_t0 = LOAD_ASSET(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;
|
|
}
|
|
|
|
// LTodo: we should only invalidate one texture
|
|
gSPInvalidateTexCache(gMasterDisp++, NULL);
|
|
}
|
|
|
|
void Texture_Mottle(u16* dst, u16* src, u8 mode) {
|
|
return;
|
|
s32 var_v1;
|
|
s32 var_s3;
|
|
u8* var_s0_2;
|
|
u8* var_s4_2;
|
|
s32 temp_ft3;
|
|
|
|
// LTodo: [HD-Textures] This is broken
|
|
dst = LOAD_ASSET(dst);
|
|
src = LOAD_ASSET(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++) {
|
|
dst[var_s3 + (temp_ft3 + var_v1) % 32U] = 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++) {
|
|
dst[var_s3 + (temp_ft3 + var_v1) % 64U] = 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++) {
|
|
dst[var_s3 + (temp_ft3 + var_v1) % 16U] = 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++) {
|
|
dst[var_s3 + (temp_ft3 + var_v1) % 32U] = 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];
|
|
}
|
|
}
|
|
}
|
|
|
|
// LTodo: we should only invalidate one texture
|
|
gSPInvalidateTexCache(gMasterDisp++, NULL);
|
|
}
|
|
|
|
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);
|
|
|
|
skeleton = LOAD_ASSET(skeleton);
|
|
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_edisplay_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 = LOAD_ASSET(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* anim, s32 frame, Vec3f* frameTable) {
|
|
Animation* animation = LOAD_ASSET(anim);
|
|
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* anim) {
|
|
Animation* animation = LOAD_ASSET(anim);
|
|
|
|
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 = LOAD_ASSET(skeletonSegment);
|
|
|
|
limb = SEGMENTED_TO_VIRTUAL(skeleton[0]);
|
|
animation = LOAD_ASSET(animationSegment);
|
|
key = SEGMENTED_TO_VIRTUAL(animation->jointKey);
|
|
frameData = 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, 8192, 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) {
|
|
gDPSetTileCustom((*gfxPtr)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, height, 0, G_TX_NOMIRROR | G_TX_CLAMP,
|
|
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gDPSetTextureImage((*gfxPtr)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, texture);
|
|
gDPLoadSync((*gfxPtr)++);
|
|
gDPLoadTile((*gfxPtr)++, G_TX_LOADTILE, 0, 0, width - 1 << 2, height - 1 << 2);
|
|
|
|
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) {
|
|
gDPSetTileCustom((*gfxPtr)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, height, 0, G_TX_NOMIRROR | G_TX_CLAMP,
|
|
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gDPSetTextureImage((*gfxPtr)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, texture);
|
|
gDPLoadSync((*gfxPtr)++);
|
|
gDPLoadTile((*gfxPtr)++, G_TX_LOADTILE, 0, 0, width - 1 << 2, height - 1 << 2);
|
|
|
|
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) {
|
|
gDPSetTileCustom((*gfxPtr)++, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 0, G_TX_NOMIRROR | G_TX_CLAMP,
|
|
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gDPSetTextureImage((*gfxPtr)++, G_IM_FMT_IA, G_IM_SIZ_8b, width, texture);
|
|
gDPLoadSync((*gfxPtr)++);
|
|
gDPLoadTile((*gfxPtr)++, G_TX_LOADTILE, 0, 0, width - 1 << 2, height - 1 << 2);
|
|
|
|
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_game_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_stdlib_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 = LOAD_ASSET(src1);
|
|
u16* var_a2 = LOAD_ASSET(src2);
|
|
u16* var_a3 = LOAD_ASSET(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);
|
|
}
|
|
}
|