Enable relevant RT64 enhancements, fix pause background corruption if song of soaring was played before ever pausing
This commit is contained in:
parent
3326a1bcce
commit
958808acb0
|
@ -14,6 +14,7 @@ namespace ultramodern {
|
|||
|
||||
RT64::Application* RT64Init(uint8_t* rom, uint8_t* rdram, ultramodern::WindowHandle window_handle);
|
||||
void RT64UpdateConfig(RT64::Application* application, const ultramodern::GraphicsConfig& old_config, const ultramodern::GraphicsConfig& new_config);
|
||||
void RT64EnableInstantPresent(RT64::Application* application);
|
||||
void RT64SendDL(uint8_t* rdram, const OSTask* task);
|
||||
void RT64UpdateScreen(uint32_t vi_origin);
|
||||
void RT64ChangeWindow();
|
||||
|
|
|
@ -31,8 +31,6 @@ s16 KaleidoScope_SetPageVertices(PlayState* play, Vtx* vtx, s16 vtxPage, s16 num
|
|||
s32 cur_y;
|
||||
u32 row;
|
||||
|
||||
gSegments[0x0D] = OS_K0_TO_PHYSICAL(play->pauseCtx.iconItemLangSegment);
|
||||
|
||||
cur_y = PAGE_BG_HEIGHT / 2;
|
||||
|
||||
// 2 verts per row plus 2 extra verts at the start and the end.
|
||||
|
@ -74,10 +72,10 @@ s16 KaleidoScope_SetPageVertices(PlayState* play, Vtx* vtx, s16 vtxPage, s16 num
|
|||
|
||||
// These are overlay symbols, so their addresses need to be offset to get their actual loaded vram address.
|
||||
// TODO remove this once the recompiler is able to handle overlay symbols automatically for patch functions.
|
||||
s16** sVtxPageQuadsXRelocated = (s16**)((u8*)&sVtxPageQuadsX[0] + gKaleidoMgrOverlayTable[0].offset);
|
||||
s16** sVtxPageQuadsWidthRelocated = (s16**)((u8*)&sVtxPageQuadsWidth[0] + gKaleidoMgrOverlayTable[0].offset);
|
||||
s16** sVtxPageQuadsYRelocated = (s16**)((u8*)&sVtxPageQuadsY[0] + gKaleidoMgrOverlayTable[0].offset);
|
||||
s16** sVtxPageQuadsHeightRelocated = (s16**)((u8*)&sVtxPageQuadsHeight[0] + gKaleidoMgrOverlayTable[0].offset);
|
||||
s16** sVtxPageQuadsXRelocated = (s16**)KaleidoManager_GetRamAddr(sVtxPageQuadsX);
|
||||
s16** sVtxPageQuadsWidthRelocated = (s16**)KaleidoManager_GetRamAddr(sVtxPageQuadsWidth);
|
||||
s16** sVtxPageQuadsYRelocated = (s16**)KaleidoManager_GetRamAddr(sVtxPageQuadsY);
|
||||
s16** sVtxPageQuadsHeightRelocated = (s16**)KaleidoManager_GetRamAddr(sVtxPageQuadsHeight);
|
||||
|
||||
s16 k = 60;
|
||||
|
||||
|
@ -128,8 +126,7 @@ typedef u8 bg_image_t[(2 + PAGE_BG_WIDTH) * (2 + PAGE_BG_HEIGHT)];
|
|||
|
||||
#define BG_IMAGE_COUNT 4
|
||||
TexturePtr* bg_pointers[BG_IMAGE_COUNT];
|
||||
bg_image_t bg_images[BG_IMAGE_COUNT];
|
||||
u32 bg_image_count = 0;
|
||||
bg_image_t bg_images[BG_IMAGE_COUNT] __attribute__((aligned(8)));
|
||||
|
||||
void assemble_image(TexturePtr* textures, bg_image_t* image_out) {
|
||||
u8* pixels_out_start = *image_out;
|
||||
|
@ -165,6 +162,58 @@ void assemble_image(TexturePtr* textures, bg_image_t* image_out) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool assembled_kaleido_images = false;
|
||||
|
||||
extern TexturePtr sMaskPageBgTextures[];
|
||||
extern TexturePtr sItemPageBgTextures[];
|
||||
extern TexturePtr sMapPageBgTextures[];
|
||||
extern TexturePtr sQuestPageBgTextures[];
|
||||
|
||||
extern void (*sKaleidoScopeUpdateFunc)(PlayState* play);
|
||||
extern void (*sKaleidoScopeDrawFunc)(PlayState* play);
|
||||
|
||||
extern void KaleidoScope_Update(PlayState* play);
|
||||
extern void KaleidoScope_Draw(PlayState* play);
|
||||
|
||||
void KaleidoUpdateWrapper(PlayState* play) {
|
||||
KaleidoScope_Update(play);
|
||||
}
|
||||
|
||||
void KaleidoDrawWrapper(PlayState* play) {
|
||||
// @recomp Update the background image pointers to reflect the overlay's load address.
|
||||
bg_pointers[0] = KaleidoManager_GetRamAddr(sMaskPageBgTextures);
|
||||
bg_pointers[1] = KaleidoManager_GetRamAddr(sItemPageBgTextures);
|
||||
bg_pointers[2] = KaleidoManager_GetRamAddr(sMapPageBgTextures);
|
||||
bg_pointers[3] = KaleidoManager_GetRamAddr(sQuestPageBgTextures);
|
||||
|
||||
KaleidoScope_Draw(play);
|
||||
|
||||
// @recomp Check if this is the first time kaleido has been drawn. If so, assemble the background textures
|
||||
// into the full seamless image.
|
||||
if (!assembled_kaleido_images) {
|
||||
assembled_kaleido_images = true;
|
||||
// Record the old value for segments 0x08 and 0x0D, then update them with the correct values so that segmented addresses
|
||||
// can be converted in assemble_image.
|
||||
uintptr_t old_segment_08 = gSegments[0x08];
|
||||
uintptr_t old_segment_0D = gSegments[0x0D];
|
||||
gSegments[0x08] = OS_K0_TO_PHYSICAL(play->pauseCtx.iconItemSegment);
|
||||
gSegments[0x0D] = OS_K0_TO_PHYSICAL(play->pauseCtx.iconItemLangSegment);
|
||||
assemble_image(KaleidoManager_GetRamAddr(sMaskPageBgTextures), &bg_images[0]);
|
||||
assemble_image(KaleidoManager_GetRamAddr(sItemPageBgTextures), &bg_images[1]);
|
||||
assemble_image(KaleidoManager_GetRamAddr(sMapPageBgTextures), &bg_images[2]);
|
||||
assemble_image(KaleidoManager_GetRamAddr(sQuestPageBgTextures), &bg_images[3]);
|
||||
gSegments[0x08] = old_segment_08;
|
||||
gSegments[0x0D] = old_segment_0D;
|
||||
}
|
||||
}
|
||||
|
||||
void KaleidoScopeCall_Init(PlayState* play) {
|
||||
// @recomp Set the update and draw func pointers to the wrappers instead of the actual functions.
|
||||
sKaleidoScopeUpdateFunc = KaleidoUpdateWrapper;
|
||||
sKaleidoScopeDrawFunc = KaleidoDrawWrapper;
|
||||
KaleidoSetup_Init(play);
|
||||
}
|
||||
|
||||
// @recomp patched to fix bilerp seams.
|
||||
Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, TexturePtr* textures) {
|
||||
s32 i;
|
||||
|
@ -172,24 +221,17 @@ Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, TexturePtr* textures
|
|||
|
||||
bg_image_t* cur_image = NULL;
|
||||
|
||||
// Check if this texture set has already been assembled into an image.
|
||||
// Check if this texture set has been assembled into a full image.
|
||||
u32 image_index;
|
||||
for (image_index = 0; image_index < bg_image_count; image_index++) {
|
||||
for (image_index = 0; image_index < BG_IMAGE_COUNT; image_index++) {
|
||||
if (bg_pointers[image_index] == textures) {
|
||||
cur_image = &bg_images[image_index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no image was found and there's a free image slot, assemble the image.
|
||||
if (cur_image == NULL && image_index < BG_IMAGE_COUNT) {
|
||||
assemble_image(textures, &bg_images[image_index]);
|
||||
bg_pointers[image_index] = textures;
|
||||
cur_image = &bg_images[image_index];
|
||||
bg_image_count++;
|
||||
}
|
||||
|
||||
if (cur_image == NULL) {
|
||||
// No image was found and there are no free slots.
|
||||
// No image was found.
|
||||
return gfx;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ s32 func_80847190(PlayState* play, Player* this, s32 arg2) {
|
|||
static float filtered_gyro_x, filtered_gyro_y;
|
||||
static int applied_gyro_x, applied_gyro_y;
|
||||
|
||||
const float filter_factor = 0.50f;
|
||||
const float filter_factor = 0.00f;
|
||||
|
||||
// TODO remappable gyro reset button
|
||||
if (play->state.input[0].press.button & BTN_L) {
|
||||
|
|
|
@ -394,17 +394,16 @@ void Interface_Draw(PlayState* play) {
|
|||
gEXSetScissorAlign(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_RIGHT, 0, -margin_reduction, -SCREEN_WIDTH, margin_reduction, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
|
||||
// @recomp Move the item being equipped from the center of the screen to the right edge as the timer counts down
|
||||
if (gKaleidoMgrOverlayTable[0].loadedRamAddr != NULL) {
|
||||
// These are overlay symbols, so their addresses need to be offset to get their actual loaded vram address.
|
||||
// TODO remove this once the recompiler is able to handle overlay symbols automatically for patch functions.
|
||||
if ((pauseCtx->state == PAUSE_STATE_MAIN) && ((pauseCtx->mainState == PAUSE_MAIN_STATE_EQUIP_ITEM) ||
|
||||
(pauseCtx->mainState == PAUSE_MAIN_STATE_EQUIP_MASK))) {
|
||||
extern s16 sEquipAnimTimer;
|
||||
extern s16 sMaskEquipAnimTimer;
|
||||
extern s16 sEquipState;
|
||||
extern s16 sMaskEquipState;
|
||||
s16 equip_timer = *(s16*)((u8*)&sEquipAnimTimer + gKaleidoMgrOverlayTable[0].offset);
|
||||
s16 mask_equip_timer = *(s16*)((u8*)&sMaskEquipAnimTimer + gKaleidoMgrOverlayTable[0].offset);
|
||||
s16 equip_state = *(s16*)((u8*)&sEquipState + gKaleidoMgrOverlayTable[0].offset);
|
||||
s16 mask_equip_state = *(s16*)((u8*)&sMaskEquipState + gKaleidoMgrOverlayTable[0].offset);
|
||||
s16 equip_timer = *(s16*)KaleidoManager_GetRamAddr(&sEquipAnimTimer);
|
||||
s16 mask_equip_timer = *(s16*)KaleidoManager_GetRamAddr(&sMaskEquipAnimTimer);
|
||||
s16 equip_state = *(s16*)KaleidoManager_GetRamAddr(&sEquipState);
|
||||
s16 mask_equip_state = *(s16*)KaleidoManager_GetRamAddr(&sMaskEquipState);
|
||||
|
||||
s16 timer = MIN(equip_timer, mask_equip_timer);
|
||||
s32 max_timer = 10;
|
||||
|
|
|
@ -114,7 +114,7 @@ void recomp::reset_graphics_options() {
|
|||
new_config.wm_option = ultramodern::WindowMode::Windowed;
|
||||
new_config.ar_option = RT64::UserConfiguration::AspectRatio::Expand;
|
||||
new_config.msaa_option = RT64::UserConfiguration::Antialiasing::MSAA4X;
|
||||
new_config.rr_option = RT64::UserConfiguration::RefreshRate::Original;
|
||||
new_config.rr_option = RT64::UserConfiguration::RefreshRate::Display;
|
||||
new_config.rr_manual_value = 60;
|
||||
ultramodern::set_graphics_config(new_config);
|
||||
}
|
||||
|
|
|
@ -201,6 +201,13 @@ RT64::Application* RT64Init(uint8_t* rom, uint8_t* rdram, ultramodern::WindowHan
|
|||
|
||||
device_max_msaa = compute_max_supported_aa(common_sample_counts);
|
||||
|
||||
// Force gbi depth branches to prevent LODs from kicking in.
|
||||
ret->enhancementConfig.f3dex.forceBranch = true;
|
||||
// Scale LODs based on the output resolution.
|
||||
ret->enhancementConfig.textureLOD.scale = true;
|
||||
|
||||
ret->updateEnhancementConfig();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -260,6 +267,13 @@ void RT64UpdateConfig(RT64::Application* application, const ultramodern::Graphic
|
|||
}
|
||||
}
|
||||
|
||||
void RT64EnableInstantPresent(RT64::Application* application) {
|
||||
// Enable the present early presentation mode for minimal latency.
|
||||
application->enhancementConfig.presentation.mode = RT64::EnhancementConfiguration::Presentation::Mode::PresentEarly;
|
||||
|
||||
application->updateEnhancementConfig();
|
||||
}
|
||||
|
||||
RT64::UserConfiguration::Antialiasing RT64MaxMSAA() {
|
||||
return device_max_msaa;
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@ ultramodern::GraphicsConfig ultramodern::get_graphics_config() {
|
|||
}
|
||||
|
||||
void gfx_thread_func(uint8_t* rdram, uint8_t* rom, std::atomic_flag* thread_ready, ultramodern::WindowHandle window_handle) {
|
||||
bool enabled_instant_present = false;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
ultramodern::set_native_thread_name("Gfx Thread");
|
||||
|
@ -293,6 +294,11 @@ void gfx_thread_func(uint8_t* rdram, uint8_t* rom, std::atomic_flag* thread_read
|
|||
if (events_context.action_queue.wait_dequeue_timed(action, 1ms)) {
|
||||
// Determine the action type and act on it
|
||||
if (const auto* task_action = std::get_if<SpTaskAction>(&action)) {
|
||||
// Turn on instant present if the game has been started and it hasn't been turned on yet.
|
||||
if (ultramodern::is_game_started() && !enabled_instant_present) {
|
||||
RT64EnableInstantPresent(application);
|
||||
enabled_instant_present = true;
|
||||
}
|
||||
// Tell the game that the RSP completed instantly. This will allow it to queue other task types, but it won't
|
||||
// start another graphics task until the RDP is also complete. Games usually preserve the RSP inputs until the RDP
|
||||
// is finished as well, so sending this early shouldn't be an issue in most cases.
|
||||
|
|
Loading…
Reference in New Issue