diff --git a/source/utils/DrawUtils.cpp b/source/utils/DrawUtils.cpp index 8e88c8c..7907a52 100644 --- a/source/utils/DrawUtils.cpp +++ b/source/utils/DrawUtils.cpp @@ -1,5 +1,6 @@ #include "DrawUtils.h" +#include "dc.h" #include "logger.h" #include "utils.h" #include @@ -24,18 +25,6 @@ static SFT pFont = {}; static Color font_col(0xFFFFFFFF); -#define __SetDCPitchReg ((void (*)(uint32_t, uint32_t))(0x101C400 + 0x1e714)) - -extern "C" uint32_t __OSPhysicalToEffectiveUncached(uint32_t); - -static uint32_t __ReadReg32(uint32_t index) { - if (OSIsECOMode()) { - return 0; - } - auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000); - return regs[index]; -} - void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_, uint32_t drcSize_) { DrawUtils::tvBuffer = (uint8_t *) tvBuffer_; DrawUtils::tvSize = tvSize_; @@ -75,19 +64,19 @@ void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_, } } - auto tvScanBufferWidth = __ReadReg32(0x184d + SCREEN_TV * 0x200); + auto tvScanBufferWidth = DCReadReg32(SCREEN_TV, D1GRPH_X_END_REG); if (tvScanBufferWidth == 640) { // 480i/480p/576i 4:3 DrawUtils::usedTVWidth = 640; - __SetDCPitchReg(SCREEN_TV, 640); + SetDCPitchReg(SCREEN_TV, 640); DrawUtils::usedTVScale = bigScale ? 0.75 : 0.75f; } else if (tvScanBufferWidth == 854) { // 480i/480p/576i 16:9 DrawUtils::usedTVWidth = 896; - __SetDCPitchReg(SCREEN_TV, 896); + SetDCPitchReg(SCREEN_TV, 896); DrawUtils::usedTVScale = bigScale ? 1.0 : 1.0f; } else if (tvScanBufferWidth == 1280) { // 720p 16:9 DrawUtils::usedTVWidth = 1280; - __SetDCPitchReg(SCREEN_TV, 1280); + SetDCPitchReg(SCREEN_TV, 1280); if (bigScale) { DrawUtils::usedTVScale = 1.5; } else { @@ -102,11 +91,11 @@ void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_, } } else if (tvScanBufferWidth == 1920) { // 1080i/1080p 16:9 DrawUtils::usedTVWidth = 1920; - __SetDCPitchReg(SCREEN_TV, 1920); + SetDCPitchReg(SCREEN_TV, 1920); DrawUtils::usedTVScale = bigScale ? 2.25 : 1.125f; } else { DrawUtils::usedTVWidth = tvScanBufferWidth; - __SetDCPitchReg(SCREEN_TV, tvScanBufferWidth); + SetDCPitchReg(SCREEN_TV, tvScanBufferWidth); DrawUtils::usedTVScale = 1.0f; DEBUG_FUNCTION_LINE_WARN("Unknown tv width detected, config menu might not show properly"); } diff --git a/source/utils/config/ConfigUtils.cpp b/source/utils/config/ConfigUtils.cpp index 4225153..a8d12bd 100644 --- a/source/utils/config/ConfigUtils.cpp +++ b/source/utils/config/ConfigUtils.cpp @@ -1,6 +1,7 @@ #include "ConfigUtils.h" #include "../../globals.h" #include "../DrawUtils.h" +#include "../dc.h" #include "../logger.h" #include "ConfigRenderer.h" #include "config/WUPSConfigAPI.h" @@ -236,41 +237,20 @@ void ConfigUtils::displayMenu() { } } -extern "C" uint32_t __OSPhysicalToEffectiveUncached(uint32_t); - -static uint32_t __ReadReg32(uint32_t index) { - if (OSIsECOMode()) { - return 0; - } - auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000); - return regs[index]; -} - -static void __WriteReg32(uint32_t index, uint32_t val) { - if (OSIsECOMode()) { - return; - } - auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000); - regs[index] = val; -} - - -extern "C" void (*real_GX2SetTVBuffer)(void *buffer, uint32_t buffer_size, int32_t tv_render_mode, GX2SurfaceFormat format, GX2BufferingMode buffering_mode); -extern "C" void (*real_GX2SetDRCBuffer)(void *buffer, uint32_t buffer_size, uint32_t drc_mode, GX2SurfaceFormat surface_format, GX2BufferingMode buffering_mode); - void ConfigUtils::openConfigMenu() { gOnlyAcceptFromThread = OSGetCurrentThread(); bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled(); // Save copy of DC reg values - auto tvRender1 = __ReadReg32(0x1841 + SCREEN_TV * 0x200); - auto tvRender2 = __ReadReg32(0x1840 + SCREEN_TV * 0x200); - auto tvPitch1 = __ReadReg32(0x1848 + SCREEN_TV * 0x200); - auto tvPitch2 = __ReadReg32(0x1866 + SCREEN_TV * 0x200); - auto drcRender1 = __ReadReg32(0x1841 + SCREEN_DRC * 0x200); - auto drcRender2 = __ReadReg32(0x1840 + SCREEN_DRC * 0x200); - auto drcPitch1 = __ReadReg32(0x1848 + SCREEN_DRC * 0x200); - auto drcPitch2 = __ReadReg32(0x1866 + SCREEN_DRC * 0x200); + auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG); + auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG); + auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG); + auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG); + + auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG); + auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG); + auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG); + auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG); OSScreenInit(); @@ -354,15 +334,15 @@ void ConfigUtils::openConfigMenu() { error_exit: // Restore DC reg values - __WriteReg32(0x1841 + SCREEN_TV * 0x200, tvRender1); - __WriteReg32(0x1840 + SCREEN_TV * 0x200, tvRender2); - __WriteReg32(0x1848 + SCREEN_TV * 0x200, tvPitch1); - __WriteReg32(0x1866 + SCREEN_TV * 0x200, tvPitch2); + DCWriteReg32(SCREEN_TV, D1GRPH_CONTROL_REG, tvRender1); + DCWriteReg32(SCREEN_TV, D1GRPH_ENABLE_REG, tvRender2); + DCWriteReg32(SCREEN_TV, D1GRPH_PITCH_REG, tvPitch1); + DCWriteReg32(SCREEN_TV, D1OVL_PITCH_REG, tvPitch2); - __WriteReg32(0x1841 + SCREEN_DRC * 0x200, drcRender1); - __WriteReg32(0x1840 + SCREEN_DRC * 0x200, drcRender2); - __WriteReg32(0x1848 + SCREEN_DRC * 0x200, drcPitch1); - __WriteReg32(0x1866 + SCREEN_DRC * 0x200, drcPitch2); + DCWriteReg32(SCREEN_DRC, D1GRPH_CONTROL_REG, drcRender1); + DCWriteReg32(SCREEN_DRC, D1GRPH_ENABLE_REG, drcRender2); + DCWriteReg32(SCREEN_DRC, D1GRPH_PITCH_REG, drcPitch1); + DCWriteReg32(SCREEN_DRC, D1OVL_PITCH_REG, drcPitch2); if (!skipScreen0Free && screenbuffer0) { MEMFreeToMappedMemory(screenbuffer0); diff --git a/source/utils/dc.h b/source/utils/dc.h new file mode 100644 index 0000000..3200f05 --- /dev/null +++ b/source/utils/dc.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +extern "C" uint32_t __OSPhysicalToEffectiveUncached(uint32_t); + +static inline uint32_t DCReadReg32(OSScreenID screen, uint32_t index) { + if (OSIsECOMode()) { + return 0; + } + auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000); + return regs[index + (screen * 0x200)]; +} + + +static inline void DCWriteReg32(OSScreenID screen, uint32_t index, uint32_t val) { + if (OSIsECOMode()) { + return; + } + auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000); + regs[index + (screen * 0x200)] = val; +} + +// https://www.x.org/docs/AMD/old/42589_rv630_rrg_1.01o.pdf (reg id in document / 4) +#define D1GRPH_ENABLE_REG 0x1840 +#define D1GRPH_CONTROL_REG 0x1841 +#define D1GRPH_PITCH_REG 0x1848 +#define D1OVL_PITCH_REG 0x1866 +#define D1GRPH_X_END_REG 0x184d +#define D1GRPH_Y_END_REG 0x184e + +static inline void SetDCPitchReg(OSScreenID screen, uint16_t pitch) { + DCWriteReg32(screen, D1GRPH_PITCH_REG, pitch); + DCWriteReg32(screen, D1OVL_PITCH_REG, pitch); +} \ No newline at end of file