mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-06-06 11:07:24 -04:00
Add pillarboxing to cutscenes. (#35)
* Update RT64 to fix scissor origin leaking bug. * Add pillarboxing to cutscenes.
This commit is contained in:
+1
-1
Submodule lib/rt64 updated: c29698d153...aec97ec579
@@ -8,5 +8,6 @@ DECLARE_FUNC(float, recomp_get_target_aspect_ratio, float);
|
||||
DECLARE_FUNC(s32, recomp_get_target_framerate, s32);
|
||||
DECLARE_FUNC(s32, recomp_high_precision_fb_enabled);
|
||||
DECLARE_FUNC(float, recomp_get_resolution_scale);
|
||||
DECLARE_FUNC(float, recomp_get_cutscene_aspect_ratio);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#include "patches.h"
|
||||
#include "transform_ids.h"
|
||||
#include "functions.h"
|
||||
#include "graphics.h"
|
||||
|
||||
#define ANIMATED_PILLARBOX_SCALE 0
|
||||
|
||||
extern enum map_e map_get(void);
|
||||
|
||||
#if ANIMATED_PILLARBOX_SCALE
|
||||
f32 pillarbox_scale = 0.0f;
|
||||
#else
|
||||
f32 pillarbox_scale = 1.0f;
|
||||
#endif
|
||||
|
||||
bool pillarbox_active() {
|
||||
switch (map_get()) {
|
||||
case MAP_1E_CS_START_NINTENDO:
|
||||
case MAP_1F_CS_START_RAREWARE:
|
||||
case MAP_20_CS_END_NOT_100:
|
||||
case MAP_7B_CS_INTRO_GL_DINGPOT_1:
|
||||
case MAP_7C_CS_INTRO_BANJOS_HOUSE_1:
|
||||
case MAP_7D_CS_SPIRAL_MOUNTAIN_1:
|
||||
case MAP_7E_CS_SPIRAL_MOUNTAIN_2:
|
||||
case MAP_81_CS_INTRO_GL_DINGPOT_2:
|
||||
case MAP_82_CS_ENTERING_GL_MACHINE_ROOM:
|
||||
case MAP_83_CS_GAME_OVER_MACHINE_ROOM:
|
||||
case MAP_84_CS_UNUSED_MACHINE_ROOM:
|
||||
case MAP_85_CS_SPIRAL_MOUNTAIN_3:
|
||||
case MAP_86_CS_SPIRAL_MOUNTAIN_4:
|
||||
case MAP_87_CS_SPIRAL_MOUNTAIN_5:
|
||||
case MAP_88_CS_SPIRAL_MOUNTAIN_6:
|
||||
case MAP_89_CS_INTRO_BANJOS_HOUSE_2:
|
||||
case MAP_8A_CS_INTRO_BANJOS_HOUSE_3:
|
||||
case MAP_94_CS_INTRO_SPIRAL_7:
|
||||
case MAP_95_CS_END_ALL_100:
|
||||
case MAP_96_CS_END_BEACH_1:
|
||||
case MAP_97_CS_END_BEACH_2:
|
||||
case MAP_98_CS_END_SPIRAL_MOUNTAIN_1:
|
||||
case MAP_99_CS_END_SPIRAL_MOUNTAIN_2:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void pillarbox_draw(Gfx **gfx, Mtx **mtx, Vtx **vtx) {
|
||||
#if ANIMATED_PILLARBOX_SCALE
|
||||
const f32 pillarbox_scale_speed = 1.0f * time_getDelta();
|
||||
if (pillarbox_active()) {
|
||||
pillarbox_scale = MIN(pillarbox_scale + pillarbox_scale_speed, 1.0f);
|
||||
}
|
||||
else {
|
||||
pillarbox_scale = MAX(pillarbox_scale - pillarbox_scale_speed, 0.0f);
|
||||
}
|
||||
#else
|
||||
if (!pillarbox_active()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
float original_aspect = (float)DEFAULT_FRAMEBUFFER_WIDTH / DEFAULT_FRAMEBUFFER_HEIGHT;
|
||||
float cur_aspect = recomp_get_target_aspect_ratio(original_aspect);
|
||||
float target_aspect = MIN(recomp_get_cutscene_aspect_ratio(), cur_aspect);
|
||||
float target_width = DEFAULT_FRAMEBUFFER_HEIGHT * target_aspect;
|
||||
float wide_width = DEFAULT_FRAMEBUFFER_HEIGHT * cur_aspect;
|
||||
float pillar_width = wide_width - target_width * pillarbox_scale;
|
||||
if (pillar_width >= 0.0f) {
|
||||
u32 prev_ortho_id = cur_ortho_projection_transform_id;
|
||||
cur_ortho_projection_transform_id = PROJECTION_PILLARBOX_TRANSFORM_ID;
|
||||
viewport_setRenderViewportAndOrthoMatrix(gfx, mtx);
|
||||
|
||||
Vtx *verts = *vtx;
|
||||
for (s32 ix = -1; ix < 2; ix += 2) {
|
||||
for (s32 iy = 0; iy < 2; iy++) {
|
||||
(*vtx)->v.ob[0] = ix * pillar_width * 2;
|
||||
(*vtx)->v.ob[1] = iy * DEFAULT_FRAMEBUFFER_HEIGHT * 4 - DEFAULT_FRAMEBUFFER_HEIGHT * 2;
|
||||
(*vtx)->v.ob[2] = -0x14;
|
||||
(*vtx)++;
|
||||
}
|
||||
}
|
||||
|
||||
gEXPushOtherMode((*gfx)++);
|
||||
gEXPushCombineMode((*gfx)++);
|
||||
gEXPushGeometryMode((*gfx)++);
|
||||
gSPClearGeometryMode((*gfx)++, G_CULL_BOTH);
|
||||
gDPSetRenderMode((*gfx)++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
||||
gDPSetCycleType((*gfx)++, G_CYC_1CYCLE);
|
||||
gDPSetCombineLERP((*gfx)++, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
u32 id = PILLARBOX_RECTANGLE_TRANSFORM_ID_START;
|
||||
for (s32 ix = -1; ix < 2; ix += 2) {
|
||||
guTranslate(*mtx, ix * wide_width * 2, 0.0f, 0.0f);
|
||||
gSPMatrix((*gfx)++, OS_K0_TO_PHYSICAL(*mtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
(*mtx)++;
|
||||
|
||||
gEXMatrixGroupSimpleVerts((*gfx)++, id++, G_EX_PUSH, G_MTX_MODELVIEW, G_EX_EDIT_NONE);
|
||||
gSPVertex((*gfx)++, verts, 4, 0);
|
||||
gSP1Quadrangle((*gfx)++, 0, 1, 3, 2, 0);
|
||||
gEXPopMatrixGroup((*gfx)++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
gEXPopOtherMode((*gfx)++);
|
||||
gEXPopCombineMode((*gfx)++);
|
||||
gEXPopGeometryMode((*gfx)++);
|
||||
|
||||
cur_ortho_projection_transform_id = prev_ortho_id;
|
||||
}
|
||||
}
|
||||
@@ -85,6 +85,7 @@ extern void printbuffer_draw(Gfx **gfx, Mtx **mtx, Vtx **vtx);
|
||||
|
||||
extern u32 cur_pushed_text_transform_id;
|
||||
extern u32 cur_pushed_text_transform_origin;
|
||||
extern void pillarbox_draw(Gfx **gdl, Mtx **mptr, Vtx **vptr);
|
||||
|
||||
// @recomp Patched to set the projection transform ID for the main projection.
|
||||
RECOMP_PATCH void func_802E39D0(Gfx **gdl, Mtx **mptr, Vtx **vptr, s32 framebuffer_idx, s32 arg4) {
|
||||
@@ -173,6 +174,10 @@ RECOMP_PATCH void func_802E39D0(Gfx **gdl, Mtx **mptr, Vtx **vptr, s32 framebuff
|
||||
) {
|
||||
gctransition_draw(gdl, mptr, vptr);
|
||||
}
|
||||
|
||||
// @recomp Draw a pillarbox over the current scene to hide the extended widescreen area if active (e.g. cutscenes).
|
||||
pillarbox_draw(gdl, mptr, vptr);
|
||||
|
||||
finishFrame(gdl);
|
||||
osWritebackDCache(m_start, sizeof(Mtx) * (*mptr - m_start));
|
||||
osWritebackDCache(v_start, sizeof(Vtx) * (*vptr - v_start));
|
||||
|
||||
@@ -47,3 +47,4 @@ recomp_set_right_analog_suppressed = 0x8F0000A8;
|
||||
osContGetReadData_recomp = 0x8F0000AC;
|
||||
bcopy_recomp = 0x8F0000B0;
|
||||
recomp_get_note_saving_enabled = 0x8F0000B4;
|
||||
recomp_get_cutscene_aspect_ratio = 0x8F0000B8;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define PROJECTION_COPYRIGHT_TRANSFORM_ID 0x00001006
|
||||
#define PROJECTION_GAME_OVER_TRANSFORM_ID 0x00001007
|
||||
#define PROJECTION_THE_END_TRANSFORM_ID 0x00001008
|
||||
#define PROJECTION_PILLARBOX_TRANSFORM_ID 0x00001009
|
||||
#define PROJECTION_PORTRAIT_TRANSFORM_ID_START 0x00001100 // 1 for each portrait ID
|
||||
|
||||
// Map models: 0x00400000 - 0x00EFFFFF
|
||||
@@ -107,6 +108,9 @@
|
||||
#define RAIN_PARTICLE_ID_COUNT 256
|
||||
#define RAIN_PARTICLE_ID_MAX 0x8000
|
||||
|
||||
// Pillarbox Rectangles: 0x31000000 - 0x31000010
|
||||
#define PILLARBOX_RECTANGLE_TRANSFORM_ID_START 0x31000000
|
||||
|
||||
// Markers: 0x10000000 - 0x1FFFFFFF
|
||||
#define BANJO_TRANSFORM_ID_START 0x10000000
|
||||
#define MARKER_TRANSFORM_ID_START (BANJO_TRANSFORM_ID_START + MARKER_TRANSFORM_ID_COUNT)
|
||||
|
||||
@@ -101,6 +101,11 @@ extern "C" void recomp_get_target_aspect_ratio(uint8_t* rdram, recomp_context* c
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void recomp_get_cutscene_aspect_ratio(uint8_t *rdram, recomp_context *ctx) {
|
||||
float ar = 16.0f / 9.0f;
|
||||
_return(ctx, ar);
|
||||
}
|
||||
|
||||
extern "C" void recomp_get_bgm_volume(uint8_t* rdram, recomp_context* ctx) {
|
||||
_return(ctx, banjo::get_bgm_volume() / 100.0f);
|
||||
}
|
||||
|
||||
@@ -623,6 +623,7 @@ int main(int argc, char** argv) {
|
||||
REGISTER_FUNC(recomp_get_window_resolution);
|
||||
REGISTER_FUNC(recomp_get_target_aspect_ratio);
|
||||
REGISTER_FUNC(recomp_get_target_framerate);
|
||||
REGISTER_FUNC(recomp_get_cutscene_aspect_ratio);
|
||||
REGISTER_FUNC(recomp_get_analog_cam_enabled);
|
||||
REGISTER_FUNC(recomp_get_camera_inputs);
|
||||
REGISTER_FUNC(recomp_get_bgm_volume);
|
||||
|
||||
Reference in New Issue
Block a user