mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-07-07 12:03:31 -04:00
Fix seams in bottles bonus, mumbo's picture and aspect ratio adjustment. (#7)
This commit is contained in:
+1
-1
Submodule lib/rt64 updated: 7242637a73...2fb9bd809b
@@ -13,6 +13,10 @@ void reset_projection_ids() {
|
||||
cur_ortho_projection_transform_id = 0;
|
||||
}
|
||||
|
||||
bool perspective_interpolation_skipped = FALSE;
|
||||
|
||||
s32 getGameMode(void);
|
||||
|
||||
extern f32 sViewportFOVy;
|
||||
extern f32 sViewportAspect;
|
||||
extern f32 sViewportNear;
|
||||
@@ -69,7 +73,16 @@ RECOMP_PATCH void viewport_setRenderPerspectiveMatrix(Gfx **gfx, Mtx **mtx, f32
|
||||
gEXMatrixGroupNoInterpolate((*gfx)++, G_EX_NOPUSH, G_MTX_PROJECTION, G_EX_EDIT_NONE);
|
||||
}
|
||||
else if (cur_perspective_projection_transform_id != 0) {
|
||||
gEXMatrixGroupSimpleNormal((*gfx)++, cur_perspective_projection_transform_id, G_EX_NOPUSH, G_MTX_PROJECTION, G_EX_EDIT_NONE);
|
||||
// Force the projection to not adjust itself for a wider aspect ratio when it's being rendered for the Bottles' bonus puzzle or the Mumbo photo.
|
||||
u16 aspect = G_EX_ASPECT_AUTO;
|
||||
bool inPictureGameMode = (getGameMode() == GAME_MODE_8_BOTTLES_BONUS) || (getGameMode() == GAME_MODE_A_SNS_PICTURE);
|
||||
bool isGameplayTransformId = (cur_perspective_projection_transform_id == PROJECTION_GAMEPLAY_TRANSFORM_ID);
|
||||
bool isTransitionTransformId = (cur_perspective_projection_transform_id == PROJECTION_TRANSITION_TRANSFORM_ID);
|
||||
if (inPictureGameMode && (isGameplayTransformId || isTransitionTransformId)) {
|
||||
aspect = G_EX_ASPECT_STRETCH;
|
||||
}
|
||||
|
||||
gEXMatrixGroup((*gfx)++, cur_perspective_projection_transform_id, G_EX_INTERPOLATE_SIMPLE, G_EX_NOPUSH, G_MTX_PROJECTION, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR, G_EX_EDIT_NONE, aspect, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_AUTO);
|
||||
}
|
||||
else {
|
||||
gEXMatrixGroupSimpleNormal((*gfx)++, G_EX_ID_AUTO, G_EX_NOPUSH, G_MTX_PROJECTION, G_EX_EDIT_NONE);
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
#include "patches.h"
|
||||
#include "transform_ids.h"
|
||||
#include "functions.h"
|
||||
|
||||
#define TILE_SIZE 32
|
||||
#define TILE_COUNT_X 5
|
||||
#define TILE_COUNT_Y 4
|
||||
#define IMAGE_WIDTH (TILE_SIZE * TILE_COUNT_X)
|
||||
#define IMAGE_HEIGHT (TILE_SIZE * TILE_COUNT_Y)
|
||||
#define FROM_XZ 0
|
||||
#define FROM_YZ 1
|
||||
|
||||
extern f32 D_80368250;
|
||||
extern f32 D_80368360[3];
|
||||
extern f32 D_8037DFF0[3];
|
||||
extern BKModelBin *D_8037DEA8;
|
||||
extern BKModelBin *D_8037DFE8;
|
||||
extern BKModelBin *chBottleBonusBookselfModelBin;
|
||||
extern ActorMarker *D_8037E000;
|
||||
|
||||
extern s32 getGameMode(void);
|
||||
extern s16 *func_8030C704(void);
|
||||
extern void chBottlesBonus_func_802DD080(Gfx **gfx, Mtx **mtx);
|
||||
extern Actor *func_802DF160(Gfx **gfx, Mtx **mtx, Vtx **vtx);
|
||||
extern void actor_postdrawMethod(ActorMarker *);
|
||||
extern void chBottlesBonusCursor_draw(Gfx **gfx, Mtx **mtx, Vtx **vtx);
|
||||
extern void chBottlesBonus_func_802DD158(Gfx **gfx, Mtx **mtx);
|
||||
extern BKGfxList *model_getDisplayList(BKModelBin *arg0);
|
||||
|
||||
void patch_picture_model(BKModelBin *model_bin, s32 min_xy, s32 max_xy, s32 min_z, s32 max_z, u32 from) {
|
||||
// Use pad0 to indicate if the model's been patched already.
|
||||
if (model_bin->pad0[0] == 0xBA) {
|
||||
return;
|
||||
}
|
||||
|
||||
model_bin->pad0[0] = 0xBA;
|
||||
|
||||
BKGfxList *gfx_list = model_getDisplayList(model_bin);
|
||||
Vtx *vtx_list = model_getVtxList(model_bin)->vtx_18;
|
||||
Gfx *cur_gfx = &gfx_list->list[0];
|
||||
Gfx *end_gfx = (Gfx *)((char *)model_bin + model_bin->vtx_list_offset_10);
|
||||
bool in_framebuffer_tile = FALSE;
|
||||
while (cur_gfx < end_gfx) {
|
||||
if (cur_gfx->words.w0 >> 24 == G_SETTIMG) {
|
||||
in_framebuffer_tile = cur_gfx->words.w1 == 0x04000000;
|
||||
if (in_framebuffer_tile) {
|
||||
// Patch the settimg and the 6 commands after it, replacing with a load of the framebuffer texture.
|
||||
Gfx* g = cur_gfx;
|
||||
Gfx* ng = cur_gfx + 1;
|
||||
u8 fmt = (ng->words.w0 >> 21) & 0x7;
|
||||
gDPLoadTextureTile(g++, 0x04000000, fmt, G_IM_SIZ_16b, 160, 128, 0, 0, 160 - 1, 128 - 1, 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);
|
||||
}
|
||||
}
|
||||
else if (cur_gfx->words.w0 >> 24 == G_VTX) {
|
||||
// Patch vertices. Get the loaded vertex count for this command.
|
||||
u32 cur_vtx_count = (cur_gfx->words.w0 >> 10) & 0b111111;
|
||||
|
||||
// Get the vertex address, converting from a segmented address if necessary.
|
||||
Vtx *cur_vtx;
|
||||
if (cur_gfx->words.w1 >> 24 == 0x01) {
|
||||
cur_vtx = (Vtx *)(SEGMENT_OFFSET(cur_gfx->words.w1) + (char *)vtx_list);
|
||||
}
|
||||
else {
|
||||
// Not a segmented address (should never happen, but may help with compatibility for future mods).
|
||||
cur_vtx = (Vtx *)cur_gfx->words.w1;
|
||||
}
|
||||
|
||||
if (in_framebuffer_tile) {
|
||||
if (from == FROM_YZ) {
|
||||
for (u32 i = 0; i < cur_vtx_count; i++) {
|
||||
float xy_frac = (cur_vtx[i].v.ob[1] - (float)min_xy) / (max_xy - min_xy);
|
||||
float z_frac = (cur_vtx[i].v.ob[2] - (float)min_z) / (max_z - min_z);
|
||||
cur_vtx[i].v.tc[0] = z_frac * 160.0f * 64.0f;
|
||||
cur_vtx[i].v.tc[1] = (1.0f - xy_frac) * 128.0f * 64.0f;
|
||||
}
|
||||
}
|
||||
else if (from == FROM_XZ) {
|
||||
for (u32 i = 0; i < cur_vtx_count; i++) {
|
||||
float xy_frac = (cur_vtx[i].v.ob[0] - (float)min_xy) / (max_xy - min_xy);
|
||||
float z_frac = (cur_vtx[i].v.ob[2] - (float)min_z) / (max_z - min_z);
|
||||
cur_vtx[i].v.tc[0] = xy_frac * 160.0f * 64.0f;
|
||||
cur_vtx[i].v.tc[1] = (1.0f - z_frac) * 128.0f * 64.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < cur_vtx_count; i++) {
|
||||
if (cur_vtx[i].v.ob[0] == 568) {
|
||||
cur_vtx[i].v.ob[0] = 567;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_gfx++;
|
||||
}
|
||||
}
|
||||
|
||||
// @recomp Patches the model for the puzzle to fix the seams.
|
||||
RECOMP_PATCH Actor *chBottlesBonus_draw(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
Actor *sp6C;
|
||||
f32 sp60[3];
|
||||
f32 sp54[3];
|
||||
void *sp50;
|
||||
|
||||
sp6C = marker_getActor(marker);
|
||||
sp50 = func_8030C704(); //grabs frame as texture?
|
||||
if ((sp50 == NULL) || (getGameMode() != GAME_MODE_8_BOTTLES_BONUS))
|
||||
return sp6C;
|
||||
|
||||
chBottlesBonus_func_802DD080(gfx, mtx);
|
||||
{ sp60[0] = 0.0f; sp60[1] = 0.0f; sp60[2] = 0.0f; };
|
||||
{ sp54[0] = 0.0f; sp54[1] = 0.0f; sp54[2] = 0.0f; };
|
||||
modelRender_setDepthMode(MODEL_RENDER_DEPTH_FULL);
|
||||
modelRender_draw(gfx, mtx, sp60, NULL, 1.0f, sp54, chBottleBonusBookselfModelBin);
|
||||
modelRender_draw(gfx, mtx, sp60, NULL, 1.0f, sp54, D_8037DEA8);
|
||||
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_POINT);
|
||||
gDPSetColorDither((*gfx)++, G_CD_DISABLE);
|
||||
func_802DF160(gfx, mtx, vtx);
|
||||
func_80253190(gfx);
|
||||
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_POINT);
|
||||
gSPSegment((*gfx)++, 0x04, osVirtualToPhysical(sp50));
|
||||
modelRender_preDraw((GenFunction_1)actor_predrawMethod, (s32)sp6C);
|
||||
modelRender_postDraw((GenFunction_1)actor_postdrawMethod, (s32)marker);
|
||||
|
||||
// @recomp Load and patch the puzzle model.
|
||||
BKModelBin *model_bin = marker_loadModelBin(marker);
|
||||
patch_picture_model(model_bin, 260, 398, -273, -100, FROM_YZ);
|
||||
|
||||
modelRender_draw(gfx, mtx, sp60, NULL, D_80368250, sp54, model_bin);
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_BILERP);
|
||||
gDPSetColorDither((*gfx)++, G_CD_MAGICSQ);
|
||||
chBottlesBonusCursor_draw(gfx, mtx, vtx);
|
||||
chBottlesBonus_func_802DD158(gfx, mtx);
|
||||
return sp6C;
|
||||
}
|
||||
|
||||
// @recomp Patches the model for the background picture to fix the seams.
|
||||
RECOMP_PATCH Actor *func_802DF160(Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
Actor *this;
|
||||
void *sp38;
|
||||
|
||||
this = marker_getActor(D_8037E000);
|
||||
sp38 = func_8030C704();
|
||||
modelRender_setDepthMode(MODEL_RENDER_DEPTH_FULL);
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_POINT);
|
||||
gSPSegment((*gfx)++, 0x04, osVirtualToPhysical(sp38));
|
||||
modelRender_preDraw((GenFunction_1)actor_predrawMethod, (s32)this);
|
||||
modelRender_postDraw((GenFunction_1)actor_postdrawMethod, (s32)D_8037E000);
|
||||
|
||||
// @recomp Load and patch the picture model.
|
||||
BKModelBin *model_bin = marker_loadModelBin(D_8037E000);
|
||||
patch_picture_model(model_bin, 262, 397, -273, -100, FROM_YZ);
|
||||
|
||||
modelRender_draw(gfx, mtx, &D_80368360, NULL, 1.0f, NULL, model_bin);
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_BILERP);
|
||||
return this;
|
||||
}
|
||||
|
||||
// @recomp Patches the model for the photo to fix the seams.
|
||||
RECOMP_PATCH Actor *func_802DEC00(ActorMarker *marker, Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
Actor *this;
|
||||
f32 sp58[3];
|
||||
f32 sp4C[3];
|
||||
void *sp48;
|
||||
|
||||
|
||||
this = marker_getActor(marker);
|
||||
sp48 = func_8030C704();
|
||||
|
||||
if ((sp48 == 0) || (getGameMode() != GAME_MODE_A_SNS_PICTURE))
|
||||
return this;
|
||||
|
||||
chBottlesBonus_func_802DD080(gfx, mtx);
|
||||
sp58[0] = 0.0f;
|
||||
sp58[1] = 0.0f;
|
||||
sp58[2] = 50.0f;
|
||||
|
||||
sp4C[0] = 0.0f;
|
||||
sp4C[1] = 0.0f;
|
||||
sp4C[2] = 0.0f;
|
||||
|
||||
D_8037DFF0[0] = 0.0f;
|
||||
D_8037DFF0[1] = 270.0f;
|
||||
D_8037DFF0[2] = 0.0f;
|
||||
modelRender_setDepthMode(MODEL_RENDER_DEPTH_FULL);
|
||||
modelRender_draw(gfx, mtx, sp58, NULL, 1.0f, sp4C, D_8037DFE8);
|
||||
gDPSetColorDither((*gfx)++, G_CD_DISABLE);
|
||||
func_80253190(gfx);
|
||||
gSPSegment((*gfx)++, 0x04, osVirtualToPhysical(sp48));
|
||||
modelRender_preDraw((GenFunction_1)actor_predrawMethod, (s32)this);
|
||||
modelRender_postDraw((GenFunction_1)actor_postdrawMethod, (s32)marker);
|
||||
|
||||
// @recomp Load and patch the photo model.
|
||||
BKModelBin *model_bin = marker_loadModelBin(marker);
|
||||
patch_picture_model(model_bin, -55, -5, -6, 34, FROM_XZ);
|
||||
|
||||
modelRender_draw(gfx, mtx, this->position, NULL, 4.5f, sp4C, model_bin);
|
||||
gDPSetTextureFilter((*gfx)++, G_TF_BILERP);
|
||||
gDPSetColorDither((*gfx)++, G_CD_MAGICSQ);
|
||||
chBottlesBonus_func_802DD158(gfx, mtx);
|
||||
return this;
|
||||
}
|
||||
@@ -293,9 +293,13 @@ RECOMP_PATCH void gctransition_draw(Gfx **gdl, Mtx **mptr, Vtx **vptr){
|
||||
modelRender_setDepthMode(MODEL_RENDER_DEPTH_FULL);
|
||||
}
|
||||
|
||||
// @recomp Calculate the ratio between the original aspect ratio and the current aspect ratio.
|
||||
// @recomp Calculate the ratio between the original aspect ratio and the current aspect ratio, except when in picture mode.
|
||||
float original_aspect = (float)DEFAULT_FRAMEBUFFER_WIDTH / DEFAULT_FRAMEBUFFER_HEIGHT;
|
||||
float cur_aspect = recomp_get_target_aspect_ratio(original_aspect);
|
||||
if (getGameMode() == GAME_MODE_A_SNS_PICTURE) {
|
||||
cur_aspect = original_aspect;
|
||||
}
|
||||
|
||||
float aspect_ratio_ratio = cur_aspect / original_aspect;
|
||||
|
||||
// @recomp Determine what scaling to use based on the transition type.
|
||||
|
||||
Reference in New Issue
Block a user