mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 13:35:12 +00:00
WIP: uncapped framerate 3
This commit is contained in:
parent
e8fe92bdad
commit
02ab54b3ad
13 changed files with 437 additions and 260 deletions
|
@ -11,6 +11,7 @@
|
|||
#include "audio/external.h"
|
||||
#include "textures.h"
|
||||
#include "game/rendering_graph_node.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
||||
/**
|
||||
* This file implements environment effects that are not snow:
|
||||
|
@ -36,17 +37,26 @@ Vtx_t gBubbleTempVtx[3] = {
|
|||
{ { 0, 0, 0 }, 0, { -498, 964 }, { 0xFF, 0xFF, 0xFF, 0xFF } },
|
||||
};
|
||||
|
||||
static Gfx sGfxSaved[60 / 5];
|
||||
static Gfx *sBubbleInterpolatedDisplayListPos[60 / 5];
|
||||
static Vec3s sPrevBubblePositions[60];
|
||||
Gfx *envfx_update_bubble_particles_internal(s32 mode, UNUSED Vec3s marioPos, Vec3s camFrom, Vec3s camTo, u8 interpolated);
|
||||
|
||||
void patch_interpolated_bubble_particles(void) {
|
||||
s32 i;
|
||||
for (i = 0; i < 60 / 5; i++) {
|
||||
if (sBubbleInterpolatedDisplayListPos[i] != NULL) {
|
||||
*sBubbleInterpolatedDisplayListPos[i] = sGfxSaved[i];
|
||||
sBubbleInterpolatedDisplayListPos[i] = NULL;
|
||||
static s32 sBubbleGfxMode;
|
||||
static Gfx* sBubbleGfxPos;
|
||||
static Vtx* sBubbleInternalGfxPos[65 / 5];
|
||||
static Vec3s sBubbleGfxCamFrom;
|
||||
static Vec3s sBubbleGfxCamTo;
|
||||
|
||||
void patch_bubble_particles_before(void) {
|
||||
if (sBubbleGfxPos) {
|
||||
for (s32 i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
}
|
||||
sBubbleGfxPos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void patch_bubble_particles_interpolated(UNUSED f32 delta) {
|
||||
if (sBubbleGfxPos) {
|
||||
envfx_update_bubble_particles_internal(sBubbleGfxMode, NULL, sBubbleGfxCamFrom, sBubbleGfxCamTo, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,6 +113,7 @@ void envfx_update_flower(Vec3s centerPos) {
|
|||
(gEnvFxBuffer + i)->zPos, &floorGeo);
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->animFrame = random_float() * 5.0f;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
} else if ((timer & 0x03) == 0) {
|
||||
(gEnvFxBuffer + i)->animFrame += 1;
|
||||
if ((gEnvFxBuffer + i)->animFrame > 5) {
|
||||
|
@ -147,8 +158,7 @@ void envfx_set_lava_bubble_position(s32 index, Vec3s centerPos) {
|
|||
(gEnvFxBuffer + index)->zPos = -16000 - (gEnvFxBuffer + index)->zPos;
|
||||
}
|
||||
|
||||
floorY =
|
||||
find_floor((gEnvFxBuffer + index)->xPos, centerY + 500, (gEnvFxBuffer + index)->zPos, &surface);
|
||||
floorY = find_floor((gEnvFxBuffer + index)->xPos, centerY + 500, (gEnvFxBuffer + index)->zPos, &surface);
|
||||
if (surface == NULL) {
|
||||
(gEnvFxBuffer + index)->yPos = FLOOR_LOWER_LIMIT_MISC;
|
||||
return;
|
||||
|
@ -178,6 +188,7 @@ void envfx_update_lava(Vec3s centerPos) {
|
|||
for (i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
if ((gEnvFxBuffer + i)->isAlive == 0) {
|
||||
envfx_set_lava_bubble_position(i, centerPos);
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
} else if ((timer & 0x01) == 0) {
|
||||
(gEnvFxBuffer + i)->animFrame += 1;
|
||||
|
@ -257,10 +268,13 @@ void envfx_update_whirlpool(void) {
|
|||
(gEnvFxBuffer + i)->unusedBubbleVar = 0;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
|
||||
envfx_rotate_around_whirlpool(&(gEnvFxBuffer + i)->xPos, &(gEnvFxBuffer + i)->yPos,
|
||||
&(gEnvFxBuffer + i)->zPos);
|
||||
} else {
|
||||
}
|
||||
|
||||
if ((gEnvFxBuffer + i)->isAlive != 0) {
|
||||
(gEnvFxBuffer + i)->angleAndDist[1] -= 40;
|
||||
(gEnvFxBuffer + i)->angleAndDist[0] +=
|
||||
(s16)(3000 - (gEnvFxBuffer + i)->angleAndDist[1] * 2) + 0x400;
|
||||
|
@ -307,15 +321,11 @@ void envfx_update_jetstream(void) {
|
|||
if ((gEnvFxBuffer + i)->isAlive == 0) {
|
||||
(gEnvFxBuffer + i)->angleAndDist[1] = random_float() * 300.0f;
|
||||
(gEnvFxBuffer + i)->angleAndDist[0] = random_u16();
|
||||
(gEnvFxBuffer + i)->xPos =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_X]
|
||||
+ sins((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->zPos =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_Z]
|
||||
+ coss((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->yPos =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_Y] + (random_float() * 400.0f - 200.0f);
|
||||
(gEnvFxBuffer + i)->xPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_X] + sins((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->zPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_Z] + coss((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->yPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_Y] + (random_float() * 400.0f - 200.0f);
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
} else {
|
||||
(gEnvFxBuffer + i)->angleAndDist[1] += 10;
|
||||
(gEnvFxBuffer + i)->xPos += sins((gEnvFxBuffer + i)->angleAndDist[0]) * 10.0f;
|
||||
|
@ -381,31 +391,31 @@ s32 envfx_init_bubble(s32 mode) {
|
|||
* Also sets the given vertices to the correct shape for each mode,
|
||||
* though they are not being rotated yet.
|
||||
*/
|
||||
void envfx_bubbles_update_switch(s32 mode, Vec3s camTo, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3) {
|
||||
void envfx_bubbles_update_switch(s32 mode, Vec3s camTo, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3, u8 interpolated) {
|
||||
switch (mode) {
|
||||
case ENVFX_FLOWERS:
|
||||
envfx_update_flower(camTo);
|
||||
if (!interpolated) { envfx_update_flower(camTo); }
|
||||
vertex1[0] = 50; vertex1[1] = 0; vertex1[2] = 0;
|
||||
vertex2[0] = 0; vertex2[1] = 75; vertex2[2] = 0;
|
||||
vertex3[0] = -50; vertex3[1] = 0; vertex3[2] = 0;
|
||||
break;
|
||||
|
||||
case ENVFX_LAVA_BUBBLES:
|
||||
envfx_update_lava(camTo);
|
||||
if (!interpolated) { envfx_update_lava(camTo); }
|
||||
vertex1[0] = 100; vertex1[1] = 0; vertex1[2] = 0;
|
||||
vertex2[0] = 0; vertex2[1] = 150; vertex2[2] = 0;
|
||||
vertex3[0] = -100; vertex3[1] = 0; vertex3[2] = 0;
|
||||
break;
|
||||
|
||||
case ENVFX_WHIRLPOOL_BUBBLES:
|
||||
envfx_update_whirlpool();
|
||||
if (!interpolated) { envfx_update_whirlpool(); }
|
||||
vertex1[0] = 40; vertex1[1] = 0; vertex1[2] = 0;
|
||||
vertex2[0] = 0; vertex2[1] = 60; vertex2[2] = 0;
|
||||
vertex3[0] = -40; vertex3[1] = 0; vertex3[2] = 0;
|
||||
break;
|
||||
|
||||
case ENVFX_JETSTREAM_BUBBLES:
|
||||
envfx_update_jetstream();
|
||||
if (!interpolated) { envfx_update_jetstream(); }
|
||||
vertex1[0] = 40; vertex1[1] = 0; vertex1[2] = 0;
|
||||
vertex2[0] = 0; vertex2[1] = 60; vertex2[2] = 0;
|
||||
vertex3[0] = -40; vertex3[1] = 0; vertex3[2] = 0;
|
||||
|
@ -419,9 +429,15 @@ void envfx_bubbles_update_switch(s32 mode, Vec3s camTo, Vec3s vertex1, Vec3s ver
|
|||
* that will be translated to bubble positions to draw the bubble image
|
||||
*/
|
||||
void append_bubble_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3,
|
||||
Vtx *template) {
|
||||
Vtx *template, u8 interpolated) {
|
||||
s32 i = 0;
|
||||
Vtx *vertBuf = alloc_display_list(15 * sizeof(Vtx));
|
||||
Vtx *vertBuf;
|
||||
if (interpolated) {
|
||||
vertBuf = sBubbleInternalGfxPos[index/5];
|
||||
} else {
|
||||
vertBuf = alloc_display_list(15 * sizeof(Vtx));
|
||||
sBubbleInternalGfxPos[index/5] = vertBuf;
|
||||
}
|
||||
|
||||
if (vertBuf == NULL) {
|
||||
return;
|
||||
|
@ -429,19 +445,37 @@ void append_bubble_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s verte
|
|||
|
||||
for (i = 0; i < 15; i += 3) {
|
||||
vertBuf[i] = template[0];
|
||||
(vertBuf + i)->v.ob[0] = (gEnvFxBuffer + (index + i / 3))->xPos + vertex1[0];
|
||||
(vertBuf + i)->v.ob[1] = (gEnvFxBuffer + (index + i / 3))->yPos + vertex1[1];
|
||||
(vertBuf + i)->v.ob[2] = (gEnvFxBuffer + (index + i / 3))->zPos + vertex1[2];
|
||||
s32 xPos;
|
||||
s32 yPos;
|
||||
s32 zPos;
|
||||
|
||||
s32 particleIndex = (index + i / 3);
|
||||
struct EnvFxParticle* particle = (gEnvFxBuffer + particleIndex);
|
||||
|
||||
if (interpolated) {
|
||||
extern f32 gRenderingDelta;
|
||||
xPos = delta_interpolate_s32(particle->prevPos[0], particle->xPos, gRenderingDelta);
|
||||
yPos = delta_interpolate_s32(particle->prevPos[1], particle->yPos, gRenderingDelta);
|
||||
zPos = delta_interpolate_s32(particle->prevPos[2], particle->zPos, gRenderingDelta);
|
||||
} else {
|
||||
xPos = particle->prevPos[0];
|
||||
yPos = particle->prevPos[1];
|
||||
zPos = particle->prevPos[2];
|
||||
}
|
||||
|
||||
(vertBuf + i)->v.ob[0] = xPos + vertex1[0];
|
||||
(vertBuf + i)->v.ob[1] = yPos + vertex1[1];
|
||||
(vertBuf + i)->v.ob[2] = zPos + vertex1[2];
|
||||
|
||||
vertBuf[i + 1] = template[1];
|
||||
(vertBuf + i + 1)->v.ob[0] = (gEnvFxBuffer + (index + i / 3))->xPos + vertex2[0];
|
||||
(vertBuf + i + 1)->v.ob[1] = (gEnvFxBuffer + (index + i / 3))->yPos + vertex2[1];
|
||||
(vertBuf + i + 1)->v.ob[2] = (gEnvFxBuffer + (index + i / 3))->zPos + vertex2[2];
|
||||
(vertBuf + i + 1)->v.ob[0] = xPos + vertex2[0];
|
||||
(vertBuf + i + 1)->v.ob[1] = yPos + vertex2[1];
|
||||
(vertBuf + i + 1)->v.ob[2] = zPos + vertex2[2];
|
||||
|
||||
vertBuf[i + 2] = template[2];
|
||||
(vertBuf + i + 2)->v.ob[0] = (gEnvFxBuffer + (index + i / 3))->xPos + vertex3[0];
|
||||
(vertBuf + i + 2)->v.ob[1] = (gEnvFxBuffer + (index + i / 3))->yPos + vertex3[1];
|
||||
(vertBuf + i + 2)->v.ob[2] = (gEnvFxBuffer + (index + i / 3))->zPos + vertex3[2];
|
||||
(vertBuf + i + 2)->v.ob[0] = xPos + vertex3[0];
|
||||
(vertBuf + i + 2)->v.ob[1] = yPos + vertex3[1];
|
||||
(vertBuf + i + 2)->v.ob[2] = zPos + vertex3[2];
|
||||
}
|
||||
|
||||
gSPVertex(gfx, VIRTUAL_TO_PHYSICAL(vertBuf), 15, 0);
|
||||
|
@ -478,28 +512,25 @@ void envfx_set_bubble_texture(s32 mode, s16 index) {
|
|||
gSPDisplayList(sGfxCursor++, &tiny_bubble_dl_0B006D68);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the bubble particle positions, then generates and returns a display
|
||||
* list drawing them.
|
||||
*/
|
||||
Gfx *envfx_update_bubble_particles(s32 mode, UNUSED Vec3s marioPos, Vec3s camFrom, Vec3s camTo) {
|
||||
Gfx *envfx_update_bubble_particles_internal(s32 mode, UNUSED Vec3s marioPos, Vec3s camFrom, Vec3s camTo, u8 interpolated) {
|
||||
s32 i;
|
||||
s16 radius, pitch, yaw;
|
||||
|
||||
Vec3s vertex1 = { 0 };
|
||||
Vec3s vertex2 = { 0 };
|
||||
Vec3s vertex3 = { 0 };
|
||||
Vec3s interpolatedVertices[3] = { 0 };
|
||||
|
||||
static Vec3s prevVertex1;
|
||||
static Vec3s prevVertex2;
|
||||
static Vec3s prevVertex3;
|
||||
static u32 prevTimestamp;
|
||||
|
||||
Gfx *gfxStart;
|
||||
if (interpolated) {
|
||||
gfxStart = sBubbleGfxPos;
|
||||
} else {
|
||||
gfxStart = alloc_display_list(((sBubbleParticleMaxCount / 5) * 10 + sBubbleParticleMaxCount + 3) * sizeof(Gfx));
|
||||
sBubbleGfxPos = gfxStart;
|
||||
sBubbleGfxMode = mode;
|
||||
vec3s_copy(sBubbleGfxCamFrom, camFrom);
|
||||
vec3s_copy(sBubbleGfxCamTo, camTo);
|
||||
}
|
||||
|
||||
gfxStart = alloc_display_list(((sBubbleParticleMaxCount / 5) * 10 + sBubbleParticleMaxCount + 3)
|
||||
* sizeof(Gfx));
|
||||
if (gfxStart == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -507,60 +538,21 @@ Gfx *envfx_update_bubble_particles(s32 mode, UNUSED Vec3s marioPos, Vec3s camFro
|
|||
sGfxCursor = gfxStart;
|
||||
|
||||
orbit_from_positions(camTo, camFrom, &radius, &pitch, &yaw);
|
||||
envfx_bubbles_update_switch(mode, camTo, vertex1, vertex2, vertex3);
|
||||
envfx_bubbles_update_switch(mode, camTo, vertex1, vertex2, vertex3, interpolated);
|
||||
rotate_triangle_vertices(vertex1, vertex2, vertex3, pitch, yaw);
|
||||
|
||||
if (gGlobalTimer == prevTimestamp + 1) {
|
||||
// TODO: fixme
|
||||
//interpolate_vectors_s16(interpolatedVertices[0], prevVertex1, vertex1);
|
||||
vec3s_copy(interpolatedVertices[0], vertex1);
|
||||
//interpolate_vectors_s16(interpolatedVertices[1], prevVertex2, vertex2);
|
||||
vec3s_copy(interpolatedVertices[1], vertex2);
|
||||
//interpolate_vectors_s16(interpolatedVertices[2], prevVertex3, vertex3);
|
||||
vec3s_copy(interpolatedVertices[2], vertex3);
|
||||
}
|
||||
vec3s_copy(prevVertex1, vertex1);
|
||||
vec3s_copy(prevVertex2, vertex2);
|
||||
vec3s_copy(prevVertex3, vertex3);
|
||||
prevTimestamp = gGlobalTimer;
|
||||
|
||||
gSPDisplayList(sGfxCursor++, &tiny_bubble_dl_0B006D38);
|
||||
|
||||
for (i = 0; i < sBubbleParticleMaxCount; i += 5) {
|
||||
Vtx *interpolatedVertBuf = alloc_display_list(15 * sizeof(Vtx));
|
||||
if (interpolatedVertBuf == NULL) { continue; }
|
||||
s32 j, k;
|
||||
gDPPipeSync(sGfxCursor++);
|
||||
envfx_set_bubble_texture(mode, i);
|
||||
sBubbleInterpolatedDisplayListPos[i / 5] = sGfxCursor;
|
||||
for (j = 0; j < 5; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
Vtx *v = &interpolatedVertBuf[j * 3 + k];
|
||||
v->v = gBubbleTempVtx[k];
|
||||
if (gGlobalTimer != gEnvFxBuffer[i + j].spawnTimestamp && mode != ENVFX_LAVA_BUBBLES) {
|
||||
v->v.ob[0] = (sPrevBubblePositions[i + j][0] + gEnvFxBuffer[i + j].xPos) / 2.0f + interpolatedVertices[k][0];
|
||||
v->v.ob[1] = (sPrevBubblePositions[i + j][1] + gEnvFxBuffer[i + j].yPos) / 2.0f + interpolatedVertices[k][1];
|
||||
v->v.ob[2] = (sPrevBubblePositions[i + j][2] + gEnvFxBuffer[i + j].zPos) / 2.0f + interpolatedVertices[k][2];
|
||||
} else {
|
||||
v->v.ob[0] = gEnvFxBuffer[i + j].xPos + interpolatedVertices[k][0];
|
||||
v->v.ob[1] = gEnvFxBuffer[i + j].yPos + interpolatedVertices[k][1];
|
||||
v->v.ob[2] = gEnvFxBuffer[i + j].zPos + interpolatedVertices[k][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
gSPVertex(sGfxCursor++, VIRTUAL_TO_PHYSICAL(interpolatedVertBuf), 15, 0);
|
||||
append_bubble_vertex_buffer(&sGfxSaved[i / 5], i, vertex1, vertex2, vertex3, (Vtx *) gBubbleTempVtx);
|
||||
append_bubble_vertex_buffer(sGfxCursor++, i, vertex1, vertex2, vertex3, (Vtx *) gBubbleTempVtx, interpolated);
|
||||
gSP1Triangle(sGfxCursor++, 0, 1, 2, 0);
|
||||
gSP1Triangle(sGfxCursor++, 3, 4, 5, 0);
|
||||
gSP1Triangle(sGfxCursor++, 6, 7, 8, 0);
|
||||
gSP1Triangle(sGfxCursor++, 9, 10, 11, 0);
|
||||
gSP1Triangle(sGfxCursor++, 12, 13, 14, 0);
|
||||
}
|
||||
for (i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
sPrevBubblePositions[i][0] = gEnvFxBuffer[i].xPos;
|
||||
sPrevBubblePositions[i][1] = gEnvFxBuffer[i].yPos;
|
||||
sPrevBubblePositions[i][2] = gEnvFxBuffer[i].zPos;
|
||||
}
|
||||
|
||||
gSPDisplayList(sGfxCursor++, &tiny_bubble_dl_0B006AB0);
|
||||
gSPEndDisplayList(sGfxCursor++);
|
||||
|
@ -568,6 +560,14 @@ Gfx *envfx_update_bubble_particles(s32 mode, UNUSED Vec3s marioPos, Vec3s camFro
|
|||
return gfxStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the bubble particle positions, then generates and returns a display
|
||||
* list drawing them.
|
||||
*/
|
||||
Gfx *envfx_update_bubble_particles(s32 mode, UNUSED Vec3s marioPos, Vec3s camFrom, Vec3s camTo) {
|
||||
return envfx_update_bubble_particles_internal(mode,marioPos, camFrom, camTo, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum particle count from the gEnvFxBubbleConfig variable,
|
||||
* which is set by the whirlpool or jet stream behavior.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "engine/behavior_script.h"
|
||||
#include "audio/external.h"
|
||||
#include "obj_behaviors.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
||||
/**
|
||||
* This file contains the function that handles 'environment effects',
|
||||
|
@ -54,23 +55,27 @@ extern void *tiny_bubble_dl_0B006AB0;
|
|||
extern void *tiny_bubble_dl_0B006A50;
|
||||
extern void *tiny_bubble_dl_0B006CD8;
|
||||
|
||||
static struct {
|
||||
Gfx *pos;
|
||||
Vtx vertices[15];
|
||||
} sPrevSnowVertices[140 / 5];
|
||||
static s16 sPrevSnowParticleCount;
|
||||
static u32 sPrevSnowTimestamp;
|
||||
Gfx *envfx_update_snow_internal(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo, u8 interpolated);
|
||||
|
||||
void patch_interpolated_snow_particles(void) {
|
||||
int i;
|
||||
static s32 sSnowGfxMode;
|
||||
static Gfx* sSnowGfxPos;
|
||||
static Vtx* sSnowInternalGfxPos[140 / 5];
|
||||
static Vec3s sSnowGfxCamFrom;
|
||||
static Vec3s sSnowGfxCamTo;
|
||||
static Vec3s sSnowGfxMarioPos;
|
||||
|
||||
if (gGlobalTimer != sPrevSnowTimestamp + 1) {
|
||||
return;
|
||||
void patch_snow_particles_before(void) {
|
||||
if (sSnowGfxPos) {
|
||||
for (s32 i = 0; i < gSnowParticleCount; i++) {
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
}
|
||||
sSnowGfxPos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < sPrevSnowParticleCount; i += 5) {
|
||||
gSPVertex(sPrevSnowVertices[i / 5].pos,
|
||||
VIRTUAL_TO_PHYSICAL(sPrevSnowVertices[i / 5].vertices), 15, 0);
|
||||
void patch_snow_particles_interpolated(UNUSED f32 delta) {
|
||||
if (sSnowGfxPos) {
|
||||
envfx_update_snow_internal(sSnowGfxMode, sSnowGfxMarioPos, sSnowGfxCamFrom, sSnowGfxCamTo, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,6 +243,7 @@ void envfx_update_snow_normal(s32 snowCylinderX, s32 snowCylinderY, s32 snowCyli
|
|||
(gEnvFxBuffer + i)->yPos = 200.0f * random_float() + snowCylinderY;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
} else {
|
||||
(gEnvFxBuffer + i)->xPos += random_float() * 2 - 1.0f + (s16)(deltaX / 1.2);
|
||||
(gEnvFxBuffer + i)->yPos -= 2 -(s16)(deltaY * 0.8);
|
||||
|
@ -273,6 +279,7 @@ void envfx_update_snow_blizzard(s32 snowCylinderX, s32 snowCylinderY, s32 snowCy
|
|||
(gEnvFxBuffer + i)->yPos = 400.0f * random_float() - 200.0f + snowCylinderY;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
} else {
|
||||
(gEnvFxBuffer + i)->xPos += random_float() * 2 - 1.0f + (s16)(deltaX / 1.2) + 20.0f;
|
||||
(gEnvFxBuffer + i)->yPos -= 5 -(s16)(deltaY * 0.8);
|
||||
|
@ -317,6 +324,7 @@ void envfx_update_snow_water(s32 snowCylinderX, s32 snowCylinderY, s32 snowCylin
|
|||
(gEnvFxBuffer + i)->yPos = 400.0f * random_float() - 200.0f + snowCylinderY;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -364,57 +372,61 @@ void rotate_triangle_vertices(Vec3s vertex1, Vec3s vertex2, Vec3s vertex3, s16 p
|
|||
* around (0,0,0) that will be translated to snowflake positions to draw the
|
||||
* snowflake image.
|
||||
*/
|
||||
void append_snowflake_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3) {
|
||||
void append_snowflake_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s vertex2, Vec3s vertex3, u8 interpolated) {
|
||||
s32 i = 0;
|
||||
Vtx *vertBuf = (Vtx *) alloc_display_list(15 * sizeof(Vtx));
|
||||
Vtx *vertBufInterpolated = (Vtx *) alloc_display_list(15 * sizeof(Vtx));
|
||||
Vtx *v;
|
||||
Vtx *vertBuf;
|
||||
|
||||
if (vertBuf == NULL || vertBufInterpolated == NULL) {
|
||||
if (interpolated) {
|
||||
vertBuf = sSnowInternalGfxPos[index/5];
|
||||
} else {
|
||||
vertBuf = (Vtx *) alloc_display_list(15 * sizeof(Vtx));
|
||||
sSnowInternalGfxPos[index/5] = vertBuf;
|
||||
}
|
||||
|
||||
if (vertBuf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 15; i += 3) {
|
||||
vertBuf[i] = gSnowTempVtx[0];
|
||||
(vertBuf + i)->v.ob[0] = (gEnvFxBuffer + (index + i / 3))->xPos + vertex1[0];
|
||||
(vertBuf + i)->v.ob[1] = (gEnvFxBuffer + (index + i / 3))->yPos + vertex1[1];
|
||||
(vertBuf + i)->v.ob[2] = (gEnvFxBuffer + (index + i / 3))->zPos + vertex1[2];
|
||||
|
||||
s32 xPos;
|
||||
s32 yPos;
|
||||
s32 zPos;
|
||||
s32 particleIndex = (index + i / 3);
|
||||
struct EnvFxParticle* particle = (gEnvFxBuffer + particleIndex);
|
||||
|
||||
if (interpolated) {
|
||||
extern f32 gRenderingDelta;
|
||||
xPos = delta_interpolate_s32(particle->prevPos[0], particle->xPos, gRenderingDelta);
|
||||
yPos = delta_interpolate_s32(particle->prevPos[1], particle->yPos, gRenderingDelta);
|
||||
zPos = delta_interpolate_s32(particle->prevPos[2], particle->zPos, gRenderingDelta);
|
||||
} else {
|
||||
xPos = particle->prevPos[0];
|
||||
yPos = particle->prevPos[1];
|
||||
zPos = particle->prevPos[2];
|
||||
}
|
||||
|
||||
(vertBuf + i)->v.ob[0] = xPos + vertex1[0];
|
||||
(vertBuf + i)->v.ob[1] = yPos + vertex1[1];
|
||||
(vertBuf + i)->v.ob[2] = zPos + vertex1[2];
|
||||
|
||||
vertBuf[i + 1] = gSnowTempVtx[1];
|
||||
(vertBuf + i + 1)->v.ob[0] = (gEnvFxBuffer + (index + i / 3))->xPos + vertex2[0];
|
||||
(vertBuf + i + 1)->v.ob[1] = (gEnvFxBuffer + (index + i / 3))->yPos + vertex2[1];
|
||||
(vertBuf + i + 1)->v.ob[2] = (gEnvFxBuffer + (index + i / 3))->zPos + vertex2[2];
|
||||
(vertBuf + i + 1)->v.ob[0] = xPos + vertex2[0];
|
||||
(vertBuf + i + 1)->v.ob[1] = yPos + vertex2[1];
|
||||
(vertBuf + i + 1)->v.ob[2] = zPos + vertex2[2];
|
||||
|
||||
vertBuf[i + 2] = gSnowTempVtx[2];
|
||||
(vertBuf + i + 2)->v.ob[0] = (gEnvFxBuffer + (index + i / 3))->xPos + vertex3[0];
|
||||
(vertBuf + i + 2)->v.ob[1] = (gEnvFxBuffer + (index + i / 3))->yPos + vertex3[1];
|
||||
(vertBuf + i + 2)->v.ob[2] = (gEnvFxBuffer + (index + i / 3))->zPos + vertex3[2];
|
||||
(vertBuf + i + 2)->v.ob[0] = xPos + vertex3[0];
|
||||
(vertBuf + i + 2)->v.ob[1] = yPos + vertex3[1];
|
||||
(vertBuf + i + 2)->v.ob[2] = zPos + vertex3[2];
|
||||
}
|
||||
|
||||
for (i = 0; i < 15; i++) {
|
||||
v = &sPrevSnowVertices[index / 5].vertices[i];
|
||||
vertBufInterpolated[i] = gSnowTempVtx[i % 3];
|
||||
if (index < sPrevSnowParticleCount && gGlobalTimer == sPrevSnowTimestamp + 1 &&
|
||||
gGlobalTimer != gEnvFxBuffer[index + i / 3].spawnTimestamp) {
|
||||
vertBufInterpolated[i].v.ob[0] = (v->v.ob[0] + vertBuf[i].v.ob[0]) / 2;
|
||||
vertBufInterpolated[i].v.ob[1] = (v->v.ob[1] + vertBuf[i].v.ob[1]) / 2;
|
||||
vertBufInterpolated[i].v.ob[2] = (v->v.ob[2] + vertBuf[i].v.ob[2]) / 2;
|
||||
} else {
|
||||
vertBufInterpolated[i].v.ob[0] = vertBuf[i].v.ob[0];
|
||||
vertBufInterpolated[i].v.ob[1] = vertBuf[i].v.ob[1];
|
||||
vertBufInterpolated[i].v.ob[2] = vertBuf[i].v.ob[2];
|
||||
}
|
||||
*v = vertBuf[i];
|
||||
}
|
||||
sPrevSnowVertices[index / 5].pos = gfx;
|
||||
gSPVertex(gfx, VIRTUAL_TO_PHYSICAL(vertBufInterpolated), 15, 0);
|
||||
gSPVertex(gfx, VIRTUAL_TO_PHYSICAL(vertBuf), 15, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates positions of snow particles and returns a pointer to a display list
|
||||
* drawing all snowflakes.
|
||||
*/
|
||||
Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo) {
|
||||
|
||||
Gfx *envfx_update_snow_internal(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo, u8 interpolated) {
|
||||
s32 i;
|
||||
s16 radius, pitch, yaw;
|
||||
Vec3s snowCylinderPos;
|
||||
|
@ -426,7 +438,17 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
|
|||
vertex2 = gSnowFlakeVertex2;
|
||||
vertex3 = gSnowFlakeVertex3;
|
||||
|
||||
gfxStart = (Gfx *) alloc_display_list((gSnowParticleCount * 6 + 3) * sizeof(Gfx));
|
||||
if (interpolated) {
|
||||
gfxStart = sSnowGfxPos;
|
||||
} else {
|
||||
gfxStart = (Gfx *) alloc_display_list((gSnowParticleCount * 6 + 3) * sizeof(Gfx));
|
||||
sSnowGfxPos = gfxStart;
|
||||
sSnowGfxMode = snowMode;
|
||||
vec3s_copy(sSnowGfxMarioPos, marioPos);
|
||||
vec3s_copy(sSnowGfxCamFrom, camFrom);
|
||||
vec3s_copy(sSnowGfxCamTo, camTo);
|
||||
}
|
||||
|
||||
gfx = gfxStart;
|
||||
|
||||
if (gfxStart == NULL) {
|
||||
|
@ -449,7 +471,7 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
|
|||
}
|
||||
|
||||
pos_from_orbit(camTo, snowCylinderPos, radius, pitch, yaw);
|
||||
envfx_update_snow_normal(snowCylinderPos[0], snowCylinderPos[1], snowCylinderPos[2]);
|
||||
if (!interpolated) { envfx_update_snow_normal(snowCylinderPos[0], snowCylinderPos[1], snowCylinderPos[2]); }
|
||||
break;
|
||||
|
||||
case ENVFX_SNOW_WATER:
|
||||
|
@ -460,7 +482,7 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
|
|||
}
|
||||
|
||||
pos_from_orbit(camTo, snowCylinderPos, radius, pitch, yaw);
|
||||
envfx_update_snow_water(snowCylinderPos[0], snowCylinderPos[1], snowCylinderPos[2]);
|
||||
if (!interpolated) { envfx_update_snow_water(snowCylinderPos[0], snowCylinderPos[1], snowCylinderPos[2]); }
|
||||
break;
|
||||
case ENVFX_SNOW_BLIZZARD:
|
||||
if (radius > 250) {
|
||||
|
@ -470,7 +492,7 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
|
|||
}
|
||||
|
||||
pos_from_orbit(camTo, snowCylinderPos, radius, pitch, yaw);
|
||||
envfx_update_snow_blizzard(snowCylinderPos[0], snowCylinderPos[1], snowCylinderPos[2]);
|
||||
if (!interpolated) { envfx_update_snow_blizzard(snowCylinderPos[0], snowCylinderPos[1], snowCylinderPos[2]); }
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -483,7 +505,7 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
|
|||
}
|
||||
|
||||
for (i = 0; i < gSnowParticleCount; i += 5) {
|
||||
append_snowflake_vertex_buffer(gfx++, i, (s16 *) &vertex1, (s16 *) &vertex2, (s16 *) &vertex3);
|
||||
append_snowflake_vertex_buffer(gfx++, i, (s16 *) &vertex1, (s16 *) &vertex2, (s16 *) &vertex3, interpolated);
|
||||
|
||||
gSP1Triangle(gfx++, 0, 1, 2, 0);
|
||||
gSP1Triangle(gfx++, 3, 4, 5, 0);
|
||||
|
@ -491,14 +513,20 @@ Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo)
|
|||
gSP1Triangle(gfx++, 9, 10, 11, 0);
|
||||
gSP1Triangle(gfx++, 12, 13, 14, 0);
|
||||
}
|
||||
sPrevSnowParticleCount = gSnowParticleCount;
|
||||
sPrevSnowTimestamp = gGlobalTimer;
|
||||
|
||||
gSPDisplayList(gfx++, &tiny_bubble_dl_0B006AB0) gSPEndDisplayList(gfx++);
|
||||
|
||||
return gfxStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates positions of snow particles and returns a pointer to a display list
|
||||
* drawing all snowflakes.
|
||||
*/
|
||||
Gfx *envfx_update_snow(s32 snowMode, Vec3s marioPos, Vec3s camFrom, Vec3s camTo) {
|
||||
return envfx_update_snow_internal(snowMode, marioPos, camFrom, camTo, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the environment effects (snow, flowers, bubbles)
|
||||
* and returns a display list drawing them.
|
||||
|
|
|
@ -27,6 +27,7 @@ struct EnvFxParticle {
|
|||
s32 bubbleY; // for Bubbles, yPos is always set to this
|
||||
//s8 filler20[56 - 0x20];
|
||||
u32 spawnTimestamp;
|
||||
Vec3s prevPos;
|
||||
};
|
||||
|
||||
extern s8 gEnvFxMode;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "print.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "pc/network/network.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
||||
extern bool gDjuiInMainMenu;
|
||||
u8 gOverrideHideHud;
|
||||
|
@ -64,18 +65,26 @@ static struct UnusedHUDStruct sUnusedHUDValues = { 0x00, 0x0A, 0x00 };
|
|||
|
||||
static struct CameraHUD sCameraHUD = { CAM_STATUS_NONE };
|
||||
|
||||
static u32 sPowerMeterLastRenderTimestamp;
|
||||
static s16 sPowerMeterLastY;
|
||||
static u32 sPowerMeterPrevTimestamp;
|
||||
static f32 sPowerMeterPrevY;
|
||||
static Gfx *sPowerMeterDisplayListPos;
|
||||
|
||||
void patch_interpolated_hud(void) {
|
||||
void patch_hud_before(void) {
|
||||
if (sPowerMeterDisplayListPos != NULL) {
|
||||
sPowerMeterPrevY = sPowerMeterHUD.y;
|
||||
sPowerMeterPrevTimestamp = gGlobalTimer;
|
||||
sPowerMeterDisplayListPos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void patch_hud_interpolated(f32 delta) {
|
||||
if (sPowerMeterDisplayListPos != NULL) {
|
||||
Mtx *mtx = alloc_display_list(sizeof(Mtx));
|
||||
if (mtx == NULL) { return; }
|
||||
guTranslate(mtx, (f32) sPowerMeterHUD.x, (f32) sPowerMeterHUD.y, 0);
|
||||
f32 interpY = delta_interpolate_f32(sPowerMeterPrevY, (f32)sPowerMeterHUD.y, delta);
|
||||
guTranslate(mtx, (f32) sPowerMeterHUD.x, interpY, 0);
|
||||
gSPMatrix(sPowerMeterDisplayListPos, VIRTUAL_TO_PHYSICAL(mtx),
|
||||
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
||||
sPowerMeterDisplayListPos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +140,6 @@ void render_power_meter_health_segment(s16 numHealthWedges) {
|
|||
*/
|
||||
void render_dl_power_meter(s16 numHealthWedges) {
|
||||
Mtx *mtx;
|
||||
f32 interpolatedY;
|
||||
|
||||
mtx = alloc_display_list(sizeof(Mtx));
|
||||
|
||||
|
@ -139,14 +147,7 @@ void render_dl_power_meter(s16 numHealthWedges) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (gGlobalTimer == sPowerMeterLastRenderTimestamp + 1) {
|
||||
interpolatedY = (sPowerMeterLastY + sPowerMeterHUD.y) / 2.0f;
|
||||
} else {
|
||||
interpolatedY = sPowerMeterHUD.y;
|
||||
}
|
||||
guTranslate(mtx, (f32) sPowerMeterHUD.x, interpolatedY, 0);
|
||||
sPowerMeterLastY = sPowerMeterHUD.y;
|
||||
sPowerMeterLastRenderTimestamp = gGlobalTimer;
|
||||
guTranslate(mtx, (f32) sPowerMeterHUD.x, sPowerMeterPrevY, 0);
|
||||
sPowerMeterDisplayListPos = gDisplayListHead;
|
||||
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtx++),
|
||||
|
@ -202,6 +203,7 @@ static void animate_power_meter_deemphasizing(void) {
|
|||
|
||||
if (sPowerMeterHUD.y >= 201) {
|
||||
sPowerMeterHUD.y = 200;
|
||||
sPowerMeterPrevY = 200;
|
||||
sPowerMeterHUD.animation = POWER_METER_VISIBLE;
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +228,7 @@ void handle_power_meter_actions(s16 numHealthWedges) {
|
|||
if (numHealthWedges < 8 && sPowerMeterStoredHealth == 8 && sPowerMeterHUD.animation == POWER_METER_HIDDEN) {
|
||||
sPowerMeterHUD.animation = POWER_METER_EMPHASIZED;
|
||||
sPowerMeterHUD.y = 166;
|
||||
sPowerMeterPrevY = 166;
|
||||
}
|
||||
|
||||
// Show power meter if health is full, has 8
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "pc/cheats.h"
|
||||
#include "pc/network/network.h"
|
||||
#include "pc/djui/djui.h"
|
||||
#include "pc/utils/misc.h"
|
||||
#ifdef BETTERCAMERA
|
||||
#include "bettercamera.h"
|
||||
#endif
|
||||
|
@ -130,44 +131,63 @@ s32 gDialogResponse = 0;
|
|||
static struct CachedChar { u8 used; u8 data[CHCACHE_BUFLEN]; } charCache[256];
|
||||
#endif // VERSION
|
||||
|
||||
static Gfx *sInterpolatedDialogOffsetPos;
|
||||
static f32 sInterpolatedDialogOffset;
|
||||
static Gfx *sInterpolatedDialogRotationPos;
|
||||
static f32 sInterpolatedDialogScale;
|
||||
static f32 sInterpolatedDialogRotation;
|
||||
static Gfx *sInterpolatedDialogZoomPos;
|
||||
static Gfx *sDialogOffsetPos;
|
||||
static Gfx *sDialogRotationPos;
|
||||
static Gfx *sDialogZoomPos;
|
||||
|
||||
void patch_interpolated_dialog(void) {
|
||||
static f32 sDialogOffset;
|
||||
static f32 sDialogOffsetPrev;
|
||||
static f32 sDialogScale;
|
||||
static f32 sDialogScalePrev;
|
||||
static f32 sDialogRotation;
|
||||
static f32 sDialogRotationPrev;
|
||||
|
||||
void patch_dialog_before(void) {
|
||||
sDialogOffsetPos = NULL;
|
||||
sDialogRotationPos = NULL;
|
||||
sDialogZoomPos = NULL;
|
||||
}
|
||||
|
||||
void patch_dialog_interpolated(f32 delta) {
|
||||
Mtx *matrix;
|
||||
|
||||
if (sInterpolatedDialogOffsetPos != NULL) {
|
||||
if (sDialogOffsetPos != NULL) {
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
if (matrix == NULL) { return; }
|
||||
guTranslate(matrix, 0, sInterpolatedDialogOffset, 0);
|
||||
gSPMatrix(sInterpolatedDialogOffsetPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
sInterpolatedDialogOffsetPos = NULL;
|
||||
f32 interpOffset = delta_interpolate_f32(sDialogOffsetPrev, sDialogOffset, delta);
|
||||
guTranslate(matrix, 0, interpOffset, 0);
|
||||
gSPMatrix(sDialogOffsetPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
}
|
||||
if (sInterpolatedDialogRotationPos != NULL) {
|
||||
|
||||
if (sDialogRotationPos != NULL) {
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
if (matrix == NULL) { return; }
|
||||
guScale(matrix, 1.0 / sInterpolatedDialogScale, 1.0 / sInterpolatedDialogScale, 1.0f);
|
||||
gSPMatrix(sInterpolatedDialogRotationPos++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
|
||||
f32 interpScale = delta_interpolate_f32(sDialogScalePrev, sDialogScale, delta);
|
||||
guScale(matrix, 1.0 / interpScale, 1.0 / interpScale, 1.0f);
|
||||
gSPMatrix(sDialogRotationPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
if (matrix == NULL) { return; }
|
||||
guRotate(matrix, sInterpolatedDialogRotation * 4.0f, 0, 0, 1.0f);
|
||||
gSPMatrix(sInterpolatedDialogRotationPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
sInterpolatedDialogRotationPos = NULL;
|
||||
|
||||
f32 interpRotation = delta_interpolate_f32(sDialogRotationPrev, sDialogRotation, delta);
|
||||
guRotate(matrix, interpRotation * 4.0f, 0, 0, 1.0f);
|
||||
gSPMatrix((sDialogRotationPos + 1), VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
}
|
||||
if (sInterpolatedDialogZoomPos != NULL) {
|
||||
|
||||
if (sDialogZoomPos != NULL) {
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
if (matrix == NULL) { return; }
|
||||
guTranslate(matrix, 65.0 - (65.0 / sInterpolatedDialogScale), (40.0 / sInterpolatedDialogScale) - 40, 0);
|
||||
gSPMatrix(sInterpolatedDialogZoomPos++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
|
||||
f32 interpScale = delta_interpolate_f32(sDialogScalePrev, sDialogScale, delta);
|
||||
guTranslate(matrix, 65.0 - (65.0 / interpScale), (40.0 / interpScale) - 40, 0);
|
||||
gSPMatrix(sDialogZoomPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
|
||||
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
if (matrix == NULL) { return; }
|
||||
guScale(matrix, 1.0 / sInterpolatedDialogScale, 1.0 / sInterpolatedDialogScale, 1.0f);
|
||||
gSPMatrix(sInterpolatedDialogZoomPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
sInterpolatedDialogZoomPos = NULL;
|
||||
|
||||
guScale(matrix, 1.0 / interpScale, 1.0 / interpScale, 1.0f);
|
||||
gSPMatrix((sDialogZoomPos + 1), VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1121,31 +1141,34 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) {
|
|||
switch (gDialogBoxType) {
|
||||
case DIALOG_TYPE_ROTATE: // Renders a dialog black box with zoom and rotation
|
||||
if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) {
|
||||
sInterpolatedDialogRotationPos = gDisplayListHead;
|
||||
sDialogRotationPos = gDisplayListHead;
|
||||
if (gDialogBoxState == DIALOG_STATE_OPENING) {
|
||||
sInterpolatedDialogScale = gDialogBoxScale - 2 / 2;
|
||||
sInterpolatedDialogRotation = gDialogBoxOpenTimer - 7.5f / 2;
|
||||
sDialogScale = gDialogBoxScale - 1.5f;
|
||||
sDialogRotation = gDialogBoxOpenTimer - 7.5f;
|
||||
} else {
|
||||
sInterpolatedDialogScale = gDialogBoxScale + 2 / 2;
|
||||
sInterpolatedDialogRotation = gDialogBoxOpenTimer + 7.5f / 2;
|
||||
sDialogScale = gDialogBoxScale + 2.0f;
|
||||
sDialogRotation = gDialogBoxOpenTimer + 10.0f;
|
||||
}
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f);
|
||||
sDialogScalePrev = gDialogBoxScale;
|
||||
sDialogRotationPrev = gDialogBoxOpenTimer;
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / sDialogScalePrev, 1.0 / sDialogScalePrev, 1.0f);
|
||||
// convert the speed into angle
|
||||
create_dl_rotation_matrix(MENU_MTX_NOPUSH, gDialogBoxOpenTimer * 4.0f, 0, 0, 1.0f);
|
||||
create_dl_rotation_matrix(MENU_MTX_NOPUSH, sDialogRotationPrev * 4.0f, 0, 0, 1.0f);
|
||||
}
|
||||
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 150);
|
||||
break;
|
||||
case DIALOG_TYPE_ZOOM: // Renders a dialog white box with zoom
|
||||
if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) {
|
||||
sInterpolatedDialogZoomPos = gDisplayListHead;
|
||||
sDialogZoomPos = gDisplayListHead;
|
||||
if (gDialogBoxState == DIALOG_STATE_OPENING) {
|
||||
sInterpolatedDialogScale = gDialogBoxScale - 2 / 2;
|
||||
sDialogScale = gDialogBoxScale - 2;
|
||||
} else {
|
||||
sInterpolatedDialogScale = gDialogBoxScale + 2 / 2;
|
||||
sDialogScale = gDialogBoxScale + 2;
|
||||
}
|
||||
create_dl_translation_matrix(MENU_MTX_NOPUSH, 65.0 - (65.0 / gDialogBoxScale),
|
||||
(40.0 / gDialogBoxScale) - 40, 0);
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f);
|
||||
sDialogScalePrev = gDialogBoxScale;
|
||||
create_dl_translation_matrix(MENU_MTX_NOPUSH, 65.0 - (65.0 / sDialogScalePrev),
|
||||
(40.0 / sDialogScalePrev) - 40, 0);
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / sDialogScalePrev, 1.0 / sDialogScalePrev, 1.0f);
|
||||
}
|
||||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 150);
|
||||
break;
|
||||
|
@ -1425,9 +1448,10 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l
|
|||
#ifdef VERSION_EU
|
||||
gDialogY -= gDialogScrollOffsetY;
|
||||
#else
|
||||
sInterpolatedDialogOffset = gDialogScrollOffsetY + dialog->linesPerBox;
|
||||
sInterpolatedDialogOffsetPos = gDisplayListHead;
|
||||
create_dl_translation_matrix(MENU_MTX_NOPUSH, 0, (f32) gDialogScrollOffsetY, 0);
|
||||
sDialogOffset = gDialogScrollOffsetY + dialog->linesPerBox * 2;
|
||||
sDialogOffsetPrev = gDialogScrollOffsetY;
|
||||
sDialogOffsetPos = gDisplayListHead;
|
||||
create_dl_translation_matrix(MENU_MTX_NOPUSH, 0, (f32) sDialogOffsetPrev, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "paintings.h"
|
||||
#include "save_file.h"
|
||||
#include "segment2.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
||||
/**
|
||||
* @file paintings.c
|
||||
|
@ -189,29 +190,74 @@ struct Painting **sPaintingGroups[] = {
|
|||
s16 gPaintingUpdateCounter = 1;
|
||||
s16 gLastPaintingUpdateCounter = 0;
|
||||
|
||||
static Vtx sLastVertices[2 * 264 * 3];
|
||||
static u32 sLastVerticesTimestamp;
|
||||
|
||||
typedef struct {
|
||||
float ob[3]; /* x, y, z */
|
||||
signed char n[3]; /* normal */
|
||||
} Vtx_Interp;
|
||||
|
||||
static Vtx_Interp sVertexBuffers[2][2 * 264 * 3];
|
||||
static u8 sVerticesCurIndex = 0;
|
||||
static u8 sVertexSwaps = 0;
|
||||
static Vtx_Interp* sVerticesCur = sVertexBuffers[0];
|
||||
static Vtx_Interp* sVerticesPrev = NULL;
|
||||
static u32 sVerticesPrevTimestamp;
|
||||
static Vtx *sVerticesPtr[2];
|
||||
static s32 sVerticesCount;
|
||||
|
||||
void patch_interpolated_paintings(void) {
|
||||
if (sVerticesPtr[0] != NULL) {
|
||||
void patch_paintings_before(void) {
|
||||
|
||||
if (gGlobalTimer == sVerticesPrevTimestamp + 1) {
|
||||
sVerticesCurIndex = !sVerticesCurIndex;
|
||||
sVerticesCur = sVertexBuffers[sVerticesCurIndex];
|
||||
sVerticesPrev = sVertexBuffers[!sVerticesCurIndex];
|
||||
sVertexSwaps++;
|
||||
} else {
|
||||
sVerticesPrev = NULL;
|
||||
sVertexSwaps = 0;
|
||||
}
|
||||
|
||||
sVerticesPtr[0] = NULL;
|
||||
sVerticesPtr[1] = NULL;
|
||||
sVerticesCount = 0;
|
||||
}
|
||||
|
||||
void patch_paintings_interpolated(f32 delta) {
|
||||
if (sVerticesPtr[0] != NULL && sVerticesPrev != NULL && sVertexSwaps > 2) {
|
||||
s32 i;
|
||||
if (sVerticesPtr[1] != NULL) {
|
||||
for (i = 0; i < sVerticesCount / 2; i++) {
|
||||
sVerticesPtr[0][i] = sLastVertices[i];
|
||||
Vec3f obInterp;
|
||||
delta_interpolate_vec3f(obInterp, sVerticesPrev[i].ob, sVerticesCur[i].ob, delta);
|
||||
s8 nInterp[3];
|
||||
delta_interpolate_normal(nInterp, sVerticesPrev[i].n, sVerticesCur[i].n, delta);
|
||||
for (u8 j = 0; j < 3; j++) {
|
||||
sVerticesPtr[0][i].n.ob[j] = obInterp[j];
|
||||
sVerticesPtr[0][i].n.n[j] = nInterp[j];
|
||||
}
|
||||
}
|
||||
for (; i < sVerticesCount; i++) {
|
||||
sVerticesPtr[1][i - sVerticesCount / 2] = sLastVertices[i];
|
||||
Vec3f obInterp;
|
||||
delta_interpolate_vec3f(obInterp, sVerticesPrev[i].ob, sVerticesCur[i].ob, delta);
|
||||
s8 nInterp[3];
|
||||
delta_interpolate_normal(nInterp, sVerticesPrev[i].n, sVerticesCur[i].n, delta);
|
||||
for (u8 j = 0; j < 3; j++) {
|
||||
sVerticesPtr[1][i - sVerticesCount / 2].n.ob[j] = obInterp[j];
|
||||
sVerticesPtr[1][i - sVerticesCount / 2].n.n[j] = nInterp[j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < sVerticesCount; i++) {
|
||||
sVerticesPtr[0][i] = sLastVertices[i];
|
||||
Vec3f obInterp;
|
||||
delta_interpolate_vec3f(obInterp, sVerticesPrev[i].ob, sVerticesCur[i].ob, delta);
|
||||
s8 nInterp[3];
|
||||
delta_interpolate_normal(nInterp, sVerticesPrev[i].n, sVerticesCur[i].n, delta);
|
||||
for (u8 j = 0; j < 3; j++) {
|
||||
sVerticesPtr[0][i].n.ob[j] = obInterp[j];
|
||||
sVerticesPtr[0][i].n.n[j] = nInterp[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
sVerticesPtr[0] = NULL;
|
||||
sVerticesPtr[1] = NULL;
|
||||
sVerticesCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -932,16 +978,25 @@ Gfx *render_painting(u8 *img, s16 tWidth, s16 tHeight, s16 *textureMap, s16 mapV
|
|||
sVerticesCount = 0;
|
||||
}
|
||||
for (map = 0; map < numVtx; map++) {
|
||||
Vtx v = verts[map];
|
||||
if (gGlobalTimer == sLastVerticesTimestamp + 1) {
|
||||
Vtx* v = &verts[map];
|
||||
if (gGlobalTimer == sVerticesPrevTimestamp + 1) {
|
||||
s32 i;
|
||||
Vtx_Interp* vCur = &sVerticesCur[sVerticesCount + map];
|
||||
Vtx_Interp* vPrev = (sVerticesPrev && sVertexSwaps > 2) ? &sVerticesPrev[sVerticesCount + map] : NULL;
|
||||
for (i = 0; i < 3; i++) {
|
||||
verts[map].n.ob[i] = (v.n.ob[i] + sLastVertices[sVerticesCount + map].n.ob[i]) / 2;
|
||||
verts[map].n.n[i] = (v.n.n[i] + sLastVertices[sVerticesCount + map].n.n[i]) / 2;
|
||||
// save current
|
||||
vCur->ob[i] = v->n.ob[i];
|
||||
vCur->n[i] = v->n.n[i];
|
||||
|
||||
// override verts with prev
|
||||
if (vPrev) {
|
||||
v->n.ob[i] = vPrev->ob[i];
|
||||
v->n.n[i] = vPrev->n[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
sLastVertices[sVerticesCount + map] = v;
|
||||
}
|
||||
|
||||
sVerticesPtr[sVerticesCount / numVtx] = verts;
|
||||
sVerticesCount += numVtx;
|
||||
|
||||
|
@ -1010,7 +1065,7 @@ Gfx *painting_ripple_image(struct Painting *painting) {
|
|||
meshTris = textureMap[meshVerts * 3 + 1];
|
||||
gSPDisplayList(gfx++, render_painting(textures[i], tWidth, tHeight, textureMap, meshVerts, meshTris, painting->alpha));
|
||||
}
|
||||
sLastVerticesTimestamp = gGlobalTimer;
|
||||
sVerticesPrevTimestamp = gGlobalTimer;
|
||||
|
||||
// Update the ripple, may automatically reset the painting's state.
|
||||
painting_update_ripple_state(painting);
|
||||
|
@ -1048,7 +1103,7 @@ Gfx *painting_ripple_env_mapped(struct Painting *painting) {
|
|||
meshVerts = textureMap[0];
|
||||
meshTris = textureMap[meshVerts * 3 + 1];
|
||||
gSPDisplayList(gfx++, render_painting(tArray[0], tWidth, tHeight, textureMap, meshVerts, meshTris, painting->alpha));
|
||||
sLastVerticesTimestamp = gGlobalTimer;
|
||||
sVerticesPrevTimestamp = gGlobalTimer;
|
||||
|
||||
// Update the ripple, may automatically reset the painting's state.
|
||||
painting_update_ripple_state(painting);
|
||||
|
|
|
@ -170,8 +170,8 @@ void mtx_patch_interpolated(f32 delta) {
|
|||
}
|
||||
|
||||
if (sViewportClipPos != NULL) {
|
||||
delta_interpolate_vectors_s16(sViewportInterp.vp.vtrans, sViewportPrev.vp.vtrans, sViewport->vp.vtrans, delta);
|
||||
delta_interpolate_vectors_s16(sViewportInterp.vp.vscale, sViewportPrev.vp.vscale, sViewport->vp.vscale, delta);
|
||||
delta_interpolate_vec3s(sViewportInterp.vp.vtrans, sViewportPrev.vp.vtrans, sViewport->vp.vtrans, delta);
|
||||
delta_interpolate_vec3s(sViewportInterp.vp.vscale, sViewportPrev.vp.vscale, sViewport->vp.vscale, delta);
|
||||
|
||||
Gfx *saved = gDisplayListHead;
|
||||
|
||||
|
|
|
@ -12,25 +12,42 @@
|
|||
#include "screen_transition.h"
|
||||
#include "segment2.h"
|
||||
#include "sm64.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
||||
u8 sTransitionColorFadeCount[4] = { 0 };
|
||||
u16 sTransitionTextureFadeCount[2] = { 0 };
|
||||
|
||||
static Gfx *sScreenTransitionVerticesPos[2];
|
||||
static Vtx *sScreenTransitionVertices;
|
||||
static Vtx *sScreenTransitionVerticesPrev;
|
||||
static Vtx sScreenTransitionInterp[8] = { 0 };
|
||||
|
||||
void reset_screen_transition_timers(void) {
|
||||
for (s32 i = 0; i < 4; i++) { sTransitionColorFadeCount[i] = 0; }
|
||||
for (s32 i = 0; i < 2; i++) { sTransitionTextureFadeCount[i] = 0; }
|
||||
}
|
||||
|
||||
void patch_screen_transition_interpolated(void) {
|
||||
|
||||
extern void patch_screen_transition_before(void) {
|
||||
sScreenTransitionVerticesPos[0] = NULL;
|
||||
sScreenTransitionVerticesPos[1] = NULL;
|
||||
sScreenTransitionVertices = NULL;
|
||||
sScreenTransitionVerticesPrev = NULL;
|
||||
}
|
||||
|
||||
void patch_screen_transition_interpolated(f32 delta) {
|
||||
if (sScreenTransitionVerticesPos[0] != NULL) {
|
||||
gSPVertex(sScreenTransitionVerticesPos[0], VIRTUAL_TO_PHYSICAL(sScreenTransitionVertices), 8, 0);
|
||||
gSPVertex(sScreenTransitionVerticesPos[1], VIRTUAL_TO_PHYSICAL(sScreenTransitionVertices), 4, 0);
|
||||
sScreenTransitionVerticesPos[0] = NULL;
|
||||
sScreenTransitionVerticesPos[1] = NULL;
|
||||
sScreenTransitionVertices = NULL;
|
||||
for (s32 i = 0; i < 8; i++) {
|
||||
sScreenTransitionInterp[i] = sScreenTransitionVerticesPrev[i];
|
||||
delta_interpolate_vec3f(sScreenTransitionInterp[i].n.ob,
|
||||
sScreenTransitionVerticesPrev[i].n.ob,
|
||||
sScreenTransitionVertices[i].n.ob, delta);
|
||||
delta_interpolate_rgba(sScreenTransitionInterp[i].v.cn,
|
||||
sScreenTransitionVerticesPrev[i].v.cn,
|
||||
sScreenTransitionVertices[i].v.cn, delta);
|
||||
}
|
||||
gSPVertex(sScreenTransitionVerticesPos[0], VIRTUAL_TO_PHYSICAL(sScreenTransitionInterp), 8, 0);
|
||||
gSPVertex(sScreenTransitionVerticesPos[1], VIRTUAL_TO_PHYSICAL(sScreenTransitionInterp), 4, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,19 +266,20 @@ s32 render_textured_transition(s8 fadeTimer, s8 transTime, struct WarpTransition
|
|||
s16 centerTransX = center_tex_transition_x(transData, texTransTime, texTransPos);
|
||||
s16 centerTransY = center_tex_transition_y(transData, texTransTime, texTransPos);
|
||||
s16 texTransRadius = calc_tex_transition_radius(fadeTimer, 1.0f, transTime, transData);
|
||||
s16 texTransRadiusInterpolated = calc_tex_transition_radius(fadeTimer, 0.5f, transTime, transData);
|
||||
s16 texTransRadiusPrev = calc_tex_transition_radius(fadeTimer, 0.0f, transTime, transData);
|
||||
Vtx *verts = alloc_display_list(8 * sizeof(*verts));
|
||||
Vtx *vertsInterpolated = alloc_display_list(8 * sizeof(*vertsInterpolated));
|
||||
Vtx *vertsPrev = alloc_display_list(8 * sizeof(*vertsPrev));
|
||||
|
||||
if (verts != NULL && vertsInterpolated != NULL) {
|
||||
if (verts != NULL && vertsPrev != NULL) {
|
||||
load_tex_transition_vertex(verts, fadeTimer, transData, centerTransX, centerTransY, texTransRadius, transTexType);
|
||||
load_tex_transition_vertex(vertsInterpolated, fadeTimer, transData, centerTransX, centerTransY, texTransRadiusInterpolated, transTexType);
|
||||
load_tex_transition_vertex(vertsPrev, fadeTimer, transData, centerTransX, centerTransY, texTransRadiusPrev, transTexType);
|
||||
sScreenTransitionVertices = verts;
|
||||
sScreenTransitionVerticesPrev = vertsPrev;
|
||||
gSPDisplayList(gDisplayListHead++, dl_proj_mtx_fullscreen)
|
||||
gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_OPA_SURF, G_RM_AA_OPA_SURF2);
|
||||
sScreenTransitionVerticesPos[0] = gDisplayListHead;
|
||||
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(vertsInterpolated), 8, 0);
|
||||
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(vertsPrev), 8, 0);
|
||||
gSPDisplayList(gDisplayListHead++, dl_transition_draw_filled_region);
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA);
|
||||
|
@ -279,7 +297,7 @@ s32 render_textured_transition(s8 fadeTimer, s8 transTime, struct WarpTransition
|
|||
}
|
||||
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON);
|
||||
sScreenTransitionVerticesPos[1] = gDisplayListHead;
|
||||
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(vertsInterpolated), 4, 0);
|
||||
gSPVertex(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(vertsPrev), 4, 0);
|
||||
gSPDisplayList(gDisplayListHead++, dl_draw_quad_verts_0123);
|
||||
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
|
||||
gSPDisplayList(gDisplayListHead++, dl_screen_transition_end);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "gfx_dimensions.h"
|
||||
#include "game/rendering_graph_node.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
||||
// frame counts for the zoom in, hold, and zoom out of title model
|
||||
#define INTRO_STEPS_ZOOM_IN 20
|
||||
|
@ -60,14 +61,20 @@ s8 gameOverBackgroundFlipOrder[] = { 0x00, 0x01, 0x02, 0x03, 0x07, 0x0B,
|
|||
|
||||
static Gfx *sIntroScalePos;
|
||||
static Vec3f sIntroScale;
|
||||
static Vec3f sIntroScalePrev;
|
||||
|
||||
void patch_title_screen_scales(void) {
|
||||
void patch_title_screen_before(void) {
|
||||
sIntroScalePos = NULL;
|
||||
}
|
||||
|
||||
void patch_title_screen_interpolated(f32 delta) {
|
||||
if (sIntroScalePos != NULL) {
|
||||
Mtx *scaleMat = alloc_display_list(sizeof(*scaleMat));
|
||||
if (scaleMat == NULL) { return; }
|
||||
guScale(scaleMat, sIntroScale[0], sIntroScale[1], sIntroScale[2]);
|
||||
Vec3f scaleInterp;
|
||||
delta_interpolate_vec3f(scaleInterp, sIntroScalePrev, sIntroScale, delta);
|
||||
guScale(scaleMat, scaleInterp[0], scaleInterp[1], scaleInterp[2]);
|
||||
gSPMatrix(sIntroScalePos, scaleMat, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
||||
sIntroScalePos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +89,6 @@ Gfx *geo_title_screen(s32 state, struct GraphNode *sp54, UNUSED void *context) {
|
|||
f32 scaleY; // sp30
|
||||
f32 scaleZ; // sp2c
|
||||
Vec3f scale;
|
||||
Vec3f scaleInterpolated;
|
||||
graphNode = sp54;
|
||||
dl = NULL;
|
||||
dlIter = NULL;
|
||||
|
@ -119,14 +125,12 @@ Gfx *geo_title_screen(s32 state, struct GraphNode *sp54, UNUSED void *context) {
|
|||
scaleY = 0.0f;
|
||||
scaleZ = 0.0f;
|
||||
}
|
||||
|
||||
vec3f_copy(sIntroScalePrev, sIntroScale);
|
||||
vec3f_set(scale, scaleX, scaleY, scaleZ);
|
||||
|
||||
// TODO: fixme
|
||||
//interpolate_vectors(scaleInterpolated, sIntroScale, scale);
|
||||
vec3f_copy(scaleInterpolated, scale);
|
||||
|
||||
vec3f_set(sIntroScale, scaleX, scaleY, scaleZ);
|
||||
guScale(scaleMat, scaleInterpolated[0], scaleInterpolated[1], scaleInterpolated[2]);
|
||||
|
||||
guScale(scaleMat, sIntroScalePrev[0], sIntroScalePrev[1], sIntroScalePrev[2]);
|
||||
sIntroScalePos = dlIter;
|
||||
gSPMatrix(dlIter++, scaleMat, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
|
||||
gSPDisplayList(dlIter++, &intro_seg7_dl_0700B3A0); // draw model
|
||||
|
|
|
@ -39,10 +39,10 @@ extern bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct);
|
|||
|
||||
static void debug_warp_level1() {
|
||||
// warp to credits
|
||||
set_mario_action(&gMarioStates[0], ACT_JUMBO_STAR_CUTSCENE, 0);
|
||||
return;
|
||||
//set_mario_action(&gMarioStates[0], ACT_JUMBO_STAR_CUTSCENE, 0);
|
||||
//return;
|
||||
|
||||
dynos_warp_to_level(LEVEL_BOB, 1, 1);
|
||||
dynos_warp_to_level(LEVEL_CCM, 1, 1);
|
||||
}
|
||||
|
||||
static void debug_warp_level2() {
|
||||
|
|
|
@ -100,28 +100,42 @@ void send_display_list(struct SPTask *spTask) {
|
|||
|
||||
static void patch_interpolations_before(void) {
|
||||
extern void mtx_patch_before(void);
|
||||
extern void patch_screen_transition_before(void);
|
||||
extern void patch_title_screen_before(void);
|
||||
extern void patch_dialog_before(void);
|
||||
extern void patch_hud_before(void);
|
||||
extern void patch_paintings_before(void);
|
||||
extern void patch_bubble_particles_before(void);
|
||||
extern void patch_snow_particles_before(void);
|
||||
mtx_patch_before();
|
||||
patch_screen_transition_before();
|
||||
patch_title_screen_before();
|
||||
patch_dialog_before();
|
||||
patch_hud_before();
|
||||
patch_paintings_before();
|
||||
patch_bubble_particles_before();
|
||||
patch_snow_particles_before();
|
||||
}
|
||||
|
||||
static inline void patch_interpolations(f32 delta) {
|
||||
extern void mtx_patch_interpolated(f32 delta);
|
||||
extern void patch_screen_transition_interpolated(void);
|
||||
extern void patch_title_screen_scales(void);
|
||||
extern void patch_interpolated_dialog(void);
|
||||
extern void patch_interpolated_hud(void);
|
||||
extern void patch_interpolated_paintings(void);
|
||||
extern void patch_interpolated_bubble_particles(void);
|
||||
extern void patch_interpolated_snow_particles(void);
|
||||
extern void patch_screen_transition_interpolated(f32 delta);
|
||||
extern void patch_title_screen_interpolated(f32 delta);
|
||||
extern void patch_dialog_interpolated(f32 delta);
|
||||
extern void patch_hud_interpolated(f32 delta);
|
||||
extern void patch_paintings_interpolated(f32 delta);
|
||||
extern void patch_bubble_particles_interpolated(f32 delta);
|
||||
extern void patch_snow_particles_interpolated(f32 delta);
|
||||
extern void djui_render_patch(void);
|
||||
mtx_patch_interpolated(delta);
|
||||
/*patch_screen_transition_interpolated();
|
||||
patch_title_screen_scales();
|
||||
patch_interpolated_dialog();
|
||||
patch_interpolated_hud();
|
||||
patch_interpolated_paintings();
|
||||
patch_interpolated_bubble_particles();
|
||||
patch_interpolated_snow_particles();
|
||||
djui_render_patch();*/
|
||||
patch_screen_transition_interpolated(delta);
|
||||
patch_title_screen_interpolated(delta);
|
||||
patch_dialog_interpolated(delta);
|
||||
patch_hud_interpolated(delta);
|
||||
patch_paintings_interpolated(delta);
|
||||
patch_bubble_particles_interpolated(delta);
|
||||
patch_snow_particles_interpolated(delta);
|
||||
/*djui_render_patch();*/
|
||||
}
|
||||
|
||||
void produce_uncapped_frames(void) {
|
||||
|
|
|
@ -120,7 +120,25 @@ f32 delta_interpolate_f32(f32 start, f32 end, f32 delta) {
|
|||
return start * (1.0f - delta) + end * delta;
|
||||
}
|
||||
|
||||
void delta_interpolate_vectors_s16(Vec3s res, Vec3s a, Vec3s b, f32 delta) {
|
||||
s32 delta_interpolate_s32(s32 a, s32 b, f32 delta) {
|
||||
return a * (1.0f - delta) + b * delta;
|
||||
}
|
||||
|
||||
void delta_interpolate_vec3f(Vec3f res, Vec3f a, Vec3f b, f32 delta) {
|
||||
f32 antiDelta = 1.0f - delta;
|
||||
res[0] = ((a[0] * antiDelta) + (b[0] * delta));
|
||||
res[1] = ((a[1] * antiDelta) + (b[1] * delta));
|
||||
res[2] = ((a[2] * antiDelta) + (b[2] * delta));
|
||||
}
|
||||
|
||||
void delta_interpolate_vec3s(Vec3s res, Vec3s a, Vec3s b, f32 delta) {
|
||||
f32 antiDelta = 1.0f - delta;
|
||||
res[0] = ((a[0] * antiDelta) + (b[0] * delta));
|
||||
res[1] = ((a[1] * antiDelta) + (b[1] * delta));
|
||||
res[2] = ((a[2] * antiDelta) + (b[2] * delta));
|
||||
}
|
||||
|
||||
void delta_interpolate_normal(s8* res, s8* a, s8* b, f32 delta) {
|
||||
f32 antiDelta = 1.0f - delta;
|
||||
res[0] = ((a[0] * antiDelta) + (b[0] * delta));
|
||||
res[1] = ((a[1] * antiDelta) + (b[1] * delta));
|
||||
|
@ -136,6 +154,14 @@ void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta) {
|
|||
}
|
||||
}
|
||||
|
||||
void delta_interpolate_rgba(u8* res, u8* a, u8* b, f32 delta) {
|
||||
f32 antiDelta = 1.0f - delta;
|
||||
res[0] = ((a[0] * antiDelta) + (b[0] * delta));
|
||||
res[1] = ((a[1] * antiDelta) + (b[1] * delta));
|
||||
res[2] = ((a[2] * antiDelta) + (b[2] * delta));
|
||||
res[3] = ((a[3] * antiDelta) + (b[3] * delta));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
void interpolate_vectors(Vec3f res, Vec3f a, Vec3f b) {
|
||||
|
|
|
@ -15,7 +15,11 @@ u32 clock_elapsed_ticks(void);
|
|||
void file_get_line(char* buffer, size_t maxLength, FILE* fp);
|
||||
|
||||
f32 delta_interpolate_f32(f32 start, f32 end, f32 delta);
|
||||
void delta_interpolate_vectors_s16(Vec3s res, Vec3s a, Vec3s b, f32 delta);
|
||||
s32 delta_interpolate_s32(s32 a, s32 b, f32 delta);
|
||||
void delta_interpolate_vec3f(Vec3f res, Vec3f a, Vec3f b, f32 delta);
|
||||
void delta_interpolate_vec3s(Vec3s res, Vec3s a, Vec3s b, f32 delta);
|
||||
void delta_interpolate_normal(s8* res, s8* a, s8* b, f32 delta);
|
||||
void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta);
|
||||
void delta_interpolate_rgba(u8* res, u8* a, u8* b, f32 delta);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue