diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp index 0c9c7e55ea..2242424170 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp @@ -49,13 +49,14 @@ void Config::Load() iniFile.Get("Settings", "KeepAR", &bKeepAR, false); iniFile.Get("Settings", "HideCursor", &bHideCursor, false); + iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false); iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0); iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0); iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0); iniFile.Get("Settings", "Multisample", &iMultisampleMode, 0); - if(iMultisampleMode == 0) + if (iMultisampleMode == 0) iMultisampleMode = 1; std::string s; iniFile.Get("Settings", "TexDumpPath", &s, 0); @@ -95,6 +96,7 @@ void Config::Save() iniFile.Set("Settings", "KeepAR", bKeepAR); iniFile.Set("Settings", "HideCursor", bHideCursor); + iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache); iniFile.Set("Settings", "ShowFPS", bShowFPS); iniFile.Set("Settings", "OverlayStats", bOverlayStats); iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Config.h b/Source/Plugins/Plugin_VideoOGL/Src/Config.h index 4fc640d681..d5a000b4c6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Config.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Config.h @@ -39,6 +39,7 @@ struct Config bool bStretchToFit; bool bKeepAR; bool bHideCursor; + bool bSafeTextureCache; // Enhancements int iMultisampleMode; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp index 446d5a063d..84add16651 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp @@ -50,6 +50,7 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog) EVT_CHECKBOX(ID_EFBTOTEXTUREDISABLEHOTKEY, ConfigDialog::AdvancedSettingsChanged) EVT_CHECKBOX(ID_PROJECTIONHACK1,ConfigDialog::AdvancedSettingsChanged) EVT_CHECKBOX(ID_PROJECTIONHACK2,ConfigDialog::AdvancedSettingsChanged) + EVT_CHECKBOX(ID_SAFETEXTURECACHE,ConfigDialog::AdvancedSettingsChanged) EVT_DIRPICKER_CHANGED(ID_TEXTUREPATH, ConfigDialog::TexturePathChange) END_EVENT_TABLE() @@ -209,6 +210,11 @@ void ConfigDialog::CreateGUIControls() #endif m_EFBToTextureDisableHotKey->SetValue(g_Config.bEBFToTextureDisableHotKey); + m_SafeTextureCache = new wxCheckBox(m_PageAdvanced, ID_SAFETEXTURECACHE, wxT("Safe texture cache"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_SafeTextureCache->SetToolTip(wxT("This is useful to prevent Metroid Prime from crashing, but can cause problems in other games.")); + m_SafeTextureCache->Enable(true); + m_SafeTextureCache->SetValue(g_Config.bSafeTextureCache); + m_ProjectionHax1 = new wxCheckBox(m_PageAdvanced, ID_PROJECTIONHACK1, wxT("Projection before R945"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_ProjectionHax1->SetToolTip(wxT("This may reveal otherwise invisible graphics" " in\ngames like Mario Galaxy or Ikaruga.")); @@ -248,6 +254,7 @@ void ConfigDialog::CreateGUIControls() sHacks->Add(m_EFBToTextureDisableHotKey, wxGBPosition(0, 1), wxGBSpan(1, 1), wxALL, 5); sHacks->Add(m_ProjectionHax1, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALL, 5); sHacks->Add(m_ProjectionHax2, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5); + sHacks->Add(m_SafeTextureCache, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALL, 5); sbHacks->Add(sHacks); sAdvanced->Add(sbHacks, 0, wxEXPAND|wxALL, 5); m_PageAdvanced->SetSizer(sAdvanced); @@ -384,6 +391,9 @@ void ConfigDialog::AdvancedSettingsChanged(wxCommandEvent& event) case ID_PROJECTIONHACK2: g_Config.bProjectionHax2 = m_ProjectionHax2->IsChecked(); break; + case ID_SAFETEXTURECACHE: + g_Config.bSafeTextureCache = m_SafeTextureCache->IsChecked(); + break; default: break; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h index ee343e23a6..af029e727d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h @@ -96,6 +96,7 @@ class ConfigDialog : public wxDialog wxCheckBox *m_EFBToTextureDisable, *m_EFBToTextureDisableHotKey; wxCheckBox *m_ProjectionHax1; wxCheckBox *m_ProjectionHax2; + wxCheckBox *m_SafeTextureCache; enum { @@ -131,6 +132,7 @@ class ConfigDialog : public wxDialog ID_WIREFRAME, ID_DISABLELIGHTING, ID_DISABLETEXTURING, + ID_SAFETEXTURECACHE, ID_DUMPTEXTURES, ID_TEXTUREPATH, diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index 8ce4700833..d0b4e5aea3 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -108,9 +108,11 @@ void TextureMngr::TCacheEntry::Destroy() { glDeleteTextures(1, &texture); if (!isRenderTarget) { - u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr + hashoffset*4); - if (*ptr == hash) - *ptr = oldpixel; + if (!g_Config.bSafeTextureCache) { + u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr + hashoffset * 4); + if (*ptr == hash) + *ptr = oldpixel; + } } texture = 0; } @@ -255,10 +257,14 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width TCacheEntry& entry = textures[address]; entry.hashoffset = 0; - entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF); entry.paletteHash = palhash; entry.oldpixel = ((u32 *)ptr)[entry.hashoffset]; - ((u32 *)ptr)[entry.hashoffset] = entry.hash; + if (g_Config.bSafeTextureCache) { + entry.hash = entry.oldpixel; + } else { + entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF); + ((u32 *)ptr)[entry.hashoffset] = entry.hash; + } entry.addr = address; entry.isRenderTarget = false;