MDEC: Add option to use old conversion routines

That way texture packs for games which use MDEC for decoding
backgrounds will still be compatible.
This commit is contained in:
Connor McLaughlin 2023-01-12 17:01:02 +10:00
parent 3e0be0a577
commit af5d49649c
4 changed files with 51 additions and 6 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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;

View File

@ -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");