mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-04-22 02:39:08 -05:00
Merge branch 'master' into wii-network
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
@@ -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
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<item
|
||||
android:id="@+id/clearGameList"
|
||||
android:title="@string/clear_game_list"
|
||||
android:showAsAction="ifRoom|withText" />
|
||||
</menu>
|
||||
@@ -17,9 +17,10 @@
|
||||
<string name="parent_directory">親ディレクトリ</string>
|
||||
<string name="folder">フォルダ</string>
|
||||
<string name="file_size">ファイルサイズ: </string>
|
||||
<string name="cant_use_compressed_filetypes">圧縮ファイル形式はサポートされていません</string>
|
||||
|
||||
<!-- Game List Activity -->
|
||||
<string name="clear_game_list">クリア</string>
|
||||
<string name="clear_game_list_confirm">ゲームリストからすべての項目を削除しますか?</string>
|
||||
<string name="game_list">ゲームリスト</string>
|
||||
<string name="browse_folder">フォルダの参照</string>
|
||||
<string name="settings">設定</string>
|
||||
@@ -61,7 +62,7 @@
|
||||
<string name="cpu_settings">CPU設定</string>
|
||||
<string name="emu_core_to_use">使用するエミュレーションコア</string>
|
||||
<string name="dual_core">デュアルコア</string>
|
||||
<string name="on_off">有効/無効</string>
|
||||
<string name="dual_core_descrip">処理のための2つのCPUコアを使用して。速度が向上します。</string>
|
||||
<string name="video_settings">ビデオ設定</string>
|
||||
<string name="software_renderer">Software Renderer</string>
|
||||
<string name="opengl_es3">OpenGL ES 3</string>
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
<string name="parent_directory">Parent Directory</string>
|
||||
<string name="folder">Folder</string>
|
||||
<string name="file_size">File Size: </string>
|
||||
<string name="cant_use_compressed_filetypes">Can not use compressed file types</string>
|
||||
|
||||
<!-- Game List Activity -->
|
||||
<string name="clear_game_list">Clear game list</string>
|
||||
<string name="clear_game_list_confirm">Do you want to clear the game list?</string>
|
||||
<string name="game_list">Game List</string>
|
||||
<string name="browse_folder">Browse Folder</string>
|
||||
<string name="settings">Settings</string>
|
||||
@@ -58,11 +59,11 @@
|
||||
<string name="jitil_recompiler">JITIL Recompiler</string>
|
||||
<string name="jit_arm_recompiler">JIT ARM Recompiler</string>
|
||||
<string name="cpu_core">CPU Core</string>
|
||||
<string name="cpu_settings">CPU Settings</string>
|
||||
<string name="cpu_settings">CPU</string>
|
||||
<string name="emu_core_to_use">Emulation core to use</string>
|
||||
<string name="dual_core">Dual Core</string>
|
||||
<string name="on_off">On/Off</string>
|
||||
<string name="video_settings">Video Settings</string>
|
||||
<string name="dual_core_descrip">Split workload to two CPU cores instead of one. Increases speed.</string>
|
||||
<string name="video_settings">Video</string>
|
||||
<string name="software_renderer">Software Renderer</string>
|
||||
<string name="opengl_es3">OpenGL ES 3</string>
|
||||
<string name="video_backend">Video Backend</string>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- CPU Settings -->
|
||||
<CheckBoxPreference
|
||||
android:key="dualCorePref"
|
||||
android:summary="@string/on_off"
|
||||
android:summary="@string/dual_core_descrip"
|
||||
android:title="@string/dual_core" />
|
||||
|
||||
<ListPreference
|
||||
|
||||
@@ -36,8 +36,8 @@ public final class AboutFragment extends Fragment
|
||||
String no = getString(R.string.no);
|
||||
|
||||
List<FolderBrowserItem> Input = new ArrayList<FolderBrowserItem>();
|
||||
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);
|
||||
|
||||
@@ -128,6 +128,8 @@ public final class DolphinEmulator<MainActivity> 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<MainActivity> 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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<String> validExts = new HashSet<String>(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff"));
|
||||
Set<String> invalidExts = new HashSet<String>(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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,11 +58,6 @@ public final class FolderBrowserAdapter extends ArrayAdapter<FolderBrowserItem>
|
||||
if(mainText != null)
|
||||
{
|
||||
mainText.setText(item.getName());
|
||||
|
||||
if (!item.isValid())
|
||||
{
|
||||
mainText.setTextColor(0xFFFF0000);
|
||||
}
|
||||
}
|
||||
|
||||
if(subtitleText != null)
|
||||
|
||||
@@ -10,7 +10,6 @@ public final class FolderBrowserItem implements Comparable<FolderBrowserItem>
|
||||
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<FolderBrowserItem>
|
||||
* @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<FolderBrowserItem>
|
||||
*
|
||||
* @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<FolderBrowserItem>
|
||||
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.
|
||||
|
||||
@@ -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<GameListItem> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ public final class GameListItem implements Comparable<GameListItem>
|
||||
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<GameListItem>
|
||||
* @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<GameListItem>
|
||||
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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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<std::recursive_mutex> 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<int>& 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<const Player *> &player_list)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
std::map<PlayerId, Player>::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<std::recursive_mutex> 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<std::recursive_mutex> 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<std::recursive_mutex> 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<std::mutex> 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;
|
||||
}
|
||||
|
||||
@@ -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<int>& pid_list);
|
||||
void GetPlayers(std::vector<const Player *>& 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<NetPad> m_pad_buffer[4];
|
||||
Common::FifoQueue<NetWiimote> 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;
|
||||
|
||||
@@ -24,7 +24,7 @@ struct Rpt : public std::vector<u8>
|
||||
|
||||
typedef std::vector<Rpt> NetWiimote;
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-18"
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-23"
|
||||
|
||||
// messages
|
||||
enum
|
||||
|
||||
@@ -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<sf::SocketTCP, Client>::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<sf::SocketTCP, Client>::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<std::recursive_mutex> lkp(m_crit.players);
|
||||
std::map<sf::SocketTCP, Client>::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<std::recursive_mutex> lkg(m_crit.game);
|
||||
if (m_is_running)
|
||||
return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
std::map<sf::SocketTCP, Client>::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<std::recursive_mutex> 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<sf::SocketTCP, Client>::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<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac, player.pid);
|
||||
|
||||
@@ -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<sf::SocketTCP, Client> m_players;
|
||||
|
||||
|
||||
@@ -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."));
|
||||
|
||||
@@ -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<std::string> 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() ) )
|
||||
|
||||
@@ -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<const Player *> 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<const Player *>& 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()
|
||||
|
||||
@@ -124,13 +124,14 @@ private:
|
||||
class PadMapDiag : public wxDialog
|
||||
{
|
||||
public:
|
||||
PadMapDiag(wxWindow* const parent, int map[]);
|
||||
PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector<const Player *>& player_list);
|
||||
|
||||
private:
|
||||
void OnAdjust(wxCommandEvent& event);
|
||||
|
||||
wxChoice* m_map_cbox[4];
|
||||
int* const m_mapping;
|
||||
PadMapping* const m_mapping;
|
||||
std::vector<const Player *>& m_player_list;
|
||||
};
|
||||
|
||||
namespace NetPlay
|
||||
|
||||
@@ -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<std::pair<Vendor, Bug>, 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<Bug, BugInfo> 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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -11,51 +11,27 @@
|
||||
#include "RenderBase.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
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<CallbackType, Callback> s_callbacks;
|
||||
static std::list<Message> 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<OSDCALLBACK> m_callbacks;
|
||||
static std::list<MESSAGE> 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<MESSAGE>::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<MESSAGE>::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<CallbackType, Callback>(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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
#ifndef _OSD_H_
|
||||
#define _OSD_H_
|
||||
|
||||
namespace OSD
|
||||
{
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
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<void()> 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_
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<float> 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]);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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."));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; i<max_uniforms; i++)
|
||||
{
|
||||
glGetActiveUniform(glprogid, i, sizeof(name), NULL, &size, NULL, name);
|
||||
for (int a = 0; a < NUM_UNIFORMS; ++a)
|
||||
{
|
||||
if(strstr(name, UniformNames[a]))
|
||||
{
|
||||
UniformSize[a] = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (Sonicadvance): For some reason this fails on my hardware
|
||||
//glGetUniformIndices(glprogid, NUM_UNIFORMS, UniformNames, UniformLocations);
|
||||
// Got to do it this crappy way.
|
||||
UniformLocations[0] = glGetUniformLocation(glprogid, UniformNames[0]);
|
||||
if (!g_ActiveConfig.backend_info.bSupportsGLSLUBO)
|
||||
for (int a = 1; a < NUM_UNIFORMS; ++a)
|
||||
UniformLocations[a] = glGetUniformLocation(glprogid, UniformNames[a]);
|
||||
|
||||
// Bind Texture Sampler
|
||||
for (int a = 0; a <= 9; ++a)
|
||||
@@ -538,8 +556,8 @@ void ProgramShaderCache::CreateHeader ( void )
|
||||
|
||||
, v==GLSL_120 ? "attribute" : "in"
|
||||
, v==GLSL_120 ? "attribute" : "out"
|
||||
, DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "in" : v==GLSL_120 ? "varying" : "centroid in"
|
||||
, DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "out" : v==GLSL_120 ? "varying" : "centroid out"
|
||||
, v==GLSL_120 ? "varying" : DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "in" : "centroid in"
|
||||
, v==GLSL_120 ? "varying" : DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "out" : "centroid out"
|
||||
|
||||
, v==GLSL_120 ? "#define texture texture2D" : ""
|
||||
, v==GLSL_120 ? "#define round(x) floor((x)+0.5f)" : ""
|
||||
|
||||
@@ -56,6 +56,7 @@ struct SHADER
|
||||
|
||||
std::string strvprog, strpprog;
|
||||
GLint UniformLocations[NUM_UNIFORMS];
|
||||
u32 UniformSize[NUM_UNIFORMS];
|
||||
|
||||
void SetProgramVariables();
|
||||
void SetProgramBindings();
|
||||
|
||||
@@ -271,9 +271,9 @@ void InitDriverInfo()
|
||||
{
|
||||
std::string svendor = std::string(g_ogl_config.gl_vendor);
|
||||
std::string srenderer = std::string(g_ogl_config.gl_renderer);
|
||||
std::string sversion = std::string(g_ogl_config.gl_version);
|
||||
DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN;
|
||||
DriverDetails::Driver driver = DriverDetails::DRIVER_UNKNOWN;
|
||||
u32 devfamily = 0;
|
||||
double version = 0.0;
|
||||
|
||||
// Get the vendor first
|
||||
@@ -281,13 +281,12 @@ void InitDriverInfo()
|
||||
vendor = DriverDetails::VENDOR_NVIDIA;
|
||||
else if (svendor == "ATI Technologies Inc." || svendor == "Advanced Micro Devices, Inc.")
|
||||
vendor = DriverDetails::VENDOR_ATI;
|
||||
else if (std::string::npos != sversion.find("Mesa"))
|
||||
vendor = DriverDetails::VENDOR_MESA;
|
||||
else if (std::string::npos != svendor.find("Intel"))
|
||||
vendor = DriverDetails::VENDOR_INTEL;
|
||||
else if (svendor == "ARM")
|
||||
{
|
||||
vendor = DriverDetails::VENDOR_ARM;
|
||||
driver = DriverDetails::DRIVER_ARM;
|
||||
}
|
||||
else if (svendor == "http://limadriver.org/")
|
||||
{
|
||||
vendor = DriverDetails::VENDOR_ARM;
|
||||
@@ -308,24 +307,40 @@ void InitDriverInfo()
|
||||
case DriverDetails::VENDOR_QUALCOMM:
|
||||
{
|
||||
if (std::string::npos != srenderer.find("Adreno (TM) 3"))
|
||||
devfamily = 300;
|
||||
driver = DriverDetails::DRIVER_QUALCOMM_3XX;
|
||||
else
|
||||
devfamily = 200;
|
||||
driver = DriverDetails::DRIVER_QUALCOMM_2XX;
|
||||
double glVersion;
|
||||
sscanf(g_ogl_config.gl_version, "OpenGL ES %lg V@%lg", &glVersion, &version);
|
||||
}
|
||||
break;
|
||||
case DriverDetails::VENDOR_ARM:
|
||||
if (std::string::npos != srenderer.find("Mali-T6"))
|
||||
devfamily = 600;
|
||||
driver = DriverDetails::DRIVER_ARM_T6XX;
|
||||
else if(std::string::npos != srenderer.find("Mali-4"))
|
||||
devfamily = 400;
|
||||
driver = DriverDetails::DRIVER_ARM_4XX;
|
||||
break;
|
||||
case DriverDetails::VENDOR_MESA:
|
||||
{
|
||||
if(svendor == "nouveau")
|
||||
driver = DriverDetails::DRIVER_NOUVEAU;
|
||||
else if(svendor == "Intel Open Source Technology Center")
|
||||
driver = DriverDetails::DRIVER_I965;
|
||||
else if(std::string::npos != srenderer.find("AMD") || std::string::npos != srenderer.find("ATI"))
|
||||
driver = DriverDetails::DRIVER_R600;
|
||||
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
int release = 0;
|
||||
sscanf(g_ogl_config.gl_version, "%*s Mesa %d.%d.%d", &major, &minor, &release);
|
||||
version = 100*major + 10*minor + release;
|
||||
}
|
||||
break;
|
||||
// We don't care about these
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DriverDetails::Init(vendor, driver, devfamily, version);
|
||||
DriverDetails::Init(vendor, driver, version);
|
||||
}
|
||||
|
||||
// Init functions
|
||||
@@ -491,18 +506,12 @@ Renderer::Renderer()
|
||||
if(g_ogl_config.max_samples < 1)
|
||||
g_ogl_config.max_samples = 1;
|
||||
|
||||
if(g_Config.backend_info.bSupportsGLSLUBO && (
|
||||
// hd3000 get corruption, hd4000 also and a big slowdown
|
||||
!strcmp(g_ogl_config.gl_vendor, "Intel Open Source Technology Center") && (
|
||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.0") ||
|
||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.1") ||
|
||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.2") ||
|
||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.3") ||
|
||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.1.0") ||
|
||||
!strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.1.1") )
|
||||
)) {
|
||||
if(g_Config.backend_info.bSupportsGLSLUBO && DriverDetails::HasBug(DriverDetails::BUG_BROKENUBO))
|
||||
{
|
||||
g_Config.backend_info.bSupportsGLSLUBO = false;
|
||||
ERROR_LOG(VIDEO, "Buggy driver detected. Disable UBO");
|
||||
OSD::AddMessage("Major performance warning: Buggy GPU driver detected.", 20000);
|
||||
OSD::AddMessage("Please either install the closed-source GPU driver or update your Mesa 3D version.", 20000);
|
||||
}
|
||||
|
||||
UpdateActiveConfig();
|
||||
@@ -510,7 +519,7 @@ Renderer::Renderer()
|
||||
OSD::AddMessage(StringFromFormat("Video Info: %s, %s, %s",
|
||||
g_ogl_config.gl_vendor,
|
||||
g_ogl_config.gl_renderer,
|
||||
g_ogl_config.gl_version).c_str(), 5000);
|
||||
g_ogl_config.gl_version), 5000);
|
||||
|
||||
WARN_LOG(VIDEO,"Missing OGL Extensions: %s%s%s%s%s%s%s%s%s%s",
|
||||
g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
|
||||
@@ -1805,7 +1814,7 @@ void TakeScreenshot(ScrStrct* threadStruct)
|
||||
|
||||
// Show success messages
|
||||
OSD::AddMessage(StringFromFormat("Saved %i x %i %s", (int)FloatW, (int)FloatH,
|
||||
threadStruct->filename.c_str()).c_str(), 2000);
|
||||
threadStruct->filename.c_str()), 2000);
|
||||
delete threadStruct;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user