summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Data/Sys/ApprovedInis.json2
-rw-r--r--Data/Sys/GameSettings/SDVE41.ini12
-rw-r--r--Data/Sys/GameSettings/SDVP41.ini12
-rw-r--r--Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml.in3
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt5
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt4
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt6
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TitleDatabase.kt17
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt105
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt5
-rw-r--r--Source/Android/jni/AndroidCommon/IDCache.cpp26
-rw-r--r--Source/Android/jni/AndroidCommon/IDCache.h4
-rw-r--r--Source/Android/jni/CMakeLists.txt2
-rw-r--r--Source/Android/jni/GameList/GameFile.cpp17
-rw-r--r--Source/Android/jni/GameList/TitleDatabase.cpp37
-rw-r--r--Source/Android/jni/GameList/TitleDatabase.h13
-rw-r--r--Source/Core/Core/HW/DVD/AMMediaboard.cpp2
-rw-r--r--Source/Core/Core/HW/EXI/EXI_DeviceGecko.cpp13
-rw-r--r--Source/Core/Core/HW/EXI/EXI_DeviceGecko.h1
-rw-r--r--Source/Core/Core/TitleDatabase.cpp5
-rw-r--r--Source/Core/Core/TitleDatabase.h2
-rw-r--r--Source/Core/DolphinQt/Config/ToolTipControls/ToolTipWidget.h13
-rw-r--r--Source/Core/VideoBackends/D3D/D3DVertexManager.cpp3
-rw-r--r--Source/Core/VideoBackends/D3D/D3DVertexManager.h1
-rw-r--r--Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp3
-rw-r--r--Source/Core/VideoBackends/D3D12/D3D12VertexManager.h1
-rw-r--r--Source/Core/VideoBackends/OGL/OGLVertexManager.cpp6
-rw-r--r--Source/Core/VideoBackends/OGL/OGLVertexManager.h1
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp3
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKVertexManager.h1
-rw-r--r--Source/Core/VideoCommon/VertexManagerBase.cpp71
-rw-r--r--Source/Core/VideoCommon/VertexManagerBase.h40
34 files changed, 331 insertions, 109 deletions
diff --git a/Data/Sys/ApprovedInis.json b/Data/Sys/ApprovedInis.json
index 8588402c03..2d15a8876a 100644
--- a/Data/Sys/ApprovedInis.json
+++ b/Data/Sys/ApprovedInis.json
@@ -1 +1 @@
-{"D43J01":{"loophack":"CAB9CED2D904F12CCB21F5B1DE9B5433620C3E13"},"DPOJ8P":{"Bypass Modem Detection":"90BA66E25640A538FEFA6693715718139079FA7B"},"G2BE5G":{"Disable interlaced rendering":"7FFF6BDD93713BEDFD23739C32B86153FA19AEA0"},"G2BP7D":{"Disable interlaced rendering":"56E85D7285F10348E1E5354E379918D07E79EDA9"},"G2VE08":{"16:9 Widescreen":"3ED033396382424533A263A39687A0961EC994A6"},"G2VP08":{"16:9 Widescreen":"EEBC3C5F04BB70AFCA1A4C3D638335CDC9142BA2"},"G3RP52":{"16:9 Widescreen":"7F6B7743F0DDD3704B15882330E490103AE24E36","60fps":"4C9A8572A35F1DB85BBB2F32ED34288A343F1FC0"},"G3YP52":{"16:9 Widescreen":"3D102AFEE2F4945894E74BB702ED3ED2294C6FEC","Force PAL60":"FD61581C593EA34DD358AE33819FAB310F2CE961"},"G4AEE9":{"16:9 Aspect Ratio Fix":"8C2564CF47BB6A9B57D712C90E17F459B0BB6CCD"},"G4ME69":{"16:9 Widescreen":"6FC6E5D91693FAABE25CC721F2121CB0B5CA9D12"},"G5SE7D":{"16:9 Widescreen":"16119398BFE241A84151C046E0BC5BCF89D22049","Remove Bloom":"A5F2FB2B3BFF61F34F8AB1DD5A912A0FD8DFA720"},"G5SP7D":{"16:9 Widescreen":"718AA8BD831961C33114852FDA75BB58F768F46A"},"G8ME01":{"16:9 Aspect Ratio Fix - Centered HUD":"8C2FC3FC6F7766AA8E87425BF3BDD2E46E73DE71","16:9 Aspect Ratio Fix - Centered HUD with letterboxing":"AE3DBE2604CA0660165CA870C4B80E2B523C9475","16:9 Aspect Ratio Fix - Normal HUD":"F6E8264CF14D0189219C1E2D20C4182F190F4B88","16:9 Aspect Ratio Fix - Stretched HUD":"8EA4C7B80ADE3E8FEC28EEFA3A046B6B04162E81","No Letterbox":"B1DE2A3526F2E4511F2B94A5171BF7B3C2C52B9B"},"G8MJ01":{"16:9 Aspect Ratio Fix - Centered HUD":"B3181CA1AAB11EAE9132184DA48D76E775AC0A24","16:9 Aspect Ratio Fix - Centered HUD with letterboxing":"904C0EEEF16D761F7BDF7099DEB384DD9AB26E00","16:9 Aspect Ratio Fix - Normal HUD":"631CE99BDE3F1475303C00C67E3C130D4EB2547B","16:9 Aspect Ratio Fix - Stretched HUD":"81F7AD591F12A01DE82850457ECF147998D1238F"},"G8MP01":{"16:9 Aspect Ratio Fix - Centered HUD":"75AF5D7FA49BE9C3C73EA1482B49CD9B36CE817E","16:9 Aspect Ratio Fix - Centered HUD with letterboxing":"C2E5003E74551DF693A7CB814850CA51D77549EF","16:9 Aspect Ratio Fix - Normal HUD":"FB26AA84B0CB787705E84E869B649307776A2839","16:9 Aspect Ratio Fix - Stretched HUD":"C5F8A81520193418C07C7BC4881F02BE9C4DC9BC","No Letterbox":"7828F5B0C8B470620755C16C60A5A4554F92640C"},"G9SE8P":{"16:9 Widescreen":"CD043229AC47AC93D537B6A0725A2D0BB6FEF4E8"},"G9SJ8P":{"16:9 Widescreen":"C55EF90B542AA3973352A232629A828BC22A8509"},"G9SP8P":{"16:9 Widescreen":"9521774ADEE769CFCCE86F8170FE626387E73019"},"GAFE01":{"16:9 Widescreen":"D24F6D9BE5D79D3C795C2844634A0214BB68B5DA","Make Game Save Copyable (donny2112)":"F9A812FF62A20D5440CAB79DB6AFAE068457A10E"},"GAHEGG":{"Limit internal frame rate (speed hack)":"2873E5178C8068AFA8AFE751F903A69CA9A41F16"},"GAL":{"Trophy Viewer":"DBDB50216B22CDFFF77BDD80261CD0FF75803D3B"},"GALE01r0":{"Normal C Stick Functionality in Singleplayer Modes":"9DC8D90D986FAC175F45006AFF20CF00EDFBE053","Proper 16:9 Widescreen Support":"18B4159E77013EDFE499A33281B771C442970E3B","Properly Display in 4:3":"DC2BCA7D99EBDE1DC7C68CA6AC7F543B93FD6A67"},"GALE01r1":{"Normal C Stick Functionality in Singleplayer Modes":"F6030959C1CAC92F37287D556F18B3C5298FAD5B"},"GALE01r2":{"Disable Rumble":"CFDEEA8AD2A99394BFFEA7211EF03394E7471FA9","Normal C Stick Functionality in Singleplayer Modes":"BCD918A72368B2A30E797C76994E7539A1C0B5D9","PAL Stock Icons":"6B92D95F0EEA165EA84FD753F74B0A9E2079C2D7","Proper 16:9 Widescreen Support":"CEDF18354CDCFC49398551C629E51B053331A55B","Widescreen Support v1.2 [Dan Salvato]":"D32ED4CD685F3FF649F7E749E8C182C657013918"},"GALP01":{"Normal C Stick Functionality in Singleplayer Modes":"4817F202678559291F9F76B46DC7561A45D00B77","Proper 16:9 Widescreen Support":"BFCBE098FE8679B9140A48EA1D8620D5A369697C","Properly Display in 4:3":"5BA2933B8365E21553AA273B91954A4C722B1035"},"GAZE69":{"60FPS":"BC281053C5266B21FDDC6C8996A6021DEA03D459"},"GBLE52":{"16:9 Widescreen":"C0F3AB3BBC9B21F4BF25F44E48CF1CD36D2B3F45"},"GBLP52":{"16:9 Widescreen":"797040CB097BFD369490A1BE29659929D76CE6F7"},"GBRJ18":{"16:9 Widescreen":"B3C867AB34D90E2E9C5B799D800F4C191DE279FA"},"GBSE8P":{"16:9 Widescreen":"4148D453F61A5B81E53669335BC667E651865C76"},"GBSP8P":{"16:9 Widescreen":"6CB029AE768BA5B9995D5F12C1EBB37B3D1FE242"},"GC6E01":{"16:9 Widescreen":"DE932CCAD1B5EB1FAA8D08733BD0D3940C78382A","60 FPS [Nerdzilla]":"85F98064F17AFE0FB02A99A182AF3FEB7644DCAA","Allow Memory Card saving with Savestates":"2F64F98686E62B60E466E931A9EBCD19A750FF4E"},"GC6J01":{"60 FPS [Nerdzilla]":"A6146772E37970EA5564F51A622A04792158B321","Allow Memory Card saving with Savestates":"D8F327304A88FBC717BB1F775494C5F864B9E8D2"},"GC6P01":{"16:9 Widescreen [Ralf]":"05C9016BF58A628A3FD7B16E1B9BB0769A14846F","60 FPS [Nerdzilla]":"1D3FB017C0D20754E48A8BA54EEE7DC4851BE84B","Allow Memory Card saving with Savestates":"EDEE0E28EEA1834868F2865336290FFBDFB9C6DA"},"GC8JA4":{"Fix C4 texture tiling (used for buttons and some character icons)":"843297019804192AF1FC660BC85F4B10891D0BA3"},"GCBE7D":{"16:9 Widescreen":"478DA1D596D8513C343850719155813CB61A56DD"},"GCBP7D":{"16:9 Widescreen":"478DA1D596D8513C343850719155813CB61A56DD","60Hz":"DF2C4DDF082C9E67919443C5ACC485AB2CF7F8D0"},"GCCE01":{"16:9 Widescreen":"BA0066518E7EA8599A81F8496BD39DE20CC369D6","Fix GBA connections":"483BDB94615C690045C3759795AF13CE76552286","Fix buffer overrun bug (crash at Goblin Wall)":"6C107FEC15C76201233CA2645EB5FAB4FF9751CE"},"GCCJGC":{"Fix GBA connections":"4C104D24329172F5D0F8649DE9423B931FE72CA3"},"GCCP01":{"16:9 Widescreen":"2580E7379633CF4DE13B9EC945DB17543477828A","Fix GBA connections":"2EAA60A8A115AD68A795109FB59E4A726D29016D"},"GCN":{"Fix C4 texture tiling (used for buttons and some character icons)":"601FE183C9524ACCF068874DABD73921C86769CF"},"GCVEEB":{"16:9 Widescreen":"ADA686C90189D1D7D23E23E525EFC96EFA104BB9"},"GD7E70":{"Deinterlacing Fix":"6F8B6E33214162E5CDEBD2BC6A60FAFA04D2EB10"},"GD7PB2":{"Deinterlacing Fix":"3B798C9D63E755349B253FAF9186BAE1F703D96A"},"GDJEB2":{"16:9 Aspect Ratio":"05B0B7D2DD405D9611A482D84DCED44C42C05D97"},"GDREAF":{"Fix audio issues":"F8EAE60FEB0CFB4477FDC4B9E136B63F68DFA63A"},"GDRP69":{"Fix audio issues":"E23D98B2CE185C3993A40F2495D37E41B971BF91"},"GDSE78":{"Limit internal frame rate (speed hack)":"BE8F752F2A2660380B2AC5953F394DD867880EB3"},"GDSP78":{"Limit internal frame rate (speed hack)":"5F8EF8AA8C08D7B3173A59534E8482804C0446D9"},"GE4":{"Limit internal frame rate (speed hack)":"9ABA0E4C533142BBA35DD87180EE38CAE3711226"},"GEDE01":{"Fix startup hang":"21068C3CE905FB0CFFAA7408A93154AF8A5295A2"},"GEDJ01":{"Fix startup hang":"7061F3CF11BF64D3BA7F32CCF2BAC42FF3614AB6"},"GEDP01":{"Fix startup hang":"6F1B00517CBA30BEB738EAA90E71221378CD570D"},"GEME7F":{"Force Progressive Scan":"CB04E00918C9C0F161715D21D046ED6620F7ADEF"},"GEMJ28":{"Force Progressive Scan":"41D8F2C833C0B7B79FCA038752052059207AE4D5"},"GEZE8P":{"16:9 Widescreen [gamemasterplc]":"5CEBCFBEA4E444495D2FD6D8B6607DFB2349CC1B"},"GF7E01":{"16:9 Aspect Ratio":"C96D5AF47EAF25F63E138FF118E3B82935626C06","16:9 Widescreen [gamemasterplc]":"C59CCA3EF8A5E97B32EB64DB9AE80E652ED281C6","60 FPS":"FEAF52B44E1EEB8AC5A416D2184CB525D74E2D7A"},"GF7P01":{"16:9 Widescreen [gamemasterplc]":"1230053B5C347B62E432EFD6635433A183D18619"},"GFQEA4":{"16:9 Widescreen":"5CD9568CE58EF82EB371594667015C9B799454B9"},"GFTE01":{"16:9 Widescreen [gamemasterplc]":"A8F2918A04304652E4E0501984B2E2666AB8A756"},"GFZJ01":{"Make Save Copyable":"F659D22CB1DFF15C3915D7630D838EED8DB0BA48"},"GFZP01":{"Make Save Copyable":"F659D22CB1DFF15C3915D7630D838EED8DB0BA48"},"GGTE01":{"16:9 Widescreen [darkludx]":"EF128E7A9C22676834F558BA0F0F7FD8B9028727","Experimental 60fps":"D40344111D989EA009901F8B1C45B5AC8D39E6D2","Simple 60FPS":"5232A937D1D813FF58DD71D716284ED6AB535689"},"GGTJ01":{"Experimental 60fps":"BEC2310911003AF9E4B984A4051E0F885B8CC825","Simple 60FPS":"D62E777A2F019D7BD0AFFBCE876BD9AE408F1667"},"GGTP01":{"16:9 Widescreen":"FA9CD330ECDA01275DA88BD0803DE47757D16A4E","Experimental 60fps":"EB1ACD613BB432A3391CFFF1F0145A6ACE66B210","Simple 60FPS":"43FAD0DDD130BE1E4C8C7603EF6CA7DAA0DF5EE9"},"GGVD78":{"16:9 Widescreen":"9D07DBB5EC2FAA47F2E4587FBD75FD6F3E7E91B0","EFB Copy Fix":"FE52240DF6D132C15A8324E8A477F2BF2250D208"},"GGVE78":{"16:9 Widescreen":"86E561452235BF88D41884558EF34F54CE0FEB48","EFB Copy Fix":"5E38E10829D5F77243C95E9E41518BB3ADE24139"},"GGVP78":{"16:9 Widescreen":"F9B2108D833084FA36A53E00F1647A9579F847D3","EFB Copy Fix":"5E38E10829D5F77243C95E9E41518BB3ADE24139"},"GGVX78":{"EFB Copy Fix":"740F2D1C01DA39D1760D96B03974A48E6F74578D"},"GH2E69":{"Limit internal frame rate (speed hack)":"C874194B083036964F8B2606BA680C646F642D96"},"GH2P69":{"Limit internal frame rate (speed hack)":"D437A732A1907B3F32FA6C2C64F40A80032878B5"},"GHAE08":{"Fix audio issues":"9799AFF8463EC86C9230E31E2627E141F0C129D3"},"GHAJ08":{"Fix audio issues":"B45A8FC32D14567B8D6C95F303E00A72C0E1D344"},"GHAP08":{"Fix audio issues":"BC7F3CFC97593AA2055C370C175950DC478D2709"},"GHKD7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"1AF09E98F0B72833A0F4E519EC3D4130C36D615E"},"GHKE7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"9BFBDE9184BC05EBD545625DEE486E3AAB36B6A3"},"GHKF7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"919E853513192C97F3CF49246A65ECBF39E7C201"},"GHKP7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"1AF09E98F0B72833A0F4E519EC3D4130C36D615E"},"GHKS7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"919E853513192C97F3CF49246A65ECBF39E7C201"},"GHLE69":{"16:9 Widescreen":"742BFC79D8F0BA5D6215772B58F5A0EADD7BFAFF"},"GHQE7D":{"16:9 Widescreen":"520E5F718D3BD1291C55021776091E0DE0FB4822","Limit internal frame rate during startup (speed hack)":"F6BF450D22104FD2527122EA6E81B1F70E916B95"},"GHQP7D":{"16:9 Widescreen":"AAE14CDC13A0C082A850DED85417100A8C8A0687","60Hz":"884A33613AE8D916128E3FF39B3AA9F63DAADC58","Limit internal frame rate during startup (speed hack)":"BD475ADEF145AC9226514CD1B2D4D5F3BFE67964"},"GHSE69":{"16:9 Widescreen":"3538CDBD13FA939B7BA5F0F82253401AFDD1E2CD"},"GHSP69":{"16:9 Widescreen":"409754E2EBB6F05DEE1AFC647E25B15D462638FF"},"GICD78":{"EFB Copy Fix":"3A94591A149AE88C150AB3320BBC909FE54BAEA5"},"GICE78":{"EFB Copy Fix":"5BF55685B8867A85EAA9C86571309B17BF7DED32"},"GICF78":{"EFB Copy Fix":"85AABAEB9A59C4F96D9330A3B884F6D757DA1683"},"GICH78":{"EFB Copy Fix":"3A94591A149AE88C150AB3320BBC909FE54BAEA5"},"GICJG9":{"EFB Copy Fix":"969134EA21A160EBDA91C0870266E7D1707FDC43"},"GICP78":{"EFB Copy Fix":"13B158CF41F5412BC637F50644193D43CC3DA49A"},"GIQE78":{"EFB Copy Fix":"E15AA1E30D26E5735D68AAADE436E7B7E4A33A35"},"GIQJ8P":{"EFB Copy Fix":"FFFCB76E98DDB06A7BBBC0AA73C869C87EB787D6"},"GIQX78":{"EFB Copy Fix":"485DA99FAB35646DAA2A138B0315361495ABE778"},"GIQY78":{"EFB Copy Fix":"485DA99FAB35646DAA2A138B0315361495ABE778"},"GK2":{"16:9 Widescreen [Vague Rant]":"6B4C59C2A2C5D71C7A38C8513A76E6467E307A26"},"GK2E52":{"60 FPS":"8F2397930A50C3C176188526EB9612578F9CBCE5"},"GK4":{"16:9 Widescreen":"4652969A4DA869FD28F2CAA3869A38F5C2AAFEB1"},"GKB":{"16:9 Widescreen Region-Free":"4652969A4DA869FD28F2CAA3869A38F5C2AAFEB1"},"GKBPAF":{"60Hz":"8E4E0ABA0E6D102A33206F34F4DEE63159B3CB4F"},"GKDP01":{"16:9 Widescreen":"DF4657937DE730107B636C73E959277EB963D210","60Hz":"6740D7B914CC897AF50798C0AB391965294FD1E1"},"GKRPB2":{"16:9 Widescreen":"69C01A4F91D991CF866237FED94A138308FC104F","60Hz":"40D06A5C7A3D873ABC73DEDF573738C2E3E37FF0"},"GKWJ18":{"16:9 Widescreen":"696570101FA040778EAD310377C484C846D87430"},"GKYE01":{"16:9 Widescreen":"6520EF1B7D88F00747B120A3A010458602ED989D"},"GKYJ01":{"16:9 Widescreen":"47B8EF7D02831AA5C375C698797BF2D5475FEFF2"},"GKYP01":{"16:9 Widescreen":"69413C75036D2975716066E6574461B981FF0124"},"GLEE08":{"Fix audio issues":"7355F358CAC6F418D37E4C23E64F7867D46E4FC9"},"GLEJ08":{"Fix audio issues":"12B24A6D7389A2AC5AB75FC0BF8493E7661F2A73"},"GLEP08":{"Fix audio issues":"81BD39F5527552DE89E3B59BA86298900F0A3168"},"GLSD64":{"Fix freeze in opening cutscene":"5E2A73717BD66EF647846DD64C33BC80AD9B5227"},"GLSE64":{"Fix freeze in opening cutscene":"1CE78E7954415A44DF693C0BB879AA5A4FF059A3"},"GLSF64":{"Fix freeze in opening cutscene":"009B0C4AD80A9C28C987934D254C2C4AACC9A07A"},"GLSP64":{"16:9 Widescreen":"8E7A544C10E7A5E2F0304A0D2586879627EF6586","60Hz":"B67144E87B54246137142992A3BC83DC13BE68A7","Fix freeze in opening cutscene":"3D0894616C9A7FA5ED91C1D2F461BF14DF47ECEC"},"GM4E01":{"16:9 Menu Backgrounds Add-On":"87D1A6A3E29ADA03B0D29C2F1841C18E62DB0A15","16:9 Widescreen v2":"78BE50F93E81A1972CA31ABC318949E366E82BD0"},"GM4P01":{"16:9 Menu Backgrounds Add-On":"87D1A6A3E29ADA03B0D29C2F1841C18E62DB0A15","16:9 Widescreen v2":"6D950B6EEFD6D304E1A424355B74A595D32BDF2F"},"GMBE8P":{"16:9 Widescreen":"D12DE9E3941BCE6EB50B8DA92140E09AFC0104C8","NA Stretched HUD":"0151A6683E1FBFD20096807C54A6952C4A4BAD40"},"GMBP8P":{"16:9 Widescreen":"8A688981F33A2C53882EF08FCF20B88AD43EF417"},"GMNE78":{"Limit internal frame rate (speed hack)":"DE38BC8493EA24F93B6D805F28746AA99C53C677"},"GMNP78":{"Limit internal frame rate (speed hack)":"65FB9B430F7D58EBC76DAADE8CA9DBBAA32B8B51"},"GMOP70":{"16:9 Widescreen":"CE4D298616BD42E4D8F8936B325CD1FD7F5B956B","60Hz":"0CD2CC787A5FF551901E41C85C8AAC02017ECB89"},"GMPE01":{"16:9 Widescreen":"4F98592DB3DEE3857469A8D8605FAF4BD6F7C76D","QOL - Allow Digital Presses for Map Screen":"E232B27564E9AA0C32DE163C9C056317A7B2B12E","QOL - Automatically Advance Text Boxes":"59607671BFC4717ACAF9807BB7EB0D9F982866D4","QOL - Disable Advance on Results":"CAEA37F3FEF89400513353EB85875F2A3AF4C03E","QOL - Faster Boot Time":"F75FBBD838C5B84FF687962FBA9195B217DE132C","QOL - Increased Board Speed":"19F264DE7F07EAC9433CA4B591BEBA1EC976C9F1","QOL - Increased Taunt Capabilities":"C70391D4961A0E820DE40141C89341369A9F021B","QOL - Instant Text Display":"F4E6913CF034E5778B9F9CA5FF448FF1B78B3333","QOL - Rumble Always Off":"93621947019532F02C25937FD3EEEE21A788CB07","QOL - Show Controller Port Number of Who Paused":"D7249AC3C949FEB860CF4350C5B7B79AC16569F1"},"GMPJ01":{"16:9 Widescreen":"A795811F2F0C92D9DCABDE97D9E39B47B1DBCEFD"},"GMPP01":{"16:9 Widescreen":"A795811F2F0C92D9DCABDE97D9E39B47B1DBCEFD"},"GMSE01":{"60FPS":"2805B1A0DD53EB64877D375D10F667700955720F","Disable Heat Wave":"988DC355648FA0EFB8AE6353CCE5F28C8B82BA54","Widescreen":"BD718F961DBA5372B1D0257D454D535746C453A0"},"GMSJ01":{"16:9 Widescreen":"E8112A01040A06460E368F142C5D1FD0B4085D94"},"GMSJ01r0":{"60FPS":"9894B5B6B5215844D48411021FF8EECFE851D79D"},"GMSJ01r1":{"60FPS":"2DB69DB7A3753D543CD85CA4C77B4EF0AED7486E"},"GMSP01":{"60FPS":"D07009B710B3BBC6B12E54ED6A7969D58197EDAF","Widescreen":"0B7B89BF0868393076EF5F9DBD689DD0EDBCB84C"},"GNHE5d":{"Nop Hack":"89393A24E2336841AA4CD0AD3BE1C9A66B89E9EF"},"GOCE5D":{"16:9 Widescreen":"E4D800B90F16A15D9252EED1B2A23AEAF5CD230A"},"GOME01":{"16:9 Widescreen":"C33CBBF6F22195BF626104B4827200B3EE1CF30C"},"GOMP01":{"16:9 Widescreen":"874784CCD4AC3DC9C69654E471C18AD0F5E4D9AE"},"GONE69":{"Widescreen Hack Culling":"6412A67E1C26E146A9526AFC9F0EE517B214069D"},"GP4J18":{"16:9 Widescreen":"BF4D2D6AF66F285E81173B3B20D5369DB6FB351B"},"GP5E01":{"16:9 Widescreen":"5ED053787332DB5EEB8B963BA5DF197B58C6BB75","QOL - Automatically Advance Text Boxes":"41EF84663008668682BB75DC8B874E38669AE041","QOL - Disable Advance on Results":"6C36BEFE751131298BC8B39012892F6A6903CE60","QOL - Faster Boot Time":"8E952E6E12639AC20F6F9FDD150C12F0C294DF43","QOL - Increased Board Speed":"4BD72B8ED75ED8EFB3329C104BAD114FDDB8AD2C","QOL - Increased Capsule Throwing Speed":"C5BA3C9D386D09DD6CB9242A12A0D041BEB93160","QOL - Increased Taunt Capabilities":"C360EBDDCB0237076052C983BD9719411CA67CDE","QOL - Instant Text Display":"2CD4A06A3B9C18CC9EA2A2DEBD96E066CD1D700A","QOL - Show Controller Port Number of Who Paused":"5BA3648D18346EDC97B23475D4748C637E6095A2"},"GP5J01":{"16:9 Widescreen":"81E69B6BEE85E06805EC24E1CFEA9405BF459DF8"},"GP5P01":{"16:9 Widescreen":"FD4FCCB97C06F0173A30D4CC9A99422B2C0ABA9B"},"GP6E01":{"16:9 Widescreen":"B502AF0887792E9B140516D14BA75F99772C17BE","QOL - Auto Advance Text Boxes":"E645DF70CE0266D174D917A817A7FBEEE974A9F0","QOL - Disable Advance on Results":"798E566B621F6A32BF23C588E76EAC0776E2A8A3","QOL - Faster Boot Time":"B089A3C80D5DA86ABF6258F8BFB1DC78BB54A973","QOL - Increased Board Speed":"501C52ACF117950888A66DB2BEDBDFD7D9B20235","QOL - Increased Orb Throwing Speed":"845F439278DA8CBC225658FF4E2F82D707422BFB","QOL - Increased Taunt Capabilities":"0AED27341A06186AD92D5725C0B9693CA8F85B7B","QOL - Instant Text Display":"5AAC4E21927D4AEE7AC329CE793D4CDAEDDF7A3F","QOL - Show Controller Port Number of Who Paused":"DF5D2F068D76ABF2B1C294D413B9154B8C356929"},"GP6J01":{"16:9 Widescreen":"88F50F8298F82E3E5C161277BD4A985CE893A9D0"},"GP6P01":{"16:9 Widescreen":"DCCE59CA987624C753F0A86BEBA4287635901C93","Remove Black Bars":"138A86D43B5830BFE1926F58C0A4FBE2971BB02D"},"GP7E01":{"16:9 Widescreen":"87EBF72D90503EBC5CE9BC994795669E48A92A4A","QOL - Auto Advance Text Boxes":"82338AB5D82A7F398B4EB674CA4866DD1F4A1E65","QOL - Controller Options Always Acesssible":"D2F9CC0B9E52136E77187395FB7DA9B64B2C3B30","QOL - Disable Advance on Results":"A644551162A61DE7997B2A84F5BFDEFFD3FC2FB5","QOL - Faster Boot Time":"1939B5C575AE8FF6890BDDDD1B3FEA472D8CABA0","QOL - Increased Board Speed":"7E06A2EBCFECADB8074152B489984237A6FE9F21","QOL - Increased Orb Throwing Speed":"6671BEE71920D6B845AE1257AFE3AB3B95CD6FBD","QOL - Increased Taunt Capabilities":"9F60923F95FFE709CCD06966CD2DF743263934D1","QOL - Instant Text Display":"48FA6002E42DA9BB83ABC980A32C60CE3B21C4FC","QOL - Show Controller Port Number of Who Paused":"5E6F8C6C87D5944DB18A4E4F9A45F61EE87A4163"},"GP7J01":{"16:9 Widescreen":"A081F0729068D233E99DC00C64E36CA33C945640"},"GP7P01":{"16:9 Widescreen":"75D6CDA4EA301A71F7701A0487544E79136850B9","60Hz":"6D0D5B7CA58C38A3147F8ED981B5B21CC6C519CD"},"GPIE01r0":{"16:9 Widescreen":"2B58166A66644F984E64077A6245C94C79B51063"},"GPIE01r1":{"16:9 Widescreen":"9A1545AB4E2B9216B95AFFA83420D723512DA8C8","60FPS":"3337C767EAA21D30C6CFEAE9985FFCABFC63E2E3","Disable Pikmin optimizations":"CBD15E9104929F0631713AE482475CB2B90E71F2","No Blur":"A25CDDB79991F090BD7F12840AD06F13BD5CCF95"},"GPIP01":{"16:9 Widescreen":"5AE44D5B0E0D4C412B453B95CF5A41DBA4D685E6","60Hz":"AE59FF751E167632AE283F38CC4B96BDF7B9B81F","Turn off blur":"4ED79A548DBD7DBD35928A2F1138315FF103E260"},"GPNE08":{"16:9 Widescreen [Ralf, darkludx]":"ED3D9BB08C5F1D21BC8D5C73155C00E3C25C466F"},"GPNP08":{"16:9 Widescreen [Ralf]":"469B18FE8219031D355557B836EF02B625040A4F"},"GPOE8P":{"16:9 Widescreen (Plus) [Ralf]":"5563671A6702785FFE106DAB7EF3F4FE6D9F705B","Make Save Copyable NTSC Port - 1.0\/1.1":"7A4B3E596BA4FDA8F3FCF984079B3F44CB2D6AB3","Make Save Copyable NTSC Port - PLUS\/1.2":"304DB311F2107E88EBCE058535B266F9263AA8E2","Save Validation Code v 1.0\/v1.1":"9F6259132453DCC0607EAB35DB182C76818F2F9F","Save Validation Code v1.2\/Plus":"17EB6CFB408EF27D44C053A1336C3B87B6A05018"},"GPOE8Pr0":{"16:9 Widescreen":"99986BB1D4ABE45C429D48B01BFB578FEA69C14F"},"GPOE8Pr1":{"16:9 Widescreen (Plus) [Ralf]":"5563671A6702785FFE106DAB7EF3F4FE6D9F705B"},"GPOP8P":{"16:9 Widescreen":"DF133C61C29D5CFA87A2A785C962C205F80E6D04","Game Save Valid":"40EC1590DB26C7C58D00E3065F1E404341EF0E73","Game Save copyable":"2F5FB98927DAFF141D1CCD1EACA8AF626397E284"},"GPVE01":{"16:9 Widescreen":"E5B51080CFD518FE584CF3B61A1099CD032479D6","60 FPS":"6662E99E41F77763EEE524477DF341836EC7032E"},"GPVP01":{"16:9 Widescreen":"78F3C9A789827B063A6701987262276A66ABD82B"},"GQPE78":{"EFB Copy Fix":"880B114E9A308084CAB92C004A9EE067B371C310"},"GQPP78":{"16:9 Widescreen":"CA5A618C8FD5537271F0304F8BD58884007F872C","EFB Copy Fix":"5D9A14954AE8D639C9B254F3BA73A70F284BBC8D"},"GQSDAF":{"16:9 Widescreen":"CA82C44B2E8FC5C184E3FF935BC89661B7DB55D6","60Hz":"952165FD78543EB6D2F5230F7570B0513773D332","No Blur":"DEB7DF358423F0EF30C9FD49F4F14590836D52A6"},"GQSEAF":{"16:9 Widescreen":"48AFE1D32843C6B5AD4337A49F15FD447DF2A752","Remove Blur":"EF448CF1FA6A15EB2661EA5338703C13D52EF65B"},"GQSFAF":{"16:9 Widescreen":"76C30E1737CC5C3B5DE32532B5F9A5CD50B690F8","No Blur":"986BAE5103CDE9286D2D34FD28FE2540D0759AAB"},"GR2E52":{"16:9 Widescreen":"5F55CE7DA7E1E3261CF2FF88F34CDA63BA511003"},"GR2J52":{"16:9 Widescreen":"D3C6FA690BED07BFA65C2E1FCDE2FFA5AA0EEEE4"},"GR2P52":{"16:9 Widescreen":"D7BCADD4E76B5E3F7D9D463F55A2777528E37E94"},"GRNE52":{"16:9 Widescreen":"483D74C47AD1012606D591A226AB3144C7FB201C"},"GRNJ52":{"16:9 Widescreen":"949281B7221B20680B7BC29E4754B73A326EBE85"},"GRNP52":{"16:9 Widescreen":"11051B094FE5A8B2E73060BFF786C1588E36979A"},"GROE5Z":{"16:9 Widescreen":"FADBAB5EC280CF8ED4C9536A33F4184BA210C9B0"},"GRYE41":{"Disable Culling to Fix Rise and Shrine Hang":"AF0A575EB6071EAC0D2EC3D2EA30A23EB05A4192"},"GSAE01r0":{"viWidth 704 Aspect Ratio Fix":"0D529180B9B28BB06E21EDBDBA61C17EEF0FFB7F"},"GSAE01r1":{"Increase Player LoD Range":"60BA00CA149C7094F61976DA22E3EDAF1770C4BE","viWidth 704 Aspect Ratio Fix":"CB15ED22625690A5DBE4607FE30160125421461D"},"GSAP01":{"viWidth 704 Aspect Ratio Fix":"749EDA62B1B73354599929F1B50E992E111C5493"},"GSNE8P":{"16:9 Widescreen":"CFDF3FA5B48B347E49E8E521D7BE47FCC9A5CBF4","60Hz Aspect Ratio Fix":"D90F66C0D46D9BEF27C8E13BC8804DB1F382C8B1"},"GSNJ8P":{"60Hz Aspect Ratio Fix":"98DF9D67DE77F66A4B09F25C5621805DEB40865B"},"GSNP8P":{"60Hz Aspect Ratio Fix":"D90F66C0D46D9BEF27C8E13BC8804DB1F382C8B1"},"GSO":{"16:9 Widescreen Region Free":"0D60D0593F6DA28B1236381B22082506B9533F0E"},"GSPE69":{"16:9 Widescreen":"80E18A8963F4EFD3C03494C95934452FCB6E521B"},"GSPP69":{"16:9 Widescreen":"162E87E9F5511CD82216811055836C11B374C45B","60Hz":"E5DF2DF34D2F0BDEE4205C891576511EC572C5DC"},"GSWE64":{"16:9 Widescreen":"6480326CCA8FF64A4868EC6E9FDE9F38819A75A1","Disable Dithering":"85F65E4B627641862C1A6091D29A3BB0626B04C3"},"GTEE01":{"16:9 Widescreen":"6B57EBCB9CC0ACE2EDA0F13E3F1F55F3FABC3A26"},"GTEP01":{"16:9 Widescreen":"72785784363C46180AF8E388348FD77667E7D382"},"GTOJAF":{"Remove Blur":"53A2EDF113F2ED7E54A16AA0E73FDB2C44C79DE5"},"GTRE78r0":{"Limit internal frame rate (speed hack)":"42B85EFC5DEF8B243521EAD434DDCBDF95664CB1"},"GTRE78r1":{"Limit internal frame rate (speed hack)":"ADB3A41B992EAB15AE484B2E575ACF3354415186"},"GTRJ8N":{"Limit internal frame rate (speed hack)":"47DBEFDCF22ADC2AB148A54AC885FE19B3C07E3F"},"GTRP78":{"Limit internal frame rate (speed hack)":"E8752E1B60DF76CD0CC7408074E742B0966BC904"},"GTSE4F":{"16:9":"03D0C232C92FC50DD86A8D216F36B7BC83E381A6","Border Fix":"C578CB61AD5B1B6A186BB17C8E7D1613B2CFD965"},"GTZE41":{"16:9 Widescreen":"ECCE87E0006475C73E7D936AA0150BD20166F9EF"},"GTZP41":{"16:9 Widescreen":"62D8F159B93167171E0860D96C4BB32A5BF5648B"},"GU2D78":{"EFB Copy Fix":"CFF4C3F932B08732627572EDA1A0CD2D9C71AE0C"},"GU2F78":{"EFB Copy Fix":"CFF4C3F932B08732627572EDA1A0CD2D9C71AE0C"},"GU3D78":{"EFB Copy Fix":"8A0E3114862ADFE421874211BD6F5220AA425BF5"},"GU3X78":{"EFB Copy Fix":"E3303FDAE7ECA17A72EDC440C32D94648A6453A0"},"GU4Y78":{"EFB Copy Fix":"D54767785E139A8BC8C4B75573FBD5A0B686D8E3"},"GUNE5Dr0":{"16:9 Widescreen":"C942EBCBE8A487C25E296EC1FAC2358DA1487DBD","60 FPS":"A441630EC5FF0EB74D2243A3092D22E69C6BEA02"},"GUNE5Dr1":{"16:9 Widescreen":"39BD84CBE2AFACFEDEC5E9020D1A8B0D36DD53F9","60 FPS":"05779F1A3D0C43305D52A95447D612CB424942C0"},"GUNP5D":{"16:9 Widescreen":"FE3BA1DAA1AF278A7839E27BF466B0BA0B390EC2","50 FPS":"3B20499A3F8D1D7CCA5B0015F2D80ECED25842A6"},"GV4E69":{"Fix 2D Rendering":"8679891FCAA250FCFF670B26E0CB9875900D17FD"},"GVJE08":{"16:9 Widescreen":"09EFDA75D876A675121C8344D8FDD09A70A1A846"},"GVJP08":{"16:9 Widescreen":"93938F4C6112C91549F2B52E6259170F7501EC07"},"GVPE69":{"Fix 2D Rendering":"3159CA79B0A890131763EA6CB163684BEE886E3F"},"GVSE8P":{"16:9 Widescreen":"4CE9C491160A4B631142EE9CE802C694163F1CA3"},"GWRE01":{"16:9 Widescreen":"AC42770B06662BE1DC863EC80F44B5E034C63664"},"GWRP01":{"16:9 Widescreen":"9DDDFAB28C4BD35CF64050E1EF684DC042B1AFFA"},"GWWE01":{"16:9 Widescreen":"98B2E75D8E1CED4A964D3129A5DC10E30538CAA6"},"GWWJ01":{"16:9 Widescreen":"2DAD9A5E2A140F02CCBA727C4BE7C74BAC156778"},"GWWP01":{"16:9 Widescreen":"2DAD9A5E2A140F02CCBA727C4BE7C74BAC156778"},"GWZE01":{"16:9 Widescreen":"9EFC191DE6D21A1681FE241AB2EE4A131259F317"},"GXCE01":{"16:9 Widescreen":"901A1E78A3A0124F55548507D3B3707125C64A8A"},"GXSE8P":{"16:9 Widescreen":"F50BBA440184FC77A4DFFAA58FF2BB888E2E072F","Aspect Ratio Fix":"4214C74DFB8A74FC3AA4A643E869BC4D9A38EDA0"},"GXSJ8P":{"Aspect Ratio Fix":"227909607984BBC3D36AAC7DB9DFE385F3363C49"},"GXXE01":{"16:9 Widescreen":"7CAFDAD7B5E7459CCC1BB209D439DDCBB5BE4E4E","60 FPS":"7E2829049003FC9DC8BC28044B33CAFF3768B54C","Allow Memory Card saving with Savestates":"64FAA15062F0D0C319F904BBDE9C4489A25D6369"},"GXXJ01":{"16:9 Widescreen":"AF704A8C6838FDF47054D9EDD9106B3F46781FA9","60 FPS":"4F5FD45B4EC1B33FE076FA06F8FF863C46A06BBA","Allow Memory Card saving with Savestates":"8293802260536FA2EF2EFDAB5266DE36BB88DE1B"},"GXXP01":{"16:9 Widescreen":"02716B2585BEE74F8FCDD97A78F6A0D3DC7F331B","60 FPS":"BF6171EA5CCF4B57AA596372589DDB5E6904DD7A","Allow Memory Card saving with Savestates":"3CAFBC4AE6FC5CE9F53377F86AB5BD8F1BC8861A"},"GYAE78":{"16:9 Widescreen":"8B00EFBBB05B7158C78D26D13C03A22F3DEC41B2","60FPS":"96C6D047DBB7F80DC661CE44B639A8378E992C27","Remove Bloom\/Fix Upper Left":"2C05DE9919EA7863CC386704A030A6EE1453CCA5"},"GYFPA4":{"60Hz":"402ED10AC842041AB4B39AE8F2D81B2D7AEF9CB4"},"GZ2E01":{"16:9 Widescreen v2":"E7521ED27BFC972628906CBE8D5403ED57253BB8","Hyrule Field Speed Hack":"FCB673D46E716C7F63C618B8D8BF83AEE0B501F0"},"GZ2J01":{"16:9 Widescreen":"F985A0A58D8E2B23E8A557FAFF8D367AFFEADD07","Hyrule Field Speed Hack":"FCB673D46E716C7F63C618B8D8BF83AEE0B501F0"},"GZ2P01":{"16:9 Widescreen v2":"CAC38B0D334B925A57AA3118D35932B8A185137E","Hyrule Field Speed Hack":"0F63623D4D984B7706F718F57C0ABDB6DBADCF8D"},"GZ3E70":{"16:9 Widescreen":"167F9E9A9B372CB3A01F308B46FF1403F8599C51","Deinterlacing Fix":"EF1291C0E45277CDAE4D0F61E1949C1E75E5A3E1"},"GZBJB2":{"Deinterlacing Fix":"19D67BD12A18F0E3A960BBB92E2F490BEF5C00C1"},"GZDP70":{"16:9 Widescreen":"2E424E0BBAE6EF5D6A8FB4224EA1D0746BAC37D3"},"GZLE01":{"16:9 Widescreen":"9FA864EE7DD8CE7FF538EB4E0243F20137430BD8","Remove Distance Blur":"78EA34CEF8E01701491C280F155F1C12EC9BF1A2"},"GZLJ01":{"16:9 Widescreen":"E03B61989025CA33937E63A057E6E40A403811BC"},"GZLP01":{"16:9 Widescreen":"3EFFF6C52B5633A1729FAA6883D8579E77F7D057","Remove Distance Blur":"14BECBEA4DD281EBD0F7FE7DEE8020B6F2418ACD"},"GZPE70":{"16:9 Widescreen":"7142F2495507AC7136992128ED0FCA6BC72B61F4"},"GZPP70":{"16:9 Widescreen":"591FD6C9668C79FF1CE8558EBED2486A7A327F05","60Hz":"A59B84DB5486521AEE1C23B6C741ECD35216E5AD"},"GZSE70":{"16:9 Widescreen":"8E86EAC7EA4F4D2854DD9020CD795630CA64C4EE"},"HAF":{"BufferPatch":"181195871F63B89B1CF09AFA4420CF89B9883108"},"HAL":{"RSAPatch":"AD12237401ABE9FE4A545AADB5C5AE10355E2076"},"P1RE01":{"60 FPS":"FD15A2EC38E46C1C3153336BC44F11B08ED906D0"},"R3R":{"60fps [Nick Reynolds and Vague Rant]":"AA205FCB7FAFDE78E84B48C7BEF0FA2FBEB56107"},"R7XE69":{"Idle loop speed hack":"53F3273525BB719D535007FB97E7F381D808A8A9"},"R7XJ13":{"Idle loop speed hack":"4590D425BCBAFA0D1E32D27B46068843F6A2BE09"},"R7XP69":{"Idle loop speed hack":"53F3273525BB719D535007FB97E7F381D808A8A9"},"RB7E54":{"Limit internal frame rate in loading screens (fix hangs)":"BD1A252B43FD339391ED33554542E786BAD6671B"},"RB7P54":{"Limit internal frame rate in loading screens (fix hangs)":"90247F89DF8EB7A4AFA2C425CD3006257A95A8F8"},"RBU":{"60FPS":"EF7741840B8B87BAC5C62DC72F97651005B84F71"},"RDGEA4":{"60fps":"E7294BFA8DD6009B77FA53319C027BDAD95C7373"},"RGQE70":{"crashfix":"5F4CF8D4DA19A0FF74FF9EB925AC0236069BFD59"},"RGWE41":{"Limit internal frame rate (speed hack)":"A0B4B457C42E3E2EE6D4E3E1F7E6EEAB2F70EBA5"},"RGWP41":{"Limit internal frame rate (speed hack)":"64A43222F25CA56BC44ED3FF80B555B16E6B9822"},"RGWX41r0":{"Limit internal frame rate (speed hack)":"64A43222F25CA56BC44ED3FF80B555B16E6B9822"},"RGWX41r1":{"Limit internal frame rate (speed hack)":"AFB612191047500D6BE2ACC7B4E96E6B72941B39"},"RHO":{"60FPS":"5897530606A27FBE8C0079620923D8BC40AD3D0E"},"RJ2E52":{"Limit internal frame rate (speed hack)":"880DB9C1D639AA2ECD7AE6C96C93E8D83FBC38AF"},"RJ2JGD":{"Limit internal frame rate (speed hack)":"A387F6E3D973DCFD7D5A2E27183837358295B425"},"RJ2P52":{"Limit internal frame rate (speed hack)":"507BFC06E65A3C05D312305D44D1051A054003BF"},"RLEEFS":{"Fix crash on main menu":"793642AC6862C2F3412035A9E3D7172CC4A1D5C7"},"RM8E01":{"16:9 Widescreen":"E61344EB1542A78D497981C307B6549985C7A05A","Extra - Disable Music":"25223F9EFAABF601CAC7810004F124E4056598B1","QOL - Faster Boot Time":"BCC4279F8B28636AD773F01540E78DF40EAD6087","QOL - Increased Board Speed":"B65AF1819966CD3435D88801E8C79704E3A52DB5","QOL - Increased Taunt Capabilities":"66495D7CB532FAE778AFC22CF45D17D0FFDE5310","QOL - Increased Text Display":"B4186DDC54F33F4D6A22188EF50CEB43FB205673","QOL - Invert IR Stick for GameCube Mod":"9D90A9C66AE8AD91B201B40C4145D1323B701A77","QOL - Remove Explanations":"330DD53AB993A99576564FEFD222D7BD211B878F"},"RM8J01":{"16:9 Widescreen":"A140BDCB8E1721CB6B4CD878E412113322258B57"},"RM8P01":{"16:9 Widescreen":"F664C32AFD3D785FC6E04D8990A3FA1C72A18C5C"},"RMHE08":{"Bloom OFF":"CCF233DA57B3E75221870DE502955114B0D4E7FA"},"RMHJ08":{"Bloom OFF":"29D3625B7ED577587E56AA07CB0EB8C47C97E823"},"RMHP08":{"Bloom OFF":"1720C1173D4698167080DBFC4232F21757C4DA08"},"RO2P7N":{"Hangfix":"EEE9C8DE4671C18DD7F81DD08D39B64C57600DEA"},"RPBE01":{"Fix black screen effects":"775ABECA6073E02C5C68CF4D644194D966A418F5"},"RPBJ01r0":{"Fix black screen effects":"0EAB5D8DE827894AFEF97C10ACB67378E6983323"},"RPBJ01r1":{"Fix black screen effects":"4905E08643E9D00136F7EAF51978CF2F54D10D07"},"RPBJ01r2":{"Fix black screen effects":"4905E08643E9D00136F7EAF51978CF2F54D10D07"},"RPBP01":{"Fix black screen effects":"82AEB60F9A9083F93060531A970FFAABE0833A40"},"RQZ":{"Limit internal frame rate (speed hack)":"7B3B31BA970B319459C2E30B94E973CD1F2AE998"},"RRBE41r0":{"Idle loop speed hack":"20C7A2D4A3D6D55A8029A9D200D57CBD11F60B88"},"RRBE41r1":{"Idle loop speed hack":"0A30FA4C7E787197A00B7267368F372EFF623776"},"RRBE41r2":{"Idle loop speed hack":"2227787007F16F0CD454422AE6EB94656464B6D0"},"RRBJ41":{"Idle loop speed hack":"E9209EB728AA13375B2ABEF1C15D066DAFBF2EBF"},"RRBP41":{"Idle loop speed hack":"8A47BC311138EE3A11E049DF3EE6AED38990FB49"},"RTH":{"Disable blur":"812EE46AC967BFCD239335B10A664D71A93E8175"},"RUUE01r0":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"B62652D5BBE0701900090CFEB32003AE6E5A5015","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"244D1FC7D6284DC8832CF7F34506B0DE4DBF8914","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"6FDD09D51EC3D754BA7F80630B1FE1D3FEF6FE97","QOL - Disable Grass Deterioration":"D566F2AF5BB1EDB8284461DEA85FF3B5A8DEBDD6","QOL - Enable Fast Text":"C7D8A7926ED952A2797DA312B41B08DCCDC3A274"},"RUUE01r1":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"FC7BF1D6A5B4ED39EA4671C241E78F3BC8037E97","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"0235631B6F9A439B9718635F5AB7ADAFA2B6B3DE","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"5DEAC5F3390CE19487A9473A1988E7BB5EA4790F","QOL - Disable Grass Deterioration":"0FE1EF4DE5C8AE691E96634BC66BA034850C6C0F","QOL - Enable Fast Text":"B2BFF779434FDBEF08FFD73C4B140FCE0A8FDF0E"},"RUUJ01r1":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"D79F773E1363B694784C94DD309709D41D368A08","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"C88CFD7E6C18F570DE974D6C0202987E4F1B72C4","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"3C92010E7DE2E93C48AFF25B30A18BBFCBD12707","QOL - Enable Fast Text":"EFC4517A0915A19F1EC93BFBF91C501124857C18"},"RUUK01r1":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"1B89E8A6E6E09757373FF116BBC0989C06651709","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"EF883FB0C237BF51ABD88C35D34571D240C79484","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"F08D0F233F3F5833DFAFE5C8049C37D32360F0FA","QOL - Enable Fast Text":"EFC4517A0915A19F1EC93BFBF91C501124857C18"},"RUUP01r0":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"C55A5CDEF4C868E66C1FB2902D3285B2C350D7F1","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"D28D4E4FBD153A6D4C49E2D250213F37BEC941E5","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"80C3F50C018E076DF2CD39732A5ABB8A1C0E88B1","QOL - Disable Grass Deterioration":"3B278C19AC76D27488C55201BA0DB63864F66AAF","QOL - Enable Fast Text":"EFC4517A0915A19F1EC93BFBF91C501124857C18"},"RUUP01r1":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"00D994940AD323786A9DA780D1347AE5FBABAC8A","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"9121BEDD72436F4EAB47E4CE96ABD864118B22F3","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"8FC58B3DC4817515822EBB82BB7A8055270EE51D","QOL - Disable Grass Deterioration":"9B199D77AF748518358D32966F3F55F5C5759C3A","QOL - Enable Fast Text":"827CF5DFC90A258C36BF32DC3883371973E0B706"},"RX4E4Z":{"Fix file reads (dcache bypass)":"9E4E0F1465A9A1E85349DBA3B1278AC215A97DBB"},"RX4PMT":{"Fix file reads (dcache bypass)":"EE85907C03F0295794821383B93F8D5B91D2697A"},"RZDE01r0":{"Hyrule Field Speed Hack":"15EAD073414C9903D6CAE5229DCE582BD17A9162"},"RZDE01r2":{"Hyrule Field Speed Hack":"27395CC8BC2C51201D566657D31A471A850482FB"},"RZDJ01":{"Hyrule Field Speed Hack":"B3F7473F8C911A32F1D616491C9E78EBBD7A6309"},"RZDK01":{"Hyrule Field Speed Hack":"A280C0114B800D7DC056ECFB5E482229DA0B1550"},"RZDP01":{"Hyrule Field Speed Hack":"2A83ADFB760F9498841ED0ED68B0C0438232472C"},"SAOE78":{"Fix crash on boot":"EA11FA4908FB20B61876ACD360EC7657A6D39FB2"},"SAOEVZ":{"Fix crash on boot":"AA55C214DE7545DE0E203CC39F06BF3D31451BE9"},"SBDE08":{"60FPS":"A9E50FFAEBE9F262F5518BBCA73628BE727A445E"},"SBDP08":{"60FPS":"A9E50FFAEBE9F262F5518BBCA73628BE727A445E"},"SC2":{"Limit internal frame rate (speed hack)":"B3FB0FCE108E85E6198BAF3535850470049E2BE2"},"SCYE4Q":{"BAT Speedhack":"D702C348A02C6778BAB5851210A258E9AD53F8F5"},"SCYP4Q":{"BAT Speedhack":"D702C348A02C6778BAB5851210A258E9AD53F8F5"},"SCYR4Q":{"BAT Speedhack":"F90BDE3B7892FD161384FBC3CA72D05F8B6EB43C"},"SCYX4Q":{"BAT Speedhack":"91BAE02F25F4A12582800CDB93D213419CB146C0"},"SCYY4Q":{"BAT Speedhack":"CBD80E291536141196823032D867E002CFE8AA16"},"SCYZ4Q":{"BAT Speedhack":"CBD80E291536141196823032D867E002CFE8AA16"},"SDVE41":{"Limit internal frame rate (speed hack)":"5F83B73ADB49CC1E0AB30AEB4E5E64197B21F444"},"SDVP41":{"Limit internal frame rate (speed hack)":"6F282D2EBE6F5574516052FCB5B94D612C59B6D9"},"SGLEA4":{"Fix black screen":"258378187ACF475A55EFEAF8A703681252E014C3"},"SGLPA4":{"Fix black screen":"6F8CD59D897338CA90939149E1A62588620C6D88"},"SQIE4Q":{"BAT Speedhack":"37009D83FCAE2E26E93CB9AB2A99BACBECAE5010"},"SQIP4Q":{"BAT Speedhack":"37009D83FCAE2E26E93CB9AB2A99BACBECAE5010"},"SQIY4Q":{"BAT Speedhack":"37009D83FCAE2E26E93CB9AB2A99BACBECAE5010"},"STSE4Q":{"BAT Speedhack":"259F13AB4489F5B6EFD48F1D1F4A1FFDEFD6BB48"},"STSP4Qr1":{"BAT Speedhack":"259F13AB4489F5B6EFD48F1D1F4A1FFDEFD6BB48"},"STSP4Qr2":{"BAT Speedhack":"31A4FA663DD548275EE4D7241E51E3AA30B27136"},"STSX4Q":{"BAT Speedhack":"31A4FA663DD548275EE4D7241E51E3AA30B27136"},"STSY4Qr0":{"BAT Speedhack":"259F13AB4489F5B6EFD48F1D1F4A1FFDEFD6BB48"},"STSY4Qr1":{"BAT Speedhack":"31A4FA663DD548275EE4D7241E51E3AA30B27136"},"STSZ4Q":{"BAT Speedhack":"259F13AB4489F5B6EFD48F1D1F4A1FFDEFD6BB48"},"SVX":{"Idle loop speed hack":"5E57373BB0BBADF394E421FA9987CD90F354D19E"},"SX4E01":{"60 FPS":"206E79C5E9B5E07CEB7F52D0F5E5FF3400009265"},"WR2E41":{"Limit internal frame rate (speed hack)":"169567FB65FB2CCB0210213C6DAD65E9937AB9DB"},"WR2P41":{"Limit internal frame rate (speed hack)":"0F70B210236BE666004AB5681151242C22496DBB"}} \ No newline at end of file
+{"D43J01":{"loophack":"CAB9CED2D904F12CCB21F5B1DE9B5433620C3E13"},"DPOJ8P":{"Bypass Modem Detection":"90BA66E25640A538FEFA6693715718139079FA7B"},"G2BE5G":{"Disable interlaced rendering":"7FFF6BDD93713BEDFD23739C32B86153FA19AEA0"},"G2BP7D":{"Disable interlaced rendering":"56E85D7285F10348E1E5354E379918D07E79EDA9"},"G2VE08":{"16:9 Widescreen":"3ED033396382424533A263A39687A0961EC994A6"},"G2VP08":{"16:9 Widescreen":"EEBC3C5F04BB70AFCA1A4C3D638335CDC9142BA2"},"G3RP52":{"16:9 Widescreen":"7F6B7743F0DDD3704B15882330E490103AE24E36","60fps":"4C9A8572A35F1DB85BBB2F32ED34288A343F1FC0"},"G3YP52":{"16:9 Widescreen":"3D102AFEE2F4945894E74BB702ED3ED2294C6FEC","Force PAL60":"FD61581C593EA34DD358AE33819FAB310F2CE961"},"G4AEE9":{"16:9 Aspect Ratio Fix":"8C2564CF47BB6A9B57D712C90E17F459B0BB6CCD"},"G4ME69":{"16:9 Widescreen":"6FC6E5D91693FAABE25CC721F2121CB0B5CA9D12"},"G5SE7D":{"16:9 Widescreen":"16119398BFE241A84151C046E0BC5BCF89D22049","Remove Bloom":"A5F2FB2B3BFF61F34F8AB1DD5A912A0FD8DFA720"},"G5SP7D":{"16:9 Widescreen":"718AA8BD831961C33114852FDA75BB58F768F46A"},"G8ME01":{"16:9 Aspect Ratio Fix - Centered HUD":"8C2FC3FC6F7766AA8E87425BF3BDD2E46E73DE71","16:9 Aspect Ratio Fix - Centered HUD with letterboxing":"AE3DBE2604CA0660165CA870C4B80E2B523C9475","16:9 Aspect Ratio Fix - Normal HUD":"F6E8264CF14D0189219C1E2D20C4182F190F4B88","16:9 Aspect Ratio Fix - Stretched HUD":"8EA4C7B80ADE3E8FEC28EEFA3A046B6B04162E81","No Letterbox":"B1DE2A3526F2E4511F2B94A5171BF7B3C2C52B9B"},"G8MJ01":{"16:9 Aspect Ratio Fix - Centered HUD":"B3181CA1AAB11EAE9132184DA48D76E775AC0A24","16:9 Aspect Ratio Fix - Centered HUD with letterboxing":"904C0EEEF16D761F7BDF7099DEB384DD9AB26E00","16:9 Aspect Ratio Fix - Normal HUD":"631CE99BDE3F1475303C00C67E3C130D4EB2547B","16:9 Aspect Ratio Fix - Stretched HUD":"81F7AD591F12A01DE82850457ECF147998D1238F"},"G8MP01":{"16:9 Aspect Ratio Fix - Centered HUD":"75AF5D7FA49BE9C3C73EA1482B49CD9B36CE817E","16:9 Aspect Ratio Fix - Centered HUD with letterboxing":"C2E5003E74551DF693A7CB814850CA51D77549EF","16:9 Aspect Ratio Fix - Normal HUD":"FB26AA84B0CB787705E84E869B649307776A2839","16:9 Aspect Ratio Fix - Stretched HUD":"C5F8A81520193418C07C7BC4881F02BE9C4DC9BC","No Letterbox":"7828F5B0C8B470620755C16C60A5A4554F92640C"},"G9SE8P":{"16:9 Widescreen":"CD043229AC47AC93D537B6A0725A2D0BB6FEF4E8"},"G9SJ8P":{"16:9 Widescreen":"C55EF90B542AA3973352A232629A828BC22A8509"},"G9SP8P":{"16:9 Widescreen":"9521774ADEE769CFCCE86F8170FE626387E73019"},"GAFE01":{"16:9 Widescreen":"D24F6D9BE5D79D3C795C2844634A0214BB68B5DA","Make Game Save Copyable (donny2112)":"F9A812FF62A20D5440CAB79DB6AFAE068457A10E"},"GAHEGG":{"Limit internal frame rate (speed hack)":"2873E5178C8068AFA8AFE751F903A69CA9A41F16"},"GAL":{"Trophy Viewer":"DBDB50216B22CDFFF77BDD80261CD0FF75803D3B"},"GALE01r0":{"Normal C Stick Functionality in Singleplayer Modes":"9DC8D90D986FAC175F45006AFF20CF00EDFBE053","Proper 16:9 Widescreen Support":"18B4159E77013EDFE499A33281B771C442970E3B","Properly Display in 4:3":"DC2BCA7D99EBDE1DC7C68CA6AC7F543B93FD6A67"},"GALE01r1":{"Normal C Stick Functionality in Singleplayer Modes":"F6030959C1CAC92F37287D556F18B3C5298FAD5B"},"GALE01r2":{"Disable Rumble":"CFDEEA8AD2A99394BFFEA7211EF03394E7471FA9","Normal C Stick Functionality in Singleplayer Modes":"BCD918A72368B2A30E797C76994E7539A1C0B5D9","PAL Stock Icons":"6B92D95F0EEA165EA84FD753F74B0A9E2079C2D7","Proper 16:9 Widescreen Support":"CEDF18354CDCFC49398551C629E51B053331A55B","Widescreen Support v1.2 [Dan Salvato]":"D32ED4CD685F3FF649F7E749E8C182C657013918"},"GALP01":{"Normal C Stick Functionality in Singleplayer Modes":"4817F202678559291F9F76B46DC7561A45D00B77","Proper 16:9 Widescreen Support":"BFCBE098FE8679B9140A48EA1D8620D5A369697C","Properly Display in 4:3":"5BA2933B8365E21553AA273B91954A4C722B1035"},"GAZE69":{"60FPS":"BC281053C5266B21FDDC6C8996A6021DEA03D459"},"GBLE52":{"16:9 Widescreen":"C0F3AB3BBC9B21F4BF25F44E48CF1CD36D2B3F45"},"GBLP52":{"16:9 Widescreen":"797040CB097BFD369490A1BE29659929D76CE6F7"},"GBRJ18":{"16:9 Widescreen":"B3C867AB34D90E2E9C5B799D800F4C191DE279FA"},"GBSE8P":{"16:9 Widescreen":"4148D453F61A5B81E53669335BC667E651865C76"},"GBSP8P":{"16:9 Widescreen":"6CB029AE768BA5B9995D5F12C1EBB37B3D1FE242"},"GC6E01":{"16:9 Widescreen":"DE932CCAD1B5EB1FAA8D08733BD0D3940C78382A","60 FPS [Nerdzilla]":"85F98064F17AFE0FB02A99A182AF3FEB7644DCAA","Allow Memory Card saving with Savestates":"2F64F98686E62B60E466E931A9EBCD19A750FF4E"},"GC6J01":{"60 FPS [Nerdzilla]":"A6146772E37970EA5564F51A622A04792158B321","Allow Memory Card saving with Savestates":"D8F327304A88FBC717BB1F775494C5F864B9E8D2"},"GC6P01":{"16:9 Widescreen [Ralf]":"05C9016BF58A628A3FD7B16E1B9BB0769A14846F","60 FPS [Nerdzilla]":"1D3FB017C0D20754E48A8BA54EEE7DC4851BE84B","Allow Memory Card saving with Savestates":"EDEE0E28EEA1834868F2865336290FFBDFB9C6DA"},"GC8JA4":{"Fix C4 texture tiling (used for buttons and some character icons)":"843297019804192AF1FC660BC85F4B10891D0BA3"},"GCBE7D":{"16:9 Widescreen":"478DA1D596D8513C343850719155813CB61A56DD"},"GCBP7D":{"16:9 Widescreen":"478DA1D596D8513C343850719155813CB61A56DD","60Hz":"DF2C4DDF082C9E67919443C5ACC485AB2CF7F8D0"},"GCCE01":{"16:9 Widescreen":"BA0066518E7EA8599A81F8496BD39DE20CC369D6","Fix GBA connections":"483BDB94615C690045C3759795AF13CE76552286","Fix buffer overrun bug (crash at Goblin Wall)":"6C107FEC15C76201233CA2645EB5FAB4FF9751CE"},"GCCJGC":{"Fix GBA connections":"4C104D24329172F5D0F8649DE9423B931FE72CA3"},"GCCP01":{"16:9 Widescreen":"2580E7379633CF4DE13B9EC945DB17543477828A","Fix GBA connections":"2EAA60A8A115AD68A795109FB59E4A726D29016D"},"GCN":{"Fix C4 texture tiling (used for buttons and some character icons)":"601FE183C9524ACCF068874DABD73921C86769CF"},"GCVEEB":{"16:9 Widescreen":"ADA686C90189D1D7D23E23E525EFC96EFA104BB9"},"GD7E70":{"Deinterlacing Fix":"6F8B6E33214162E5CDEBD2BC6A60FAFA04D2EB10"},"GD7PB2":{"Deinterlacing Fix":"3B798C9D63E755349B253FAF9186BAE1F703D96A"},"GDJEB2":{"16:9 Aspect Ratio":"05B0B7D2DD405D9611A482D84DCED44C42C05D97"},"GDREAF":{"Fix audio issues":"F8EAE60FEB0CFB4477FDC4B9E136B63F68DFA63A"},"GDRP69":{"Fix audio issues":"E23D98B2CE185C3993A40F2495D37E41B971BF91"},"GDSE78":{"Limit internal frame rate (speed hack)":"BE8F752F2A2660380B2AC5953F394DD867880EB3"},"GDSP78":{"Limit internal frame rate (speed hack)":"5F8EF8AA8C08D7B3173A59534E8482804C0446D9"},"GE4":{"Limit internal frame rate (speed hack)":"9ABA0E4C533142BBA35DD87180EE38CAE3711226"},"GEDE01":{"Fix startup hang":"21068C3CE905FB0CFFAA7408A93154AF8A5295A2"},"GEDJ01":{"Fix startup hang":"7061F3CF11BF64D3BA7F32CCF2BAC42FF3614AB6"},"GEDP01":{"Fix startup hang":"6F1B00517CBA30BEB738EAA90E71221378CD570D"},"GEME7F":{"Force Progressive Scan":"CB04E00918C9C0F161715D21D046ED6620F7ADEF"},"GEMJ28":{"Force Progressive Scan":"41D8F2C833C0B7B79FCA038752052059207AE4D5"},"GEZE8P":{"16:9 Widescreen [gamemasterplc]":"5CEBCFBEA4E444495D2FD6D8B6607DFB2349CC1B"},"GF7E01":{"16:9 Aspect Ratio":"C96D5AF47EAF25F63E138FF118E3B82935626C06","16:9 Widescreen [gamemasterplc]":"C59CCA3EF8A5E97B32EB64DB9AE80E652ED281C6","60 FPS":"FEAF52B44E1EEB8AC5A416D2184CB525D74E2D7A"},"GF7P01":{"16:9 Widescreen [gamemasterplc]":"1230053B5C347B62E432EFD6635433A183D18619"},"GFQEA4":{"16:9 Widescreen":"5CD9568CE58EF82EB371594667015C9B799454B9"},"GFTE01":{"16:9 Widescreen [gamemasterplc]":"A8F2918A04304652E4E0501984B2E2666AB8A756"},"GFZJ01":{"Make Save Copyable":"F659D22CB1DFF15C3915D7630D838EED8DB0BA48"},"GFZP01":{"Make Save Copyable":"F659D22CB1DFF15C3915D7630D838EED8DB0BA48"},"GGTE01":{"16:9 Widescreen [darkludx]":"EF128E7A9C22676834F558BA0F0F7FD8B9028727","Experimental 60fps":"D40344111D989EA009901F8B1C45B5AC8D39E6D2","Simple 60FPS":"5232A937D1D813FF58DD71D716284ED6AB535689"},"GGTJ01":{"Experimental 60fps":"BEC2310911003AF9E4B984A4051E0F885B8CC825","Simple 60FPS":"D62E777A2F019D7BD0AFFBCE876BD9AE408F1667"},"GGTP01":{"16:9 Widescreen":"FA9CD330ECDA01275DA88BD0803DE47757D16A4E","Experimental 60fps":"EB1ACD613BB432A3391CFFF1F0145A6ACE66B210","Simple 60FPS":"43FAD0DDD130BE1E4C8C7603EF6CA7DAA0DF5EE9"},"GGVD78":{"16:9 Widescreen":"9D07DBB5EC2FAA47F2E4587FBD75FD6F3E7E91B0","EFB Copy Fix":"FE52240DF6D132C15A8324E8A477F2BF2250D208"},"GGVE78":{"16:9 Widescreen":"86E561452235BF88D41884558EF34F54CE0FEB48","EFB Copy Fix":"5E38E10829D5F77243C95E9E41518BB3ADE24139"},"GGVP78":{"16:9 Widescreen":"F9B2108D833084FA36A53E00F1647A9579F847D3","EFB Copy Fix":"5E38E10829D5F77243C95E9E41518BB3ADE24139"},"GGVX78":{"EFB Copy Fix":"740F2D1C01DA39D1760D96B03974A48E6F74578D"},"GH2E69":{"Limit internal frame rate (speed hack)":"C874194B083036964F8B2606BA680C646F642D96"},"GH2P69":{"Limit internal frame rate (speed hack)":"D437A732A1907B3F32FA6C2C64F40A80032878B5"},"GHAE08":{"Fix audio issues":"9799AFF8463EC86C9230E31E2627E141F0C129D3"},"GHAJ08":{"Fix audio issues":"B45A8FC32D14567B8D6C95F303E00A72C0E1D344"},"GHAP08":{"Fix audio issues":"BC7F3CFC97593AA2055C370C175950DC478D2709"},"GHKD7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"1AF09E98F0B72833A0F4E519EC3D4130C36D615E"},"GHKE7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"9BFBDE9184BC05EBD545625DEE486E3AAB36B6A3"},"GHKF7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"919E853513192C97F3CF49246A65ECBF39E7C201"},"GHKP7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"1AF09E98F0B72833A0F4E519EC3D4130C36D615E"},"GHKS7D":{"Limit internal frame rate (speed hack, also fixes audio and gameplay bugs)":"919E853513192C97F3CF49246A65ECBF39E7C201"},"GHLE69":{"16:9 Widescreen":"742BFC79D8F0BA5D6215772B58F5A0EADD7BFAFF"},"GHQE7D":{"16:9 Widescreen":"520E5F718D3BD1291C55021776091E0DE0FB4822","Limit internal frame rate during startup (speed hack)":"F6BF450D22104FD2527122EA6E81B1F70E916B95"},"GHQP7D":{"16:9 Widescreen":"AAE14CDC13A0C082A850DED85417100A8C8A0687","60Hz":"884A33613AE8D916128E3FF39B3AA9F63DAADC58","Limit internal frame rate during startup (speed hack)":"BD475ADEF145AC9226514CD1B2D4D5F3BFE67964"},"GHSE69":{"16:9 Widescreen":"3538CDBD13FA939B7BA5F0F82253401AFDD1E2CD"},"GHSP69":{"16:9 Widescreen":"409754E2EBB6F05DEE1AFC647E25B15D462638FF"},"GICD78":{"EFB Copy Fix":"3A94591A149AE88C150AB3320BBC909FE54BAEA5"},"GICE78":{"EFB Copy Fix":"5BF55685B8867A85EAA9C86571309B17BF7DED32"},"GICF78":{"EFB Copy Fix":"85AABAEB9A59C4F96D9330A3B884F6D757DA1683"},"GICH78":{"EFB Copy Fix":"3A94591A149AE88C150AB3320BBC909FE54BAEA5"},"GICJG9":{"EFB Copy Fix":"969134EA21A160EBDA91C0870266E7D1707FDC43"},"GICP78":{"EFB Copy Fix":"13B158CF41F5412BC637F50644193D43CC3DA49A"},"GIQE78":{"EFB Copy Fix":"E15AA1E30D26E5735D68AAADE436E7B7E4A33A35"},"GIQJ8P":{"EFB Copy Fix":"FFFCB76E98DDB06A7BBBC0AA73C869C87EB787D6"},"GIQX78":{"EFB Copy Fix":"485DA99FAB35646DAA2A138B0315361495ABE778"},"GIQY78":{"EFB Copy Fix":"485DA99FAB35646DAA2A138B0315361495ABE778"},"GK2":{"16:9 Widescreen [Vague Rant]":"6B4C59C2A2C5D71C7A38C8513A76E6467E307A26"},"GK2E52":{"60 FPS":"8F2397930A50C3C176188526EB9612578F9CBCE5"},"GK4":{"16:9 Widescreen":"4652969A4DA869FD28F2CAA3869A38F5C2AAFEB1"},"GKB":{"16:9 Widescreen Region-Free":"4652969A4DA869FD28F2CAA3869A38F5C2AAFEB1"},"GKBPAF":{"60Hz":"8E4E0ABA0E6D102A33206F34F4DEE63159B3CB4F"},"GKDP01":{"16:9 Widescreen":"DF4657937DE730107B636C73E959277EB963D210","60Hz":"6740D7B914CC897AF50798C0AB391965294FD1E1"},"GKRPB2":{"16:9 Widescreen":"69C01A4F91D991CF866237FED94A138308FC104F","60Hz":"40D06A5C7A3D873ABC73DEDF573738C2E3E37FF0"},"GKWJ18":{"16:9 Widescreen":"696570101FA040778EAD310377C484C846D87430"},"GKYE01":{"16:9 Widescreen":"6520EF1B7D88F00747B120A3A010458602ED989D"},"GKYJ01":{"16:9 Widescreen":"47B8EF7D02831AA5C375C698797BF2D5475FEFF2"},"GKYP01":{"16:9 Widescreen":"69413C75036D2975716066E6574461B981FF0124"},"GLEE08":{"Fix audio issues":"7355F358CAC6F418D37E4C23E64F7867D46E4FC9"},"GLEJ08":{"Fix audio issues":"12B24A6D7389A2AC5AB75FC0BF8493E7661F2A73"},"GLEP08":{"Fix audio issues":"81BD39F5527552DE89E3B59BA86298900F0A3168"},"GLSD64":{"Fix freeze in opening cutscene":"5E2A73717BD66EF647846DD64C33BC80AD9B5227"},"GLSE64":{"Fix freeze in opening cutscene":"1CE78E7954415A44DF693C0BB879AA5A4FF059A3"},"GLSF64":{"Fix freeze in opening cutscene":"009B0C4AD80A9C28C987934D254C2C4AACC9A07A"},"GLSP64":{"16:9 Widescreen":"8E7A544C10E7A5E2F0304A0D2586879627EF6586","60Hz":"B67144E87B54246137142992A3BC83DC13BE68A7","Fix freeze in opening cutscene":"3D0894616C9A7FA5ED91C1D2F461BF14DF47ECEC"},"GM4E01":{"16:9 Menu Backgrounds Add-On":"87D1A6A3E29ADA03B0D29C2F1841C18E62DB0A15","16:9 Widescreen v2":"78BE50F93E81A1972CA31ABC318949E366E82BD0"},"GM4P01":{"16:9 Menu Backgrounds Add-On":"87D1A6A3E29ADA03B0D29C2F1841C18E62DB0A15","16:9 Widescreen v2":"6D950B6EEFD6D304E1A424355B74A595D32BDF2F"},"GMBE8P":{"16:9 Widescreen":"D12DE9E3941BCE6EB50B8DA92140E09AFC0104C8","NA Stretched HUD":"0151A6683E1FBFD20096807C54A6952C4A4BAD40"},"GMBP8P":{"16:9 Widescreen":"8A688981F33A2C53882EF08FCF20B88AD43EF417"},"GMNE78":{"Limit internal frame rate (speed hack)":"DE38BC8493EA24F93B6D805F28746AA99C53C677"},"GMNP78":{"Limit internal frame rate (speed hack)":"65FB9B430F7D58EBC76DAADE8CA9DBBAA32B8B51"},"GMOP70":{"16:9 Widescreen":"CE4D298616BD42E4D8F8936B325CD1FD7F5B956B","60Hz":"0CD2CC787A5FF551901E41C85C8AAC02017ECB89"},"GMPE01":{"16:9 Widescreen":"4F98592DB3DEE3857469A8D8605FAF4BD6F7C76D","QOL - Allow Digital Presses for Map Screen":"E232B27564E9AA0C32DE163C9C056317A7B2B12E","QOL - Automatically Advance Text Boxes":"59607671BFC4717ACAF9807BB7EB0D9F982866D4","QOL - Disable Advance on Results":"CAEA37F3FEF89400513353EB85875F2A3AF4C03E","QOL - Faster Boot Time":"F75FBBD838C5B84FF687962FBA9195B217DE132C","QOL - Increased Board Speed":"19F264DE7F07EAC9433CA4B591BEBA1EC976C9F1","QOL - Increased Taunt Capabilities":"C70391D4961A0E820DE40141C89341369A9F021B","QOL - Instant Text Display":"F4E6913CF034E5778B9F9CA5FF448FF1B78B3333","QOL - Rumble Always Off":"93621947019532F02C25937FD3EEEE21A788CB07","QOL - Show Controller Port Number of Who Paused":"D7249AC3C949FEB860CF4350C5B7B79AC16569F1"},"GMPJ01":{"16:9 Widescreen":"A795811F2F0C92D9DCABDE97D9E39B47B1DBCEFD"},"GMPP01":{"16:9 Widescreen":"A795811F2F0C92D9DCABDE97D9E39B47B1DBCEFD"},"GMSE01":{"60FPS":"2805B1A0DD53EB64877D375D10F667700955720F","Disable Heat Wave":"988DC355648FA0EFB8AE6353CCE5F28C8B82BA54","Widescreen":"BD718F961DBA5372B1D0257D454D535746C453A0"},"GMSJ01":{"16:9 Widescreen":"E8112A01040A06460E368F142C5D1FD0B4085D94"},"GMSJ01r0":{"60FPS":"9894B5B6B5215844D48411021FF8EECFE851D79D"},"GMSJ01r1":{"60FPS":"2DB69DB7A3753D543CD85CA4C77B4EF0AED7486E"},"GMSP01":{"60FPS":"D07009B710B3BBC6B12E54ED6A7969D58197EDAF","Widescreen":"0B7B89BF0868393076EF5F9DBD689DD0EDBCB84C"},"GNHE5d":{"Nop Hack":"89393A24E2336841AA4CD0AD3BE1C9A66B89E9EF"},"GOCE5D":{"16:9 Widescreen":"E4D800B90F16A15D9252EED1B2A23AEAF5CD230A"},"GOME01":{"16:9 Widescreen":"C33CBBF6F22195BF626104B4827200B3EE1CF30C"},"GOMP01":{"16:9 Widescreen":"874784CCD4AC3DC9C69654E471C18AD0F5E4D9AE"},"GONE69":{"Widescreen Hack Culling":"6412A67E1C26E146A9526AFC9F0EE517B214069D"},"GP4J18":{"16:9 Widescreen":"BF4D2D6AF66F285E81173B3B20D5369DB6FB351B"},"GP5E01":{"16:9 Widescreen":"5ED053787332DB5EEB8B963BA5DF197B58C6BB75","QOL - Automatically Advance Text Boxes":"41EF84663008668682BB75DC8B874E38669AE041","QOL - Disable Advance on Results":"6C36BEFE751131298BC8B39012892F6A6903CE60","QOL - Faster Boot Time":"8E952E6E12639AC20F6F9FDD150C12F0C294DF43","QOL - Increased Board Speed":"4BD72B8ED75ED8EFB3329C104BAD114FDDB8AD2C","QOL - Increased Capsule Throwing Speed":"C5BA3C9D386D09DD6CB9242A12A0D041BEB93160","QOL - Increased Taunt Capabilities":"C360EBDDCB0237076052C983BD9719411CA67CDE","QOL - Instant Text Display":"2CD4A06A3B9C18CC9EA2A2DEBD96E066CD1D700A","QOL - Show Controller Port Number of Who Paused":"5BA3648D18346EDC97B23475D4748C637E6095A2"},"GP5J01":{"16:9 Widescreen":"81E69B6BEE85E06805EC24E1CFEA9405BF459DF8"},"GP5P01":{"16:9 Widescreen":"FD4FCCB97C06F0173A30D4CC9A99422B2C0ABA9B"},"GP6E01":{"16:9 Widescreen":"B502AF0887792E9B140516D14BA75F99772C17BE","QOL - Auto Advance Text Boxes":"E645DF70CE0266D174D917A817A7FBEEE974A9F0","QOL - Disable Advance on Results":"798E566B621F6A32BF23C588E76EAC0776E2A8A3","QOL - Faster Boot Time":"B089A3C80D5DA86ABF6258F8BFB1DC78BB54A973","QOL - Increased Board Speed":"501C52ACF117950888A66DB2BEDBDFD7D9B20235","QOL - Increased Orb Throwing Speed":"845F439278DA8CBC225658FF4E2F82D707422BFB","QOL - Increased Taunt Capabilities":"0AED27341A06186AD92D5725C0B9693CA8F85B7B","QOL - Instant Text Display":"5AAC4E21927D4AEE7AC329CE793D4CDAEDDF7A3F","QOL - Show Controller Port Number of Who Paused":"DF5D2F068D76ABF2B1C294D413B9154B8C356929"},"GP6J01":{"16:9 Widescreen":"88F50F8298F82E3E5C161277BD4A985CE893A9D0"},"GP6P01":{"16:9 Widescreen":"DCCE59CA987624C753F0A86BEBA4287635901C93","Remove Black Bars":"138A86D43B5830BFE1926F58C0A4FBE2971BB02D"},"GP7E01":{"16:9 Widescreen":"87EBF72D90503EBC5CE9BC994795669E48A92A4A","QOL - Auto Advance Text Boxes":"82338AB5D82A7F398B4EB674CA4866DD1F4A1E65","QOL - Controller Options Always Acesssible":"D2F9CC0B9E52136E77187395FB7DA9B64B2C3B30","QOL - Disable Advance on Results":"A644551162A61DE7997B2A84F5BFDEFFD3FC2FB5","QOL - Faster Boot Time":"1939B5C575AE8FF6890BDDDD1B3FEA472D8CABA0","QOL - Increased Board Speed":"7E06A2EBCFECADB8074152B489984237A6FE9F21","QOL - Increased Orb Throwing Speed":"6671BEE71920D6B845AE1257AFE3AB3B95CD6FBD","QOL - Increased Taunt Capabilities":"9F60923F95FFE709CCD06966CD2DF743263934D1","QOL - Instant Text Display":"48FA6002E42DA9BB83ABC980A32C60CE3B21C4FC","QOL - Show Controller Port Number of Who Paused":"5E6F8C6C87D5944DB18A4E4F9A45F61EE87A4163"},"GP7J01":{"16:9 Widescreen":"A081F0729068D233E99DC00C64E36CA33C945640"},"GP7P01":{"16:9 Widescreen":"75D6CDA4EA301A71F7701A0487544E79136850B9","60Hz":"6D0D5B7CA58C38A3147F8ED981B5B21CC6C519CD"},"GPIE01r0":{"16:9 Widescreen":"2B58166A66644F984E64077A6245C94C79B51063"},"GPIE01r1":{"16:9 Widescreen":"9A1545AB4E2B9216B95AFFA83420D723512DA8C8","60FPS":"3337C767EAA21D30C6CFEAE9985FFCABFC63E2E3","Disable Pikmin optimizations":"CBD15E9104929F0631713AE482475CB2B90E71F2","No Blur":"A25CDDB79991F090BD7F12840AD06F13BD5CCF95"},"GPIP01":{"16:9 Widescreen":"5AE44D5B0E0D4C412B453B95CF5A41DBA4D685E6","60Hz":"AE59FF751E167632AE283F38CC4B96BDF7B9B81F","Turn off blur":"4ED79A548DBD7DBD35928A2F1138315FF103E260"},"GPNE08":{"16:9 Widescreen [Ralf, darkludx]":"ED3D9BB08C5F1D21BC8D5C73155C00E3C25C466F"},"GPNP08":{"16:9 Widescreen [Ralf]":"469B18FE8219031D355557B836EF02B625040A4F"},"GPOE8P":{"16:9 Widescreen (Plus) [Ralf]":"5563671A6702785FFE106DAB7EF3F4FE6D9F705B","Make Save Copyable NTSC Port - 1.0\/1.1":"7A4B3E596BA4FDA8F3FCF984079B3F44CB2D6AB3","Make Save Copyable NTSC Port - PLUS\/1.2":"304DB311F2107E88EBCE058535B266F9263AA8E2","Save Validation Code v 1.0\/v1.1":"9F6259132453DCC0607EAB35DB182C76818F2F9F","Save Validation Code v1.2\/Plus":"17EB6CFB408EF27D44C053A1336C3B87B6A05018"},"GPOE8Pr0":{"16:9 Widescreen":"99986BB1D4ABE45C429D48B01BFB578FEA69C14F"},"GPOE8Pr1":{"16:9 Widescreen (Plus) [Ralf]":"5563671A6702785FFE106DAB7EF3F4FE6D9F705B"},"GPOP8P":{"16:9 Widescreen":"DF133C61C29D5CFA87A2A785C962C205F80E6D04","Game Save Valid":"40EC1590DB26C7C58D00E3065F1E404341EF0E73","Game Save copyable":"2F5FB98927DAFF141D1CCD1EACA8AF626397E284"},"GPVE01":{"16:9 Widescreen":"E5B51080CFD518FE584CF3B61A1099CD032479D6","60 FPS":"6662E99E41F77763EEE524477DF341836EC7032E"},"GPVP01":{"16:9 Widescreen":"78F3C9A789827B063A6701987262276A66ABD82B"},"GQPE78":{"EFB Copy Fix":"880B114E9A308084CAB92C004A9EE067B371C310"},"GQPP78":{"16:9 Widescreen":"CA5A618C8FD5537271F0304F8BD58884007F872C","EFB Copy Fix":"5D9A14954AE8D639C9B254F3BA73A70F284BBC8D"},"GQSDAF":{"16:9 Widescreen":"CA82C44B2E8FC5C184E3FF935BC89661B7DB55D6","60Hz":"952165FD78543EB6D2F5230F7570B0513773D332","No Blur":"DEB7DF358423F0EF30C9FD49F4F14590836D52A6"},"GQSEAF":{"16:9 Widescreen":"48AFE1D32843C6B5AD4337A49F15FD447DF2A752","Remove Blur":"EF448CF1FA6A15EB2661EA5338703C13D52EF65B"},"GQSFAF":{"16:9 Widescreen":"76C30E1737CC5C3B5DE32532B5F9A5CD50B690F8","No Blur":"986BAE5103CDE9286D2D34FD28FE2540D0759AAB"},"GR2E52":{"16:9 Widescreen":"5F55CE7DA7E1E3261CF2FF88F34CDA63BA511003"},"GR2J52":{"16:9 Widescreen":"D3C6FA690BED07BFA65C2E1FCDE2FFA5AA0EEEE4"},"GR2P52":{"16:9 Widescreen":"D7BCADD4E76B5E3F7D9D463F55A2777528E37E94"},"GRNE52":{"16:9 Widescreen":"483D74C47AD1012606D591A226AB3144C7FB201C"},"GRNJ52":{"16:9 Widescreen":"949281B7221B20680B7BC29E4754B73A326EBE85"},"GRNP52":{"16:9 Widescreen":"11051B094FE5A8B2E73060BFF786C1588E36979A"},"GROE5Z":{"16:9 Widescreen":"FADBAB5EC280CF8ED4C9536A33F4184BA210C9B0"},"GRYE41":{"Disable Culling to Fix Rise and Shrine Hang":"AF0A575EB6071EAC0D2EC3D2EA30A23EB05A4192"},"GSAE01r0":{"viWidth 704 Aspect Ratio Fix":"0D529180B9B28BB06E21EDBDBA61C17EEF0FFB7F"},"GSAE01r1":{"Increase Player LoD Range":"60BA00CA149C7094F61976DA22E3EDAF1770C4BE","viWidth 704 Aspect Ratio Fix":"CB15ED22625690A5DBE4607FE30160125421461D"},"GSAP01":{"viWidth 704 Aspect Ratio Fix":"749EDA62B1B73354599929F1B50E992E111C5493"},"GSNE8P":{"16:9 Widescreen":"CFDF3FA5B48B347E49E8E521D7BE47FCC9A5CBF4","60Hz Aspect Ratio Fix":"D90F66C0D46D9BEF27C8E13BC8804DB1F382C8B1"},"GSNJ8P":{"60Hz Aspect Ratio Fix":"98DF9D67DE77F66A4B09F25C5621805DEB40865B"},"GSNP8P":{"60Hz Aspect Ratio Fix":"D90F66C0D46D9BEF27C8E13BC8804DB1F382C8B1"},"GSO":{"16:9 Widescreen Region Free":"0D60D0593F6DA28B1236381B22082506B9533F0E"},"GSPE69":{"16:9 Widescreen":"80E18A8963F4EFD3C03494C95934452FCB6E521B"},"GSPP69":{"16:9 Widescreen":"162E87E9F5511CD82216811055836C11B374C45B","60Hz":"E5DF2DF34D2F0BDEE4205C891576511EC572C5DC"},"GSWE64":{"16:9 Widescreen":"6480326CCA8FF64A4868EC6E9FDE9F38819A75A1","Disable Dithering":"85F65E4B627641862C1A6091D29A3BB0626B04C3"},"GTEE01":{"16:9 Widescreen":"6B57EBCB9CC0ACE2EDA0F13E3F1F55F3FABC3A26"},"GTEP01":{"16:9 Widescreen":"72785784363C46180AF8E388348FD77667E7D382"},"GTOJAF":{"Remove Blur":"53A2EDF113F2ED7E54A16AA0E73FDB2C44C79DE5"},"GTRE78r0":{"Limit internal frame rate (speed hack)":"42B85EFC5DEF8B243521EAD434DDCBDF95664CB1"},"GTRE78r1":{"Limit internal frame rate (speed hack)":"ADB3A41B992EAB15AE484B2E575ACF3354415186"},"GTRJ8N":{"Limit internal frame rate (speed hack)":"47DBEFDCF22ADC2AB148A54AC885FE19B3C07E3F"},"GTRP78":{"Limit internal frame rate (speed hack)":"E8752E1B60DF76CD0CC7408074E742B0966BC904"},"GTSE4F":{"16:9":"03D0C232C92FC50DD86A8D216F36B7BC83E381A6","Border Fix":"C578CB61AD5B1B6A186BB17C8E7D1613B2CFD965"},"GTZE41":{"16:9 Widescreen":"ECCE87E0006475C73E7D936AA0150BD20166F9EF"},"GTZP41":{"16:9 Widescreen":"62D8F159B93167171E0860D96C4BB32A5BF5648B"},"GU2D78":{"EFB Copy Fix":"CFF4C3F932B08732627572EDA1A0CD2D9C71AE0C"},"GU2F78":{"EFB Copy Fix":"CFF4C3F932B08732627572EDA1A0CD2D9C71AE0C"},"GU3D78":{"EFB Copy Fix":"8A0E3114862ADFE421874211BD6F5220AA425BF5"},"GU3X78":{"EFB Copy Fix":"E3303FDAE7ECA17A72EDC440C32D94648A6453A0"},"GU4Y78":{"EFB Copy Fix":"D54767785E139A8BC8C4B75573FBD5A0B686D8E3"},"GUNE5Dr0":{"16:9 Widescreen":"C942EBCBE8A487C25E296EC1FAC2358DA1487DBD","60 FPS":"A441630EC5FF0EB74D2243A3092D22E69C6BEA02"},"GUNE5Dr1":{"16:9 Widescreen":"39BD84CBE2AFACFEDEC5E9020D1A8B0D36DD53F9","60 FPS":"05779F1A3D0C43305D52A95447D612CB424942C0"},"GUNP5D":{"16:9 Widescreen":"FE3BA1DAA1AF278A7839E27BF466B0BA0B390EC2","50 FPS":"3B20499A3F8D1D7CCA5B0015F2D80ECED25842A6"},"GV4E69":{"Fix 2D Rendering":"8679891FCAA250FCFF670B26E0CB9875900D17FD"},"GVJE08":{"16:9 Widescreen":"09EFDA75D876A675121C8344D8FDD09A70A1A846"},"GVJP08":{"16:9 Widescreen":"93938F4C6112C91549F2B52E6259170F7501EC07"},"GVPE69":{"Fix 2D Rendering":"3159CA79B0A890131763EA6CB163684BEE886E3F"},"GVSE8P":{"16:9 Widescreen":"4CE9C491160A4B631142EE9CE802C694163F1CA3"},"GWRE01":{"16:9 Widescreen":"AC42770B06662BE1DC863EC80F44B5E034C63664"},"GWRP01":{"16:9 Widescreen":"9DDDFAB28C4BD35CF64050E1EF684DC042B1AFFA"},"GWWE01":{"16:9 Widescreen":"98B2E75D8E1CED4A964D3129A5DC10E30538CAA6"},"GWWJ01":{"16:9 Widescreen":"2DAD9A5E2A140F02CCBA727C4BE7C74BAC156778"},"GWWP01":{"16:9 Widescreen":"2DAD9A5E2A140F02CCBA727C4BE7C74BAC156778"},"GWZE01":{"16:9 Widescreen":"9EFC191DE6D21A1681FE241AB2EE4A131259F317"},"GXCE01":{"16:9 Widescreen":"901A1E78A3A0124F55548507D3B3707125C64A8A"},"GXSE8P":{"16:9 Widescreen":"F50BBA440184FC77A4DFFAA58FF2BB888E2E072F","Aspect Ratio Fix":"4214C74DFB8A74FC3AA4A643E869BC4D9A38EDA0"},"GXSJ8P":{"Aspect Ratio Fix":"227909607984BBC3D36AAC7DB9DFE385F3363C49"},"GXXE01":{"16:9 Widescreen":"7CAFDAD7B5E7459CCC1BB209D439DDCBB5BE4E4E","60 FPS":"7E2829049003FC9DC8BC28044B33CAFF3768B54C","Allow Memory Card saving with Savestates":"64FAA15062F0D0C319F904BBDE9C4489A25D6369"},"GXXJ01":{"16:9 Widescreen":"AF704A8C6838FDF47054D9EDD9106B3F46781FA9","60 FPS":"4F5FD45B4EC1B33FE076FA06F8FF863C46A06BBA","Allow Memory Card saving with Savestates":"8293802260536FA2EF2EFDAB5266DE36BB88DE1B"},"GXXP01":{"16:9 Widescreen":"02716B2585BEE74F8FCDD97A78F6A0D3DC7F331B","60 FPS":"BF6171EA5CCF4B57AA596372589DDB5E6904DD7A","Allow Memory Card saving with Savestates":"3CAFBC4AE6FC5CE9F53377F86AB5BD8F1BC8861A"},"GYAE78":{"16:9 Widescreen":"8B00EFBBB05B7158C78D26D13C03A22F3DEC41B2","60FPS":"96C6D047DBB7F80DC661CE44B639A8378E992C27","Remove Bloom\/Fix Upper Left":"2C05DE9919EA7863CC386704A030A6EE1453CCA5"},"GYFPA4":{"60Hz":"402ED10AC842041AB4B39AE8F2D81B2D7AEF9CB4"},"GZ2E01":{"16:9 Widescreen v2":"E7521ED27BFC972628906CBE8D5403ED57253BB8","Hyrule Field Speed Hack":"FCB673D46E716C7F63C618B8D8BF83AEE0B501F0"},"GZ2J01":{"16:9 Widescreen":"F985A0A58D8E2B23E8A557FAFF8D367AFFEADD07","Hyrule Field Speed Hack":"FCB673D46E716C7F63C618B8D8BF83AEE0B501F0"},"GZ2P01":{"16:9 Widescreen v2":"CAC38B0D334B925A57AA3118D35932B8A185137E","Hyrule Field Speed Hack":"0F63623D4D984B7706F718F57C0ABDB6DBADCF8D"},"GZ3E70":{"16:9 Widescreen":"167F9E9A9B372CB3A01F308B46FF1403F8599C51","Deinterlacing Fix":"EF1291C0E45277CDAE4D0F61E1949C1E75E5A3E1"},"GZBJB2":{"Deinterlacing Fix":"19D67BD12A18F0E3A960BBB92E2F490BEF5C00C1"},"GZDP70":{"16:9 Widescreen":"2E424E0BBAE6EF5D6A8FB4224EA1D0746BAC37D3"},"GZLE01":{"16:9 Widescreen":"9FA864EE7DD8CE7FF538EB4E0243F20137430BD8","Remove Distance Blur":"78EA34CEF8E01701491C280F155F1C12EC9BF1A2"},"GZLJ01":{"16:9 Widescreen":"E03B61989025CA33937E63A057E6E40A403811BC"},"GZLP01":{"16:9 Widescreen":"3EFFF6C52B5633A1729FAA6883D8579E77F7D057","Remove Distance Blur":"14BECBEA4DD281EBD0F7FE7DEE8020B6F2418ACD"},"GZPE70":{"16:9 Widescreen":"7142F2495507AC7136992128ED0FCA6BC72B61F4"},"GZPP70":{"16:9 Widescreen":"591FD6C9668C79FF1CE8558EBED2486A7A327F05","60Hz":"A59B84DB5486521AEE1C23B6C741ECD35216E5AD"},"GZSE70":{"16:9 Widescreen":"8E86EAC7EA4F4D2854DD9020CD795630CA64C4EE"},"HAF":{"BufferPatch":"181195871F63B89B1CF09AFA4420CF89B9883108"},"HAL":{"RSAPatch":"AD12237401ABE9FE4A545AADB5C5AE10355E2076"},"P1RE01":{"60 FPS":"FD15A2EC38E46C1C3153336BC44F11B08ED906D0"},"R3R":{"60fps [Nick Reynolds and Vague Rant]":"AA205FCB7FAFDE78E84B48C7BEF0FA2FBEB56107"},"R7XE69":{"Idle loop speed hack":"53F3273525BB719D535007FB97E7F381D808A8A9"},"R7XJ13":{"Idle loop speed hack":"4590D425BCBAFA0D1E32D27B46068843F6A2BE09"},"R7XP69":{"Idle loop speed hack":"53F3273525BB719D535007FB97E7F381D808A8A9"},"RB7E54":{"Limit internal frame rate in loading screens (fix hangs)":"BD1A252B43FD339391ED33554542E786BAD6671B"},"RB7P54":{"Limit internal frame rate in loading screens (fix hangs)":"90247F89DF8EB7A4AFA2C425CD3006257A95A8F8"},"RBU":{"60FPS":"EF7741840B8B87BAC5C62DC72F97651005B84F71"},"RDGEA4":{"60fps":"E7294BFA8DD6009B77FA53319C027BDAD95C7373"},"RGQE70":{"crashfix":"5F4CF8D4DA19A0FF74FF9EB925AC0236069BFD59"},"RGWE41":{"Limit internal frame rate (speed hack)":"A0B4B457C42E3E2EE6D4E3E1F7E6EEAB2F70EBA5"},"RGWP41":{"Limit internal frame rate (speed hack)":"64A43222F25CA56BC44ED3FF80B555B16E6B9822"},"RGWX41r0":{"Limit internal frame rate (speed hack)":"64A43222F25CA56BC44ED3FF80B555B16E6B9822"},"RGWX41r1":{"Limit internal frame rate (speed hack)":"AFB612191047500D6BE2ACC7B4E96E6B72941B39"},"RHO":{"60FPS":"5897530606A27FBE8C0079620923D8BC40AD3D0E"},"RJ2E52":{"Limit internal frame rate (speed hack)":"880DB9C1D639AA2ECD7AE6C96C93E8D83FBC38AF"},"RJ2JGD":{"Limit internal frame rate (speed hack)":"A387F6E3D973DCFD7D5A2E27183837358295B425"},"RJ2P52":{"Limit internal frame rate (speed hack)":"507BFC06E65A3C05D312305D44D1051A054003BF"},"RLEEFS":{"Fix crash on main menu":"793642AC6862C2F3412035A9E3D7172CC4A1D5C7"},"RM8E01":{"16:9 Widescreen":"E61344EB1542A78D497981C307B6549985C7A05A","Extra - Disable Music":"25223F9EFAABF601CAC7810004F124E4056598B1","QOL - Faster Boot Time":"BCC4279F8B28636AD773F01540E78DF40EAD6087","QOL - Increased Board Speed":"B65AF1819966CD3435D88801E8C79704E3A52DB5","QOL - Increased Taunt Capabilities":"66495D7CB532FAE778AFC22CF45D17D0FFDE5310","QOL - Increased Text Display":"B4186DDC54F33F4D6A22188EF50CEB43FB205673","QOL - Invert IR Stick for GameCube Mod":"9D90A9C66AE8AD91B201B40C4145D1323B701A77","QOL - Remove Explanations":"330DD53AB993A99576564FEFD222D7BD211B878F"},"RM8J01":{"16:9 Widescreen":"A140BDCB8E1721CB6B4CD878E412113322258B57"},"RM8P01":{"16:9 Widescreen":"F664C32AFD3D785FC6E04D8990A3FA1C72A18C5C"},"RMHE08":{"Bloom OFF":"CCF233DA57B3E75221870DE502955114B0D4E7FA"},"RMHJ08":{"Bloom OFF":"29D3625B7ED577587E56AA07CB0EB8C47C97E823"},"RMHP08":{"Bloom OFF":"1720C1173D4698167080DBFC4232F21757C4DA08"},"RO2P7N":{"Hangfix":"EEE9C8DE4671C18DD7F81DD08D39B64C57600DEA"},"RPBE01":{"Fix black screen effects":"775ABECA6073E02C5C68CF4D644194D966A418F5"},"RPBJ01r0":{"Fix black screen effects":"0EAB5D8DE827894AFEF97C10ACB67378E6983323"},"RPBJ01r1":{"Fix black screen effects":"4905E08643E9D00136F7EAF51978CF2F54D10D07"},"RPBJ01r2":{"Fix black screen effects":"4905E08643E9D00136F7EAF51978CF2F54D10D07"},"RPBP01":{"Fix black screen effects":"82AEB60F9A9083F93060531A970FFAABE0833A40"},"RQZ":{"Limit internal frame rate (speed hack)":"7B3B31BA970B319459C2E30B94E973CD1F2AE998"},"RRBE41r0":{"Idle loop speed hack":"20C7A2D4A3D6D55A8029A9D200D57CBD11F60B88"},"RRBE41r1":{"Idle loop speed hack":"0A30FA4C7E787197A00B7267368F372EFF623776"},"RRBE41r2":{"Idle loop speed hack":"2227787007F16F0CD454422AE6EB94656464B6D0"},"RRBJ41":{"Idle loop speed hack":"E9209EB728AA13375B2ABEF1C15D066DAFBF2EBF"},"RRBP41":{"Idle loop speed hack":"8A47BC311138EE3A11E049DF3EE6AED38990FB49"},"RTH":{"Disable blur":"812EE46AC967BFCD239335B10A664D71A93E8175"},"RUUE01r0":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"B62652D5BBE0701900090CFEB32003AE6E5A5015","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"244D1FC7D6284DC8832CF7F34506B0DE4DBF8914","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"6FDD09D51EC3D754BA7F80630B1FE1D3FEF6FE97","QOL - Disable Grass Deterioration":"D566F2AF5BB1EDB8284461DEA85FF3B5A8DEBDD6","QOL - Enable Fast Text":"C7D8A7926ED952A2797DA312B41B08DCCDC3A274"},"RUUE01r1":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"FC7BF1D6A5B4ED39EA4671C241E78F3BC8037E97","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"0235631B6F9A439B9718635F5AB7ADAFA2B6B3DE","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"5DEAC5F3390CE19487A9473A1988E7BB5EA4790F","QOL - Disable Grass Deterioration":"0FE1EF4DE5C8AE691E96634BC66BA034850C6C0F","QOL - Enable Fast Text":"B2BFF779434FDBEF08FFD73C4B140FCE0A8FDF0E"},"RUUJ01r1":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"D79F773E1363B694784C94DD309709D41D368A08","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"C88CFD7E6C18F570DE974D6C0202987E4F1B72C4","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"3C92010E7DE2E93C48AFF25B30A18BBFCBD12707","QOL - Enable Fast Text":"EFC4517A0915A19F1EC93BFBF91C501124857C18"},"RUUK01r1":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"1B89E8A6E6E09757373FF116BBC0989C06651709","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"EF883FB0C237BF51ABD88C35D34571D240C79484","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"F08D0F233F3F5833DFAFE5C8049C37D32360F0FA","QOL - Enable Fast Text":"EFC4517A0915A19F1EC93BFBF91C501124857C18"},"RUUP01r0":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"C55A5CDEF4C868E66C1FB2902D3285B2C350D7F1","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"D28D4E4FBD153A6D4C49E2D250213F37BEC941E5","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"80C3F50C018E076DF2CD39732A5ABB8A1C0E88B1","QOL - Disable Grass Deterioration":"3B278C19AC76D27488C55201BA0DB63864F66AAF","QOL - Enable Fast Text":"EFC4517A0915A19F1EC93BFBF91C501124857C18"},"RUUP01r1":{"QOL - Classic Controller Support (ACCF: Deluxe) v1.2":"00D994940AD323786A9DA780D1347AE5FBABAC8A","QOL - Classic Controller Support (GBAtemp - Left Stick Cursor) v1.1":"9121BEDD72436F4EAB47E4CE96ABD864118B22F3","QOL - Classic Controller Support (GBAtemp - Right Stick Cursor) v1.1":"8FC58B3DC4817515822EBB82BB7A8055270EE51D","QOL - Disable Grass Deterioration":"9B199D77AF748518358D32966F3F55F5C5759C3A","QOL - Enable Fast Text":"827CF5DFC90A258C36BF32DC3883371973E0B706"},"RX4E4Z":{"Fix file reads (dcache bypass)":"9E4E0F1465A9A1E85349DBA3B1278AC215A97DBB"},"RX4PMT":{"Fix file reads (dcache bypass)":"EE85907C03F0295794821383B93F8D5B91D2697A"},"RZDE01r0":{"Hyrule Field Speed Hack":"15EAD073414C9903D6CAE5229DCE582BD17A9162"},"RZDE01r2":{"Hyrule Field Speed Hack":"27395CC8BC2C51201D566657D31A471A850482FB"},"RZDJ01":{"Hyrule Field Speed Hack":"B3F7473F8C911A32F1D616491C9E78EBBD7A6309"},"RZDK01":{"Hyrule Field Speed Hack":"A280C0114B800D7DC056ECFB5E482229DA0B1550"},"RZDP01":{"Hyrule Field Speed Hack":"2A83ADFB760F9498841ED0ED68B0C0438232472C"},"SAOE78":{"Fix crash on boot":"EA11FA4908FB20B61876ACD360EC7657A6D39FB2"},"SAOEVZ":{"Fix crash on boot":"AA55C214DE7545DE0E203CC39F06BF3D31451BE9"},"SBDE08":{"60FPS":"A9E50FFAEBE9F262F5518BBCA73628BE727A445E"},"SBDP08":{"60FPS":"A9E50FFAEBE9F262F5518BBCA73628BE727A445E"},"SC2":{"Limit internal frame rate (speed hack)":"B3FB0FCE108E85E6198BAF3535850470049E2BE2"},"SCYE4Q":{"BAT Speedhack":"D702C348A02C6778BAB5851210A258E9AD53F8F5"},"SCYP4Q":{"BAT Speedhack":"D702C348A02C6778BAB5851210A258E9AD53F8F5"},"SCYR4Q":{"BAT Speedhack":"F90BDE3B7892FD161384FBC3CA72D05F8B6EB43C"},"SCYX4Q":{"BAT Speedhack":"91BAE02F25F4A12582800CDB93D213419CB146C0"},"SCYY4Q":{"BAT Speedhack":"CBD80E291536141196823032D867E002CFE8AA16"},"SCYZ4Q":{"BAT Speedhack":"CBD80E291536141196823032D867E002CFE8AA16"},"SGLEA4":{"Fix black screen":"258378187ACF475A55EFEAF8A703681252E014C3"},"SGLPA4":{"Fix black screen":"6F8CD59D897338CA90939149E1A62588620C6D88"},"SQIE4Q":{"BAT Speedhack":"37009D83FCAE2E26E93CB9AB2A99BACBECAE5010"},"SQIP4Q":{"BAT Speedhack":"37009D83FCAE2E26E93CB9AB2A99BACBECAE5010"},"SQIY4Q":{"BAT Speedhack":"37009D83FCAE2E26E93CB9AB2A99BACBECAE5010"},"STSE4Q":{"BAT Speedhack":"259F13AB4489F5B6EFD48F1D1F4A1FFDEFD6BB48"},"STSP4Qr1":{"BAT Speedhack":"259F13AB4489F5B6EFD48F1D1F4A1FFDEFD6BB48"},"STSP4Qr2":{"BAT Speedhack":"31A4FA663DD548275EE4D7241E51E3AA30B27136"},"STSX4Q":{"BAT Speedhack":"31A4FA663DD548275EE4D7241E51E3AA30B27136"},"STSY4Qr0":{"BAT Speedhack":"259F13AB4489F5B6EFD48F1D1F4A1FFDEFD6BB48"},"STSY4Qr1":{"BAT Speedhack":"31A4FA663DD548275EE4D7241E51E3AA30B27136"},"STSZ4Q":{"BAT Speedhack":"259F13AB4489F5B6EFD48F1D1F4A1FFDEFD6BB48"},"SVX":{"Idle loop speed hack":"5E57373BB0BBADF394E421FA9987CD90F354D19E"},"SX4E01":{"60 FPS":"206E79C5E9B5E07CEB7F52D0F5E5FF3400009265"},"WR2E41":{"Limit internal frame rate (speed hack)":"169567FB65FB2CCB0210213C6DAD65E9937AB9DB"},"WR2P41":{"Limit internal frame rate (speed hack)":"0F70B210236BE666004AB5681151242C22496DBB"}} \ No newline at end of file
diff --git a/Data/Sys/GameSettings/SDVE41.ini b/Data/Sys/GameSettings/SDVE41.ini
deleted file mode 100644
index 2d1fbde5de..0000000000
--- a/Data/Sys/GameSettings/SDVE41.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-# SDVE41 - Driver: San Francisco
-
-[OnFrame]
-$Limit internal frame rate (speed hack)
-# This NOPs a branch that skips a VIWaitForRetrace.
-0x803b40b8:dword:0x60000000
-
-[OnFrame_Enabled]
-$Limit internal frame rate (speed hack)
-
-[Patches_RetroAchievements_Verified]
-$Limit internal frame rate (speed hack)
diff --git a/Data/Sys/GameSettings/SDVP41.ini b/Data/Sys/GameSettings/SDVP41.ini
deleted file mode 100644
index b22b9dfb1a..0000000000
--- a/Data/Sys/GameSettings/SDVP41.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-# SDVP41 - Driver: San Francisco
-
-[OnFrame]
-$Limit internal frame rate (speed hack)
-# This NOPs a branch that skips a VIWaitForRetrace.
-0x803b2cdc:dword:0x60000000
-
-[OnFrame_Enabled]
-$Limit internal frame rate (speed hack)
-
-[Patches_RetroAchievements_Verified]
-$Limit internal frame rate (speed hack)
diff --git a/Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml.in b/Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml.in
index 28e0cb370b..cd00055a12 100644
--- a/Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml.in
+++ b/Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml.in
@@ -46,7 +46,4 @@
<url type="contact">https://dolphin-emu.org/docs/faq/#ive-got-idea-make-dolphin-better-how-should-i-tell</url>
<url type="vcs-browser">https://github.com/dolphin-emu/dolphin</url>
<url type="contribute">https://github.com/dolphin-emu/dolphin/blob/master/Contributing.md</url>
- <custom>
- <value key="flathub::manifest">https://github.com/dolphin-emu/dolphin/blob/${DOLPHIN_WC_REVISION}/Flatpak/org.DolphinEmu.dolphin-emu.yml</value>
- </custom>
</component>
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt
index dbcfdd42e2..e7ea8e5519 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.kt
@@ -61,13 +61,14 @@ class GameAdapter : RecyclerView.Adapter<GameViewHolder>(),
val gameFile = mGameFiles[position]
holder.apply {
+ val title = gameFile.getTitle(GameFileCacheManager.getTitleDatabase())
if (BooleanSetting.MAIN_SHOW_GAME_TITLES.boolean) {
- binding.textGameTitle.text = gameFile.getTitle()
+ binding.textGameTitle.text = title
binding.textGameTitle.visibility = View.VISIBLE
binding.textGameTitleInner.visibility = View.GONE
binding.textGameCaption.visibility = View.VISIBLE
} else {
- binding.textGameTitleInner.text = gameFile.getTitle()
+ binding.textGameTitleInner.text = title
binding.textGameTitleInner.visibility = View.VISIBLE
binding.textGameTitle.visibility = View.GONE
binding.textGameCaption.visibility = View.GONE
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt
index 4f43601e68..7cbb3000e2 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.kt
@@ -48,7 +48,7 @@ class GameRowPresenter : Presenter() {
holder.apply {
imageScreenshot.setImageDrawable(null)
- cardParent.titleText = gameFile.getTitle()
+ cardParent.titleText = gameFile.getTitle(GameFileCacheManager.getTitleDatabase())
holder.gameFile = gameFile
// Set the background color of the card
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt
index 0384da89c0..b97fd987e6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt
@@ -51,7 +51,7 @@ class GameDetailsDialog : DialogFragment() {
textTimePlayed.visibility = View.GONE
}
- textGameTitle.text = gameFile.getTitle()
+ textGameTitle.text = gameFile.getTitle(GameFileCacheManager.getTitleDatabase())
textDescription.text = gameFile.getDescription()
if (gameFile.getDescription().isEmpty()) {
textDescription.visibility = View.GONE
@@ -118,7 +118,7 @@ class GameDetailsDialog : DialogFragment() {
textTimePlayed.visibility = View.GONE
}
- textGameTitle.text = gameFile.getTitle()
+ textGameTitle.text = gameFile.getTitle(GameFileCacheManager.getTitleDatabase())
textDescription.text = gameFile.getDescription()
if (gameFile.getDescription().isEmpty()) {
tvBinding.textDescription.visibility = View.GONE
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
index c3602facf4..97f456c7a6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
@@ -112,6 +112,7 @@ import org.dolphinemu.dolphinemu.features.netplay.model.Player
import org.dolphinemu.dolphinemu.features.netplay.model.SaveTransferProgress
import org.dolphinemu.dolphinemu.features.netplay.model.TraversalState
import org.dolphinemu.dolphinemu.model.GameFile
+import org.dolphinemu.dolphinemu.services.GameFileCacheManager
import org.dolphinemu.dolphinemu.ui.theme.DolphinScaffold
import org.dolphinemu.dolphinemu.ui.theme.DolphinTheme
import org.dolphinemu.dolphinemu.ui.theme.MenuSpacer
@@ -855,6 +856,7 @@ private fun GameGridItem(
gameFile: GameFile,
onClick: () -> Unit,
) {
+ val titleDatabase = GameFileCacheManager.getTitleDatabase()
Card(
onClick = onClick,
) {
@@ -864,7 +866,7 @@ private fun GameGridItem(
.data(gameFile)
.error(R.drawable.no_banner)
.build(),
- contentDescription = gameFile.getTitle(),
+ contentDescription = gameFile.getTitle(titleDatabase),
contentScale = ContentScale.Crop,
imageLoader = CoilUtils.imageLoader,
modifier = Modifier
@@ -872,7 +874,7 @@ private fun GameGridItem(
.aspectRatio(0.7f)
)
Text(
- text = gameFile.getTitle(),
+ text = gameFile.getTitle(titleDatabase),
style = MaterialTheme.typography.bodySmall,
maxLines = 2,
minLines = 2,
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt
index 26da174285..4794f5c1b7 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt
@@ -12,7 +12,7 @@ class GameFile private constructor(private val pointer: Long) {
external fun getPlatform(): Int
- external fun getTitle(): String
+ external fun getTitle(titleDatabase: TitleDatabase?): String
external fun getDescription(): String
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TitleDatabase.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TitleDatabase.kt
new file mode 100644
index 0000000000..e5089673b8
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TitleDatabase.kt
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.dolphinemu.dolphinemu.model
+
+import androidx.annotation.Keep
+
+@Keep
+class TitleDatabase private constructor(private val pointer: Long) {
+ external fun finalize()
+
+ external fun userTitleMapEquals(other: TitleDatabase?): Boolean
+
+ companion object {
+ @JvmStatic
+ external suspend fun load(): TitleDatabase
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt
index 2ba2c246b3..a5e54aa0de 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/GameFileCacheManager.kt
@@ -2,32 +2,36 @@
package org.dolphinemu.dolphinemu.services
-import android.os.Handler
-import android.os.Looper
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.asFlow
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.MainScope
+import kotlinx.coroutines.async
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting
import org.dolphinemu.dolphinemu.features.settings.model.ConfigChangedCallback
import org.dolphinemu.dolphinemu.model.GameFile
import org.dolphinemu.dolphinemu.model.GameFileCache
+import org.dolphinemu.dolphinemu.model.TitleDatabase
import org.dolphinemu.dolphinemu.ui.platform.Platform
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner
import java.util.Arrays
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Executors
+import java.util.concurrent.atomic.AtomicReference
/**
- * Loads game list data on a separate thread.
+ * Loads game list data in the background.
*/
object GameFileCacheManager {
private var gameFileCache: GameFileCache? = null
private val gameFiles = MutableLiveData(emptyArray<GameFile>())
+ private var titleDatabase = AtomicReference<TitleDatabase>(null)
private var firstLoadDone = false
- private var runRescanAfterLoad = false
private var recursiveScanEnabled = false
- private val executor: ExecutorService = Executors.newFixedThreadPool(1)
private val loadInProgress = MutableLiveData(false)
private val rescanInProgress = MutableLiveData(false)
@@ -88,6 +92,8 @@ object GameFileCacheManager {
}
}
+ fun getTitleDatabase(): TitleDatabase? = titleDatabase.get()
+
/**
* Returns true if in the process of loading the cache for the first time.
*/
@@ -120,7 +126,9 @@ object GameFileCacheManager {
if (!loadInProgress.value!!) {
loadInProgress.value = true
- AfterDirectoryInitializationRunner().runWithoutLifecycle { executor.execute(::load) }
+ AfterDirectoryInitializationRunner().runWithoutLifecycle {
+ MainScope().launch { load() }
+ }
}
}
@@ -136,7 +144,9 @@ object GameFileCacheManager {
if (!rescanInProgress.value!!) {
rescanInProgress.value = true
- AfterDirectoryInitializationRunner().runWithoutLifecycle { executor.execute(::rescan) }
+ AfterDirectoryInitializationRunner().runWithoutLifecycle {
+ MainScope().launch { rescan() }
+ }
}
}
@@ -144,9 +154,9 @@ object GameFileCacheManager {
fun addOrGet(gamePath: String?): GameFile {
val nonNullGamePath = gamePath!!
- // Common case: The game is in the cache, so just grab it from there. (GameFileCache.addOrGet
+ // Common case: The game is in the cache, so we grab it from there. (GameFileCache.addOrGet
// actually already checks for this case, but we want to avoid calling it if possible
- // because the executor thread may hold a lock on gameFileCache for extended periods of time.)
+ // because rescan() may hold a lock on gameFileCache for extended periods of time.)
val allGames = gameFiles.value!!
for (game in allGames) {
if (game.getPath() == nonNullGamePath) {
@@ -165,28 +175,28 @@ object GameFileCacheManager {
* games are still present in the user's configured folders.
* If this has already been called, calling it again has no effect.
*/
- private fun load() {
+ private suspend fun load() {
if (!firstLoadDone) {
- firstLoadDone = true
- setUpAutomaticRescan()
- gameFileCache!!.load()
- if (gameFileCache!!.getSize() != 0) {
- updateGameFileArray()
+ val titleDatabaseJob = MainScope().async(Dispatchers.IO) {
+ TitleDatabase.load()
}
- }
- if (runRescanAfterLoad) {
- // Without this, there will be a short blip where the loading indicator in the GUI disappears
- // because neither loadInProgress nor rescanInProgress is true
- rescanInProgress.postValue(true)
- }
+ withContext(Dispatchers.IO) {
+ setUpAutomaticRescan()
+
+ gameFileCache!!.load()
+
+ titleDatabase.set(titleDatabaseJob.await())
- loadInProgress.postValue(false)
+ if (gameFileCache!!.getSize() != 0) {
+ updateGameFileArray()
+ }
+ }
- if (runRescanAfterLoad) {
- runRescanAfterLoad = false
- rescan()
+ firstLoadDone = true
}
+
+ loadInProgress.value = false
}
/**
@@ -195,19 +205,35 @@ object GameFileCacheManager {
* If load hasn't been called before this, the execution of this
* will be postponed until after load runs.
*/
- private fun rescan() {
- if (!firstLoadDone) {
- runRescanAfterLoad = true
- } else {
- val gamePaths = GameFileCache.getAllGamePaths()
+ private suspend fun rescan() {
+ while (!firstLoadDone) {
+ // Wait until loadInProgress becomes false
+ loadInProgress.asFlow().first { !it }
+ }
+ val titleDatabaseJob = MainScope().async(Dispatchers.IO) {
+ val newTitleDatabase = TitleDatabase.load()
+ val titleDatabaseChanged =
+ !newTitleDatabase.userTitleMapEquals(titleDatabase.get())
+ if (titleDatabaseChanged) newTitleDatabase else null
+ }
+
+ withContext(Dispatchers.IO) {
+ val gamePaths = GameFileCache.getAllGamePaths()
val changed = gameFileCache!!.update(gamePaths)
if (changed) {
updateGameFileArray()
}
val additionalMetadataChanged = gameFileCache!!.updateAdditionalMetadata()
- if (additionalMetadataChanged) {
+
+ val newTitleDatabase = titleDatabaseJob.await()
+ val titleDatabaseChanged = newTitleDatabase != null
+ if (titleDatabaseChanged) {
+ titleDatabase.set(newTitleDatabase)
+ }
+
+ if (additionalMetadataChanged || titleDatabaseChanged) {
updateGameFileArray()
}
@@ -216,13 +242,14 @@ object GameFileCacheManager {
}
}
- rescanInProgress.postValue(false)
+ rescanInProgress.value = false
}
private fun updateGameFileArray() {
val gameFilesTemp = gameFileCache!!.getAllGames()
+ val titleDatabase = titleDatabase.get()
Arrays.sort(gameFilesTemp) { lhs, rhs ->
- lhs.getTitle().compareTo(rhs.getTitle(), ignoreCase = true)
+ lhs.getTitle(titleDatabase).compareTo(rhs.getTitle(titleDatabase), ignoreCase = true)
}
gameFiles.postValue(gameFilesTemp)
}
@@ -239,10 +266,10 @@ object GameFileCacheManager {
private fun setUpAutomaticRescan() {
recursiveScanEnabled = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean
ConfigChangedCallback {
- Handler(Looper.getMainLooper()).post {
- val recursiveScanEnabled = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean
- if (this.recursiveScanEnabled != recursiveScanEnabled) {
- this.recursiveScanEnabled = recursiveScanEnabled
+ MainScope().launch {
+ val newRecursiveScanEnabled = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean
+ if (recursiveScanEnabled != newRecursiveScanEnabled) {
+ recursiveScanEnabled = newRecursiveScanEnabled
startRescan()
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt
index 2d9ad354fb..fd13ff3175 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncProgramsJobService.kt
@@ -138,7 +138,10 @@ class SyncProgramsJobService : JobService() {
TvContractCompat.PreviewPrograms.COLUMN_TYPE,
TvContractCompat.PreviewProgramColumns.TYPE_GAME
)
- values.put(TvContract.Programs.COLUMN_TITLE, game.getTitle())
+ values.put(
+ TvContract.Programs.COLUMN_TITLE,
+ game.getTitle(GameFileCacheManager.getTitleDatabase())
+ )
values.put(TvContract.Programs.COLUMN_SHORT_DESCRIPTION, game.getDescription())
values.put(TvContract.Programs.COLUMN_POSTER_ART_URI, banner.toString())
values.put(
diff --git a/Source/Android/jni/AndroidCommon/IDCache.cpp b/Source/Android/jni/AndroidCommon/IDCache.cpp
index 58cec02308..8d774dbbd9 100644
--- a/Source/Android/jni/AndroidCommon/IDCache.cpp
+++ b/Source/Android/jni/AndroidCommon/IDCache.cpp
@@ -151,6 +151,10 @@ static jclass s_audio_utils_class;
static jmethodID s_audio_utils_get_sample_rate;
static jmethodID s_audio_utils_get_frames_per_buffer;
+static jclass s_title_database_class;
+static jfieldID s_title_database_pointer;
+static jmethodID s_title_database_constructor;
+
namespace IDCache
{
JNIEnv* GetEnvForThread()
@@ -721,6 +725,21 @@ jmethodID GetAudioUtilsGetFramesPerBuffer()
return s_audio_utils_get_frames_per_buffer;
}
+jclass GetTitleDatabaseClass()
+{
+ return s_title_database_class;
+}
+
+jfieldID GetTitleDatabasePointer()
+{
+ return s_title_database_pointer;
+}
+
+jmethodID GetTitleDatabaseConstructor()
+{
+ return s_title_database_constructor;
+}
+
} // namespace IDCache
extern "C" {
@@ -1015,6 +1034,13 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
env->GetStaticMethodID(audio_utils_class, "getFramesPerBuffer", "()I");
env->DeleteLocalRef(audio_utils_class);
+ const jclass title_database_class =
+ env->FindClass("org/dolphinemu/dolphinemu/model/TitleDatabase");
+ s_title_database_class = reinterpret_cast<jclass>(env->NewGlobalRef(title_database_class));
+ s_title_database_pointer = env->GetFieldID(title_database_class, "pointer", "J");
+ s_title_database_constructor = env->GetMethodID(title_database_class, "<init>", "(J)V");
+ env->DeleteLocalRef(title_database_class);
+
return JNI_VERSION;
}
diff --git a/Source/Android/jni/AndroidCommon/IDCache.h b/Source/Android/jni/AndroidCommon/IDCache.h
index 43c4f43585..1483b3bbd3 100644
--- a/Source/Android/jni/AndroidCommon/IDCache.h
+++ b/Source/Android/jni/AndroidCommon/IDCache.h
@@ -150,4 +150,8 @@ jclass GetAudioUtilsClass();
jmethodID GetAudioUtilsGetSampleRate();
jmethodID GetAudioUtilsGetFramesPerBuffer();
+jclass GetTitleDatabaseClass();
+jfieldID GetTitleDatabasePointer();
+jmethodID GetTitleDatabaseConstructor();
+
} // namespace IDCache
diff --git a/Source/Android/jni/CMakeLists.txt b/Source/Android/jni/CMakeLists.txt
index a7ee0b6b3a..59e1e1138e 100644
--- a/Source/Android/jni/CMakeLists.txt
+++ b/Source/Android/jni/CMakeLists.txt
@@ -13,6 +13,8 @@ add_library(main SHARED
GameList/GameFile.cpp
GameList/GameFile.h
GameList/GameFileCache.cpp
+ GameList/TitleDatabase.cpp
+ GameList/TitleDatabase.h
GpuDriver.cpp
HotkeyScheduler.cpp
HotkeyScheduler.h
diff --git a/Source/Android/jni/GameList/GameFile.cpp b/Source/Android/jni/GameList/GameFile.cpp
index dc922d701c..e13f5c810a 100644
--- a/Source/Android/jni/GameList/GameFile.cpp
+++ b/Source/Android/jni/GameList/GameFile.cpp
@@ -16,6 +16,7 @@
#include "UICommon/GameFile.h"
#include "jni/AndroidCommon/AndroidCommon.h"
#include "jni/AndroidCommon/IDCache.h"
+#include "jni/GameList/TitleDatabase.h"
static std::shared_ptr<const UICommon::GameFile>* GetPointer(JNIEnv* env, jobject obj)
{
@@ -52,11 +53,19 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getPlatform
return static_cast<jint>(GetRef(env, obj)->GetPlatform());
}
-JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getTitle(JNIEnv* env,
- jobject obj)
+JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getTitle(
+ JNIEnv* env, jobject obj, jobject j_title_database)
{
- return ToJString(env,
- GetRef(env, obj)->GetName(UICommon::GameFile::Variant::LongAndPossiblyCustom));
+ const Core::TitleDatabase* title_database = TitleDatabaseFromJava(env, j_title_database);
+ if (title_database)
+ {
+ return ToJString(env, GetRef(env, obj)->GetName(*title_database));
+ }
+ else
+ {
+ return ToJString(env,
+ GetRef(env, obj)->GetName(UICommon::GameFile::Variant::LongAndPossiblyCustom));
+ }
}
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getDescription(JNIEnv* env,
diff --git a/Source/Android/jni/GameList/TitleDatabase.cpp b/Source/Android/jni/GameList/TitleDatabase.cpp
new file mode 100644
index 0000000000..c4aca48a25
--- /dev/null
+++ b/Source/Android/jni/GameList/TitleDatabase.cpp
@@ -0,0 +1,37 @@
+// Copyright 2026 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "jni/GameList/TitleDatabase.h"
+
+#include <jni.h>
+
+#include "Core/TitleDatabase.h"
+#include "jni/AndroidCommon/IDCache.h"
+
+Core::TitleDatabase* TitleDatabaseFromJava(JNIEnv* env, jobject obj)
+{
+ return reinterpret_cast<Core::TitleDatabase*>(
+ env->GetLongField(obj, IDCache::GetTitleDatabasePointer()));
+}
+extern "C" {
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_model_TitleDatabase_finalize(JNIEnv* env,
+ jobject obj)
+{
+ delete TitleDatabaseFromJava(env, obj);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_model_TitleDatabase_userTitleMapEquals(
+ JNIEnv* env, jobject obj, jobject other)
+{
+ return other != nullptr && TitleDatabaseFromJava(env, obj)->GetUserTitleMap() ==
+ TitleDatabaseFromJava(env, other)->GetUserTitleMap();
+}
+
+JNIEXPORT jobject JNICALL Java_org_dolphinemu_dolphinemu_model_TitleDatabase_load(JNIEnv* env,
+ jclass)
+{
+ return env->NewObject(IDCache::GetTitleDatabaseClass(), IDCache::GetTitleDatabaseConstructor(),
+ reinterpret_cast<jlong>(new Core::TitleDatabase));
+}
+}
diff --git a/Source/Android/jni/GameList/TitleDatabase.h b/Source/Android/jni/GameList/TitleDatabase.h
new file mode 100644
index 0000000000..fcf8f9bf32
--- /dev/null
+++ b/Source/Android/jni/GameList/TitleDatabase.h
@@ -0,0 +1,13 @@
+// Copyright 2026 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <jni.h>
+
+namespace Core
+{
+class TitleDatabase;
+}
+
+Core::TitleDatabase* TitleDatabaseFromJava(JNIEnv* env, jobject obj);
diff --git a/Source/Core/Core/HW/DVD/AMMediaboard.cpp b/Source/Core/Core/HW/DVD/AMMediaboard.cpp
index 272e5a12ff..0b3475ac31 100644
--- a/Source/Core/Core/HW/DVD/AMMediaboard.cpp
+++ b/Source/Core/Core/HW/DVD/AMMediaboard.cpp
@@ -1075,7 +1075,7 @@ static void AMMBCommandClosesocket(u32 parameter_offset)
s_sockets[u32(guest_socket)] = SOCKET_ERROR;
s_media_buffer_32[1] = ret;
- s_last_error = SSC_SUCCESS;
+ s_last_error = ret == 0 ? SSC_SUCCESS : SSC_EBADF;
}
static void AMMBCommandConnect(u32 parameter_offset)
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceGecko.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceGecko.cpp
index 06e90f83b0..5d58f4a926 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceGecko.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceGecko.cpp
@@ -19,7 +19,6 @@
namespace ExpansionInterface
{
-u16 GeckoSockServer::server_port;
int GeckoSockServer::client_count;
std::thread GeckoSockServer::connectionThread;
Common::Flag GeckoSockServer::server_running;
@@ -54,8 +53,10 @@ void GeckoSockServer::GeckoConnectionWaiter()
Common::SetCurrentThreadName("Gecko Connection Waiter");
sf::TcpListener server;
- server_port = 0xd6ec; // "dolphin gecko"
- for (int bind_tries = 0; bind_tries <= 10 && !server_running.IsSet(); bind_tries++)
+ constexpr u16 initial_port = 0xd6ec; // "dolphin gecko"
+ constexpr int port_retries = 10;
+ u16 server_port = initial_port;
+ for (int bind_tries = 0; bind_tries <= port_retries && !server_running.IsSet(); bind_tries++)
{
server_running.Set(server.listen(server_port) == sf::Socket::Status::Done);
if (!server_running.IsSet())
@@ -63,7 +64,13 @@ void GeckoSockServer::GeckoConnectionWaiter()
}
if (!server_running.IsSet())
+ {
+ const std::string message = fmt::format("USBGecko: Failed to bind to any port in range {}-{}",
+ initial_port, initial_port + port_retries);
+ ERROR_LOG_FMT(EXPANSIONINTERFACE, "{}", message);
+ Core::DisplayMessage(message, 5000);
return;
+ }
Core::DisplayMessage(fmt::format("USBGecko: Listening on TCP port {}", server_port), 5000);
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceGecko.h b/Source/Core/Core/HW/EXI/EXI_DeviceGecko.h
index 6bed93b3a4..59a8041294 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceGecko.h
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceGecko.h
@@ -39,7 +39,6 @@ private:
// Only ever one server thread
static void GeckoConnectionWaiter();
- static u16 server_port;
static Common::Flag server_running;
static std::thread connectionThread;
static std::mutex connection_lock;
diff --git a/Source/Core/Core/TitleDatabase.cpp b/Source/Core/Core/TitleDatabase.cpp
index 41ad0e0e7e..cd10bb591f 100644
--- a/Source/Core/Core/TitleDatabase.cpp
+++ b/Source/Core/Core/TitleDatabase.cpp
@@ -135,4 +135,9 @@ std::string TitleDatabase::Describe(const std::string& gametdb_id, DiscIO::Langu
return gametdb_id;
return fmt::format("{} ({})", title_name, gametdb_id);
}
+
+const std::unordered_map<std::string, std::string>& TitleDatabase::GetUserTitleMap() const
+{
+ return m_user_title_map;
+}
} // namespace Core
diff --git a/Source/Core/Core/TitleDatabase.h b/Source/Core/Core/TitleDatabase.h
index d1163d80a6..977ab5d0e8 100644
--- a/Source/Core/Core/TitleDatabase.h
+++ b/Source/Core/Core/TitleDatabase.h
@@ -33,6 +33,8 @@ public:
// Get a description for a GameTDB ID (title name if available + GameTDB ID).
std::string Describe(const std::string& gametdb_id, DiscIO::Language language) const;
+ const std::unordered_map<std::string, std::string>& GetUserTitleMap() const;
+
private:
void AddLazyMap(DiscIO::Language language, const std::string& language_code);
diff --git a/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipWidget.h b/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipWidget.h
index 94cd88b87e..cbcbccefd7 100644
--- a/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipWidget.h
+++ b/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipWidget.h
@@ -6,6 +6,7 @@
#include <optional>
#include <QString>
+#include <QTimerEvent>
#include "DolphinQt/Config/ToolTipControls/BalloonTip.h"
@@ -57,12 +58,14 @@ private:
void timerEvent(QTimerEvent* const event) override
{
- this->killTimer(*m_timer_id);
- m_timer_id.reset();
-
- BalloonTip::ShowBalloon(m_title, m_description,
- this->parentWidget()->mapToGlobal(GetToolTipPosition()), this);
+ if (m_timer_id == event->timerId())
+ {
+ this->killTimer(*m_timer_id);
+ m_timer_id.reset();
+ BalloonTip::ShowBalloon(m_title, m_description,
+ this->parentWidget()->mapToGlobal(GetToolTipPosition()), this);
+ }
Derived::timerEvent(event);
}
diff --git a/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp b/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp
index c88fee33ee..d9be7faf2f 100644
--- a/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DVertexManager.cpp
@@ -255,7 +255,10 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, vertexBufferSize);
ADDSTAT(g_stats.this_frame.bytes_index_streamed, indexBufferSize);
+}
+void VertexManager::BindCommittedBuffer(u32 vertex_stride)
+{
D3D::stateman->SetVertexBuffer(m_buffers[m_current_buffer].Get(), vertex_stride, 0);
D3D::stateman->SetIndexBuffer(m_buffers[m_current_buffer].Get());
}
diff --git a/Source/Core/VideoBackends/D3D/D3DVertexManager.h b/Source/Core/VideoBackends/D3D/D3DVertexManager.h
index ef7c4a9191..37374f6ec3 100644
--- a/Source/Core/VideoBackends/D3D/D3DVertexManager.h
+++ b/Source/Core/VideoBackends/D3D/D3DVertexManager.h
@@ -51,6 +51,7 @@ protected:
void ResetBuffer(u32 vertex_stride) override;
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
u32* out_base_index) override;
+ void BindCommittedBuffer(u32 vertex_stride) override;
void UploadUniforms() override;
private:
diff --git a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp
index 4565db29bd..5366110ecc 100644
--- a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp
+++ b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp
@@ -128,7 +128,10 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, static_cast<int>(vertex_data_size));
ADDSTAT(g_stats.this_frame.bytes_index_streamed, static_cast<int>(index_data_size));
+}
+void VertexManager::BindCommittedBuffer(u32 vertex_stride)
+{
Gfx::GetInstance()->SetVertexBuffer(m_vertex_stream_buffer.GetGPUPointer(),
m_vertex_srv.cpu_handle, vertex_stride,
m_vertex_stream_buffer.GetSize());
diff --git a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.h b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.h
index 76c0c6d7cb..d7479b0c56 100644
--- a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.h
+++ b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.h
@@ -30,6 +30,7 @@ protected:
void ResetBuffer(u32 vertex_stride) override;
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
u32* out_base_index) override;
+ void BindCommittedBuffer(u32 vertex_stride) override;
void UploadUniforms() override;
void UpdateVertexShaderConstants();
diff --git a/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp b/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
index c5382cf358..614d066a5b 100644
--- a/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLVertexManager.cpp
@@ -177,7 +177,6 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
*out_base_vertex = vertex_stride > 0 ? (m_vertex_buffer->GetCurrentOffset() / vertex_stride) : 0;
*out_base_index = m_index_buffer->GetCurrentOffset() / sizeof(u16);
- CheckBufferBinding();
m_vertex_buffer->Unmap(vertex_data_size);
m_index_buffer->Unmap(index_data_size);
@@ -185,6 +184,11 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
ADDSTAT(g_stats.this_frame.bytes_index_streamed, index_data_size);
}
+void VertexManager::BindCommittedBuffer(u32 /*vertex_stride*/)
+{
+ CheckBufferBinding();
+}
+
void VertexManager::UploadUniforms()
{
ProgramShaderCache::UploadConstants();
diff --git a/Source/Core/VideoBackends/OGL/OGLVertexManager.h b/Source/Core/VideoBackends/OGL/OGLVertexManager.h
index 55a3ef14ad..14111693f4 100644
--- a/Source/Core/VideoBackends/OGL/OGLVertexManager.h
+++ b/Source/Core/VideoBackends/OGL/OGLVertexManager.h
@@ -47,6 +47,7 @@ protected:
void ResetBuffer(u32 vertex_stride) override;
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
u32* out_base_index) override;
+ void BindCommittedBuffer(u32 vertex_stride) override;
void UploadUniforms() override;
private:
diff --git a/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp b/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp
index 18c5ad560c..ea8a1d090a 100644
--- a/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKVertexManager.cpp
@@ -184,7 +184,10 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in
ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, static_cast<int>(vertex_data_size));
ADDSTAT(g_stats.this_frame.bytes_index_streamed, static_cast<int>(index_data_size));
+}
+void VertexManager::BindCommittedBuffer(u32 /*vertex_stride*/)
+{
StateTracker::GetInstance()->SetVertexBuffer(m_vertex_stream_buffer->GetBuffer(), 0,
VERTEX_STREAM_BUFFER_SIZE);
StateTracker::GetInstance()->SetIndexBuffer(m_index_stream_buffer->GetBuffer(), 0,
diff --git a/Source/Core/VideoBackends/Vulkan/VKVertexManager.h b/Source/Core/VideoBackends/Vulkan/VKVertexManager.h
index 75d35c0d32..f00ac47e93 100644
--- a/Source/Core/VideoBackends/Vulkan/VKVertexManager.h
+++ b/Source/Core/VideoBackends/Vulkan/VKVertexManager.h
@@ -33,6 +33,7 @@ protected:
void ResetBuffer(u32 vertex_stride) override;
void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices, u32* out_base_vertex,
u32* out_base_index) override;
+ void BindCommittedBuffer(u32 vertex_stride) override;
void UploadUniforms() override;
void DestroyTexelBufferViews();
diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp
index f3f27518bf..7c1f9166ce 100644
--- a/Source/Core/VideoCommon/VertexManagerBase.cpp
+++ b/Source/Core/VideoCommon/VertexManagerBase.cpp
@@ -343,6 +343,10 @@ void VertexManagerBase::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 nu
*out_base_index = 0;
}
+void VertexManagerBase::BindCommittedBuffer(u32)
+{
+}
+
void VertexManagerBase::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_vertex)
{
// If bounding box is enabled, we need to flush any changes first, then invalidate what we have.
@@ -393,6 +397,7 @@ void VertexManagerBase::UploadUtilityVertices(const void* vertices, u32 vertex_s
m_index_generator.AddExternalIndices(indices, num_indices, num_vertices);
CommitBuffer(num_vertices, vertex_stride, num_indices, out_base_vertex, out_base_index);
+ BindCommittedBuffer(vertex_stride);
}
u32 VertexManagerBase::GetTexelBufferElementSize(TexelBufferFormat buffer_format)
@@ -560,6 +565,7 @@ void VertexManagerBase::Flush()
std::vector<std::string> texture_names;
Common::SmallVector<u32, 8> texture_units;
std::array<SamplerState, 8> samplers;
+ Common::SmallVector<SubmittedSampledTexture, 8> sampled_textures;
if (!m_cull_all)
{
if (!g_ActiveConfig.bGraphicMods)
@@ -572,6 +578,9 @@ void VertexManagerBase::Flush()
const float custom_tex_scale = cache_entry->GetWidth() / float(cache_entry->native_width);
samplers[i] = TextureCacheBase::GetSamplerState(
i, custom_tex_scale, cache_entry->is_custom_tex, cache_entry->has_arbitrary_mips);
+
+ sampled_textures.push_back(
+ SubmittedSampledTexture{.entry = cache_entry, .sampler = samplers[i], .index = i});
}
}
else
@@ -590,6 +599,9 @@ void VertexManagerBase::Flush()
const float custom_tex_scale = cache_entry->GetWidth() / float(cache_entry->native_width);
samplers[i] = TextureCacheBase::GetSamplerState(
i, custom_tex_scale, cache_entry->is_custom_tex, cache_entry->has_arbitrary_mips);
+
+ sampled_textures.push_back(
+ SubmittedSampledTexture{.entry = cache_entry, .sampler = samplers[i], .index = i});
}
}
}
@@ -633,8 +645,8 @@ void VertexManagerBase::Flush()
UpdatePipelineObject();
if (m_current_pipeline_object)
{
- RenderDrawCall(pixel_shader_manager, geometry_shader_manager, m_current_primitive_type,
- m_current_pipeline_object);
+ ProcessEmulatedMesh(pixel_shader_manager, geometry_shader_manager,
+ m_current_pipeline_object, sampled_textures);
}
}
@@ -1023,25 +1035,54 @@ void VertexManagerBase::OnEndFrame()
InvalidatePipelineObject();
}
-void VertexManagerBase::RenderDrawCall(PixelShaderManager& pixel_shader_manager,
- GeometryShaderManager& geometry_shader_manager,
- PrimitiveType primitive_type,
- const AbstractPipeline* current_pipeline)
+void VertexManagerBase::ProcessEmulatedMesh(
+ PixelShaderManager& pixel_shader_manager, GeometryShaderManager& geometry_shader_manager,
+ const AbstractPipeline* pipeline, std::span<const SubmittedSampledTexture> sampled_textures)
{
- // Now we can upload uniforms, as nothing else will override them.
- geometry_shader_manager.SetConstants(primitive_type);
+ geometry_shader_manager.SetConstants(m_current_primitive_type);
pixel_shader_manager.SetConstants();
- UploadUniforms();
- g_gfx->SetPipeline(current_pipeline);
+ const u32 vertex_stride = VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride();
+ const u32 index_size = m_index_generator.GetIndexLen();
u32 base_vertex, base_index;
- CommitBuffer(m_index_generator.GetNumVerts(),
- VertexLoaderManager::GetCurrentVertexFormat()->GetVertexStride(),
- m_index_generator.GetIndexLen(), &base_vertex, &base_index);
+ CommitBuffer(m_index_generator.GetNumVerts(), vertex_stride, index_size, &base_vertex,
+ &base_index);
+
+ SubmittedDrawCallData draw_call_data;
+ draw_call_data.pipeline = pipeline;
+ draw_call_data.frame_buffer = g_gfx->GetCurrentFramebuffer();
+ draw_call_data.base_index = base_index;
+ draw_call_data.base_vertex = base_vertex;
+ draw_call_data.index_size = index_size;
+ draw_call_data.vertex_stride = vertex_stride;
+ draw_call_data.primitive_type = m_current_primitive_type;
+ for (const SubmittedSampledTexture& texture : sampled_textures)
+ draw_call_data.textures.emplace_back(texture);
+
+ DrawSubmittedDrawData(g_framebuffer_manager.get(), draw_call_data);
+}
+
+void VertexManagerBase::DrawSubmittedDrawData(FramebufferManager* /*framebuffer_manager*/,
+ const SubmittedDrawCallData& draw_call_data)
+{
+ BindCommittedBuffer(draw_call_data.vertex_stride);
+
+ // Now we can upload uniforms, as nothing else will override them.
+ UploadUniforms();
+
+ g_gfx->SetPipeline(draw_call_data.pipeline);
+
+ for (const SubmittedSampledTexture& texture : draw_call_data.textures)
+ {
+ g_gfx->SetTexture(texture.index, texture.entry->texture.get());
+ g_gfx->SetSamplerState(texture.index, texture.sampler);
+ }
+ u32 base_vertex = draw_call_data.base_vertex;
if (g_backend_info.api_type != APIType::D3D && g_ActiveConfig.UseVSForLinePointExpand() &&
- (primitive_type == PrimitiveType::Points || primitive_type == PrimitiveType::Lines))
+ (draw_call_data.primitive_type == PrimitiveType::Points ||
+ draw_call_data.primitive_type == PrimitiveType::Lines))
{
// VS point/line expansion puts the vertex id at gl_VertexID << 2
// That means the base vertex has to be adjusted to match
@@ -1052,7 +1093,7 @@ void VertexManagerBase::RenderDrawCall(PixelShaderManager& pixel_shader_manager,
if (PerfQueryBase::ShouldEmulate())
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
- DrawCurrentBatch(base_index, m_index_generator.GetIndexLen(), base_vertex);
+ DrawCurrentBatch(draw_call_data.base_index, draw_call_data.index_size, base_vertex);
// Track the total emulated state draws
INCSTAT(g_stats.this_frame.num_draw_calls);
diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h
index 8397efe707..84d0c54460 100644
--- a/Source/Core/VideoCommon/VertexManagerBase.h
+++ b/Source/Core/VideoCommon/VertexManagerBase.h
@@ -4,18 +4,23 @@
#pragma once
#include <memory>
+#include <span>
#include <vector>
#include "Common/BitSet.h"
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
+#include "Common/SmallVector.h"
#include "VideoCommon/CPUCull.h"
#include "VideoCommon/IndexGenerator.h"
#include "VideoCommon/RenderState.h"
#include "VideoCommon/ShaderCache.h"
+#include "VideoCommon/TextureCacheBase.h"
#include "VideoCommon/VideoEvents.h"
+class AbstractFramebuffer;
class DataReader;
+class FramebufferManager;
class GeometryShaderManager;
class NativeVertexFormat;
class PixelShaderManager;
@@ -168,6 +173,29 @@ public:
// Call at the end of a frame.
void OnEndFrame();
+ struct SubmittedSampledTexture
+ {
+ RcTcacheEntry entry;
+ SamplerState sampler;
+ u32 index = 0;
+ };
+
+ struct SubmittedDrawCallData
+ {
+ const AbstractPipeline* pipeline = nullptr;
+ AbstractFramebuffer* frame_buffer = nullptr;
+ u32 base_index = 0;
+ u32 base_vertex = 0;
+ u32 index_size = 0;
+ u32 vertex_stride = 0;
+ PrimitiveType primitive_type = PrimitiveType::Points;
+ Common::SmallVector<SubmittedSampledTexture, 8> textures;
+ };
+
+ // Executes a previously captured draw call.
+ void DrawSubmittedDrawData(FramebufferManager* framebuffer_manager,
+ const SubmittedDrawCallData& draw_call_data);
+
protected:
// When utility uniforms are used, the GX uniforms need to be re-written afterwards.
static void InvalidateConstants();
@@ -179,6 +207,11 @@ protected:
virtual void CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_indices,
u32* out_base_vertex, u32* out_base_index);
+ // Binds the buffers most recently committed, so that a draw can be issued against them.
+ // Separated from CommitBuffer so that draws can rebind the buffers if the draws
+ // are triggered independently
+ virtual void BindCommittedBuffer(u32 vertex_stride);
+
// Uploads uniform buffers for GX draws.
virtual void UploadUniforms();
@@ -220,9 +253,10 @@ private:
// Minimum number of draws per command buffer when attempting to preempt a readback operation.
static constexpr u32 MINIMUM_DRAW_CALLS_PER_COMMAND_BUFFER_FOR_READBACK = 10;
- void RenderDrawCall(PixelShaderManager& pixel_shader_manager,
- GeometryShaderManager& geometry_shader_manager, PrimitiveType primitive_type,
- const AbstractPipeline* current_pipeline);
+ void ProcessEmulatedMesh(PixelShaderManager& pixel_shader_manager,
+ GeometryShaderManager& geometry_shader_manager,
+ const AbstractPipeline* pipeline,
+ std::span<const SubmittedSampledTexture> sampled_textures);
void UpdatePipelineConfig();
void UpdatePipelineObject();