mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
EE/UI: Remove the FPU multiply gamefix
It patched one product, 0.25 * pi, from the correctly-rounded 0x3f490fdb to the 0x3f490fda the EE's multiplier returns, so Tales of Destiny stops hanging. That product is one sample of the multiplier's one-ULP deficit, and eeClampMode 3 models the deficit for every operand pair -- including the asymmetry the gamefix reproduced by comparing fs and ft against their own constants, which falls out of a predicate that reads ft alone. The seven serials carry the clamp mode instead, and iFPU-arm64.cpp's multiply is a bare Fmul again. The toggle goes from the Qt, FullscreenUI, Android and iOS front ends, along with the GameDB schema enum and the harness helper that set it. Fix_FpuMultiply and the config bit stay: vu_capture's on-disk gamefix mask is bit-indexed by GamefixId, so dropping ordinal 0 would reinterpret every capture already recorded. tbl_GamefixNames keeps the name, so a GameDB that still lists it parses and does nothing.
This commit is contained in:
@@ -2470,8 +2470,8 @@ SCAJ-20181:
|
||||
SCAJ-20182:
|
||||
name: "Tales of Destiny"
|
||||
region: "NTSC-Unk"
|
||||
gameFixes:
|
||||
- FpuMulHack
|
||||
clampModes:
|
||||
eeClampMode: 3 # Hangs otherwise: it needs the EE multiplier's one-ULP deficit, which the single-precision tier does not model.
|
||||
SCAJ-20183:
|
||||
name: "ワイルドアームズ ザ フィフスヴァンガード"
|
||||
name-sort: "わいるどあーむず ざ ふぃふすゔぁんがーど"
|
||||
@@ -2517,8 +2517,8 @@ SCAJ-20192:
|
||||
SCAJ-20193:
|
||||
name: "Tales of Destiny [Director's Cut] [Premium Box]"
|
||||
region: "NTSC-C-J"
|
||||
gameFixes:
|
||||
- FpuMulHack
|
||||
clampModes:
|
||||
eeClampMode: 3 # Hangs otherwise: it needs the EE multiplier's one-ULP deficit, which the single-precision tier does not model.
|
||||
SCAJ-20194:
|
||||
name: "Minna no Golf 4 [PlayStation2 the Best]"
|
||||
region: "NTSC-Unk"
|
||||
@@ -7967,8 +7967,8 @@ SCKA-20100:
|
||||
name: "테일즈 오브 데스티니" # Undumped on ReDump as of 2025-08-28
|
||||
name-en: "Tales of Destiny"
|
||||
region: "NTSC-K"
|
||||
gameFixes:
|
||||
- FpuMulHack
|
||||
clampModes:
|
||||
eeClampMode: 3 # Hangs otherwise: it needs the EE multiplier's one-ULP deficit, which the single-precision tier does not model.
|
||||
SCKA-20101:
|
||||
name: "성검전설 4"
|
||||
name-en: "Seiken Densetsu 4"
|
||||
@@ -8069,8 +8069,8 @@ SCKA-20119:
|
||||
name: "테일즈 오브 데스티니 디렉터즈컷 [Premium Box]" # Undumped on ReDump as of 2025-08-28
|
||||
name-en: "Tales of Destiny - Director's Cut [Premium Box]"
|
||||
region: "NTSC-K"
|
||||
gameFixes:
|
||||
- FpuMulHack
|
||||
clampModes:
|
||||
eeClampMode: 3 # Hangs otherwise: it needs the EE multiplier's one-ULP deficit, which the single-precision tier does not model.
|
||||
SCKA-20120:
|
||||
name: "라쳇 & 클랭크 - 공구들고 바캉스" # Undumped on ReDump as of 2025-08-28
|
||||
name-en: "Ratchet & Clank - Vacation with Tools" # Ratchet & Clank - Size Matters
|
||||
@@ -61771,8 +61771,8 @@ SLPS-25715:
|
||||
name-sort: "ているず おぶ ですてぃにー"
|
||||
name-en: "Tales of Destiny"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- FpuMulHack
|
||||
clampModes:
|
||||
eeClampMode: 3 # Hangs otherwise: it needs the EE multiplier's one-ULP deficit, which the single-precision tier does not model.
|
||||
SLPS-25716:
|
||||
name: "デジモンセイバーズ アナザーミッション"
|
||||
name-sort: "でじもんせいばーず あなざーみっしょん"
|
||||
@@ -62558,8 +62558,8 @@ SLPS-25841:
|
||||
name-sort: "ているず おぶ ですてぃにー でぃれくたーずかっと [ぷれみあむBOX]"
|
||||
name-en: "Tales of Destiny [Director's Cut] [Premium Box]"
|
||||
region: "NTSC-J"
|
||||
gameFixes:
|
||||
- FpuMulHack
|
||||
clampModes:
|
||||
eeClampMode: 3 # Hangs otherwise: it needs the EE multiplier's one-ULP deficit, which the single-precision tier does not model.
|
||||
memcardFilters: # Allows import of non-DC Tales of Destiny data.
|
||||
- "SLPS-25841"
|
||||
- "SLPS-25842"
|
||||
@@ -62569,9 +62569,9 @@ SLPS-25842:
|
||||
name-sort: "ているず おぶ ですてぃにー でぃれくたーずかっと"
|
||||
name-en: "Tales of Destiny [Director's Cut]"
|
||||
region: "NTSC-J"
|
||||
clampModes:
|
||||
eeClampMode: 3 # Hangs otherwise: it needs the EE multiplier's one-ULP deficit, which the single-precision tier does not model.
|
||||
compat: 5
|
||||
gameFixes:
|
||||
- FpuMulHack
|
||||
memcardFilters:
|
||||
- "SLPS-25841"
|
||||
- "SLPS-25842"
|
||||
|
||||
@@ -17,7 +17,6 @@ GameFixSettingsWidget::GameFixSettingsWidget(SettingsWindow* settings_dialog, QW
|
||||
|
||||
setupTab(m_ui);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.FpuMulHack, "EmuCore/Gamefixes", "FpuMulHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.GoemonTlbHack, "EmuCore/Gamefixes", "GoemonTlbHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.SoftwareRendererFMVHack, "EmuCore/Gamefixes", "SoftwareRendererFMVHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.SkipMPEGHack, "EmuCore/Gamefixes", "SkipMPEGHack", false);
|
||||
@@ -36,7 +35,6 @@ GameFixSettingsWidget::GameFixSettingsWidget(SettingsWindow* settings_dialog, QW
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.XgKickHack, "EmuCore/Gamefixes", "XgKickHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.BlitInternalFPSHack, "EmuCore/Gamefixes", "BlitInternalFPSHack", false);
|
||||
|
||||
dialog()->registerWidgetHelp(m_ui.FpuMulHack, tr("FPU Multiply Hack"), tr("Unchecked"), tr("For Tales of Destiny."));
|
||||
dialog()->registerWidgetHelp(m_ui.GoemonTlbHack, tr("Preload TLB Hack"), tr("Unchecked"), tr("To avoid TLB miss on Goemon."));
|
||||
dialog()->registerWidgetHelp(m_ui.SoftwareRendererFMVHack, tr("Use Software Renderer For FMVs"), tr("Unchecked"), tr("Needed for some games with complex FMV rendering."));
|
||||
dialog()->registerWidgetHelp(m_ui.SkipMPEGHack, tr("Skip MPEG Hack"), tr("Unchecked"), tr("Skips videos/FMVs in games to avoid game hanging/freezes."));
|
||||
|
||||
@@ -17,13 +17,6 @@
|
||||
<string>Game Fixes</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="FpuMulHack">
|
||||
<property name="text">
|
||||
<string extracomment="FPU = Floating Point Unit. A part of the PS2's CPU. Do not translate.\nMultiply: mathematical term.\nTales of Destiny: a game's name. Leave as-is or use an official translation.">FPU Multiply Hack</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="SoftwareRendererFMVHack">
|
||||
<property name="text">
|
||||
@@ -162,7 +155,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>FpuMulHack</tabstop>
|
||||
<tabstop>SoftwareRendererFMVHack</tabstop>
|
||||
<tabstop>SkipMPEGHack</tabstop>
|
||||
<tabstop>GoemonTlbHack</tabstop>
|
||||
|
||||
+4
-1
@@ -1280,6 +1280,10 @@ struct Pcsx2Config
|
||||
{
|
||||
BITFIELD32()
|
||||
bool
|
||||
// No reader: eeMulRound (FPU.cpp) and emitDefectiveFmul
|
||||
// (iFPUd-arm64.cpp) model the multiplier defect this patched one
|
||||
// product of. The bit stays because its GamefixId indexes
|
||||
// vu_capture's on-disk gamefix mask.
|
||||
FpuMulHack : 1, // Tales of Destiny hangs.
|
||||
GoemonTlbHack : 1, // Gomeon tlb miss hack. The game need to access unmapped virtual address. Instead to handle it as exception, tlb are preloaded at startup
|
||||
SoftwareRendererFMVHack : 1, // Switches to software renderer for FMVs
|
||||
@@ -1697,7 +1701,6 @@ namespace EmuFolders
|
||||
|
||||
//------------ SPECIAL GAME FIXES!!! ---------------
|
||||
#define CHECK_VUADDSUBHACK (EmuConfig.Gamefixes.VuAddSubHack) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
|
||||
#define CHECK_FPUMULHACK (EmuConfig.Gamefixes.FpuMulHack) // Special Fix for Tales of Destiny hangs.
|
||||
#define CHECK_XGKICKHACK (EmuConfig.Gamefixes.XgKickHack) // Special Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics.
|
||||
#define CHECK_EETIMINGHACK (EmuConfig.Gamefixes.EETimingHack) // Fix all scheduled events to happen in 1 cycle.
|
||||
#define CHECK_INSTANTDMAHACK (EmuConfig.Gamefixes.InstantDMAHack) // Attempt to finish DMA's instantly, useful for games which rely on cache emulation.
|
||||
|
||||
@@ -26,7 +26,6 @@ SERIAL-12345: # !required! Serial number for the game, this is how games are loo
|
||||
# If you'd like to temporarily disable it, either comment out the line, or remove it!
|
||||
gameFixes:
|
||||
- VuAddSubHack
|
||||
- FpuMulHack
|
||||
- XGKickHack
|
||||
- EETimingHack
|
||||
- SkipMPEGHack
|
||||
@@ -207,9 +206,6 @@ These values are case-sensitive, so take care. If you incorrectly specify a Gam
|
||||
|
||||
### Game Fixes Options
|
||||
|
||||
* `FpuMulHack`
|
||||
* For Tales of Destiny: This fix addresses hanging issues.
|
||||
|
||||
* `SoftwareRendererFMVHack`
|
||||
* Used for complex FMV rendering in certain games.
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
"BlitInternalFPSHack",
|
||||
"DMABusyHack",
|
||||
"EETimingHack",
|
||||
"FpuMulHack",
|
||||
"GIFFIFOHack",
|
||||
"GoemonTlbHack",
|
||||
"IbitHack",
|
||||
|
||||
@@ -5884,7 +5884,6 @@ void FullscreenUI::DrawGameFixesSettingsPage()
|
||||
FSUI_CSTR("Game fixes should not be modified unless you are aware of what each option does and the implications of doing so."),
|
||||
false, false, ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_WRENCH, "FPU Multiply Hack"), FSUI_CSTR("For Tales of Destiny."), "EmuCore/Gamefixes", "FpuMulHack", false);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_MICROCHIP, "Use Software Renderer For FMVs"),
|
||||
FSUI_CSTR("Needed for some games with complex FMV rendering."), "EmuCore/Gamefixes", "SoftwareRendererFMVHack", false);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_FORWARD_FAST, "Skip MPEG Hack"), FSUI_CSTR("Skips videos/FMVs in games to avoid game hanging/freezes."),
|
||||
@@ -6338,7 +6337,6 @@ TRANSLATE_NOOP("FullscreenUI", "Activating game patches can cause unpredictable
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use patches at your own risk, the ARMSX2 team will provide no support for users who have enabled game patches.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Fixes");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game fixes should not be modified unless you are aware of what each option does and the implications of doing so.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "For Tales of Destiny.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Needed for some games with complex FMV rendering.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Skips videos/FMVs in games to avoid game hanging/freezes.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "To avoid TLB miss on Goemon.");
|
||||
|
||||
@@ -619,51 +619,13 @@ static void fpuEmitGuardedAddSub(const a64::VRegister& dst,
|
||||
_freeNEONreg(tmp);
|
||||
}
|
||||
|
||||
// FpuMulHack (Tales of Destiny Remake gamefix, EmuConfig.Gamefixes.FpuMulHack).
|
||||
// x86 routes every FPU multiply (MUL/MULA/MADD/MSUB) through FPU_MUL, which —
|
||||
// when the gamefix is on — patches the single specific product 0.25 * π
|
||||
// (0x3e800000 * 0x40490fdb) from the correctly-rounded 0x3f490fdb to 0x3f490fda
|
||||
// so the game stops hanging in one late-game room. Emit
|
||||
// `dst = (hit) ? 0x3f490fda : s*t`; callers clamp/accumulate dst as they normally
|
||||
// would (the magic value is an ordinary small float, so a following
|
||||
// fpuClampResult is a no-op). In the default config (gamefix off) this is a bare
|
||||
// Fmul — zero added cost.
|
||||
//
|
||||
// The patched value is not arbitrary: 0x3f490fda is π/4 one ULP low, which is
|
||||
// what the EE's multiplier actually returns. Its Booth recoding drops one ULP
|
||||
// when ft's significand has an odd digit pair (ft & 0x2AA) and the exact product
|
||||
// has no tail below the single ULP — here fs = 2^-2, so the product is exact and
|
||||
// the deficit reaches the result. The general model reproduces this pair (and
|
||||
// leaves the swapped operand order alone, exactly as the check below does).
|
||||
// It is NOT generalized here: this path has no exact product to test a tail
|
||||
// against, so it would need one built out of single-precision pieces on every
|
||||
// multiply in every game, against 1 instruction today. Its home is
|
||||
// emitDefectiveFmul (iFPUd-arm64.cpp), where the double product is already
|
||||
// there and the tail is 29 bits of it — extending it to this path needs its own
|
||||
// measured case.
|
||||
// The EE multiplier's one-ULP deficit is not modelled here: it needs the exact
|
||||
// product's tail below the single's ULP, which a single-precision multiply has
|
||||
// already discarded. It lives at emitDefectiveFmul (iFPUd-arm64.cpp), where the
|
||||
// product is a double and the tail is 29 bits of it.
|
||||
static void emitFpuMul(const a64::VRegister& dst, const a64::VRegister& s, const a64::VRegister& t)
|
||||
{
|
||||
if (!CHECK_FPUMULHACK)
|
||||
{
|
||||
armAsm->Fmul(dst, s, t);
|
||||
return;
|
||||
}
|
||||
|
||||
a64::Label noHack, done;
|
||||
armAsm->Fmov(RWARG1, s);
|
||||
armAsm->Fmov(RWARG2, t);
|
||||
armAsm->Mov(RWSCRATCH, 0x3e800000);
|
||||
armAsm->Cmp(RWARG1, RWSCRATCH);
|
||||
armAsm->B(&noHack, a64::ne);
|
||||
armAsm->Mov(RWSCRATCH, 0x40490fdb);
|
||||
armAsm->Cmp(RWARG2, RWSCRATCH);
|
||||
armAsm->B(&noHack, a64::ne);
|
||||
armAsm->Mov(RWSCRATCH, 0x3f490fda);
|
||||
armAsm->Fmov(dst, RWSCRATCH);
|
||||
armAsm->B(&done);
|
||||
armAsm->Bind(&noHack);
|
||||
armAsm->Fmul(dst, s, t);
|
||||
armAsm->Bind(&done);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
@@ -512,7 +512,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB Fixes",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -564,7 +564,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB-Fixes",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -512,7 +512,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB Fixes",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -579,7 +579,6 @@
|
||||
"perf.fix.eeTiming": "زمان بندی EE",
|
||||
"perf.fix.extraXgkick": "XGKICK اضافی",
|
||||
"perf.fix.fmvSoftware": "نرم افزار FMV",
|
||||
"perf.fix.fpuMultiply": "ضرب کردن FPU",
|
||||
"perf.fix.fullVu0Sync": "همگام سازی کامل VU0",
|
||||
"perf.fix.gamedbFixes": "رفع GameDB",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -512,7 +512,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB Fixes",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -512,7 +512,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB Fixes",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -512,7 +512,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "Correzioni GameDB",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -512,7 +512,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB Fixes",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -512,7 +512,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB Fixes",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -565,7 +565,6 @@
|
||||
"perf.fix.eeTiming": "EE Timeming",
|
||||
"perf.fix.extraXgkick": "XGKICK Zêdeyî",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Tevahiya VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB rast dike",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -512,7 +512,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "GameDB Fixes",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
@@ -511,7 +511,6 @@
|
||||
"perf.fix.eeTiming": "EE Timing",
|
||||
"perf.fix.extraXgkick": "Extra XGKICK",
|
||||
"perf.fix.fmvSoftware": "FMV Software",
|
||||
"perf.fix.fpuMultiply": "FPU Multiply",
|
||||
"perf.fix.fullVu0Sync": "Full VU0 Sync",
|
||||
"perf.fix.gamedbFixes": "Correções GameDB",
|
||||
"perf.fix.gifFifo": "GIF FIFO",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user