mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2024-11-22 20:59:21 +01:00
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);
|
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 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 RT64SendDL(uint8_t* rdram, const OSTask* task);
|
||||||
void RT64UpdateScreen(uint32_t vi_origin);
|
void RT64UpdateScreen(uint32_t vi_origin);
|
||||||
void RT64ChangeWindow();
|
void RT64ChangeWindow();
|
||||||
|
@ -31,8 +31,6 @@ s16 KaleidoScope_SetPageVertices(PlayState* play, Vtx* vtx, s16 vtxPage, s16 num
|
|||||||
s32 cur_y;
|
s32 cur_y;
|
||||||
u32 row;
|
u32 row;
|
||||||
|
|
||||||
gSegments[0x0D] = OS_K0_TO_PHYSICAL(play->pauseCtx.iconItemLangSegment);
|
|
||||||
|
|
||||||
cur_y = PAGE_BG_HEIGHT / 2;
|
cur_y = PAGE_BG_HEIGHT / 2;
|
||||||
|
|
||||||
// 2 verts per row plus 2 extra verts at the start and the end.
|
// 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.
|
// 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.
|
// 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** sVtxPageQuadsXRelocated = (s16**)KaleidoManager_GetRamAddr(sVtxPageQuadsX);
|
||||||
s16** sVtxPageQuadsWidthRelocated = (s16**)((u8*)&sVtxPageQuadsWidth[0] + gKaleidoMgrOverlayTable[0].offset);
|
s16** sVtxPageQuadsWidthRelocated = (s16**)KaleidoManager_GetRamAddr(sVtxPageQuadsWidth);
|
||||||
s16** sVtxPageQuadsYRelocated = (s16**)((u8*)&sVtxPageQuadsY[0] + gKaleidoMgrOverlayTable[0].offset);
|
s16** sVtxPageQuadsYRelocated = (s16**)KaleidoManager_GetRamAddr(sVtxPageQuadsY);
|
||||||
s16** sVtxPageQuadsHeightRelocated = (s16**)((u8*)&sVtxPageQuadsHeight[0] + gKaleidoMgrOverlayTable[0].offset);
|
s16** sVtxPageQuadsHeightRelocated = (s16**)KaleidoManager_GetRamAddr(sVtxPageQuadsHeight);
|
||||||
|
|
||||||
s16 k = 60;
|
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
|
#define BG_IMAGE_COUNT 4
|
||||||
TexturePtr* bg_pointers[BG_IMAGE_COUNT];
|
TexturePtr* bg_pointers[BG_IMAGE_COUNT];
|
||||||
bg_image_t bg_images[BG_IMAGE_COUNT];
|
bg_image_t bg_images[BG_IMAGE_COUNT] __attribute__((aligned(8)));
|
||||||
u32 bg_image_count = 0;
|
|
||||||
|
|
||||||
void assemble_image(TexturePtr* textures, bg_image_t* image_out) {
|
void assemble_image(TexturePtr* textures, bg_image_t* image_out) {
|
||||||
u8* pixels_out_start = *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.
|
// @recomp patched to fix bilerp seams.
|
||||||
Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, TexturePtr* textures) {
|
Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, TexturePtr* textures) {
|
||||||
s32 i;
|
s32 i;
|
||||||
@ -172,24 +221,17 @@ Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, TexturePtr* textures
|
|||||||
|
|
||||||
bg_image_t* cur_image = NULL;
|
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;
|
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) {
|
if (bg_pointers[image_index] == textures) {
|
||||||
cur_image = &bg_images[image_index];
|
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) {
|
if (cur_image == NULL) {
|
||||||
// No image was found and there are no free slots.
|
// No image was found.
|
||||||
return gfx;
|
return gfx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ s32 func_80847190(PlayState* play, Player* this, s32 arg2) {
|
|||||||
static float filtered_gyro_x, filtered_gyro_y;
|
static float filtered_gyro_x, filtered_gyro_y;
|
||||||
static int applied_gyro_x, applied_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
|
// TODO remappable gyro reset button
|
||||||
if (play->state.input[0].press.button & BTN_L) {
|
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);
|
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
|
// @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) {
|
if ((pauseCtx->state == PAUSE_STATE_MAIN) && ((pauseCtx->mainState == PAUSE_MAIN_STATE_EQUIP_ITEM) ||
|
||||||
// These are overlay symbols, so their addresses need to be offset to get their actual loaded vram address.
|
(pauseCtx->mainState == PAUSE_MAIN_STATE_EQUIP_MASK))) {
|
||||||
// TODO remove this once the recompiler is able to handle overlay symbols automatically for patch functions.
|
|
||||||
extern s16 sEquipAnimTimer;
|
extern s16 sEquipAnimTimer;
|
||||||
extern s16 sMaskEquipAnimTimer;
|
extern s16 sMaskEquipAnimTimer;
|
||||||
extern s16 sEquipState;
|
extern s16 sEquipState;
|
||||||
extern s16 sMaskEquipState;
|
extern s16 sMaskEquipState;
|
||||||
s16 equip_timer = *(s16*)((u8*)&sEquipAnimTimer + gKaleidoMgrOverlayTable[0].offset);
|
s16 equip_timer = *(s16*)KaleidoManager_GetRamAddr(&sEquipAnimTimer);
|
||||||
s16 mask_equip_timer = *(s16*)((u8*)&sMaskEquipAnimTimer + gKaleidoMgrOverlayTable[0].offset);
|
s16 mask_equip_timer = *(s16*)KaleidoManager_GetRamAddr(&sMaskEquipAnimTimer);
|
||||||
s16 equip_state = *(s16*)((u8*)&sEquipState + gKaleidoMgrOverlayTable[0].offset);
|
s16 equip_state = *(s16*)KaleidoManager_GetRamAddr(&sEquipState);
|
||||||
s16 mask_equip_state = *(s16*)((u8*)&sMaskEquipState + gKaleidoMgrOverlayTable[0].offset);
|
s16 mask_equip_state = *(s16*)KaleidoManager_GetRamAddr(&sMaskEquipState);
|
||||||
|
|
||||||
s16 timer = MIN(equip_timer, mask_equip_timer);
|
s16 timer = MIN(equip_timer, mask_equip_timer);
|
||||||
s32 max_timer = 10;
|
s32 max_timer = 10;
|
||||||
|
@ -114,7 +114,7 @@ void recomp::reset_graphics_options() {
|
|||||||
new_config.wm_option = ultramodern::WindowMode::Windowed;
|
new_config.wm_option = ultramodern::WindowMode::Windowed;
|
||||||
new_config.ar_option = RT64::UserConfiguration::AspectRatio::Expand;
|
new_config.ar_option = RT64::UserConfiguration::AspectRatio::Expand;
|
||||||
new_config.msaa_option = RT64::UserConfiguration::Antialiasing::MSAA4X;
|
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;
|
new_config.rr_manual_value = 60;
|
||||||
ultramodern::set_graphics_config(new_config);
|
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);
|
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;
|
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() {
|
RT64::UserConfiguration::Antialiasing RT64MaxMSAA() {
|
||||||
return device_max_msaa;
|
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) {
|
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;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
ultramodern::set_native_thread_name("Gfx Thread");
|
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)) {
|
if (events_context.action_queue.wait_dequeue_timed(action, 1ms)) {
|
||||||
// Determine the action type and act on it
|
// Determine the action type and act on it
|
||||||
if (const auto* task_action = std::get_if<SpTaskAction>(&action)) {
|
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
|
// 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
|
// 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.
|
// is finished as well, so sending this early shouldn't be an issue in most cases.
|
||||||
|
Loading…
Reference in New Issue
Block a user