diff --git a/src/core/mdec.cpp b/src/core/mdec.cpp index 022ba781d..8fc133442 100644 --- a/src/core/mdec.cpp +++ b/src/core/mdec.cpp @@ -106,6 +106,8 @@ static void CopyOutBlock(void* param, TickCount ticks, TickCount ticks_late); // from nocash spec static bool rl_decode_block(s16* blk, const u8* qt); static void IDCT(s16* blk); +static void IDCT_New(s16* blk); +static void IDCT_Old(s16* blk); static void yuv_to_rgb(u32 xx, u32 yy, const std::array<s16, 64>& Crblk, const std::array<s16, 64>& Cbblk, const std::array<s16, 64>& Yblk); static void y_to_mono(const std::array<s16, 64>& Yblk); @@ -627,9 +629,7 @@ void MDEC::CopyOutBlock(void* param, TickCount ticks, TickCount ticks_late) case DataOutputDepth_15Bit: { - // people have made texture packs using the old conversion routines.. best to just leave them be. - if (g_settings.texture_replacements.enable_vram_write_replacements || - g_settings.texture_replacements.dump_vram_writes) + if (UNLIKELY(g_settings.use_old_mdec_routines)) { const u16 a = ZeroExtend16(s_status.data_output_bit15.GetValue()) << 15; for (u32 i = 0; i < static_cast<u32>(s_block_rgb.size());) @@ -762,6 +762,15 @@ bool MDEC::rl_decode_block(s16* blk, const u8* qt) } void MDEC::IDCT(s16* blk) +{ + // people have made texture packs using the old conversion routines.. best to just leave them be. + if (UNLIKELY(g_settings.use_old_mdec_routines)) + IDCT_Old(blk); + else + IDCT_New(blk); +} + +void MDEC::IDCT_New(s16* blk) { std::array<s32, 64> temp; for (u32 x = 0; x < 8; x++) @@ -788,6 +797,33 @@ void MDEC::IDCT(s16* blk) } } +void MDEC::IDCT_Old(s16* blk) +{ + std::array<s64, 64> temp_buffer; + for (u32 x = 0; x < 8; x++) + { + for (u32 y = 0; y < 8; y++) + { + s64 sum = 0; + for (u32 u = 0; u < 8; u++) + sum += s32(blk[u * 8 + x]) * s32(s_scale_table[u * 8 + y]); + temp_buffer[x + y * 8] = sum; + } + } + for (u32 x = 0; x < 8; x++) + { + for (u32 y = 0; y < 8; y++) + { + s64 sum = 0; + for (u32 u = 0; u < 8; u++) + sum += s64(temp_buffer[u + y * 8]) * s32(s_scale_table[u * 8 + x]); + + blk[x + y * 8] = + static_cast<s16>(std::clamp<s32>(SignExtendN<9, s32>((sum >> 32) + ((sum >> 31) & 1)), -128, 127)); + } + } +} + void MDEC::yuv_to_rgb(u32 xx, u32 yy, const std::array<s16, 64>& Crblk, const std::array<s16, 64>& Cbblk, const std::array<s16, 64>& Yblk) { diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 496166d9a..47aee5e96 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -301,6 +301,8 @@ void Settings::Load(SettingsInterface& si) audio_output_muted = si.GetBoolValue("Audio", "OutputMuted", false); audio_dump_on_boot = si.GetBoolValue("Audio", "DumpOnBoot", false); + use_old_mdec_routines = si.GetBoolValue("Hacks", "UseOldMDECRoutines", false); + dma_max_slice_ticks = si.GetIntValue("Hacks", "DMAMaxSliceTicks", DEFAULT_DMA_MAX_SLICE_TICKS); dma_halt_ticks = si.GetIntValue("Hacks", "DMAHaltTicks", DEFAULT_DMA_HALT_TICKS); gpu_fifo_size = static_cast<u32>(si.GetIntValue("Hacks", "GPUFIFOSize", DEFAULT_GPU_FIFO_SIZE)); @@ -512,6 +514,7 @@ void Settings::Save(SettingsInterface& si) const si.SetBoolValue("Audio", "OutputMuted", audio_output_muted); si.SetBoolValue("Audio", "DumpOnBoot", audio_dump_on_boot); + si.SetBoolValue("Hacks", "UseOldMDECRoutines", use_old_mdec_routines); si.SetIntValue("Hacks", "DMAMaxSliceTicks", dma_max_slice_ticks); si.SetIntValue("Hacks", "DMAHaltTicks", dma_halt_ticks); si.SetIntValue("Hacks", "GPUFIFOSize", gpu_fifo_size); diff --git a/src/core/settings.h b/src/core/settings.h index d1bc2b7a8..64b9ed0d7 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -168,6 +168,8 @@ struct Settings bool audio_output_muted = false; bool audio_dump_on_boot = false; + bool use_old_mdec_routines = false; + // timing hacks section TickCount dma_max_slice_ticks = DEFAULT_DMA_MAX_SLICE_TICKS; TickCount dma_halt_ticks = DEFAULT_DMA_HALT_TICKS; diff --git a/src/duckstation-qt/advancedsettingswidget.cpp b/src/duckstation-qt/advancedsettingswidget.cpp index 5a8ca72ff..dd5333f60 100644 --- a/src/duckstation-qt/advancedsettingswidget.cpp +++ b/src/duckstation-qt/advancedsettingswidget.cpp @@ -226,8 +226,7 @@ void AdvancedSettingsWidget::addTweakOptions() "DisableAllEnhancements", false); addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Show Status Indicators"), "Display", "ShowStatusIndicators", true); - addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Show Frame Times"), "Display", - "ShowFrameTimes", false); + addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Show Frame Times"), "Display", "ShowFrameTimes", false); addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Apply Compatibility Settings"), "Main", "ApplyCompatibilitySettings", true); addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Display FPS Limit"), "Display", "MaxFPS", 0, 1000, 0); @@ -261,6 +260,8 @@ void AdvancedSettingsWidget::addTweakOptions() Settings::GetCPUFastmemModeDisplayName, "CPUFastmemMode", static_cast<u32>(CPUFastmemMode::Count), Settings::DEFAULT_CPU_FASTMEM_MODE); + addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Use Old MDEC Routines"), "Hacks", "UseOldMDECRoutines", + false); addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Enable VRAM Write Texture Replacement"), "TextureReplacements", "EnableVRAMWriteReplacements", false); addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Preload Texture Replacements"), "TextureReplacements", @@ -305,7 +306,7 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable all enhancements setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Show status indicators - setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Show frame times + setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Show frame times setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply compatibility settings setIntRangeTweakOption(m_ui.tweakOptionTable, i++, 0); // Display FPS limit setChoiceTweakOption(m_ui.tweakOptionTable, i++, 0); // Multisample antialiasing @@ -316,6 +317,7 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Recompiler memory exceptions setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Recompiler block linking setChoiceTweakOption(m_ui.tweakOptionTable, i++, Settings::DEFAULT_CPU_FASTMEM_MODE); // Recompiler fastmem mode + setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Use Old MDEC Routines setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // VRAM write texture replacement setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Preload texture replacements setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Dump replacable VRAM writes @@ -345,6 +347,7 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() sif->DeleteValue("Main", "DisableAllEnhancements"); sif->DeleteValue("Display", "ShowEnhancements"); sif->DeleteValue("Display", "ShowStatusIndicators"); + sif->DeleteValue("Display", "ShowFrameTimes"); sif->DeleteValue("Main", "ApplyCompatibilitySettings"); sif->DeleteValue("Display", "MaxFPS"); sif->DeleteValue("Display", "ActiveStartOffset"); @@ -365,6 +368,7 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() sif->DeleteValue("TextureReplacements", "DumpVRAMWriteForceAlphaChannel"); sif->DeleteValue("TextureReplacements", "DumpVRAMWriteWidthThreshold"); sif->DeleteValue("TextureReplacements", "DumpVRAMWriteHeightThreshold"); + sif->DeleteValue("Hacks", "UseOldMDECRoutines"); sif->DeleteValue("Hacks", "DMAMaxSliceTicks"); sif->DeleteValue("Hacks", "DMAHaltTicks"); sif->DeleteValue("Hacks", "GPUFIFOSize");