diff --git a/Data/User/GameConfig/GFZE01.ini b/Data/User/GameConfig/GFZE01.ini index dbdf33b12a..eb92d8aa74 100644 --- a/Data/User/GameConfig/GFZE01.ini +++ b/Data/User/GameConfig/GFZE01.ini @@ -4,7 +4,6 @@ # Values set here will override the main dolphin settings. EnableFPRF = True TLBHack = 1 -SyncGPU = 1 [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. diff --git a/Data/User/GameConfig/GFZJ01.ini b/Data/User/GameConfig/GFZJ01.ini index 22a0191407..eae0416fb7 100644 --- a/Data/User/GameConfig/GFZJ01.ini +++ b/Data/User/GameConfig/GFZJ01.ini @@ -4,7 +4,6 @@ # Values set here will override the main dolphin settings. EnableFPRF = True TLBHack = 1 -SyncGPU = 1 [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. diff --git a/Data/User/GameConfig/GFZP01.ini b/Data/User/GameConfig/GFZP01.ini index d14cc8a11d..08ad0e44e6 100644 --- a/Data/User/GameConfig/GFZP01.ini +++ b/Data/User/GameConfig/GFZP01.ini @@ -4,7 +4,6 @@ # Values set here will override the main dolphin settings. EnableFPRF = True TLBHack = 1 -SyncGPU = 1 [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. diff --git a/Data/User/GameConfig/GK2D52.ini b/Data/User/GameConfig/GK2D52.ini new file mode 100644 index 0000000000..d8267fbc92 --- /dev/null +++ b/Data/User/GameConfig/GK2D52.ini @@ -0,0 +1,18 @@ +# GK2D52 - Spider-Man 2 +[Core] +MMU = 1 +[EmuState] +EmulationStateId = 4 +EmulationIssues = Slow because it needs mmu to run. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/GK2E52.ini b/Data/User/GameConfig/GK2E52.ini new file mode 100644 index 0000000000..23d53c182b --- /dev/null +++ b/Data/User/GameConfig/GK2E52.ini @@ -0,0 +1,18 @@ +# GK2E52 - Spider-Man 2 +[Core] +MMU = 1 +[EmuState] +EmulationStateId = 4 +EmulationIssues = Slow because it needs mmu to run. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/GK2F52.ini b/Data/User/GameConfig/GK2F52.ini new file mode 100644 index 0000000000..0b05c6d201 --- /dev/null +++ b/Data/User/GameConfig/GK2F52.ini @@ -0,0 +1,18 @@ +# GK2F52 - Spider-Man 2 +[Core] +MMU = 1 +[EmuState] +EmulationStateId = 4 +EmulationIssues = Slow because it needs mmu to run. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/GK2I52.ini b/Data/User/GameConfig/GK2I52.ini new file mode 100644 index 0000000000..0f733aac78 --- /dev/null +++ b/Data/User/GameConfig/GK2I52.ini @@ -0,0 +1,18 @@ +# GK2I52 - Spider-Man 2 +[Core] +MMU = 1 +[EmuState] +EmulationStateId = 4 +EmulationIssues = Slow because it needs mmu to run. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/GK2P52.ini b/Data/User/GameConfig/GK2P52.ini new file mode 100644 index 0000000000..32d0de3b03 --- /dev/null +++ b/Data/User/GameConfig/GK2P52.ini @@ -0,0 +1,18 @@ +# GK2P52 - Spider-Man 2 +[Core] +MMU = 1 +[EmuState] +EmulationStateId = 4 +EmulationIssues = Slow because it needs mmu to run. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/GOYP69.ini b/Data/User/GameConfig/GOYP69.ini new file mode 100644 index 0000000000..3128181698 --- /dev/null +++ b/Data/User/GameConfig/GOYP69.ini @@ -0,0 +1,31 @@ +# GOYP69 - GoldenEye Rogue Agent + +[Core] +# Values set here will override the main dolphin settings. +TLBHack = 1 + +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = Videos are messed up, skip them. +EmulationStateId = 4 + +[OnLoad] +# Add memory patches to be loaded once on boot here. + +[OnFrame] +# Add memory patches to be applied every frame here. + +[ActionReplay] +# Add action replay cheats here. + +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = + +[Video_Settings] +SafeTextureCacheColorSamples = 512 + diff --git a/Data/User/GameConfig/GOYS69.ini b/Data/User/GameConfig/GOYS69.ini new file mode 100644 index 0000000000..0c54f77e43 --- /dev/null +++ b/Data/User/GameConfig/GOYS69.ini @@ -0,0 +1,31 @@ +# GOYS69 - GoldenEye Rogue Agent + +[Core] +# Values set here will override the main dolphin settings. +TLBHack = 1 + +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = Videos are messed up, skip them. +EmulationStateId = 4 + +[OnLoad] +# Add memory patches to be loaded once on boot here. + +[OnFrame] +# Add memory patches to be applied every frame here. + +[ActionReplay] +# Add action replay cheats here. + +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = + +[Video_Settings] +SafeTextureCacheColorSamples = 512 + diff --git a/Data/User/GameConfig/GQCD52.ini b/Data/User/GameConfig/GQCD52.ini new file mode 100644 index 0000000000..bed0ef720c --- /dev/null +++ b/Data/User/GameConfig/GQCD52.ini @@ -0,0 +1,20 @@ +# GQCD52 - Call of Duty 2: Big Red One +[Core] +# Values set here will override the main dolphin settings. +MMU = 1 +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = Slow because it needs mmu to run. +EmulationStateId = 4 +[OnLoad] +# Add memory patches to be loaded once on boot here. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] \ No newline at end of file diff --git a/Data/User/GameConfig/GQCE52.ini b/Data/User/GameConfig/GQCE52.ini index c43660dae8..4d7a73a134 100644 --- a/Data/User/GameConfig/GQCE52.ini +++ b/Data/User/GameConfig/GQCE52.ini @@ -1,20 +1,20 @@ # GQCE52 - Call of Duty 2: Big Red One - [Core] # Values set here will override the main dolphin settings. -TLBHack = 1 - +MMU = 1 [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = Black screen +EmulationIssues = Slow because it needs mmu to run. EmulationStateId = 4 - [OnLoad] # Add memory patches to be loaded once on boot here. - [OnFrame] -# Add memory patches to be applied every frame here. - [ActionReplay] -# Add action replay cheats here. - +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GQCF52.ini b/Data/User/GameConfig/GQCF52.ini new file mode 100644 index 0000000000..29e4d50f68 --- /dev/null +++ b/Data/User/GameConfig/GQCF52.ini @@ -0,0 +1,20 @@ +# GQCF52 - Call of Duty 2: Big Red One +[Core] +# Values set here will override the main dolphin settings. +MMU = 1 +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = Slow because it needs mmu to run. +EmulationStateId = 4 +[OnLoad] +# Add memory patches to be loaded once on boot here. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] \ No newline at end of file diff --git a/Data/User/GameConfig/GQCI52.ini b/Data/User/GameConfig/GQCI52.ini new file mode 100644 index 0000000000..5c4a86a220 --- /dev/null +++ b/Data/User/GameConfig/GQCI52.ini @@ -0,0 +1,20 @@ +# GQCI52 - Call of Duty 2: Big Red One +[Core] +# Values set here will override the main dolphin settings. +MMU = 1 +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = Slow because it needs mmu to run. +EmulationStateId = 4 +[OnLoad] +# Add memory patches to be loaded once on boot here. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Geck \ No newline at end of file diff --git a/Data/User/GameConfig/GQCP52.ini b/Data/User/GameConfig/GQCP52.ini new file mode 100644 index 0000000000..68e6d65851 --- /dev/null +++ b/Data/User/GameConfig/GQCP52.ini @@ -0,0 +1,20 @@ +# GQCP52 - Call of Duty 2: Big Red One +[Core] +# Values set here will override the main dolphin settings. +MMU = 1 +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = Slow because it needs mmu to run. +EmulationStateId = 4 +[OnLoad] +# Add memory patches to be loaded once on boot here. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] \ No newline at end of file diff --git a/Data/User/GameConfig/GQCS52.ini b/Data/User/GameConfig/GQCS52.ini index 6f13ad7dbb..54fdb0d90b 100644 --- a/Data/User/GameConfig/GQCS52.ini +++ b/Data/User/GameConfig/GQCS52.ini @@ -1,18 +1,20 @@ # GQCS52 - Call of Duty 2: Big Red One - [Core] # Values set here will override the main dolphin settings. - +MMU = 1 [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = Slow because it needs mmu to run. EmulationStateId = 4 - [OnLoad] # Add memory patches to be loaded once on boot here. - [OnFrame] -# Add memory patches to be applied every frame here. - [ActionReplay] -# Add action replay cheats here. - +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GR8D69.ini b/Data/User/GameConfig/GR8D69.ini new file mode 100644 index 0000000000..e314d09dc9 --- /dev/null +++ b/Data/User/GameConfig/GR8D69.ini @@ -0,0 +1,20 @@ +# GR8D69 - Medal of Honor Rising Sun +[Core] +# Values set here will override the main dolphin settings. +TLBHack = 1 +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 3 +EmulationIssues = Videos are messed up, skip them. +[OnLoad] +# Add memory patches to be loaded once on boot here. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GR8E69.ini b/Data/User/GameConfig/GR8E69.ini index c2879a4b0c..9114a39003 100644 --- a/Data/User/GameConfig/GR8E69.ini +++ b/Data/User/GameConfig/GR8E69.ini @@ -1,18 +1,20 @@ # GR8E69 - Medal of Honor Rising Sun - [Core] # Values set here will override the main dolphin settings. - +TLBHack = 1 [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 3 - +EmulationIssues = Videos are messed up, skip them. [OnLoad] # Add memory patches to be loaded once on boot here. - [OnFrame] -# Add memory patches to be applied every frame here. - [ActionReplay] -# Add action replay cheats here. - +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GR8F69.ini b/Data/User/GameConfig/GR8F69.ini new file mode 100644 index 0000000000..4bf6f432ab --- /dev/null +++ b/Data/User/GameConfig/GR8F69.ini @@ -0,0 +1,20 @@ +# GR8F69 - Medal of Honor Rising Sun +[Core] +# Values set here will override the main dolphin settings. +TLBHack = 1 +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 3 +EmulationIssues = Videos are messed up, skip them. +[OnLoad] +# Add memory patches to be loaded once on boot here. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GR8J69.ini b/Data/User/GameConfig/GR8J69.ini new file mode 100644 index 0000000000..7b3a2e8d96 --- /dev/null +++ b/Data/User/GameConfig/GR8J69.ini @@ -0,0 +1,20 @@ +# GR8J69 - Medal of Honor Rising Sun +[Core] +# Values set here will override the main dolphin settings. +TLBHack = 1 +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 3 +EmulationIssues = Videos are messed up, skip them. +[OnLoad] +# Add memory patches to be loaded once on boot here. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GR8P69.ini b/Data/User/GameConfig/GR8P69.ini new file mode 100644 index 0000000000..47e646f884 --- /dev/null +++ b/Data/User/GameConfig/GR8P69.ini @@ -0,0 +1,20 @@ +# GR8P69 - Medal of Honor Rising Sun +[Core] +# Values set here will override the main dolphin settings. +TLBHack = 1 +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 3 +EmulationIssues = Videos are messed up, skip them. +[OnLoad] +# Add memory patches to be loaded once on boot here. +[OnFrame] +[ActionReplay] +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GWJE52.ini b/Data/User/GameConfig/GWJE52.ini index 9617e3876c..02db0d617d 100644 --- a/Data/User/GameConfig/GWJE52.ini +++ b/Data/User/GameConfig/GWJE52.ini @@ -1,20 +1,21 @@ # GWJE52 - Tony Hawk's American Wasteland - [Core] # Values set here will override the main dolphin settings. -TLBHack=1 - +MMU = 1 [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 3 Issues="Error to compile...DC error?" - +EmulationIssues = Slow because it needs mmu to run. [OnLoad] # Add memory patches to be loaded once on boot here. - [OnFrame] -# Add memory patches to be applied every frame here. - [ActionReplay] -# Add action replay cheats here. - +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Externals/OpenAL/Win32/OpenAL32.dll b/Externals/OpenAL/Win32/OpenAL32.dll index b63bb2f301..71ced6a21f 100644 Binary files a/Externals/OpenAL/Win32/OpenAL32.dll and b/Externals/OpenAL/Win32/OpenAL32.dll differ diff --git a/Externals/OpenAL/Win32/soft_oal.dll b/Externals/OpenAL/Win32/soft_oal.dll deleted file mode 100644 index 71ced6a21f..0000000000 Binary files a/Externals/OpenAL/Win32/soft_oal.dll and /dev/null differ diff --git a/Externals/OpenAL/Win32/wrap_oal.dll b/Externals/OpenAL/Win32/wrap_oal.dll deleted file mode 100644 index 9752892aab..0000000000 Binary files a/Externals/OpenAL/Win32/wrap_oal.dll and /dev/null differ diff --git a/Externals/OpenAL/Win64/OpenAL32.dll b/Externals/OpenAL/Win64/OpenAL32.dll index f36943df40..b47ff952b7 100644 Binary files a/Externals/OpenAL/Win64/OpenAL32.dll and b/Externals/OpenAL/Win64/OpenAL32.dll differ diff --git a/Externals/OpenAL/Win64/soft_oal.dll b/Externals/OpenAL/Win64/soft_oal.dll deleted file mode 100644 index b47ff952b7..0000000000 Binary files a/Externals/OpenAL/Win64/soft_oal.dll and /dev/null differ diff --git a/Externals/OpenAL/Win64/wrap_oal.dll b/Externals/OpenAL/Win64/wrap_oal.dll deleted file mode 100644 index 1ab0365711..0000000000 Binary files a/Externals/OpenAL/Win64/wrap_oal.dll and /dev/null differ diff --git a/Source/Android/res/menu/gamelist_menu.xml b/Source/Android/res/menu/gamelist_menu.xml new file mode 100644 index 0000000000..dbec1a65f3 --- /dev/null +++ b/Source/Android/res/menu/gamelist_menu.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/Source/Android/res/values-ja/strings.xml b/Source/Android/res/values-ja/strings.xml index 9216a2ecdc..12594ca2ac 100644 --- a/Source/Android/res/values-ja/strings.xml +++ b/Source/Android/res/values-ja/strings.xml @@ -17,9 +17,10 @@ 親ディレクトリ フォルダ ファイルサイズ: - 圧縮ファイル形式はサポートされていません + クリア + ゲームリストからすべての項目を削除しますか? ゲームリスト フォルダの参照 設定 @@ -61,7 +62,7 @@ CPU設定 使用するエミュレーションコア デュアルコア - 有効/無効 + 処理のための2つのCPUコアを使用して。速度が向上します。 ビデオ設定 Software Renderer OpenGL ES 3 diff --git a/Source/Android/res/values/strings.xml b/Source/Android/res/values/strings.xml index 50bacda5df..dac787e4bc 100644 --- a/Source/Android/res/values/strings.xml +++ b/Source/Android/res/values/strings.xml @@ -17,9 +17,10 @@ Parent Directory Folder File Size: - Can not use compressed file types + Clear game list + Do you want to clear the game list? Game List Browse Folder Settings @@ -58,11 +59,11 @@ JITIL Recompiler JIT ARM Recompiler CPU Core - CPU Settings + CPU Emulation core to use Dual Core - On/Off - Video Settings + Split workload to two CPU cores instead of one. Increases speed. + Video Software Renderer OpenGL ES 3 Video Backend diff --git a/Source/Android/res/xml/cpu_prefs.xml b/Source/Android/res/xml/cpu_prefs.xml index adb6fff91f..83dc830791 100644 --- a/Source/Android/res/xml/cpu_prefs.xml +++ b/Source/Android/res/xml/cpu_prefs.xml @@ -3,7 +3,7 @@ Input = new ArrayList(); - Input.add(new FolderBrowserItem(getString(R.string.build_revision), NativeLibrary.GetVersionString(), "", true)); - Input.add(new FolderBrowserItem(getString(R.string.supports_gles3), VideoSettingsFragment.SupportsGLES3() ? yes : no, "", true)); + Input.add(new FolderBrowserItem(getString(R.string.build_revision), NativeLibrary.GetVersionString(), "")); + Input.add(new FolderBrowserItem(getString(R.string.supports_gles3), VideoSettingsFragment.SupportsGLES3() ? yes : no, "")); adapter = new FolderBrowserAdapter(m_activity, R.layout.about_layout, Input); mMainList.setAdapter(adapter); diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java index b708b756b5..a616df609a 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java @@ -128,6 +128,8 @@ public final class DolphinEmulator extends Activity CopyAsset("setting-usa.txt", WiiDir + File.separator + "setting-usa.txt"); } + // Load the configuration keys set in the Dolphin ini and gfx ini files + // into the application's shared preferences. UserPreferences.LoadDolphinConfigToPrefs(this); } } @@ -148,7 +150,6 @@ public final class DolphinEmulator extends Activity String FileName = data.getStringExtra("Select"); GLview = new NativeGLSurfaceView(this); this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - String backend = NativeLibrary.GetConfig("Dolphin.ini", "Core", "GFXBackend", "Software Renderer"); NativeLibrary.SetDimensions((int)screenWidth, (int)screenHeight); NativeLibrary.SetFilename(FileName); setContentView(GLview); diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java index 8622026b97..dedd824c87 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -18,17 +18,83 @@ public final class NativeLibrary public static native void onTouchEvent(int Action, float X, float Y); public static native void onGamePadEvent(String Device, int Button, int Action); public static native void onGamePadMoveEvent(String Device, int Axis, float Value); - public static native String GetConfig(String configFile, String Key, String Value, String Default); - public static native void SetConfig(String configFile, String Key, String Value, String Default); + + /** + * Gets a value from a key in the given ini-based config file. + * + * @param configFile The ini-based config file to get the value from. + * @param Section The section key that the actual key is in. + * @param Key The key to get the value from. + * @param Default The value to return in the event the given key doesn't exist. + * + * @return the value stored at the key, or a default value if it doesn't exist. + */ + public static native String GetConfig(String configFile, String Section, String Key, String Default); + + /** + * Sets a value to a key in the given ini config file. + * + * @param configFile The ini-based config file to add the value to. + * @param Section The section key for the ini key + * @param Key The actual ini key to set. + * @param Value The string to set the ini key to. + */ + public static native void SetConfig(String configFile, String Section, String Key, String Value); + + /** + * Sets the filename to be run during emulation. + * + * @param filename The filename to be run during emulation. + */ public static native void SetFilename(String filename); + + /** + * Sets the dimensions of the rendering window. + * + * @param width The new width of the rendering window (in pixels). + * @param height The new height of the rendering window (in pixels). + */ public static native void SetDimensions(int width, int height); + + /** + * Gets the embedded banner within the given ISO/ROM. + * + * @param filename the file path to the ISO/ROM. + * + * @return an integer array containing the color data for the banner. + */ public static native int[] GetBanner(String filename); + + /** + * Gets the embedded title of the given ISO/ROM. + * + * @param filename The file path to the ISO/ROM. + * + * @return the embedded title of the ISO/ROM. + */ public static native String GetTitle(String filename); + + /** + * Gets the Dolphin version string. + * + * @return the Dolphin version string. + */ public static native String GetVersionString(); + /** + * Begins emulation. + * + * @param surf The surface to render to. + */ public static native void Run(Surface surf); + + /** Unpauses emulation from a paused state. */ public static native void UnPauseEmulation(); + + /** Pauses emulation. */ public static native void PauseEmulation(); + + /** Stops emulation. */ public static native void StopEmulation(); static diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowser.java b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowser.java index 2895196ff7..55f88b3931 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowser.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowser.java @@ -10,7 +10,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; -import android.widget.Toast; import java.io.File; import java.util.*; @@ -50,7 +49,6 @@ public final class FolderBrowser extends Fragment // Supported extensions to filter by Set validExts = new HashSet(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff")); - Set invalidExts = new HashSet(Arrays.asList(".zip", ".rar", ".7z")); // Search for any directories or files within the current dir. for(File entry : dirs) @@ -65,17 +63,13 @@ public final class FolderBrowser extends Fragment { if(entry.isDirectory()) { - dir.add(new FolderBrowserItem(entryName, entry.getAbsolutePath(), true)); + dir.add(new FolderBrowserItem(entryName, entry.getAbsolutePath())); } else if (entry.isFile() && hasExtension) { if (validExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) { - fls.add(new FolderBrowserItem(entryName, getString(R.string.file_size)+entry.length(), entry.getAbsolutePath(), true)); - } - else if (invalidExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) - { - fls.add(new FolderBrowserItem(entryName, getString(R.string.file_size)+entry.length(), entry.getAbsolutePath(), false)); + fls.add(new FolderBrowserItem(entryName, getString(R.string.file_size)+entry.length(), entry.getAbsolutePath())); } } } @@ -92,7 +86,7 @@ public final class FolderBrowser extends Fragment // Check for a parent directory to the one we're currently in. if (!currDir.getPath().equalsIgnoreCase("/")) - dir.add(0, new FolderBrowserItem("..", getString(R.string.parent_directory), currDir.getParent(), true)); + dir.add(0, new FolderBrowserItem("..", getString(R.string.parent_directory), currDir.getParent())); adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, dir); mDrawerList = (ListView) rootView.findViewById(R.id.gamelist); @@ -124,10 +118,7 @@ public final class FolderBrowser extends Fragment } else { - if (item.isValid()) - FolderSelected(); - else - Toast.makeText(m_activity, getString(R.string.cant_use_compressed_filetypes), Toast.LENGTH_LONG).show(); + FolderSelected(); } } }; @@ -137,17 +128,8 @@ public final class FolderBrowser extends Fragment { super.onAttach(activity); - // This makes sure that the container activity has implemented - // the callback interface. If not, it throws an exception - try - { - m_activity = activity; - } - catch (ClassCastException e) - { - throw new ClassCastException(activity.toString() - + " must implement OnGameListZeroListener"); - } + // Cache the activity instance. + m_activity = activity; } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserAdapter.java index e77205b527..6de1fbcb79 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserAdapter.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserAdapter.java @@ -58,11 +58,6 @@ public final class FolderBrowserAdapter extends ArrayAdapter if(mainText != null) { mainText.setText(item.getName()); - - if (!item.isValid()) - { - mainText.setTextColor(0xFFFF0000); - } } if(subtitleText != null) diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserItem.java index ebff901961..00e41852fa 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserItem.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/folderbrowser/FolderBrowserItem.java @@ -10,7 +10,6 @@ public final class FolderBrowserItem implements Comparable private final String name; private final String subtitle; private final String path; - private final boolean isValid; private final File underlyingFile; /** @@ -19,14 +18,12 @@ public final class FolderBrowserItem implements Comparable * @param name The name of the file/folder represented by this item. * @param subtitle The subtitle of this FolderBrowserItem to display. * @param path The path of the file/folder represented by this item. - * @param isValid Whether or not this item represents a file type that can be handled. */ - public FolderBrowserItem(String name, String subtitle, String path, boolean isValid) + public FolderBrowserItem(String name, String subtitle, String path) { this.name = name; this.subtitle = subtitle; this.path = path; - this.isValid = isValid; this.underlyingFile = new File(path); } @@ -35,14 +32,12 @@ public final class FolderBrowserItem implements Comparable * * @param name The name of the file/folder represented by this item. * @param path The path of the file/folder represented by this item. - * @param isValid Whether or not this item represents a file type that can be handled. */ - public FolderBrowserItem(String name, String path, boolean isValid) + public FolderBrowserItem(String name, String path) { this.name = name; this.subtitle = ""; this.path = path; - this.isValid = isValid; this.underlyingFile = new File(path); } @@ -76,20 +71,6 @@ public final class FolderBrowserItem implements Comparable return path; } - /** - * Gets whether or not the file represented - * by this FolderBrowserItem is supported - * and can be handled correctly. - * - * @return whether or not the file represented - * by this FolderBrowserItem is supported - * and can be handled correctly. - */ - public boolean isValid() - { - return isValid; - } - /** * Gets the {@link File} representation of the underlying file/folder * represented by this FolderBrowserItem. diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java index 62a9f34189..3678cf7637 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListActivity.java @@ -7,8 +7,10 @@ package org.dolphinemu.dolphinemu.gamelist; import android.app.Activity; +import android.app.AlertDialog; import android.app.Fragment; import android.app.FragmentManager; +import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; @@ -16,6 +18,7 @@ import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.view.*; import android.widget.AdapterView; +import android.widget.ArrayAdapter; import android.widget.ListView; import java.util.ArrayList; import java.util.List; @@ -248,6 +251,20 @@ public final class GameListActivity extends Activity { return super.onPrepareOptionsMenu(menu); } + + @Override + public boolean onCreateOptionsMenu(Menu menu) + { + // Only show this in the game list. + if (this.mCurFragmentNum == 0) + { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.gamelist_menu, menu); + return true; + } + + return false; + } @Override public boolean onOptionsItemSelected(MenuItem item) @@ -259,6 +276,38 @@ public final class GameListActivity extends Activity return true; } + // If clear game list is pressed. + if (item.getItemId() == R.id.clearGameList) + { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.clear_game_list); + builder.setMessage(getString(R.string.clear_game_list_confirm)); + builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener(){ + public void onClick(DialogInterface dialog, int which) + { + String directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPathes", "0"); + int intDirs = Integer.parseInt(directories); + + for (int i = 0; i < intDirs; i++) + { + NativeLibrary.SetConfig("Dolphin.ini", "General", "GCMPath" + i, ""); + } + + ArrayAdapter adapter = ((GameListFragment)GameListActivity.this.mCurFragment).getAdapter(); + adapter.clear(); + adapter.notifyDataSetChanged(); + } + }); + builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) + { + // Do nothing. This just make "No" appear. + } + }); + + builder.show(); + } + return super.onOptionsItemSelected(item); } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListFragment.java index d77741016b..b72509419f 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListFragment.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListFragment.java @@ -51,6 +51,16 @@ public final class GameListFragment extends Fragment */ void onZeroFiles(); } + + /** + * Gets the adapter for this fragment. + * + * @return the adapter for this fragment. + */ + public GameListAdapter getAdapter() + { + return mGameAdapter; + } private void Fill() { @@ -77,7 +87,7 @@ public final class GameListFragment extends Fragment if (!entry.isDirectory()) { if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) - fls.add(new GameListItem(mMe.getApplicationContext(), entryName, getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), true)); + fls.add(new GameListItem(mMe.getApplicationContext(), entryName, getString(R.string.file_size)+entry.length(),entry.getAbsolutePath())); } } } @@ -95,11 +105,12 @@ public final class GameListFragment extends Fragment // so there should be no worries about accidentally removing a valid game. for (int i = 0; i < fls.size(); i++) { - int indexNext = i+1; - - if (indexNext < fls.size() && fls.get(indexNext).getPath().contains(fls.get(i).getPath())) + for (int j = i+1; j < fls.size(); j++) { - fls.remove(indexNext); + if (fls.get(j).getPath().equals(fls.get(i).getPath())) + { + fls.remove(j); + } } } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListItem.java index 16ba06a65a..9ecff70b9b 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListItem.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/gamelist/GameListItem.java @@ -25,7 +25,6 @@ public final class GameListItem implements Comparable private String name; private final String data; private final String path; - private final boolean isValid; private Bitmap image; /** @@ -37,12 +36,11 @@ public final class GameListItem implements Comparable * @param path The file path for the game represented by this GameListItem. * @param isValid Whether or not the emulator can handle this file. */ - public GameListItem(Context ctx, String name, String data, String path, boolean isValid) + public GameListItem(Context ctx, String name, String data, String path) { this.name = name; this.data = data; this.path = path; - this.isValid = isValid; File file = new File(path); if (!file.isDirectory() && !path.equals("")) @@ -115,16 +113,6 @@ public final class GameListItem implements Comparable return image; } - /** - * Gets whether or not the emulator can handle this GameListItem. - * - * @return true, if this GameListItem can be handled by the emulator; false, otherwise. - */ - public boolean isValid() - { - return isValid; - } - public int compareTo(GameListItem o) { if (this.name != null) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 53d5854b00..c183f88c6a 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -402,7 +402,7 @@ void SConfig::LoadSettings() ini.Get("Core", "EnableCheats", &m_LocalCoreStartupParameter.bEnableCheats, false); ini.Get("Core", "SelectedLanguage", &m_LocalCoreStartupParameter.SelectedLanguage, 0); ini.Get("Core", "DPL2Decoder", &m_LocalCoreStartupParameter.bDPL2Decoder, false); - ini.Get("Core", "Latency", &m_LocalCoreStartupParameter.iLatency, 14); + ini.Get("Core", "Latency", &m_LocalCoreStartupParameter.iLatency, 2); ini.Get("Core", "MemcardA", &m_strMemoryCardA); ini.Get("Core", "MemcardB", &m_strMemoryCardB); ini.Get("Core", "SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD); diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 0e936ddde4..3fc1b2c41a 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -388,7 +388,7 @@ void EmuThread() return; } - OSD::AddMessage(("Dolphin " + g_video_backend->GetName() + " Video Backend.").c_str(), 5000); + OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000); if (!DSP::GetDSPEmulator()->Initialize(g_pWindowHandle, _CoreParameter.bWii, _CoreParameter.bDSPThread)) diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index 33f31a1815..fc8f005fad 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -23,22 +23,6 @@ NetSettings g_NetPlaySettings; #define RPT_SIZE_HACK (1 << 16) -NetPlayClient::Player::Player() -{ - memset(pad_map, -1, sizeof(pad_map)); -} - -// called from ---GUI--- thread -std::string NetPlayClient::Player::ToString() const -{ - std::ostringstream ss; - ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |"; - for (unsigned int i=0; i<4; ++i) - ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-'); - ss << " | " << ping << "ms"; - return ss.str(); -} - NetPad::NetPad() { nHi = 0x00808080; @@ -200,16 +184,8 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) case NP_MSG_PAD_MAPPING : { - PlayerId pid; - packet >> pid; - - { - std::lock_guard lkp(m_crit.players); - Player& player = m_players[pid]; - - for (unsigned int i=0; i<4; ++i) - packet >> player.pad_map[i]; - } + for (PadMapping i = 0; i < 4; i++) + packet >> m_pad_map[i]; m_dialog->Update(); } @@ -223,7 +199,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) // trusting server for good map value (>=0 && <4) // add to pad buffer - m_pad_buffer[(unsigned)map].Push(np); + m_pad_buffer[map].Push(np); } break; @@ -361,13 +337,36 @@ void NetPlayClient::GetPlayerList(std::string& list, std::vector& pid_list) e = m_players.end(); for ( ; i!=e; ++i) { - ss << i->second.ToString() << '\n'; - pid_list.push_back(i->second.pid); + const Player *player = &(i->second); + ss << player->name << "[" << (int)player->pid << "] : " << player->revision << " | "; + for (unsigned int j = 0; j < 4; j++) + { + if (m_pad_map[j] == player->pid) + ss << j + 1; + else + ss << '-'; + } + ss << " | " << player->ping << "ms\n"; + pid_list.push_back(player->pid); } list = ss.str(); } +// called from ---GUI--- thread +void NetPlayClient::GetPlayers(std::vector &player_list) +{ + std::lock_guard lkp(m_crit.players); + std::map::const_iterator + i = m_players.begin(), + e = m_players.end(); + for ( ; i!=e; ++i) + { + const Player *player = &(i->second); + player_list.push_back(player); + } +} + // called from ---GUI--- thread void NetPlayClient::SendChatMessage(const std::string& msg) @@ -381,12 +380,12 @@ void NetPlayClient::SendChatMessage(const std::string& msg) } // called from ---CPU--- thread -void NetPlayClient::SendPadState(const PadMapping local_nb, const NetPad& np) +void NetPlayClient::SendPadState(const PadMapping in_game_pad, const NetPad& np) { // send to server sf::Packet spac; spac << (MessageId)NP_MSG_PAD_DATA; - spac << local_nb; // local pad num + spac << in_game_pad; spac << np.nHi << np.nLo; std::lock_guard lks(m_crit.send); @@ -457,13 +456,35 @@ void NetPlayClient::ClearBuffers() // called from ---CPU--- thread bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues) { - { - std::lock_guard lkp(m_crit.players); + // The interface for this is extremely silly. + // + // Imagine a physical device that links three Gamecubes together + // and emulates NetPlay that way. Which Gamecube controls which + // in-game controllers can be configured on the device (m_pad_map) + // but which sockets on each individual Gamecube should be used + // to control which players? The solution that Dolphin uses is + // that we hardcode the knowledge that they go in order, so if + // you have a 3P game with three gamecubes, then every single + // controller should be plugged into slot 1. + // + // If you have a 4P game, then one of the Gamecubes will have + // a controller plugged into slot 1, and another in slot 2. + // + // The slot number is the "local" pad number, and what player + // it actually means is the "in-game" pad number. + // + // The interface here gives us the status of local pads, and + // expects to get back "in-game" pad numbers back in response. + // e.g. it asks "here's the input that slot 1 has, and by the + // way, what's the state of P1?" + // + // We should add this split between "in-game" pads and "local" + // pads higher up. - // in game mapping for this local pad - unsigned int in_game_num = m_local_player->pad_map[pad_nb]; + int in_game_num = GetPadNum(pad_nb); - // does this local pad map in game? + // If this in-game pad is one of ours, then update from the + // information given. if (in_game_num < 4) { NetPad np(pad_status); @@ -476,89 +497,36 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_stat m_pad_buffer[in_game_num].Push(np); // send - SendPadState(pad_nb, np); + SendPadState(in_game_num, np); } } - } // unlock players - - //Common::Timer bufftimer; - //bufftimer.Start(); - - // get padstate from buffer and send to game + // Now, we need to swap out the local value with the values + // retrieved from NetPlay. This could be the value we pushed + // above if we're configured as P1 and the code is trying + // to retrieve data for slot 1. while (!m_pad_buffer[pad_nb].Pop(*netvalues)) { - // wait for receiving thread to push some data - Common::SleepCurrentThread(1); - - if (false == m_is_running) + if (!m_is_running) return false; - // TODO: check the time of bufftimer here, - // if it gets pretty high, ask the user if they want to disconnect - + // TODO: use a condition instead of sleeping + Common::SleepCurrentThread(1); } - //u64 hangtime = bufftimer.GetTimeElapsed(); - //if (hangtime > 10) - //{ - // std::ostringstream ss; - // ss << "Pad " << (int)pad_nb << ": Had to wait " << hangtime << "ms for pad data. (increase pad Buffer maybe)"; - // Core::DisplayMessage(ss.str(), 1000); - //} - return true; } // called from ---CPU--- thread void NetPlayClient::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size) { - //// in game mapping for this local wiimote - unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now - - // does this local pad map in game? - if (in_game_num < 4) - { - m_wiimote_input[_number].resize(m_wiimote_input[_number].size() + 1); - m_wiimote_input[_number].back().assign((char*)_pData, (char*)_pData + _Size); - m_wiimote_input[_number].back().channel = _channelID; - } + // XXX } // called from ---CPU--- thread void NetPlayClient::WiimoteUpdate(int _number) { - { - std::lock_guard lkp(m_crit.players); - - // in game mapping for this local wiimote - unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now - - // does this local pad map in game? - if (in_game_num < 4) - { - m_wiimote_buffer[in_game_num].Push(m_wiimote_input[_number]); - - // TODO: send it - - m_wiimote_input[_number].clear(); - } - - } // unlock players - - if (0 == m_wiimote_buffer[_number].Size()) - { - //PanicAlert("PANIC"); - return; - } - - NetWiimote nw; - m_wiimote_buffer[_number].Pop(nw); - - NetWiimote::const_iterator - i = nw.begin(), e = nw.end(); - for ( ; i!=e; ++i) - Core::Callback_WiimoteInterruptChannel(_number, i->channel, &(*i)[0], (u32)i->size() + RPT_SIZE_HACK); + // XXX } // called from ---GUI--- thread and ---NETPLAY--- thread (client side) @@ -586,13 +554,21 @@ bool NetPlayClient::StopGame() // called from ---CPU--- thread u8 NetPlayClient::GetPadNum(u8 numPAD) { - // TODO: i don't like that this loop is running everytime there is rumble - unsigned int i = 0; - for (; i<4; ++i) - if (numPAD == m_local_player->pad_map[i]) - break; + // Figure out which in-game pad maps to which local pad. + // The logic we have here is that the local slots always + // go in order. + int local_pad_count = -1; + int ingame_pad = 0; + for (; ingame_pad < 4; ingame_pad++) + { + if (m_pad_map[ingame_pad] == m_local_player->pid) + local_pad_count++; - return i; + if (local_pad_count == numPAD) + break; + } + + return ingame_pad; } // stuff hacked into dolphin @@ -658,22 +634,13 @@ u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD) //void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number) void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int) { - //CritLocker crit(crit_netplay_client); - - //if (netplay_client) - // netplay_client->WiimoteUpdate(_number); } // called from ---CPU--- thread // int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number) { - //CritLocker crit(crit_netplay_client); - - //if (netplay_client) - // return netplay_client->GetPadNum(_number); // just using gcpad mapping for now - //else - return _number; + return _number; } // called from ---CPU--- thread @@ -684,19 +651,7 @@ bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&) std::lock_guard lk(crit_netplay_client); if (netplay_client) - //{ - // if (_Size >= RPT_SIZE_HACK) - // { - // _Size -= RPT_SIZE_HACK; - // return false; - // } - // else - // { - // netplay_client->WiimoteInput(_number, _channelID, _pData, _Size); - // // don't use this packet - return true; - // } - //} + return true; else return false; } diff --git a/Source/Core/Core/Src/NetPlayClient.h b/Source/Core/Core/Src/NetPlayClient.h index d44a4c84b8..23529dbb95 100644 --- a/Source/Core/Core/Src/NetPlayClient.h +++ b/Source/Core/Core/Src/NetPlayClient.h @@ -50,6 +50,15 @@ public: extern NetSettings g_NetPlaySettings; +class Player +{ + public: + PlayerId pid; + std::string name; + std::string revision; + u32 ping; +}; + class NetPlayClient { public: @@ -59,6 +68,7 @@ public: ~NetPlayClient(); void GetPlayerList(std::string& list, std::vector& pid_list); + void GetPlayers(std::vector& player_list); bool is_connected; @@ -84,19 +94,6 @@ protected: std::recursive_mutex players, send; } m_crit; - class Player - { - public: - Player(); - std::string ToString() const; - - PlayerId pid; - std::string name; - PadMapping pad_map[4]; - std::string revision; - u32 ping; - }; - Common::FifoQueue m_pad_buffer[4]; Common::FifoQueue m_wiimote_buffer[4]; @@ -117,8 +114,10 @@ protected: u32 m_current_game; + PadMapping m_pad_map[4]; + private: - void SendPadState(const PadMapping local_nb, const NetPad& np); + void SendPadState(const PadMapping in_game_pad, const NetPad& np); unsigned int OnData(sf::Packet& packet); PlayerId m_pid; diff --git a/Source/Core/Core/Src/NetPlayProto.h b/Source/Core/Core/Src/NetPlayProto.h index d4abf60cb8..432b9766e5 100644 --- a/Source/Core/Core/Src/NetPlayProto.h +++ b/Source/Core/Core/Src/NetPlayProto.h @@ -24,7 +24,7 @@ struct Rpt : public std::vector typedef std::vector NetWiimote; -#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-18" +#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-23" // messages enum diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index 134045c5bf..30b1d26664 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -4,11 +4,6 @@ #include "NetPlayServer.h" -NetPlayServer::Client::Client() -{ - memset(pad_map, -1, sizeof(pad_map)); -} - NetPlayServer::~NetPlayServer() { if (is_connected) @@ -29,6 +24,7 @@ NetPlayServer::~NetPlayServer() // called from ---GUI--- thread NetPlayServer::NetPlayServer(const u16 port) : is_connected(false), m_is_running(false) { + memset(m_pad_map, -1, sizeof(m_pad_map)); if (m_socket.Listen(port)) { is_connected = true; @@ -155,45 +151,16 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) rpac >> player.name; // give new client first available id - player.pid = 0; - std::map::const_iterator - i, - e = m_players.end(); - for (PlayerId p = 1; 0 == player.pid; ++p) - { - for (i = m_players.begin(); ; ++i) - { - if (e == i) - { - player.pid = p; - break; - } - if (p == i->second.pid) - break; - } - } + player.pid = m_players.size() + 1; - // TODO: this is crappy // try to automatically assign new user a pad + for (unsigned int m = 0; m < 4; ++m) { - bool is_mapped[4] = {false,false,false,false}; - - for ( unsigned int m = 0; m<4; ++m) - { - for (i = m_players.begin(); i!=e; ++i) + if (m_pad_map[m] == -1) { - if (i->second.pad_map[m] >= 0) - is_mapped[(unsigned)i->second.pad_map[m]] = true; - } - } - - for ( unsigned int m = 0; m<4; ++m) - if (false == is_mapped[m]) - { - player.pad_map[0] = m; + m_pad_map[m] = player.pid; break; } - } { @@ -221,6 +188,9 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) } // sync values with new client + std::map::const_iterator + i, + e = m_players.end(); for (i = m_players.begin(); i!=e; ++i) { spac.Clear(); @@ -279,83 +249,28 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket) } // called from ---GUI--- thread -bool NetPlayServer::GetPadMapping(const int pid, int map[]) +void NetPlayServer::GetPadMapping(PadMapping map[4]) { - std::lock_guard lkp(m_crit.players); - std::map::const_iterator - i = m_players.begin(), - e = m_players.end(); - for (; i!=e; ++i) - if (pid == i->second.pid) - break; - - // player not found - if (i == e) - return false; - - // get pad mapping - for (unsigned int m = 0; m<4; ++m) - map[m] = i->second.pad_map[m]; - - return true; + for (int i = 0; i < 4; i++) + map[i] = m_pad_map[i]; } // called from ---GUI--- thread -bool NetPlayServer::SetPadMapping(const int pid, const int map[]) +void NetPlayServer::SetPadMapping(const PadMapping map[4]) { - std::lock_guard lkg(m_crit.game); - if (m_is_running) - return false; - - std::lock_guard lkp(m_crit.players); - std::map::iterator - i = m_players.begin(), - e = m_players.end(); - for (; i!=e; ++i) - if (pid == i->second.pid) - break; - - // player not found - if (i == e) - return false; - - Client& player = i->second; - - // set pad mapping - for (unsigned int m = 0; m<4; ++m) - { - player.pad_map[m] = (PadMapping)map[m]; - - // remove duplicate mappings - for (i = m_players.begin(); i!=e; ++i) - for (unsigned int p = 0; p<4; ++p) - if (p != m || i->second.pid != pid) - if (player.pad_map[m] == i->second.pad_map[p]) - i->second.pad_map[p] = -1; - } - - std::lock_guard lks(m_crit.send); - UpdatePadMapping(); // sync pad mappings with everyone - - return true; + for (int i = 0; i < 4; i++) + m_pad_map[i] = map[i]; + UpdatePadMapping(); } -// called from ---NETPLAY--- thread +// called from ---GUI--- thread and ---NETPLAY--- thread void NetPlayServer::UpdatePadMapping() { - std::map::const_iterator - i = m_players.begin(), - e = m_players.end(); - for (; i!=e; ++i) - { - sf::Packet spac; - spac << (MessageId)NP_MSG_PAD_MAPPING; - spac << i->second.pid; - for (unsigned int pm = 0; pm<4; ++pm) - spac << i->second.pad_map[pm]; - SendToClients(spac); - } - + sf::Packet spac; + spac << (MessageId)NP_MSG_PAD_MAPPING; + for (int i = 0; i < 4; i++) + spac << m_pad_map[i]; + SendToClients(spac); } // called from ---GUI--- thread and ---NETPLAY--- thread @@ -415,23 +330,15 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) int hi, lo; packet >> map >> hi >> lo; - // check if client's pad indeed maps in game - if (map >= 0 && map < 4) - map = player.pad_map[(unsigned)map]; - else - map = -1; - - // if not, they are hacking, so disconnect them - // this could happen right after a pad map change, but that isn't implemented yet - if (map < 0) + // If the data is not from the correct player, + // then disconnect them. + if (m_pad_map[map] != player.pid) return 1; - - // relay to clients + // Relay to clients sf::Packet spac; spac << (MessageId)NP_MSG_PAD_DATA; - spac << map; // in game mapping - spac << hi << lo; + spac << map << hi << lo; std::lock_guard lks(m_crit.send); SendToClients(spac, player.pid); diff --git a/Source/Core/Core/Src/NetPlayServer.h b/Source/Core/Core/Src/NetPlayServer.h index 4ef601bf06..5fbdb42802 100644 --- a/Source/Core/Core/Src/NetPlayServer.h +++ b/Source/Core/Core/Src/NetPlayServer.h @@ -35,8 +35,8 @@ public: bool StartGame(const std::string &path); bool StopGame(); - bool GetPadMapping(const int pid, int map[]); - bool SetPadMapping(const int pid, const int map[]); + void GetPadMapping(PadMapping map[]); + void SetPadMapping(const PadMapping map[]); void AdjustPadBufferSize(unsigned int size); @@ -50,11 +50,8 @@ private: class Client { public: - Client(); - PlayerId pid; std::string name; - PadMapping pad_map[4]; std::string revision; sf::SocketTCP socket; @@ -77,6 +74,7 @@ private: bool m_update_pings; u32 m_current_game; unsigned int m_target_buffer_size; + PadMapping m_pad_map[4]; std::map m_players; diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index 4ae51d78a1..e9da722739 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -513,10 +513,8 @@ void CConfigMain::InitializeGUITooltips() #if defined(__APPLE__) DPL2Decoder->SetToolTip(_("Enables Dolby Pro Logic II emulation using 5.1 surround. Not available on OSX.")); -#elif defined(__linux__) +#else DPL2Decoder->SetToolTip(_("Enables Dolby Pro Logic II emulation using 5.1 surround. OpenAL backend only.")); -#elif defined(_WIN32) - DPL2Decoder->SetToolTip(_("Enables Dolby Pro Logic II emulation using 5.1 surround. OpenAL backend only. May need to rename soft_oal.dll to OpenAL32.dll to make it work.")); #endif Latency->SetToolTip(_("Sets the latency (in ms). Higher values may reduce audio crackling. OpenAL backend only.")); diff --git a/Source/Core/DolphinWX/Src/MainAndroid.cpp b/Source/Core/DolphinWX/Src/MainAndroid.cpp index 5fc616d5ac..d5ff986841 100644 --- a/Source/Core/DolphinWX/Src/MainAndroid.cpp +++ b/Source/Core/DolphinWX/Src/MainAndroid.cpp @@ -132,25 +132,6 @@ void Host_SysMessage(const char *fmt, ...) void Host_SetWiiMoteConnectionState(int _State) {} -void OSDCallbacks(u32 UserData) -{ - switch(UserData) - { - case 0: // Init - ButtonManager::Init(); - break; - case 1: // Draw - ButtonManager::DrawButtons(); - break; - case 2: // Shutdown - ButtonManager::Shutdown(); - break; - default: - WARN_LOG(COMMON, "Error, wrong OSD type"); - break; - } -} - #define DVD_BANNER_WIDTH 96 #define DVD_BANNER_HEIGHT 32 std::vector m_volume_names; @@ -321,8 +302,8 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv * { surf = ANativeWindow_fromSurface(env, _surf); // Install our callbacks - OSD::AddCallback(OSD::OSD_INIT, OSDCallbacks, 0); - OSD::AddCallback(OSD::OSD_SHUTDOWN, OSDCallbacks, 2); + OSD::AddCallback(OSD::OSD_INIT, ButtonManager::Init); + OSD::AddCallback(OSD::OSD_SHUTDOWN, ButtonManager::Shutdown); LogManager::Init(); SConfig::Init(); @@ -337,7 +318,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv * ini.Get("Android", "ScreenControls", &onscreencontrols, true); if (onscreencontrols) - OSD::AddCallback(OSD::OSD_ONFRAME, OSDCallbacks, 1); + OSD::AddCallback(OSD::OSD_ONFRAME, ButtonManager::DrawButtons); // No use running the loop when booting fails if ( BootManager::BootCore( g_filename.c_str() ) ) diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 7f1b7c6866..7d50f42905 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -559,23 +559,13 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent&) void NetPlayDiag::OnConfigPads(wxCommandEvent&) { - int mapping[4]; - - // get selected player id - int pid = m_player_lbox->GetSelection(); - if (pid < 0) - return; - pid = m_playerids.at(pid); - - if (false == netplay_server->GetPadMapping(pid, mapping)) - return; - - PadMapDiag pmd(this, mapping); + PadMapping mapping[4]; + std::vector player_list; + netplay_server->GetPadMapping(mapping); + netplay_client->GetPlayers(player_list); + PadMapDiag pmd(this, mapping, player_list); pmd.ShowModal(); - - if (false == netplay_server->SetPadMapping(pid, mapping)) - PanicAlertT("Could not set pads. The player left or the game is currently running!\n" - "(setting pads while the game is running is not yet supported)"); + netplay_server->SetPadMapping(mapping); } ChangeGameDiag::ChangeGameDiag(wxWindow* const parent, const CGameListCtrl* const game_list, wxString& game_name) @@ -605,45 +595,40 @@ void ChangeGameDiag::OnPick(wxCommandEvent& event) EndModal(wxID_OK); } -PadMapDiag::PadMapDiag(wxWindow* const parent, int map[]) +PadMapDiag::PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector& player_list) : wxDialog(parent, wxID_ANY, _("Configure Pads"), wxDefaultPosition, wxDefaultSize) , m_mapping(map) + , m_player_list(player_list) { wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL); + h_szr->AddSpacer(10); - h_szr->AddSpacer(20); - - // labels - wxBoxSizer* const label_szr = new wxBoxSizer(wxVERTICAL); - label_szr->Add(new wxStaticText(this, wxID_ANY, _("Local")), 0, wxALIGN_TOP); - label_szr->AddStretchSpacer(1); - label_szr->Add(new wxStaticText(this, wxID_ANY, _("In-Game")), 0, wxALIGN_BOTTOM); - - h_szr->Add(label_szr, 1, wxTOP | wxEXPAND, 20); - - // set up choices - wxString pad_names[5]; - pad_names[0] = _("None"); - for (unsigned int i=1; i<5; ++i) - pad_names[i] = wxString(_("Pad ")) + (wxChar)(wxT('0')+i); + wxArrayString player_names; + player_names.Add(_("None")); + for (unsigned int i = 0; i < m_player_list.size(); i++) + player_names.Add(m_player_list[i]->name); for (unsigned int i=0; i<4; ++i) { - wxChoice* const pad_cbox = m_map_cbox[i] - = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 5, pad_names); - pad_cbox->Select(m_mapping[i] + 1); - - pad_cbox->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &PadMapDiag::OnAdjust, this); - wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL); - v_szr->Add(new wxStaticText(this,wxID_ANY, pad_names[i + 1]), 1, wxALIGN_CENTER_HORIZONTAL); - v_szr->Add(pad_cbox, 1); + v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("Pad ")) + (wxChar)(wxT('0')+i))), + 1, wxALIGN_CENTER_HORIZONTAL); + + m_map_cbox[i] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names); + m_map_cbox[i]->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &PadMapDiag::OnAdjust, this); + if (m_mapping[i] == -1) + m_map_cbox[i]->Select(0); + else + for (unsigned int j = 0; j < m_player_list.size(); j++) + if (m_mapping[i] == m_player_list[j]->pid) + m_map_cbox[i]->Select(j + 1); + + v_szr->Add(m_map_cbox[i], 1); h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20); + h_szr->AddSpacer(10); } - h_szr->AddSpacer(20); - wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); main_szr->Add(h_szr); main_szr->AddSpacer(5); @@ -656,8 +641,14 @@ PadMapDiag::PadMapDiag(wxWindow* const parent, int map[]) void PadMapDiag::OnAdjust(wxCommandEvent& event) { (void)event; - for (unsigned int i=0; i<4; ++i) - m_mapping[i] = m_map_cbox[i]->GetSelection() - 1; + for (unsigned int i = 0; i < 4; i++) + { + int player_idx = m_map_cbox[i]->GetSelection(); + if (player_idx > 0) + m_mapping[i] = m_player_list[player_idx - 1]->pid; + else + m_mapping[i] = -1; + } } void NetPlay::StopGame() diff --git a/Source/Core/DolphinWX/Src/NetWindow.h b/Source/Core/DolphinWX/Src/NetWindow.h index 75f9964e9d..3f8502a6ee 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.h +++ b/Source/Core/DolphinWX/Src/NetWindow.h @@ -124,13 +124,14 @@ private: class PadMapDiag : public wxDialog { public: - PadMapDiag(wxWindow* const parent, int map[]); + PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector& player_list); private: void OnAdjust(wxCommandEvent& event); wxChoice* m_map_cbox[4]; - int* const m_mapping; + PadMapping* const m_mapping; + std::vector& m_player_list; }; namespace NetPlay diff --git a/Source/Core/VideoCommon/Src/DriverDetails.cpp b/Source/Core/VideoCommon/Src/DriverDetails.cpp index 85b7d3a47f..0a115e1354 100644 --- a/Source/Core/VideoCommon/Src/DriverDetails.cpp +++ b/Source/Core/VideoCommon/Src/DriverDetails.cpp @@ -11,8 +11,9 @@ namespace DriverDetails { struct BugInfo { + Vendor m_vendor; // which vendor has the error + Driver m_driver; // which driver has the error Bug m_bug; // Which bug it is - u32 m_devfamily; // Which device(family) has the error double m_versionstart; // When it started double m_versionend; // When it ended bool m_hasbug; // Does it have it? @@ -21,40 +22,27 @@ namespace DriverDetails // Local members Vendor m_vendor = VENDOR_UNKNOWN; Driver m_driver = DRIVER_UNKNOWN; - u32 m_devfamily = 0; double m_version = 0.0; // This is a list of all known bugs for each vendor // We use this to check if the device and driver has a issue - BugInfo m_qualcommbugs[] = { - {BUG_NODYNUBOACCESS, 300, 14.0, -1.0}, - {BUG_BROKENCENTROID, 300, 14.0, -1.0}, - {BUG_BROKENINFOLOG, 300, -1.0, -1.0}, + BugInfo m_known_bugs[] = { + {VENDOR_QUALCOMM, DRIVER_QUALCOMM_3XX, BUG_NODYNUBOACCESS, 14.0, -1.0, true}, + {VENDOR_QUALCOMM, DRIVER_QUALCOMM_3XX, BUG_BROKENCENTROID, 14.0, -1.0, true}, + {VENDOR_QUALCOMM, DRIVER_QUALCOMM_3XX, BUG_BROKENINFOLOG, -1.0, -1.0, true}, + {VENDOR_MESA, DRIVER_NOUVEAU, BUG_BROKENUBO, 900, 916, true}, + {VENDOR_MESA, DRIVER_R600, BUG_BROKENUBO, 900, 913, true}, + {VENDOR_MESA, DRIVER_I965, BUG_BROKENUBO, 900, 920, true}, }; - std::map, BugInfo> m_bugs; - - // Private function - void InitBugMap() - { - switch(m_driver) - { - case DRIVER_QUALCOMM: - for (unsigned int a = 0; a < (sizeof(m_qualcommbugs) / sizeof(BugInfo)); ++a) - m_bugs[std::make_pair(m_vendor, m_qualcommbugs[a].m_bug)] = m_qualcommbugs[a]; - break; - default: - break; - } - } + std::map m_bugs; - void Init(Vendor vendor, Driver driver, const u32 devfamily, const double version) + void Init(Vendor vendor, Driver driver, const double version) { m_vendor = vendor; m_driver = driver; - m_devfamily = devfamily; m_version = version; - InitBugMap(); + if (driver == DRIVER_UNKNOWN) switch(vendor) { @@ -68,12 +56,6 @@ namespace DriverDetails case VENDOR_INTEL: m_driver = DRIVER_INTEL; break; - case VENDOR_ARM: - m_driver = DRIVER_ARM; - break; - case VENDOR_QUALCOMM: - m_driver = DRIVER_QUALCOMM; - break; case VENDOR_IMGTEC: m_driver = DRIVER_IMGTEC; break; @@ -83,16 +65,22 @@ namespace DriverDetails default: break; } - - for (auto it = m_bugs.begin(); it != m_bugs.end(); ++it) - if (it->second.m_devfamily == m_devfamily) - if (it->second.m_versionend == -1.0 || (it->second.m_versionstart <= m_version && it->second.m_versionend > m_version)) - it->second.m_hasbug = true; + + for(unsigned int a = 0; a < (sizeof(m_known_bugs) / sizeof(BugInfo)); ++a) + { + if( + ( m_known_bugs[a].m_vendor == m_vendor || m_known_bugs[a].m_vendor == VENDOR_ALL ) && + ( m_known_bugs[a].m_driver == m_driver || m_known_bugs[a].m_driver == DRIVER_ALL ) && + ( m_known_bugs[a].m_versionstart <= m_version || m_known_bugs[a].m_versionstart == -1 ) && + ( m_known_bugs[a].m_versionend > m_version || m_known_bugs[a].m_versionend == -1 ) + ) + m_bugs.insert(std::make_pair(m_known_bugs[a].m_bug, m_known_bugs[a])); + } } bool HasBug(Bug bug) { - auto it = m_bugs.find(std::make_pair(m_vendor, bug)); + auto it = m_bugs.find(bug); if (it == m_bugs.end()) return false; return it->second.m_hasbug; diff --git a/Source/Core/VideoCommon/Src/DriverDetails.h b/Source/Core/VideoCommon/Src/DriverDetails.h index cb8b104eea..efb0c7c6c0 100644 --- a/Source/Core/VideoCommon/Src/DriverDetails.h +++ b/Source/Core/VideoCommon/Src/DriverDetails.h @@ -10,7 +10,8 @@ namespace DriverDetails // Tegra and Nvidia are separated out due to such substantial differences enum Vendor { - VENDOR_NVIDIA = 0, + VENDOR_ALL = 0, + VENDOR_NVIDIA, VENDOR_ATI, VENDOR_INTEL, VENDOR_ARM, @@ -18,20 +19,25 @@ namespace DriverDetails VENDOR_IMGTEC, VENDOR_TEGRA, VENDOR_VIVANTE, + VENDOR_MESA, VENDOR_UNKNOWN }; // Enum of known drivers enum Driver { - DRIVER_NVIDIA = 0, // Official Nvidia, including mobile GPU + DRIVER_ALL = 0, + DRIVER_NVIDIA, // Official Nvidia, including mobile GPU DRIVER_NOUVEAU, // OSS nouveau DRIVER_ATI, // Official ATI - DRIVER_RADEONHD, // OSS Radeon + DRIVER_R600, // OSS Radeon DRIVER_INTEL, // Official Intel - DRIVER_ARM, // Official Mali driver + DRIVER_I965, // OSS Intel + DRIVER_ARM_4XX, // Official Mali driver + DRIVER_ARM_T6XX, // Official Mali driver DRIVER_LIMA, // OSS Mali driver - DRIVER_QUALCOMM, // Official Adreno driver + DRIVER_QUALCOMM_3XX, // Official Adreno driver 3xx + DRIVER_QUALCOMM_2XX, // Official Adreno driver 2xx DRIVER_FREEDRENO, // OSS Adreno driver DRIVER_IMGTEC, // OSS PowerVR driver DRIVER_VIVANTE, // Official vivante driver @@ -69,10 +75,18 @@ namespace DriverDetails // Adreno devices /always/ return 0 when querying GL_INFO_LOG_LENGTH // They also max out at 1024 bytes(1023 characters + null terminator) for the log BUG_BROKENINFOLOG, + // Bug: UBO buffer offset broken + // Affected devices: all mesa drivers + // Started Version: 9.0 (mesa doesn't support ubo before) + // Ended Version: up to 9.2 + // The offset of glBindBufferRange was ignored on all Mesa Gallium3D drivers until 9.1.3 + // Nouveau stored the offset as u16 which isn't enough for all cases with range until 9.1.6 + // I965 has broken data fetches from uniform buffers which results in a dithering until 9.2.0 + BUG_BROKENUBO, }; // Initializes our internal vendor, device family, and driver version - void Init(Vendor vendor, Driver driver, const u32 devfamily, const double version); + void Init(Vendor vendor, Driver driver, const double version); // Once Vendor and driver version is set, this will return if it has the applicable bug passed to it. bool HasBug(Bug bug); diff --git a/Source/Core/VideoCommon/Src/OnScreenDisplay.cpp b/Source/Core/VideoCommon/Src/OnScreenDisplay.cpp index 29a3837a9a..b66c2019c9 100644 --- a/Source/Core/VideoCommon/Src/OnScreenDisplay.cpp +++ b/Source/Core/VideoCommon/Src/OnScreenDisplay.cpp @@ -11,51 +11,27 @@ #include "RenderBase.h" #include "Timer.h" -#include +#include +#include namespace OSD { -struct MESSAGE +struct Message { - MESSAGE() {} - MESSAGE(const char* p, u32 dw) - { - strncpy(str, p, 255); - str[255] = '\0'; - dwTimeStamp = dw; - } - char str[256]; - u32 dwTimeStamp; + Message() {} + Message(const std::string& s, u32 ts) : str(s), timestamp(ts) {} + + std::string str; + u32 timestamp; }; -class OSDCALLBACK +static std::multimap s_callbacks; +static std::list s_msgList; + +void AddMessage(const std::string& str, u32 ms) { -private: - CallbackPtr m_functionptr; - CallbackType m_type; - u32 m_data; -public: - OSDCALLBACK(CallbackType OnType, CallbackPtr FuncPtr, u32 UserData) - { - m_type = OnType; - m_functionptr = FuncPtr; - m_data = UserData; - } - void Call() - { - m_functionptr(m_data); - } - - CallbackType Type() { return m_type; } -}; - -std::vector m_callbacks; -static std::list s_listMsgs; - -void AddMessage(const char* pstr, u32 ms) -{ - s_listMsgs.push_back(MESSAGE(pstr, Common::Timer::GetTimeMs() + ms)); + s_msgList.push_back(Message(str, Common::Timer::GetTimeMs() + ms)); } void DrawMessages() @@ -63,58 +39,50 @@ void DrawMessages() if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bOnScreenDisplayMessages) return; - if (s_listMsgs.size() > 0) + int left = 25, top = 15; + auto it = s_msgList.begin(); + while (it != s_msgList.end()) { - int left = 25, top = 15; - std::list::iterator it = s_listMsgs.begin(); - while (it != s_listMsgs.end()) + int time_left = (int)(it->timestamp - Common::Timer::GetTimeMs()); + u32 alpha = 255; + + if (time_left < 1024) { - int time_left = (int)(it->dwTimeStamp - Common::Timer::GetTimeMs()); - int alpha = 255; - - if (time_left < 1024) - { - alpha = time_left >> 2; - if (time_left < 0) - alpha = 0; - } - - alpha <<= 24; - - g_renderer->RenderText(it->str, left+1, top+1, 0x000000|alpha); - g_renderer->RenderText(it->str, left, top, 0xffff30|alpha); - top += 15; - - if (time_left <= 0) - it = s_listMsgs.erase(it); - else - ++it; + alpha = time_left >> 2; + if (time_left < 0) + alpha = 0; } + + alpha <<= 24; + + g_renderer->RenderText(it->str.c_str(), left + 1, top + 1, 0x000000 | alpha); + g_renderer->RenderText(it->str.c_str(), left, top, 0xffff30 | alpha); + top += 15; + + if (time_left <= 0) + it = s_msgList.erase(it); + else + ++it; } } void ClearMessages() { - std::list::iterator it = s_listMsgs.begin(); - - while (it != s_listMsgs.end()) - { - it = s_listMsgs.erase(it); - } + s_msgList.clear(); } // On-Screen Display Callbacks -void AddCallback(CallbackType OnType, CallbackPtr FuncPtr, u32 UserData) +void AddCallback(CallbackType type, Callback cb) { - m_callbacks.push_back(OSDCALLBACK(OnType, FuncPtr, UserData)); + s_callbacks.insert(std::pair(type, cb)); } -void DoCallbacks(CallbackType OnType) +void DoCallbacks(CallbackType type) { - for (auto it = m_callbacks.begin(); it != m_callbacks.end(); ++it) + auto it_bounds = s_callbacks.equal_range(type); + for (auto it = it_bounds.first; it != it_bounds.second; ++it) { - if (it->Type() == OnType) - it->Call(); + it->second(); } } diff --git a/Source/Core/VideoCommon/Src/OnScreenDisplay.h b/Source/Core/VideoCommon/Src/OnScreenDisplay.h index ef7d899e1f..a4a377b5d7 100644 --- a/Source/Core/VideoCommon/Src/OnScreenDisplay.h +++ b/Source/Core/VideoCommon/Src/OnScreenDisplay.h @@ -5,11 +5,13 @@ #ifndef _OSD_H_ #define _OSD_H_ -namespace OSD -{ +#include +#include +namespace OSD +{ // On-screen message display -void AddMessage(const char* str, u32 ms = 2000); +void AddMessage(const std::string& str, u32 ms = 2000); void DrawMessages(); // draw the current messages on the screen. Only call once per frame. void ClearMessages(); @@ -20,12 +22,10 @@ enum CallbackType OSD_ONFRAME, OSD_SHUTDOWN }; -typedef void(*CallbackPtr)(u32); +typedef std::function Callback; -void AddCallback(CallbackType OnType, CallbackPtr FuncPtr, u32 UserData); - -void DoCallbacks(CallbackType OnType); -} // namespace +void AddCallback(CallbackType type, Callback cb); +void DoCallbacks(CallbackType type); +} // namespace OSD #endif // _OSD_H_ - diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 6b6c796015..707aec734c 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -97,6 +97,7 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true); iniFile.Get("Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable, false); iniFile.Get("Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, false); + iniFile.Get("Hacks", "ForceDualSourceBlend", &bForceDualSourceBlend, false); iniFile.Get("Hardware", "Adapter", &iAdapter, 0); @@ -265,6 +266,7 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled); iniFile.Set("Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable); iniFile.Set("Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges); + iniFile.Set("Hacks", "ForceDualSourceBlend", bForceDualSourceBlend); iniFile.Set("Hardware", "Adapter", iAdapter); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index b856683595..4a773d30e7 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -124,7 +124,8 @@ struct VideoConfig bool bEnablePixelLighting; bool bHackedBufferUpload; bool bFastDepthCalc; - + //for dx9-backend + bool bForceDualSourceBlend; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 761563264d..ca849ccde5 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -745,6 +745,15 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle // ready to be saved HRESULT hr = PD3DX11SaveTextureToFileA(D3D::context, s_screenshot_texture, D3DX11_IFF_PNG, filename.c_str()); + if (SUCCEEDED(hr)) + { + OSD::AddMessage(StringFromFormat("Saved %i x %i %s", D3D::GetBackBufferWidth(), + D3D::GetBackBufferHeight(), filename.c_str())); + } + else + { + OSD::AddMessage(StringFromFormat("Error saving %s", filename.c_str())); + } return SUCCEEDED(hr); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp index 8a1d5c59a9..fafd06e901 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp @@ -35,6 +35,8 @@ void PerfQuery::DestroyDeviceObjects() void PerfQuery::EnableQuery(PerfQueryGroup type) { + if (!ShouldEmulate()) + return; // Is this sane? if (m_query_count > ARRAYSIZE(m_query_buffer) / 2) WeakFlush(); @@ -58,6 +60,8 @@ void PerfQuery::EnableQuery(PerfQueryGroup type) void PerfQuery::DisableQuery(PerfQueryGroup type) { + if (!ShouldEmulate()) + return; // stop query if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) { @@ -74,6 +78,8 @@ void PerfQuery::ResetQuery() u32 PerfQuery::GetQueryResult(PerfQueryType type) { + if (!ShouldEmulate()) + return 0; u32 result = 0; if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC) @@ -98,6 +104,8 @@ u32 PerfQuery::GetQueryResult(PerfQueryType type) void PerfQuery::FlushOne() { + if (!ShouldEmulate()) + return; auto& entry = m_query_buffer[m_query_read_pos]; DWORD result = 0; @@ -118,12 +126,16 @@ void PerfQuery::FlushOne() // TODO: could selectively flush things, but I don't think that will do much void PerfQuery::FlushResults() { + if (!ShouldEmulate()) + return; while (!IsFlushed()) FlushOne(); } void PerfQuery::WeakFlush() { + if (!ShouldEmulate()) + return; while (!IsFlushed()) { auto& entry = m_query_buffer[m_query_read_pos]; @@ -148,6 +160,8 @@ void PerfQuery::WeakFlush() bool PerfQuery::IsFlushed() const { + if (!ShouldEmulate()) + return true; return 0 == m_query_count; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index a4a788c7e3..ea6503e9e0 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -117,30 +117,30 @@ LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGB8ToRGBA6() /* old code here for reference const char code[] = { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0){\n" - " ocol0 = tex2D(samp0,uv0);\n" - " float4 src8 = round(ocol0*255.f);\n" - " ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2; - " ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4); - " ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6); - " ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F; - " ocol0 /= 63.f;\n" - "}\n" + "uniform sampler samp0 : register(s0);\n" + "void main(\n" + " out float4 ocol0 : COLOR0,\n" + " in float2 uv0 : TEXCOORD0){\n" + " ocol0 = tex2D(samp0,uv0);\n" + " float4 src8 = round(ocol0*255.f);\n" + " ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2; + " ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4); + " ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6); + " ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F; + " ocol0 /= 63.f;\n" + "}\n" }; */ const char code[] = { "uniform sampler samp0 : register(s0);\n" "void main(\n" - "out float4 ocol0 : COLOR0,\n" - "in float2 uv0 : TEXCOORD0){\n" - "float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n" - "float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n" - "float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n" - "ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n" + "out float4 ocol0 : COLOR0,\n" + "in float2 uv0 : TEXCOORD0){\n" + "float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n" + "float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n" + "float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n" + "ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n" "}\n" }; if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); @@ -168,26 +168,28 @@ static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConv if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX); WRITE(p, "void main(\n" - "out float4 ocol0 : COLOR0,\n"); + "out float4 ocol0 : COLOR0,\n"); switch(SSAAMode % MAX_SSAA_SHADERS) { case 0: // 1 Sample WRITE(p, "in float2 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1){\n" - "float4 texcol = tex2D(samp0,uv0.xy);\n"); + "in float uv1 : TEXCOORD1){\n" + "float4 texcol = tex2D(samp0,uv0.xy);\n"); break; - case 1: // 1 Samples SSAA - WRITE(p, "in float2 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1){\n" - "float4 texcol = tex2D(samp0,uv0.xy);\n"); - break; - case 2: // 4 Samples SSAA + case 1: // 4 Samples in 4x SSAA buffer WRITE(p, "in float4 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1,\n" - "in float4 uv2 : TEXCOORD2,\n" - "in float4 uv3 : TEXCOORD3){\n" - "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); + "in float uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3){\n" + "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); + break; + case 2: // 4 Samples in 9x SSAA buffer + WRITE(p, "in float4 uv0 : TEXCOORD0,\n" + "in float uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3){\n" + "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); break; } @@ -196,7 +198,7 @@ static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConv // Watch out for the fire fumes effect in Metroid it's really sensitive to this, // the lighting in RE0 is also way beyond sensitive since the "good value" is hardcoded and Dolphin is almost always off. WRITE(p, "float4 EncodedDepth = frac(texcol.r * (16777215.f/16777216.f) * float4(1.0f,256.0f,256.0f*256.0f,1.0f));\n" - "texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n"); + "texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n"); } else { @@ -217,7 +219,7 @@ static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConv WRITE(p, "}\n"); if (text[sizeof(text) - 1] != 0x7C) PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!"); - + uselocale(old_locale); // restore locale freelocale(locale); return D3D::CompileAndCreatePixelShader(text, (int)strlen(text)); @@ -231,10 +233,10 @@ void PixelShaderCache::Init() { char pprog[3072]; sprintf(pprog, "void main(\n" - "out float4 ocol0 : COLOR0,\n" - " in float4 incol0 : COLOR0){\n" - "ocol0 = incol0;\n" - "}\n"); + "out float4 ocol0 : COLOR0,\n" + " in float4 incol0 : COLOR0){\n" + "ocol0 = incol0;\n" + "}\n"); s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); } @@ -299,27 +301,27 @@ void PixelShaderCache::Shutdown() for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) if(s_CopyProgram[copyMatrixType][depthType][ssaaMode] - && (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])) + && (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])) s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release(); - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; + for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) + for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) + for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) + s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; - if (s_ClearProgram) s_ClearProgram->Release(); - s_ClearProgram = NULL; - if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release(); - s_rgb8_to_rgba6 = NULL; - if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release(); - s_rgba6_to_rgb8 = NULL; + if (s_ClearProgram) s_ClearProgram->Release(); + s_ClearProgram = NULL; + if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release(); + s_rgb8_to_rgba6 = NULL; + if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release(); + s_rgba6_to_rgb8 = NULL; - Clear(); - g_ps_disk_cache.Sync(); - g_ps_disk_cache.Close(); + Clear(); + g_ps_disk_cache.Sync(); + g_ps_disk_cache.Close(); - unique_shaders.clear(); + unique_shaders.clear(); } bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 625db5f44e..bd4f9fed98 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -70,7 +70,7 @@ void SetupDeviceObjects() VertexShaderManager::Dirty(); PixelShaderManager::Dirty(); TextureConverter::Init(); - + // To avoid shader compilation stutters, read back all shaders from cache. VertexShaderCache::Init(); PixelShaderCache::Init(); @@ -122,7 +122,7 @@ Renderer::Renderer() fullScreenRes = 0; D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), - fullScreenRes, backbuffer_ms_mode, false); + fullScreenRes, backbuffer_ms_mode, false); IS_AMD = D3D::IsATIDevice(); @@ -165,7 +165,7 @@ Renderer::Renderer() vp.MaxZ = 1.0f; D3D::dev->SetViewport(&vp); D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0); - + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); vp.X = 0; @@ -189,7 +189,7 @@ Renderer::~Renderer() D3D::EndFrame(); D3D::Present(); D3D::Close(); - + delete[] st; } @@ -267,7 +267,7 @@ bool Renderer::CheckForResize() return true; } - + return false; } @@ -400,7 +400,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) colmat[0] = colmat[5] = colmat[10] = 1.0f; PixelShaderManager::SetColorMatrix(colmat); // set transformation LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBDepthTexture(); - + D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat(); @@ -484,10 +484,10 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // TODO: Speed this up by batching pokes? ResetAPIState(); D3D::drawColorQuad(poke_data, - (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - - (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f, - (float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - - (float)RectToLock.bottom * 2.f / (float)Renderer::GetTargetHeight() + 1.f); + (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f, + - (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f, + (float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f, + - (float)RectToLock.bottom * 2.f / (float)Renderer::GetTargetHeight() + 1.f); RestoreAPIState(); return 0; } @@ -742,6 +742,7 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle PanicAlert("Error saving screen."); return false; } + OSD::AddMessage(StringFromFormat("Saved %i x %i %s", dst_rect.GetWidth(), dst_rect.GetHeight(), filename.c_str())); return true; } @@ -796,7 +797,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Prepare to copy the XFBs to our backbuffer D3D::dev->SetDepthStencilSurface(NULL); D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - + UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); D3DVIEWPORT9 vp; @@ -855,7 +856,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons xfbSource = xfbSourceList[i]; MathUtil::Rectangle sourceRc; - + sourceRc.left = 0; sourceRc.top = 0; sourceRc.right = (float)xfbSource->texWidth; @@ -904,7 +905,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons Width,Height, PixelShaderCache::GetColorCopyProgram(g_ActiveConfig.iMultisampleMode), VertexShaderCache::GetSimpleVertexShader(g_ActiveConfig.iMultisampleMode),Gamma); - + } D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); @@ -952,7 +953,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { char msg [255]; sprintf_s(msg,255, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", - File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), s_recordWidth, s_recordHeight); + File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), s_recordWidth, s_recordHeight); OSD::AddMessage(msg, 2000); } } @@ -1058,7 +1059,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons s_LastAA = newAA; UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - + int SupersampleCoeficient = (s_LastAA % 3) + 1; s_LastEFBScale = g_ActiveConfig.iEFBScale; @@ -1080,6 +1081,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); + SetLineWidth(); } if (XFBWrited) @@ -1140,8 +1142,8 @@ void Renderer::RestoreState() D3D::RefreshRenderState(D3DRS_ZFUNC); } // TODO: Enable this code. Caused glitches for me however (neobrain) -// for (unsigned int i = 0; i < 8; ++i) -// D3D::dev->SetTexture(i, NULL); + // for (unsigned int i = 0; i < 8; ++i) + // D3D::dev->SetTexture(i, NULL); } // ALWAYS call RestoreAPIState for each ResetAPIState call you're doing @@ -1315,9 +1317,8 @@ void Renderer::SetLineWidth() { // We can't change line width in D3D unless we use ID3DXLine float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; - float psize = bpmem.lineptwidth.linesize * fratio / 6.0f; - //little hack to compensate scaling problems in dx9 must be taken out when scaling is fixed. - psize *= 2.0f; + float psize = bpmem.lineptwidth.pointsize * fratio / 6.0f; + psize = psize > 0 ? psize : 1.0; if (psize > m_fMaxPointSize) { psize = m_fMaxPointSize; @@ -1347,7 +1348,7 @@ void Renderer::SetSamplerState(int stage, int texindex) const FourTexUnits &tex = bpmem.tex[texindex]; const TexMode0 &tm0 = tex.texMode0[stage]; const TexMode1 &tm1 = tex.texMode1[stage]; - + D3DTEXTUREFILTERTYPE min, mag, mip; if (g_ActiveConfig.bForceFiltering) { @@ -1369,7 +1370,7 @@ void Renderer::SetSamplerState(int stage, int texindex) D3D::SetSamplerState(stage, D3DSAMP_MINFILTER, min); D3D::SetSamplerState(stage, D3DSAMP_MAGFILTER, mag); D3D::SetSamplerState(stage, D3DSAMP_MIPFILTER, mip); - + D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]); D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index adb4ddf580..dc79d68def 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -37,15 +37,15 @@ inline void DumpBadShaders() { #if defined(_DEBUG) || defined(DEBUGFAST) // TODO: Reimplement! -/* std::string error_shaders; + /* std::string error_shaders; error_shaders.append(VertexShaderCache::GetCurrentShaderCode()); error_shaders.append(PixelShaderCache::GetCurrentShaderCode()); char filename[512] = "bad_shader_combo_0.txt"; int which = 0; while (File::Exists(filename)) { - which++; - sprintf(filename, "bad_shader_combo_%i.txt", which); + which++; + sprintf(filename, "bad_shader_combo_%i.txt", which); } File::WriteStringToFile(true, error_shaders, filename); PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/ @@ -64,7 +64,7 @@ void VertexManager::CreateDeviceObjects() m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; //if device caps are not enough for Vbuffer fall back to vertex arrays if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; - + m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; @@ -144,59 +144,61 @@ void VertexManager::PrepareDrawBuffers(u32 stride) int datasize = IndexGenerator::GetNumVerts() * stride; int TdataSize = IndexGenerator::GetTriangleindexLen(); int LDataSize = IndexGenerator::GetLineindexLen(); - int PDataSize = IndexGenerator::GetPointindexLen(); int IndexDataSize = TdataSize + LDataSize; - DWORD LockMode = D3DLOCK_NOOVERWRITE; - m_vertex_buffer_cursor--; - m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; - if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) + if(IndexDataSize) { - LockMode = D3DLOCK_DISCARD; - m_vertex_buffer_cursor = 0; - m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; - } - if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) - { - DestroyDeviceObjects(); - return; - } - memcpy(pVertices, s_pBaseBufferPointer, datasize); - m_vertex_buffers[m_current_vertex_buffer]->Unlock(); + DWORD LockMode = D3DLOCK_NOOVERWRITE; + m_vertex_buffer_cursor--; + m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; + if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) + { + LockMode = D3DLOCK_DISCARD; + m_vertex_buffer_cursor = 0; + m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; + } + if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) + { + DestroyDeviceObjects(); + return; + } + memcpy(pVertices, s_pBaseBufferPointer, datasize); + m_vertex_buffers[m_current_vertex_buffer]->Unlock(); - LockMode = D3DLOCK_NOOVERWRITE; - if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) - { - LockMode = D3DLOCK_DISCARD; - m_index_buffer_cursor = 0; - m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; - } - - if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) - { - DestroyDeviceObjects(); - return; + LockMode = D3DLOCK_NOOVERWRITE; + if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) + { + LockMode = D3DLOCK_DISCARD; + m_index_buffer_cursor = 0; + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + } + + if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) + { + DestroyDeviceObjects(); + return; + } + if(TdataSize) + { + memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); + pIndices += TdataSize; + } + if(LDataSize) + { + memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); + pIndices += LDataSize; + } + m_index_buffers[m_current_index_buffer]->Unlock(); } - if(TdataSize) - { - memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); - pIndices += TdataSize; - } - if(LDataSize) - { - memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); - pIndices += LDataSize; - } - m_index_buffers[m_current_index_buffer]->Unlock(); if(m_current_stride != stride || m_vertex_buffer_cursor == 0) { m_current_stride = stride; - D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, stride); + D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride); } if (m_index_buffer_cursor == 0) { D3D::SetIndices(m_index_buffers[m_current_index_buffer]); } - + ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize); ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize); } @@ -241,22 +243,28 @@ void VertexManager::DrawVertexBuffer(int stride) } if (points > 0) { - //DrawIndexedPrimitive does not support point list so we have to draw the points one by one - for (int i = 0; i < points; i++) + //DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive + u16* PointIndexBuffer = GetPointIndexBuffer(); + int i = 0; + do { + int count = i + 1; + while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count]) + { + count++; + } if (FAILED(D3D::dev->DrawPrimitive( - D3DPT_POINTLIST, - basevertex + GetPointIndexBuffer()[i], - 1))) + D3DPT_POINTLIST, + basevertex + PointIndexBuffer[i], + count - i))) { DumpBadShaders(); } INCSTAT(stats.thisFrame.numDrawCalls); - } - - + i = count; + } while (i < points); } - + } void VertexManager::DrawVertexArray(int stride) @@ -351,7 +359,7 @@ void VertexManager::vFlush() PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); u32 stride = g_nativeVertexFmt->GetVertexStride(); bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && - bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 2d11368a6d..7c53bdfe23 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -59,72 +59,76 @@ void VertexShaderCache::Init() { char* vProg = new char[2048]; sprintf(vProg,"struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float2 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;\n" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0;\n" - "OUT.vTexCoord1 = inTEX2;\n" - "return OUT;\n" - "}\n"); + "{\n" + "float4 vPosition : POSITION;\n" + "float2 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;\n" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0;\n" + "OUT.vTexCoord1 = inTEX2;\n" + "return OUT;\n" + "}\n"); SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); sprintf(vProg,"struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vColor0 : COLOR0;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n" - "{\n" - "VSOUTPUT OUT;\n" - "OUT.vPosition = inPosition;\n" - "OUT.vColor0 = inColor0;\n" - "return OUT;\n" - "}\n"); + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vColor0 : COLOR0;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n" + "{\n" + "VSOUTPUT OUT;\n" + "OUT.vPosition = inPosition;\n" + "OUT.vColor0 = inColor0;\n" + "return OUT;\n" + "}\n"); ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); sprintf(vProg, "struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float2 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inInvTexSize : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0;\n" - "OUT.vTexCoord1 = inTEX2;\n" - "return OUT;\n" - "}\n"); + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord2 : TEXCOORD2;\n" + "float4 vTexCoord3 : TEXCOORD3;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0.xyyx;\n" + "OUT.vTexCoord1 = inTEX2.x;\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n" + "return OUT;\n" + "}\n"); SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); sprintf(vProg, "struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "float4 vTexCoord2 : TEXCOORD2;\n" - "float4 vTexCoord3 : TEXCOORD3;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0.xyyx;\n" - "OUT.vTexCoord1 = inTEX2.x;\n" - "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-1.0f,-0.5f, 1.0f,-0.5f) * inTEX1.xyyx);\n" - "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 1.0f, 0.5f,-1.0f, 0.5f) * inTEX1.xyyx);\n" - "return OUT;\n" - "}\n"); + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord2 : TEXCOORD2;\n" + "float4 vTexCoord3 : TEXCOORD3;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0.xyyx;\n" + "OUT.vTexCoord1 = inTEX2.x;\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n" + "return OUT;\n" + "}\n"); SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - + Clear(); delete [] vProg; @@ -136,7 +140,7 @@ void VertexShaderCache::Init() char cache_filename[MAX_PATH]; sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); VertexShaderCacheInserter inserter; g_vs_disk_cache.OpenAndRead(cache_filename, inserter); @@ -168,7 +172,7 @@ void VertexShaderCache::Shutdown() if (ClearVertexShader) ClearVertexShader->Release(); ClearVertexShader = NULL; - + Clear(); g_vs_disk_cache.Sync(); g_vs_disk_cache.Close(); @@ -251,10 +255,16 @@ bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, const u8 *byt return false; } +float VSConstantbuffer[4*C_VENVCONST_END]; + void Renderer::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { - const float f[4] = { f1, f2, f3, f4 }; - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); + float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; + VSConstantbuffer_pointer[0] = f1; + VSConstantbuffer_pointer[1] = f2; + VSConstantbuffer_pointer[2] = f3; + VSConstantbuffer_pointer[3] = f4; + DX9::D3D::dev->SetVertexShaderConstantF(const_number, VSConstantbuffer_pointer, 1); } void Renderer::SetVSConstant4fv(unsigned int const_number, const float *f) @@ -264,15 +274,15 @@ void Renderer::SetVSConstant4fv(unsigned int const_number, const float *f) void Renderer::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f) { - float buf[4*C_VENVCONST_END]; + float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; for (unsigned int i = 0; i < count; i++) { - buf[4*i ] = *f++; - buf[4*i+1] = *f++; - buf[4*i+2] = *f++; - buf[4*i+3] = 0.f; + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = 0.f; } - DX9::D3D::dev->SetVertexShaderConstantF(const_number, buf, count); + DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], count); } void Renderer::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 1a4e1bf84d..f3ca31ba82 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -90,10 +90,24 @@ void InitBackendInfo() g_Config.backend_info.bUseRGBATextures = false; g_Config.backend_info.bUseMinimalMipCount = true; g_Config.backend_info.bSupports3DVision = true; - g_Config.backend_info.bSupportsPrimitiveRestart = false; // TODO: figure out if it does + g_Config.backend_info.bSupportsPrimitiveRestart = false; // D3D9 does not support primitive restart g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; // Dual source blend disabled by default until a proper method to test for support is found - g_Config.backend_info.bSupportsDualSourceBlend = false; + g_Config.backend_info.bSupports3DVision = true; + OSVERSIONINFO info; + ZeroMemory(&info, sizeof(OSVERSIONINFO)); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (GetVersionEx(&info)) + { + // dual source blending is only supported in windows 7 o newer. sorry xp users + // we cannot test for device caps because most drivers just declare the minimun caps + // and don't expose their support for some functionalities + g_Config.backend_info.bSupportsDualSourceBlend = g_Config.backend_info.bSupportsSeparateAlphaFunction && (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); + } + else + { + g_Config.backend_info.bSupportsDualSourceBlend = false; + } g_Config.backend_info.bSupportsFormatReinterpretation = true; g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; g_Config.backend_info.bSupportsEarlyZ = false; @@ -112,7 +126,7 @@ void InitBackendInfo() for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); } - + // Clear ppshaders string vector g_Config.backend_info.PPShaders.clear(); @@ -139,6 +153,9 @@ bool VideoBackend::Initialize(void *&window_handle) g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str()); g_Config.UpdateProjectionHack(); g_Config.VerifyValidity(); + // as only some driver/hardware configurations support dual source blending only enable it if is + // configured by user + g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend; UpdateActiveConfig(); window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait.")); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 382784b502..3fac62bd73 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -33,9 +33,12 @@ void SetPSConstant4fvByName(const char * name, unsigned int offset, const float { if (tmp.shader.UniformLocations[a] == -1) return; + else if (tmp.shader.UniformSize[a] <= offset) + return; else { - glUniform4fv(tmp.shader.UniformLocations[a] + offset, count, f); + unsigned int maxcount= tmp.shader.UniformSize[a]-offset; + glUniform4fv(tmp.shader.UniformLocations[a] + offset, std::min(count, maxcount), f); return; } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index d1684f0df5..95c5c3f46d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -78,17 +78,35 @@ void SHADER::SetProgramVariables() glUniformBlockBinding(glprogid, VSBlock_id, 2); } - // We cache our uniform locations for now - // Once we move up to a newer version of GLSL, ~1.30 - // We can remove this + // UBO workaround + for (int a = 0; a < NUM_UNIFORMS; ++a) + { + UniformLocations[a] = glGetUniformLocation(glprogid, UniformNames[a]); + UniformSize[a] = 0; + if(g_ActiveConfig.backend_info.bSupportsGLSLUBO) + break; + } + if(!g_ActiveConfig.backend_info.bSupportsGLSLUBO) + { + int max_uniforms = 0; + char name[50]; + int size; + + glGetProgramiv(glprogid, GL_ACTIVE_UNIFORMS, &max_uniforms); + for(int i=0; ifilename.c_str()).c_str(), 2000); + threadStruct->filename.c_str()), 2000); delete threadStruct; } #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index acf72eeeee..8e2c048f8d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -33,9 +33,12 @@ void SetVSConstant4fvByName(const char * name, unsigned int offset, const float { if (tmp.shader.UniformLocations[a] == -1) return; + else if (tmp.shader.UniformSize[a] <= offset) + return; else { - glUniform4fv(tmp.shader.UniformLocations[a] + offset, count, f); + unsigned int maxcount= tmp.shader.UniformSize[a]-offset; + glUniform4fv(tmp.shader.UniformLocations[a] + offset, std::min(count, maxcount), f); return; } }