diff options
| author | Rachel Bryk <RachelBryk@gmail.com> | 2013-08-15 09:00:04 -0400 |
|---|---|---|
| committer | Rachel Bryk <RachelBryk@gmail.com> | 2013-08-15 09:00:04 -0400 |
| commit | 6d67ea2fdabab5b4daff88409dcb746fab52b483 (patch) | |
| tree | bec0234d1b07915570ca3296b109ab4eb2fd2868 /Source | |
| parent | f51cb0b7eb9c0f261abd3f5d68707ba1f93e3888 (diff) | |
| parent | d16f089e88f63931d792cb4b2fca05747ed8c90a (diff) | |
Merge remote-tracking branch 'origin/master' into wiimote-netplay
Diffstat (limited to 'Source')
82 files changed, 1762 insertions, 753 deletions
diff --git a/Source/Android/res/drawable-hdpi/ic_menu_file.png b/Source/Android/res/drawable-hdpi/ic_menu_file.png Binary files differnew file mode 100644 index 0000000000..f204740905 --- /dev/null +++ b/Source/Android/res/drawable-hdpi/ic_menu_file.png diff --git a/Source/Android/res/drawable-hdpi/ic_menu_folder.png b/Source/Android/res/drawable-hdpi/ic_menu_folder.png Binary files differnew file mode 100644 index 0000000000..6f441b41da --- /dev/null +++ b/Source/Android/res/drawable-hdpi/ic_menu_folder.png diff --git a/Source/Android/res/drawable-mdpi/ic_menu_file.png b/Source/Android/res/drawable-mdpi/ic_menu_file.png Binary files differnew file mode 100644 index 0000000000..dee2577897 --- /dev/null +++ b/Source/Android/res/drawable-mdpi/ic_menu_file.png diff --git a/Source/Android/res/drawable-mdpi/ic_menu_folder.png b/Source/Android/res/drawable-mdpi/ic_menu_folder.png Binary files differnew file mode 100644 index 0000000000..cc81e57f7e --- /dev/null +++ b/Source/Android/res/drawable-mdpi/ic_menu_folder.png diff --git a/Source/Android/res/drawable-xhdpi/ic_menu_file.png b/Source/Android/res/drawable-xhdpi/ic_menu_file.png Binary files differnew file mode 100644 index 0000000000..85369c338e --- /dev/null +++ b/Source/Android/res/drawable-xhdpi/ic_menu_file.png diff --git a/Source/Android/res/drawable-xhdpi/ic_menu_folder.png b/Source/Android/res/drawable-xhdpi/ic_menu_folder.png Binary files differnew file mode 100644 index 0000000000..78500a93c1 --- /dev/null +++ b/Source/Android/res/drawable-xhdpi/ic_menu_folder.png diff --git a/Source/Android/res/layout/about_layout.xml b/Source/Android/res/layout/about_layout.xml new file mode 100644 index 0000000000..7189fd7ce5 --- /dev/null +++ b/Source/Android/res/layout/about_layout.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical" > + + <TextView + android:id="@+id/FolderTitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="5dip" + android:layout_marginTop="5dip" + android:singleLine="true" + android:text="Title" + android:textStyle="bold" /> + + <TextView + android:id="@+id/FolderSubTitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="10dip" + android:text="Subtitle" /> + + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/Source/Android/res/layout/folderbrowser.xml b/Source/Android/res/layout/folderbrowser.xml index 82b94e238f..d3ee4538fa 100644 --- a/Source/Android/res/layout/folderbrowser.xml +++ b/Source/Android/res/layout/folderbrowser.xml @@ -1,29 +1,53 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" > - <LinearLayout - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:orientation="vertical" > + android:layout_height="?android:attr/listPreferredItemHeight" + android:padding="3dip"> + + <ImageView + android:id="@+id/ImageIcon" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + + android:layout_alignParentTop="true" + android:layout_alignParentBottom="true" + android:layout_marginRight="6dip"/> - <TextView - android:id="@+id/FolderTitle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginLeft="5dip" - android:layout_marginTop="5dip" - android:singleLine="true" - android:text="Title" - android:textStyle="bold" /> - - <TextView - android:id="@+id/FolderSubTitle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginLeft="10dip" - android:text="Subtitle" /> - - </LinearLayout> -</LinearLayout> + <TextView + android:id="@+id/FolderSubTitle" + android:layout_width="fill_parent" + android:layout_height="26dip" + + android:layout_toRightOf="@id/ImageIcon" + android:layout_alignParentBottom="true" + android:layout_alignParentRight="true" + + android:singleLine="true" + android:ellipsize="marquee" + android:text="Subtitle" /> + + <TextView + android:id="@+id/FolderTitle" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + + android:layout_toRightOf="@id/ImageIcon" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:layout_above="@id/FolderSubTitle" + android:layout_alignWithParentIfMissing="true" + + android:gravity="center_vertical" + android:text="Title" + android:textStyle="bold" /> + + <ImageView + android:src="@android:drawable/divider_horizontal_dark" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:scaleType="fitXY" + android:paddingLeft="5dp" + android:paddingRight="5dp" + android:paddingBottom="2dp" + android:paddingTop="2dp" /> +</RelativeLayout> diff --git a/Source/Android/res/layout/prefs.xml b/Source/Android/res/layout/prefs.xml index 34700f56b7..d8d8664a97 100644 --- a/Source/Android/res/layout/prefs.xml +++ b/Source/Android/res/layout/prefs.xml @@ -2,23 +2,23 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <PreferenceCategory - android:summary="Settings" - android:title="CPU Settings" + android:summary="@string/settings" + android:title="@string/cpu_settings" android:key="cpuprefcat"> <CheckBoxPreference android:key="dualcorepref" - android:summary="On/Off" - android:title="Dual Core" /> + android:summary="@string/on_off" + android:title="@string/dual_core" /> </PreferenceCategory> <PreferenceCategory - android:summary="Settings" - android:title="Video Settings" + android:summary="@string/settings" + android:title="@string/video_settings" android:key="videoprefcat"> <ListPreference android:entries="@array/gpuOptions" android:entryValues="@array/gpuValues" android:key="gpupref" - android:summary="Video backend to use" - android:title="Video Backend" /> + android:summary="@string/video_backend_to_use" + android:title="@string/video_backend" /> </PreferenceCategory> </PreferenceScreen>
\ No newline at end of file diff --git a/Source/Android/res/layout/sidemenu.xml b/Source/Android/res/layout/sidemenu.xml index 76bc937489..6f4b8d3e5d 100644 --- a/Source/Android/res/layout/sidemenu.xml +++ b/Source/Android/res/layout/sidemenu.xml @@ -5,10 +5,6 @@ android:gravity="left" android:orientation="vertical" > - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" > - <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" @@ -26,6 +22,5 @@ android:textStyle="bold" /> </LinearLayout> - </LinearLayout> </LinearLayout> diff --git a/Source/Android/res/values-ja/strings.xml b/Source/Android/res/values-ja/strings.xml new file mode 100644 index 0000000000..329d464ccb --- /dev/null +++ b/Source/Android/res/values-ja/strings.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <!-- Title of the app --> + <string name="app_name">Dolphin Emulator</string> + + <!-- Navigation-related Strings --> + <string name="drawer_open">ナビゲーションウィンドウを開く</string> + <string name="drawer_close">ナビゲーションウィンドウを閉じる</string> + + <!-- About Fragment --> + <string name="build_revision">ビルドのバージョン:</string> + <string name="supports_gles3">サポートのOpenGL ES 3:</string> + + <!-- Folder Browser --> + <string name="current_dir">現在のディレクトリ: </string> + <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="game_list">ゲームリスト</string> + <string name="browse_folder">フォルダの参照</string> + <string name="settings">設定</string> + <string name="gamepad_config">ゲームパッド設定</string> + <string name="about">について</string> + <string name="loading_browser">ファイルブラウザのロード</string> + <string name="loading_settings">設定のロード</string> + <string name="loading_gamepad">ゲームパッド設定のロード</string> + <string name="loading_about">メニューについてのロード</string> + + <!-- Game List Fragment --> + <string name="file_clicked">クリックされたファイル: </string> + + <!-- Input Config Fragment --> + <string name="draw_onscreen_controls">画面上のコントロールを描画</string> + <string name="button_a">Aボタン</string> + <string name="button_b">Bボタン</string> + <string name="button_start">スタートボタン</string> + <string name="button_x">Xボタン</string> + <string name="button_y">Yボタン</string> + <string name="button_z">Zボタン</string> + <string name="dpad_up">D-Pad: ↑</string> + <string name="dpad_down">D-Pad: ↓</string> + <string name="dpad_left">D-Pad: ←</string> + <string name="dpad_right">D-Pad: →</string> + <string name="main_stick_up">コントロールスティック: ↑</string> + <string name="main_stick_down">コントロールスティック: ↓</string> + <string name="main_stick_left">コントロールスティック: ←</string> + <string name="main_stick_right">コントロールスティック: →</string> + <string name="c_stick_up">C-スティック: ↑</string> + <string name="c_stick_down">C-スティック: ↓</string> + <string name="c_stick_left">C-スティック: ←</string> + <string name="c_stick_right">C-スティック: →</string> + <string name="trigger_left">左のトリガー</string> + <string name="trigger_right">右のトリガー</string> + + <string name="not_drawing_onscreen_controls">コントロールは画面上に描画されていない</string> + <string name="drawing_onscreen_controls">コントロールは画面上に描画されています</string> + <string name="press_button_to_config">%1$sを設定するにはボタンを押して</string> + + <!-- Prefs Fragment --> + <string name="interpreter">Interpreter</string> + <string name="jit64_recompiler">JIT64 Recompiler</string> + <string name="jitil_recompiler">JITIL Recompiler</string> + <string name="jit_arm_recompiler">JIT ARM Recompiler</string> + <string name="cpu_core">CPUコア</string> + <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="video_settings">ビデオ設定</string> + <string name="software_renderer">Software Renderer</string> + <string name="video_backend">ビデオレンダラ</string> + <string name="video_backend_to_use">使用するビデオレンダラー</string> + + <!-- Miscellaneous --> + <string name="yes">はい</string> + <string name="no">いいえ</string> + +</resources> diff --git a/Source/Android/res/values/prefvalues.xml b/Source/Android/res/values/prefvalues.xml index 409666e328..8564801f6f 100644 --- a/Source/Android/res/values/prefvalues.xml +++ b/Source/Android/res/values/prefvalues.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string-array name="gpuOptions"> + <string-array name="gpuOptions" translatable="false"> <item>Software Renderer</item> <item>OpenGL ES 3</item> </string-array> - <string-array name="gpuValues"> + <string-array name="gpuValues" translatable="false"> <item>Software Renderer</item> <item>OGL</item> </string-array> diff --git a/Source/Android/res/values/strings.xml b/Source/Android/res/values/strings.xml index 40a14e3b4e..ea1e02297a 100644 --- a/Source/Android/res/values/strings.xml +++ b/Source/Android/res/values/strings.xml @@ -1,8 +1,83 @@ <?xml version="1.0" encoding="utf-8"?> <resources> + <!-- Title of the app --> <string name="app_name">Dolphin Emulator</string> + + <!-- Navigation-related Strings --> <string name="drawer_open">Open navigation drawer</string> <string name="drawer_close">Close navigation drawer</string> + + <!-- About Fragment --> + <string name="build_revision">Build Revision:</string> + <string name="supports_gles3">Supports OpenGL ES 3:</string> + + <!-- Folder Browser --> + <string name="current_dir">Current Dir: </string> + <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="game_list">Game List</string> + <string name="browse_folder">Browse Folder</string> + <string name="settings">Settings</string> + <string name="gamepad_config">Gamepad Config</string> + <string name="about">About</string> + <string name="loading_browser">Loading up the browser</string> + <string name="loading_settings">Loading up settings</string> + <string name="loading_gamepad">Loading up gamepad config</string> + <string name="loading_about">Loading about menu</string> + + <!-- Game List Fragment --> + <string name="file_clicked">File clicked: </string> + + <!-- Input Config Fragment --> + <string name="draw_onscreen_controls">Draw on-screen controls</string> + <string name="button_a">Button A</string> + <string name="button_b">Button B</string> + <string name="button_start">Button Start</string> + <string name="button_x">Button X</string> + <string name="button_y">Button Y</string> + <string name="button_z">Button Z</string> + <string name="dpad_up">D-Pad Up</string> + <string name="dpad_down">D-Pad Down</string> + <string name="dpad_left">D-Pad Left</string> + <string name="dpad_right">D-Pad Right</string> + <string name="main_stick_up">Main Stick Up</string> + <string name="main_stick_down">Main Stick Down</string> + <string name="main_stick_left">Main Stick Left</string> + <string name="main_stick_right">Main Stick Right</string> + <string name="c_stick_up">C Stick Up</string> + <string name="c_stick_down">C Stick Down</string> + <string name="c_stick_left">C Stick Left</string> + <string name="c_stick_right">C Stick Right</string> + <string name="trigger_left">Trigger L</string> + <string name="trigger_right">Trigger R</string> + + <string name="not_drawing_onscreen_controls">Not drawing on-screen controls</string> + <string name="drawing_onscreen_controls">Drawing on-screen controls</string> + <string name="press_button_to_config">Press button to configure %1$s</string> + + <!-- Prefs Fragment --> + <string name="interpreter">Interpreter</string> + <string name="jit64_recompiler">JIT64 Recompiler</string> + <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="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="software_renderer">Software Renderer</string> + <string name="video_backend">Video Backend</string> + <string name="video_backend_to_use">Video backend to use</string> + + <!-- Miscellaneous --> + <string name="yes">Yes</string> + <string name="no">No</string> </resources> diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/AboutFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/AboutFragment.java index 5c47b79a3e..e05d1c7db2 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/AboutFragment.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/AboutFragment.java @@ -16,45 +16,53 @@ import java.util.List; * Licensed under GPLv2 * Refer to the license.txt file included. */ -public class AboutFragment extends Fragment { +public final class AboutFragment extends Fragment +{ private static Activity m_activity; private ListView mMainList; private FolderBrowserAdapter adapter; - private int configPosition = 0; boolean Configuring = false; boolean firstEvent = true; - public AboutFragment() { + public AboutFragment() + { // Empty constructor required for fragment subclasses } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { View rootView = inflater.inflate(R.layout.gamelist_listview, container, false); mMainList = (ListView) rootView.findViewById(R.id.gamelist); + + String yes = getString(R.string.yes); + String no = getString(R.string.no); - List<GameListItem> Input = new ArrayList<GameListItem>(); - int a = 0; + List<FolderBrowserItem> Input = new ArrayList<FolderBrowserItem>(); + Input.add(new FolderBrowserItem(m_activity, getString(R.string.build_revision), NativeLibrary.GetVersionString(), "", true)); + Input.add(new FolderBrowserItem(m_activity, getString(R.string.supports_gles3), PrefsFragment.SupportsGLES3() ? yes : no, "", true)); - Input.add(a++, new GameListItem(m_activity, "Build Revision", NativeLibrary.GetVersionString(), "", true)); - Input.add(a++, new GameListItem(m_activity, "Supports OpenGL ES 3", PrefsFragment.SupportsGLES3() ? "Yes" : "No", "", true)); - adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, Input); + adapter = new FolderBrowserAdapter(m_activity, R.layout.about_layout, Input); mMainList.setAdapter(adapter); return mMainList; } + @Override - public void onAttach(Activity activity) { + public void onAttach(Activity activity) + { super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception - try { + try + { m_activity = activity; - } catch (ClassCastException e) { + } + catch (ClassCastException e) + { throw new ClassCastException(activity.toString() + " must implement OnGameListZeroListener"); } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java index 6cad8cb3bd..d1e23d1e53 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/DolphinEmulator.java @@ -17,7 +17,7 @@ import android.view.WindowManager; import java.io.*; import java.util.List; -public class DolphinEmulator<MainActivity> extends Activity +public final class DolphinEmulator<MainActivity> extends Activity { static private NativeGLSurfaceView GLview = null; static private boolean Running = false; @@ -25,27 +25,32 @@ public class DolphinEmulator<MainActivity> extends Activity private float screenWidth; private float screenHeight; - private void CopyAsset(String asset, String output) { + private void CopyAsset(String asset, String output) + { InputStream in = null; OutputStream out = null; - try { + + try + { in = getAssets().open(asset); out = new FileOutputStream(output); copyFile(in, out); in.close(); - in = null; - out.flush(); out.close(); - out = null; - } catch(IOException e) { - Log.e("tag", "Failed to copy asset file: " + asset, e); + } + catch(IOException e) + { + Log.e("DolphinEmulator", "Failed to copy asset file: " + asset, e); } } - private void copyFile(InputStream in, OutputStream out) throws IOException { + private void copyFile(InputStream in, OutputStream out) throws IOException + { byte[] buffer = new byte[1024]; int read; - while((read = in.read(buffer)) != -1){ + + while((read = in.read(buffer)) != -1) + { out.write(buffer, 0, read); } } @@ -57,6 +62,7 @@ public class DolphinEmulator<MainActivity> extends Activity if (Running) NativeLibrary.StopEmulation(); } + @Override public void onPause() { @@ -64,6 +70,7 @@ public class DolphinEmulator<MainActivity> extends Activity if (Running) NativeLibrary.PauseEmulation(); } + @Override public void onResume() { @@ -74,11 +81,11 @@ public class DolphinEmulator<MainActivity> extends Activity /** Called when the activity is first created. */ @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) + { super.onCreate(savedInstanceState); if (savedInstanceState == null) { - Intent ListIntent = new Intent(this, GameListActivity.class); startActivityForResult(ListIntent, 1); @@ -96,41 +103,19 @@ public class DolphinEmulator<MainActivity> extends Activity directory.mkdirs(); // Copy assets if needed - java.io.File file = new java.io.File( - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "GC" + File.separator + "dsp_coef.bin"); + File file = new File(GCDir + File.separator + "dsp_coef.bin"); if(!file.exists()) { - CopyAsset("ButtonA.png", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "ButtonA.png"); - CopyAsset("ButtonB.png", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "ButtonB.png"); - CopyAsset("ButtonStart.png", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "ButtonStart.png"); - CopyAsset("NoBanner.png", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "NoBanner.png"); - CopyAsset("GCPadNew.ini", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "Config" + File.separator + "GCPadNew.ini"); - CopyAsset("Dolphin.ini", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "Config" + File.separator + "Dolphin.ini"); - CopyAsset("dsp_coef.bin", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "GC" + File.separator + "dsp_coef.bin"); - CopyAsset("dsp_rom.bin", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "GC" + File.separator + "dsp_rom.bin"); - CopyAsset("font_ansi.bin", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "GC" + File.separator + "font_ansi.bin"); - CopyAsset("font_sjis.bin", - Environment.getExternalStorageDirectory()+File.separator+ - "dolphin-emu" + File.separator + "GC" + File.separator + "font_sjis.bin"); + CopyAsset("ButtonA.png", BaseDir + File.separator + "ButtonA.png"); + CopyAsset("ButtonB.png", BaseDir + File.separator + "ButtonB.png"); + CopyAsset("ButtonStart.png", BaseDir + File.separator + "ButtonStart.png"); + CopyAsset("NoBanner.png", BaseDir + File.separator + "NoBanner.png"); + CopyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini"); + CopyAsset("Dolphin.ini", ConfigDir + File.separator + "Dolphin.ini"); + CopyAsset("dsp_coef.bin", GCDir + File.separator + "dsp_coef.bin"); + CopyAsset("dsp_rom.bin", GCDir + File.separator + "dsp_rom.bin"); + CopyAsset("font_ansi.bin", GCDir + File.separator + "font_ansi.bin"); + CopyAsset("font_sjis.bin", GCDir + File.separator + "font_sjis.bin"); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor editor = prefs.edit(); @@ -169,11 +154,9 @@ public class DolphinEmulator<MainActivity> extends Activity @Override public boolean onTouchEvent(MotionEvent event) { - float X, Y; - int Action; - X = event.getX(); - Y = event.getY(); - Action = event.getActionMasked(); + float X = event.getX(); + float Y = event.getY(); + int Action = event.getActionMasked(); // Converts button locations 0 - 1 to OGL screen coords -1.0 - 1.0 float ScreenX = ((X / screenWidth) * 2.0f) - 1.0f; @@ -186,7 +169,8 @@ public class DolphinEmulator<MainActivity> extends Activity // Gets button presses @Override - public boolean dispatchKeyEvent(KeyEvent event) { + public boolean dispatchKeyEvent(KeyEvent event) + { int action = 0; // Special catch for the back key @@ -208,7 +192,8 @@ public class DolphinEmulator<MainActivity> extends Activity if (Running) { - switch (event.getAction()) { + switch (event.getAction()) + { case KeyEvent.ACTION_DOWN: action = 0; break; @@ -226,21 +211,21 @@ public class DolphinEmulator<MainActivity> extends Activity } @Override - public boolean dispatchGenericMotionEvent(MotionEvent event) { - if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0) || !Running) { + public boolean dispatchGenericMotionEvent(MotionEvent event) + { + if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0) || !Running) + { return super.dispatchGenericMotionEvent(event); } InputDevice input = event.getDevice(); List<InputDevice.MotionRange> motions = input.getMotionRanges(); - for (int a = 0; a < motions.size(); ++a) + + for (InputDevice.MotionRange range : motions) { - InputDevice.MotionRange range; - range = motions.get(a); - NativeLibrary.onGamePadMoveEvent(InputConfigFragment.getInputDesc(input), range.getAxis(), event.getAxisValue(range.getAxis())); + NativeLibrary.onGamePadMoveEvent(InputConfigFragment.getInputDesc(input), range.getAxis(), event.getAxisValue(range.getAxis())); } return true; } - -}
\ No newline at end of file +}
\ No newline at end of file diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java index 9094486197..3e2c93a3eb 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowser.java @@ -14,7 +14,8 @@ import android.widget.Toast; import java.io.File; import java.util.*; -public class FolderBrowser extends Fragment { +public final class FolderBrowser extends Fragment +{ private Activity m_activity; private FolderBrowserAdapter adapter; private ListView mDrawerList; @@ -24,14 +25,14 @@ public class FolderBrowser extends Fragment { // Populates the FolderView with the given currDir's contents. private void Fill(File currDir) { - m_activity.setTitle("Current Dir: " + currDir.getName()); + m_activity.setTitle(getString(R.string.current_dir) + currDir.getName()); File[] dirs = currDir.listFiles(); - List<GameListItem>dir = new ArrayList<GameListItem>(); - List<GameListItem>fls = new ArrayList<GameListItem>(); + List<FolderBrowserItem>dir = new ArrayList<FolderBrowserItem>(); + List<FolderBrowserItem>fls = new ArrayList<FolderBrowserItem>(); // Supported extensions to filter by Set<String> validExts = new HashSet<String>(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff")); - Set<String> archiveExts = new HashSet<String>(Arrays.asList(".zip", ".rar", ".7z")); + Set<String> invalidExts = new HashSet<String>(Arrays.asList(".zip", ".rar", ".7z")); // Search for any directories or supported files within the current dir. try @@ -44,17 +45,17 @@ public class FolderBrowser extends Fragment { { if(entry.isDirectory()) { - dir.add(new GameListItem(m_activity, entryName,"Folder",entry.getAbsolutePath(), true)); + dir.add(new FolderBrowserItem(m_activity, entryName, entry.getAbsolutePath(), true)); } else { if (validExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) { - fls.add(new GameListItem(m_activity, entryName,"File Size: "+entry.length(),entry.getAbsolutePath(), true)); + fls.add(new FolderBrowserItem(m_activity, entryName,getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), true)); } - else if (archiveExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) + else if (invalidExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) { - fls.add(new GameListItem(m_activity, entryName,"File Size: "+entry.length(),entry.getAbsolutePath(), false)); + fls.add(new FolderBrowserItem(m_activity, entryName,getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), false)); } } } @@ -70,16 +71,16 @@ public class FolderBrowser extends Fragment { // Check for a parent directory to the one we're currently in. if (!currDir.getPath().equalsIgnoreCase("/")) - dir.add(0, new GameListItem(m_activity, "..", "Parent Directory", currDir.getParent(), true)); + dir.add(0, new FolderBrowserItem(m_activity, "..", getString(R.string.parent_directory), currDir.getParent(), true)); adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, dir); mDrawerList = (ListView) rootView.findViewById(R.id.gamelist); mDrawerList.setAdapter(adapter); mDrawerList.setOnItemClickListener(mMenuItemClickListener); } + @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if(currentDir == null) currentDir = new File(Environment.getExternalStorageDirectory().getPath()); @@ -94,29 +95,35 @@ public class FolderBrowser extends Fragment { { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - GameListItem o = adapter.getItem(position); - if(o.getData().equalsIgnoreCase("folder") || o.getData().equalsIgnoreCase("parent directory")) + FolderBrowserItem o = adapter.getItem(position); + if(o.isDirectory() || o.getSubtitle().equalsIgnoreCase(getString(R.string.parent_directory))) { currentDir = new File(o.getPath()); Fill(currentDir); } else - if (o.isValid()) + { + if (o.isValidItem()) FolderSelected(); else - Toast.makeText(m_activity, "Can not use compressed file types.", Toast.LENGTH_LONG).show(); + Toast.makeText(m_activity, getString(R.string.cant_use_compressed_filetypes), Toast.LENGTH_LONG).show(); + } } }; @Override - public void onAttach(Activity activity) { + public void onAttach(Activity activity) + { super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception - try { + try + { m_activity = activity; - } catch (ClassCastException e) { + } + catch (ClassCastException e) + { throw new ClassCastException(activity.toString() + " must implement OnGameListZeroListener"); } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserAdapter.java index 30c1747781..979ad35865 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserAdapter.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserAdapter.java @@ -1,58 +1,88 @@ package org.dolphinemu.dolphinemu; import android.content.Context; +import android.content.res.Resources; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.ImageView; import android.widget.TextView; import java.util.List; -public class FolderBrowserAdapter extends ArrayAdapter<GameListItem>{ +public final class FolderBrowserAdapter extends ArrayAdapter<FolderBrowserItem> +{ + private final Context c; + private final int id; + private final List<FolderBrowserItem> items; - private Context c; - private int id; - private List<GameListItem>items; - - public FolderBrowserAdapter(Context context, int textViewResourceId, - List<GameListItem> objects) { + public FolderBrowserAdapter(Context context, int textViewResourceId, List<FolderBrowserItem> objects) + { super(context, textViewResourceId, objects); c = context; id = textViewResourceId; items = objects; } - public GameListItem getItem(int i) + public FolderBrowserItem getItem(int i) { return items.get(i); } + @Override - public View getView(int position, View convertView, ViewGroup parent) { + public View getView(int position, View convertView, ViewGroup parent) + { View v = convertView; - if (v == null) { - LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, null); + if (v == null) + { + LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, parent, false); } - final GameListItem o = items.get(position); - if (o != null) { - TextView t1 = (TextView) v.findViewById(R.id.FolderTitle); - TextView t2 = (TextView) v.findViewById(R.id.FolderSubTitle); + + final FolderBrowserItem item = items.get(position); + if (item != null) + { + ImageView iconView = (ImageView) v.findViewById(R.id.ImageIcon); + TextView mainText = (TextView) v.findViewById(R.id.FolderTitle); + TextView subtitleText = (TextView) v.findViewById(R.id.FolderSubTitle); - if(t1!=null) + if(mainText != null) { - t1.setText(o.getName()); - if (!o.isValid()) - t1.setTextColor(0xFFFF0000); + mainText.setText(item.getName()); + + if (!item.isValidItem()) + { + mainText.setTextColor(0xFFFF0000); + } + } + + if(subtitleText != null) + { + // Remove the subtitle for all folders, except for the parent directory folder. + if (item.isDirectory() && !item.getSubtitle().equals(c.getResources().getString(R.string.parent_directory))) + { + subtitleText.setVisibility(View.GONE); + } + else + { + subtitleText.setText(item.getSubtitle()); + } + } + + if (iconView != null) + { + if (item.isDirectory()) + { + iconView.setImageResource(R.drawable.ic_menu_folder); + } + else + { + iconView.setImageResource(R.drawable.ic_menu_file); + } } - if(t2!=null) - t2.setText(o.getData()); } return v; } - - - } - diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserItem.java new file mode 100644 index 0000000000..a895da8c43 --- /dev/null +++ b/Source/Android/src/org/dolphinemu/dolphinemu/FolderBrowserItem.java @@ -0,0 +1,131 @@ +package org.dolphinemu.dolphinemu; + +import java.io.File; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; + +/** + * Represents an item in the folder browser list. + */ +public final class FolderBrowserItem implements Comparable<FolderBrowserItem> +{ + private final Context ctx; + private final String name; + private final String subtitle; + private final String path; + private final boolean isValid; + private final File underlyingFile; + + /** + * Constructor + * + * @param ctx Context this FolderBrowserItem is being used in. + * @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(Context ctx, String name, String subtitle, String path, boolean isValid) + { + this.ctx = ctx; + this.name = name; + this.subtitle = subtitle; + this.path = path; + this.isValid = isValid; + this.underlyingFile = new File(path); + } + + /** + * Constructor. Initializes a FolderBrowserItem with an empty subtitle. + * + * @param ctx Context this FolderBrowserItem is being used in. + * @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(Context ctx, String name, String path, boolean isValid) + { + this.ctx = ctx; + this.name = name; + this.subtitle = ""; + this.path = path; + this.isValid = isValid; + this.underlyingFile = new File(path); + } + + /** + * Gets the name of the file/folder represented by this FolderBrowserItem. + * + * @return the name of the file/folder represented by this FolderBrowserItem. + */ + public String getName() + { + return name; + } + + /** + * Gets the subtitle text of this FolderBrowserItem. + * + * @return the subtitle text of this FolderBrowserItem. + */ + public String getSubtitle() + { + return subtitle; + } + + /** + * Gets the path of the file/folder represented by this FolderBrowserItem. + * + * @return the path of the file/folder represented by this FolderBrowserItem. + */ + public String getPath() + { + 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 isValidItem() + { + return isValid; + } + + /** + * Gets the {@link File} representation of the underlying file/folder + * represented by this FolderBrowserItem. + * + * @return the {@link File} representation of the underlying file/folder + * represented by this FolderBrowserItem. + */ + public File getUnderlyingFile() + { + return underlyingFile; + } + + /** + * Gets whether or not this FolderBrowserItem represents a directory. + * + * @return true if this FolderBrowserItem represents a directory, false otherwise. + */ + public boolean isDirectory() + { + return underlyingFile.isDirectory(); + } + + public int compareTo(FolderBrowserItem other) + { + if(this.name != null) + return this.name.toLowerCase().compareTo(other.getName().toLowerCase()); + else + throw new IllegalArgumentException(); + } +} diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListActivity.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListActivity.java index 9a48de4d8b..2bd61cb0f2 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListActivity.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListActivity.java @@ -22,8 +22,9 @@ import java.util.List; * Licensed under GPLv2 * Refer to the license.txt file included. */ -public class GameListActivity extends Activity - implements GameListFragment.OnGameListZeroListener{ +public final class GameListActivity extends Activity + implements GameListFragment.OnGameListZeroListener +{ private int mCurFragmentNum = 0; private Fragment mCurFragment; @@ -43,7 +44,8 @@ public class GameListActivity extends Activity } @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(Bundle savedInstanceState) + { super.onCreate(savedInstanceState); setContentView(R.layout.gamelist_activity); mMe = this; @@ -52,11 +54,11 @@ public class GameListActivity extends Activity mDrawerList = (ListView) findViewById(R.id.left_drawer); List<SideMenuItem> dir = new ArrayList<SideMenuItem>(); - dir.add(new SideMenuItem("Game List", 0)); - dir.add(new SideMenuItem("Browse Folder", 1)); - dir.add(new SideMenuItem("Settings", 2)); - dir.add(new SideMenuItem("Gamepad Config", 3)); - dir.add(new SideMenuItem("About", 4)); + dir.add(new SideMenuItem(getString(R.string.game_list), 0)); + dir.add(new SideMenuItem(getString(R.string.browse_folder), 1)); + dir.add(new SideMenuItem(getString(R.string.settings), 2)); + dir.add(new SideMenuItem(getString(R.string.gamepad_config), 3)); + dir.add(new SideMenuItem(getString(R.string.about), 4)); mDrawerAdapter = new SideMenuAdapter(this, R.layout.sidemenu, dir); mDrawerList.setAdapter(mDrawerAdapter); @@ -94,16 +96,19 @@ public class GameListActivity extends Activity FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); } + public void SwitchPage(int toPage) { if (mCurFragmentNum == toPage) return; + switch (mCurFragmentNum) { // Folder browser case 1: recreateFragment(); - break; + break; + // Settings case 2: { @@ -147,6 +152,7 @@ public class GameListActivity extends Activity } } break; + case 3: // Gamepad settings { InputConfigAdapter adapter = ((InputConfigFragment)mCurFragment).getAdapter(); @@ -162,11 +168,13 @@ public class GameListActivity extends Activity } } break; + case 0: // Game List case 4: // About /* Do Nothing */ break; } + switch(toPage) { case 0: @@ -177,46 +185,52 @@ public class GameListActivity extends Activity fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); } break; + case 1: { - Toast.makeText(mMe, "Loading up the browser", Toast.LENGTH_SHORT).show(); + Toast.makeText(mMe, getString(R.string.loading_browser), Toast.LENGTH_SHORT).show(); mCurFragmentNum = 1; mCurFragment = new FolderBrowser(); FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); } break; + case 2: { - Toast.makeText(mMe, "Loading up settings", Toast.LENGTH_SHORT).show(); + Toast.makeText(mMe, getString(R.string.loading_settings), Toast.LENGTH_SHORT).show(); mCurFragmentNum = 2; mCurFragment = new PrefsFragment(); FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); } break; + case 3: { - Toast.makeText(mMe, "Loading up gamepad config", Toast.LENGTH_SHORT).show(); + Toast.makeText(mMe, getString(R.string.loading_gamepad), Toast.LENGTH_SHORT).show(); mCurFragmentNum = 3; mCurFragment = new InputConfigFragment(); FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); } break; + case 4: { - Toast.makeText(mMe, "Loading up About", Toast.LENGTH_SHORT).show(); + Toast.makeText(mMe, getString(R.string.about), Toast.LENGTH_SHORT).show(); mCurFragmentNum = 4; mCurFragment = new AboutFragment(); FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit(); } break; + default: break; } } + private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) @@ -232,57 +246,75 @@ public class GameListActivity extends Activity */ @Override - protected void onPostCreate(Bundle savedInstanceState) { + protected void onPostCreate(Bundle savedInstanceState) + { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override - public void onConfigurationChanged(Configuration newConfig) { + public void onConfigurationChanged(Configuration newConfig) + { super.onConfigurationChanged(newConfig); - // Pass any configuration change to the drawer toggls + // Pass any configuration change to the drawer toggle mDrawerToggle.onConfigurationChanged(newConfig); } /* Called whenever we call invalidateOptionsMenu() */ @Override - public boolean onPrepareOptionsMenu(Menu menu) { + public boolean onPrepareOptionsMenu(Menu menu) + { return super.onPrepareOptionsMenu(menu); } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(MenuItem item) + { // The action bar home/up action should open or close the drawer. // ActionBarDrawerToggle will take care of this. - if (mDrawerToggle.onOptionsItemSelected(item)) { + if (mDrawerToggle.onOptionsItemSelected(item)) + { return true; } + return super.onOptionsItemSelected(item); } + public void onBackPressed() { SwitchPage(0); } - public interface OnGameConfigListener { + public interface OnGameConfigListener + { public boolean onMotionEvent(MotionEvent event); public boolean onKeyEvent(KeyEvent event); } + // Gets move(triggers, joystick) events @Override - public boolean dispatchGenericMotionEvent(MotionEvent event) { + public boolean dispatchGenericMotionEvent(MotionEvent event) + { if (mCurFragmentNum == 3) + { if (((OnGameConfigListener)mCurFragment).onMotionEvent(event)) return true; + } + return super.dispatchGenericMotionEvent(event); } + // Gets button presses @Override - public boolean dispatchKeyEvent(KeyEvent event) { + public boolean dispatchKeyEvent(KeyEvent event) + { if (mCurFragmentNum == 3) + { if (((OnGameConfigListener)mCurFragment).onKeyEvent(event)) return true; + } + return super.dispatchKeyEvent(event); } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListAdapter.java index 986f33555b..d7170bb474 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListAdapter.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListAdapter.java @@ -10,13 +10,14 @@ import android.widget.TextView; import java.util.List; -public class GameListAdapter extends ArrayAdapter<GameListItem>{ +public final class GameListAdapter extends ArrayAdapter<GameListItem> +{ + private final Context c; + private final int id; + private final List<GameListItem>items; - private Context c; - private int id; - private List<GameListItem>items; - - public GameListAdapter(Context context, int textViewResourceId, List<GameListItem> objects) { + public GameListAdapter(Context context, int textViewResourceId, List<GameListItem> objects) + { super(context, textViewResourceId, objects); c = context; id = textViewResourceId; @@ -29,26 +30,30 @@ public class GameListAdapter extends ArrayAdapter<GameListItem>{ } @Override - public View getView(int position, View convertView, ViewGroup parent) { + public View getView(int position, View convertView, ViewGroup parent) + { View v = convertView; - if (v == null) { + if (v == null) + { LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(id, null); } - final GameListItem o = items.get(position); - if (o != null) { - TextView t1 = (TextView) v.findViewById(R.id.GameItemTitle); - TextView t2 = (TextView) v.findViewById(R.id.GameItemSubText); - ImageView v1 = (ImageView) v.findViewById(R.id.GameItemIcon); - - if(t1!=null) - t1.setText(o.getName()); - if(t2!=null) - t2.setText(o.getData()); - if(v1!=null) - v1.setImageBitmap(o.getImage()); - } + final GameListItem item = items.get(position); + if (item != null) + { + TextView title = (TextView) v.findViewById(R.id.GameItemTitle); + TextView subtitle = (TextView) v.findViewById(R.id.GameItemSubText); + ImageView icon = (ImageView) v.findViewById(R.id.GameItemIcon); + + if(title != null) + title.setText(item.getName()); + if(subtitle != null) + subtitle.setText(item.getData()); + if(icon != null) + icon.setImageBitmap(item.getImage()); + } + return v; } } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListFragment.java index 152c18662b..13f66c1c83 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListFragment.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListFragment.java @@ -24,20 +24,23 @@ import java.util.Set; * Licensed under GPLv2 * Refer to the license.txt file included. */ -public class GameListFragment extends Fragment +public final class GameListFragment extends Fragment { private ListView mMainList; private GameListAdapter mGameAdapter; private static GameListActivity mMe; OnGameListZeroListener mCallback; - public interface OnGameListZeroListener { + public interface OnGameListZeroListener + { public void onZeroFiles(); } - public GameListFragment() { + public GameListFragment() + { // Empty constructor required for fragment subclasses } + private void Fill() { List<GameListItem> fls = new ArrayList<GameListItem>(); @@ -49,9 +52,9 @@ public class GameListFragment extends Fragment for (int a = 0; a < intDirectories; ++a) { - String BrowseDir = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPath" + Integer.toString(a), ""); + String BrowseDir = NativeLibrary.GetConfig("Dolphin.ini", "General", "GCMPath" + a, ""); File currentDir = new File(BrowseDir); - File[]dirs = currentDir.listFiles(); + File[] dirs = currentDir.listFiles(); try { for(File entry : dirs) @@ -63,7 +66,7 @@ public class GameListFragment extends Fragment if(!entry.isDirectory()) { if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) - fls.add(new GameListItem(mMe.getApplicationContext(), entryName,"File Size: "+entry.length(),entry.getAbsolutePath(), true)); + fls.add(new GameListItem(mMe.getApplicationContext(), entryName, getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), true)); } } } @@ -81,8 +84,8 @@ public class GameListFragment extends Fragment } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { View rootView = inflater.inflate(R.layout.gamelist_listview, container, false); mMainList = (ListView) rootView.findViewById(R.id.gamelist); mMainList.setOnItemClickListener(mGameItemClickListener); @@ -91,36 +94,43 @@ public class GameListFragment extends Fragment return mMainList; } + private AdapterView.OnItemClickListener mGameItemClickListener = new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { GameListItem o = mGameAdapter.getItem(position); - if(!(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory"))) + if(!(o.getData().equalsIgnoreCase(getString(R.string.folder))||o.getData().equalsIgnoreCase(getString(R.string.parent_directory)))) { onFileClick(o.getPath()); } } }; + private void onFileClick(String o) { - Toast.makeText(mMe, "File Clicked: " + o, Toast.LENGTH_SHORT).show(); + Toast.makeText(mMe, getString(R.string.file_clicked) + o, Toast.LENGTH_SHORT).show(); Intent intent = new Intent(); intent.putExtra("Select", o); mMe.setResult(Activity.RESULT_OK, intent); mMe.finish(); } + @Override - public void onAttach(Activity activity) { + public void onAttach(Activity activity) + { super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception - try { + try + { mCallback = (OnGameListZeroListener) activity; mMe = (GameListActivity) activity; - } catch (ClassCastException e) { + } + catch (ClassCastException e) + { throw new ClassCastException(activity.toString() + " must implement OnGameListZeroListener"); } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java index 427cd132f8..a9ef41c6d4 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/GameListItem.java @@ -8,36 +8,44 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -public class GameListItem implements Comparable<GameListItem>{ - private String name; - private String data; - private String path; +public final class GameListItem implements Comparable<GameListItem> +{ + private final String name; + private final String data; + private final String path; + private final boolean isValid; private Bitmap image; - private boolean m_valid; - public GameListItem(Context ctx, String n,String d,String p, boolean valid) + public GameListItem(Context ctx, String name, String data, String path, boolean isValid) { - name = n; - data = d; - path = p; - m_valid = valid; + this.name = name; + this.data = data; + this.path = path; + this.isValid = isValid; + File file = new File(path); if (!file.isDirectory() && !path.equals("")) { int[] Banner = NativeLibrary.GetBanner(path); if (Banner[0] == 0) { - try { - InputStream path = ctx.getAssets().open("NoBanner.png"); - image = BitmapFactory.decodeStream(path); - } catch (IOException e) { + try + { + InputStream noBannerPath = ctx.getAssets().open("NoBanner.png"); + image = BitmapFactory.decodeStream(noBannerPath); + } + catch (IOException e) + { // TODO Auto-generated catch block e.printStackTrace(); } } else + { image = Bitmap.createBitmap(Banner, 96, 32, Bitmap.Config.ARGB_8888); + } + name = NativeLibrary.GetTitle(path); } } @@ -56,13 +64,15 @@ public class GameListItem implements Comparable<GameListItem>{ { return path; } + public Bitmap getImage() { return image; } + public boolean isValid() { - return m_valid; + return isValid; } public int compareTo(GameListItem o) diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigAdapter.java index b0984dd08a..12541b8b37 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigAdapter.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigAdapter.java @@ -14,13 +14,14 @@ import java.util.List; * Licensed under GPLv2 * Refer to the license.txt file included. */ -public class InputConfigAdapter extends ArrayAdapter<InputConfigItem> { - private Context c; - private int id; - private List<InputConfigItem> items; +public final class InputConfigAdapter extends ArrayAdapter<InputConfigItem> +{ + private final Context c; + private final int id; + private final List<InputConfigItem> items; - public InputConfigAdapter(Context context, int textViewResourceId, - List<InputConfigItem> objects) { + public InputConfigAdapter(Context context, int textViewResourceId, List<InputConfigItem> objects) + { super(context, textViewResourceId, objects); c = context; id = textViewResourceId; @@ -31,26 +32,30 @@ public class InputConfigAdapter extends ArrayAdapter<InputConfigItem> { { return items.get(i); } + @Override - public View getView(int position, View convertView, ViewGroup parent) { + public View getView(int position, View convertView, ViewGroup parent) + { View v = convertView; - if (v == null) { + if (v == null) + { LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, null); + v = vi.inflate(id, parent, false); } - final InputConfigItem o = items.get(position); - if (o != null) { - TextView t1 = (TextView) v.findViewById(R.id.FolderTitle); - TextView t2 = (TextView) v.findViewById(R.id.FolderSubTitle); - - if(t1!=null) - t1.setText(o.getName()); - if(t2!=null) - t2.setText(o.getBind()); + + final InputConfigItem item = items.get(position); + if (item != null) + { + TextView title = (TextView) v.findViewById(R.id.FolderTitle); + TextView subtitle = (TextView) v.findViewById(R.id.FolderSubTitle); + + if(title != null) + title.setText(item.getName()); + + if(subtitle != null) + subtitle.setText(item.getBind()); } + return v; } - - - } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigFragment.java index 3a6e855c3b..530f8b1d3b 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigFragment.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigFragment.java @@ -18,8 +18,9 @@ import java.util.List; * Licensed under GPLv2 * Refer to the license.txt file included. */ -public class InputConfigFragment extends Fragment - implements GameListActivity.OnGameConfigListener{ +public final class InputConfigFragment extends Fragment + implements GameListActivity.OnGameConfigListener +{ private Activity m_activity; private ListView mDrawerList; private InputConfigAdapter adapter; @@ -31,45 +32,47 @@ public class InputConfigFragment extends Fragment { if (input == null) return "null"; // Happens when the inputdevice is from an unknown source + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) + { return input.getDescriptor(); + } else { List<InputDevice.MotionRange> motions = input.getMotionRanges(); String fakeid = ""; + for (InputDevice.MotionRange range : motions) fakeid += range.getAxis(); + return fakeid; } } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { List<InputConfigItem> Input = new ArrayList<InputConfigItem>(); - int a = 0; - - Input.add(a++, new InputConfigItem("Draw on-screen controls", "Android-ScreenControls", "True")); - Input.add(a++, new InputConfigItem("Button A", "Android-InputA")); - Input.add(a++, new InputConfigItem("Button B", "Android-InputB")); - Input.add(a++, new InputConfigItem("Button Start", "Android-InputStart")); - Input.add(a++, new InputConfigItem("Button X", "Android-InputX")); - Input.add(a++, new InputConfigItem("Button Y", "Android-InputY")); - Input.add(a++, new InputConfigItem("Button Z", "Android-InputZ")); - Input.add(a++, new InputConfigItem("D-Pad Up", "Android-DPadUp")); - Input.add(a++, new InputConfigItem("D-Pad Down", "Android-DPadDown")); - Input.add(a++, new InputConfigItem("D-Pad Left", "Android-DPadLeft")); - Input.add(a++, new InputConfigItem("D-Pad Right", "Android-DPadRight")); - Input.add(a++, new InputConfigItem("Main Stick Up", "Android-MainUp")); - Input.add(a++, new InputConfigItem("Main Stick Down", "Android-MainDown")); - Input.add(a++, new InputConfigItem("Main Stick Left", "Android-MainLeft")); - Input.add(a++, new InputConfigItem("Main Stick Right", "Android-MainRight")); - Input.add(a++, new InputConfigItem("C Stick Up", "Android-CStickUp")); - Input.add(a++, new InputConfigItem("C Stick Down", "Android-CStickDown")); - Input.add(a++, new InputConfigItem("C Stick Left", "Android-CStickLeft")); - Input.add(a++, new InputConfigItem("C Stick Right", "Android-CStickRight")); - Input.add(a++, new InputConfigItem("Trigger L", "Android-InputL")); - Input.add(a++, new InputConfigItem("Trigger R", "Android-InputR")); + Input.add(new InputConfigItem(getString(R.string.draw_onscreen_controls), "Android-ScreenControls", "True")); + Input.add(new InputConfigItem(getString(R.string.button_a), "Android-InputA")); + Input.add(new InputConfigItem(getString(R.string.button_b), "Android-InputB")); + Input.add(new InputConfigItem(getString(R.string.button_start), "Android-InputStart")); + Input.add(new InputConfigItem(getString(R.string.button_x), "Android-InputX")); + Input.add(new InputConfigItem(getString(R.string.button_y), "Android-InputY")); + Input.add(new InputConfigItem(getString(R.string.button_z), "Android-InputZ")); + Input.add(new InputConfigItem(getString(R.string.dpad_up), "Android-DPadUp")); + Input.add(new InputConfigItem(getString(R.string.dpad_down), "Android-DPadDown")); + Input.add(new InputConfigItem(getString(R.string.dpad_left), "Android-DPadLeft")); + Input.add(new InputConfigItem(getString(R.string.dpad_right), "Android-DPadRight")); + Input.add(new InputConfigItem(getString(R.string.main_stick_up), "Android-MainUp")); + Input.add(new InputConfigItem(getString(R.string.main_stick_down), "Android-MainDown")); + Input.add(new InputConfigItem(getString(R.string.main_stick_left), "Android-MainLeft")); + Input.add(new InputConfigItem(getString(R.string.main_stick_right), "Android-MainRight")); + Input.add(new InputConfigItem(getString(R.string.c_stick_up), "Android-CStickUp")); + Input.add(new InputConfigItem(getString(R.string.c_stick_down), "Android-CStickDown")); + Input.add(new InputConfigItem(getString(R.string.c_stick_left), "Android-CStickLeft")); + Input.add(new InputConfigItem(getString(R.string.c_stick_right), "Android-CStickRight")); + Input.add(new InputConfigItem(getString(R.string.trigger_left), "Android-InputL")); + Input.add(new InputConfigItem(getString(R.string.trigger_right), "Android-InputR")); adapter = new InputConfigAdapter(m_activity, R.layout.folderbrowser, Input); View rootView = inflater.inflate(R.layout.gamelist_listview, container, false); @@ -79,6 +82,7 @@ public class InputConfigFragment extends Fragment mDrawerList.setOnItemClickListener(mMenuItemClickListener); return mDrawerList; } + private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) @@ -90,20 +94,22 @@ public class InputConfigFragment extends Fragment String newBind; if (o.getBind().equals("True")) { - Toast.makeText(m_activity, "Not Drawing on screen controls", Toast.LENGTH_SHORT).show(); + Toast.makeText(m_activity, getString(R.string.not_drawing_onscreen_controls), Toast.LENGTH_SHORT).show(); newBind = "False"; } else { - Toast.makeText(m_activity, "Drawing on screen controls", Toast.LENGTH_SHORT).show(); + Toast.makeText(m_activity, getString(R.string.drawing_onscreen_controls), Toast.LENGTH_SHORT).show(); newBind = "True"; } adapter.remove(o); o.setBind(newBind); adapter.insert(o, position); break; + default: // gamepad controls - Toast.makeText(m_activity, "Press button to configure " + o.getName(), Toast.LENGTH_SHORT).show(); + + Toast.makeText(m_activity, getString(R.string.press_button_to_config, o.getName()), Toast.LENGTH_SHORT).show(); configPosition = position; Configuring = true; firstEvent = true; @@ -112,19 +118,21 @@ public class InputConfigFragment extends Fragment } }; - static ArrayList<Float> m_values = new ArrayList<Float>(); + private static ArrayList<Float> m_values = new ArrayList<Float>(); - void AssignBind(String bind) + private void AssignBind(String bind) { InputConfigItem o = adapter.getItem(configPosition); adapter.remove(o); o.setBind(bind); adapter.insert(o, configPosition); } + public InputConfigAdapter getAdapter() { return adapter; } + // Called from GameListActivity public boolean onMotionEvent(MotionEvent event) { @@ -138,17 +146,20 @@ public class InputConfigFragment extends Fragment if (firstEvent) { m_values.clear(); - for (InputDevice.MotionRange range : motions) { + + for (InputDevice.MotionRange range : motions) + { m_values.add(event.getAxisValue(range.getAxis())); } + firstEvent = false; } else { for (int a = 0; a < motions.size(); ++a) { - InputDevice.MotionRange range; - range = motions.get(a); + InputDevice.MotionRange range = motions.get(a); + if (m_values.get(a) > (event.getAxisValue(range.getAxis()) + 0.5f)) { AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "-"); @@ -164,10 +175,12 @@ public class InputConfigFragment extends Fragment } return true; } + public boolean onKeyEvent(KeyEvent event) { - Log.w("Dolphinemu", "Got Event " + event.getAction()); - switch (event.getAction()) { + Log.w("InputConfigFragment", "Got Event " + event.getAction()); + switch (event.getAction()) + { case KeyEvent.ACTION_DOWN: case KeyEvent.ACTION_UP: if (Configuring) @@ -177,6 +190,7 @@ public class InputConfigFragment extends Fragment Configuring = false; return true; } + default: break; } @@ -185,14 +199,18 @@ public class InputConfigFragment extends Fragment } @Override - public void onAttach(Activity activity) { + public void onAttach(Activity activity) + { super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception - try { + try + { m_activity = activity; - } catch (ClassCastException e) { + } + catch (ClassCastException e) + { throw new ClassCastException(activity.toString() + " must implement OnGameListZeroListener"); } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigItem.java index 7511406dc9..70e68261ec 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigItem.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/InputConfigItem.java @@ -1,49 +1,92 @@ -package org.dolphinemu.dolphinemu; - -/** +/* * Copyright 2013 Dolphin Emulator Project * Licensed under GPLv2 * Refer to the license.txt file included. */ -public class InputConfigItem implements Comparable<InputConfigItem>{ + +package org.dolphinemu.dolphinemu; + +/** + * Represents a controller input item (button, stick, etc). + */ +public final class InputConfigItem implements Comparable<InputConfigItem> +{ private String m_name; private String m_Config; private String m_bind; - private void Init(String n, String c, String d) + private void Init(String name, String config, String defaultBind) { - m_name = n; - m_Config = c; + m_name = name; + m_Config = config; String ConfigValues[] = m_Config.split("-"); String Key = ConfigValues[0]; String Value = ConfigValues[1]; - m_bind = NativeLibrary.GetConfig("Dolphin.ini", Key, Value, d); + m_bind = NativeLibrary.GetConfig("Dolphin.ini", Key, Value, defaultBind); } - public InputConfigItem(String n, String c, String d) + /** + * Constructor + * + * @param name Name of the input config item. + * @param config Name of the key in the configuration file that this control modifies. + * @param defaultBind Default binding to fall back upon if binding fails. + */ + public InputConfigItem(String name, String config, String defaultBind) { - Init(n, c, d); + Init(name, config, defaultBind); } - public InputConfigItem(String n, String c) + /** + * Constructor that creates an InputConfigItem + * that has a default binding of "None" + * + * @param name Name of the input config item. + * @param config Name of the key in the configuration file that this control modifies. + */ + public InputConfigItem(String name, String config) { - Init(n, c, "None"); + Init(name, config, "None"); } + + /** + * Gets the name of this InputConfigItem. + * + * @return the name of this InputConfigItem + */ public String getName() { return m_name; } + + /** + * Gets the config key this InputConfigItem modifies. + * + * @return the config key this InputConfigItem modifies. + */ public String getConfig() { return m_Config; } + + /** + * Gets the currently set binding of this InputConfigItem + * + * @return the currently set binding of this InputConfigItem + */ public String getBind() { return m_bind; } - public void setBind(String b) + + /** + * Sets a new binding for this InputConfigItem. + * + * @param bind The new binding. + */ + public void setBind(String bind) { - m_bind = b; + m_bind = bind; } public int compareTo(InputConfigItem o) diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/NativeGLSurfaceView.java b/Source/Android/src/org/dolphinemu/dolphinemu/NativeGLSurfaceView.java index 030c7ed823..ffe89714be 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/NativeGLSurfaceView.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/NativeGLSurfaceView.java @@ -4,12 +4,14 @@ import android.content.Context; import android.view.SurfaceHolder; import android.view.SurfaceView; -public class NativeGLSurfaceView extends SurfaceView { +public final class NativeGLSurfaceView extends SurfaceView +{ static private Thread myRun; static private boolean Running = false; static private boolean Created = false; - public NativeGLSurfaceView(Context context) { + public NativeGLSurfaceView(Context context) + { super(context); if (!Created) { @@ -20,8 +22,10 @@ public class NativeGLSurfaceView extends SurfaceView { NativeLibrary.Run(getHolder().getSurface()); } }; + getHolder().addCallback(new SurfaceHolder.Callback() { - public void surfaceCreated(SurfaceHolder holder) { + public void surfaceCreated(SurfaceHolder holder) + { // TODO Auto-generated method stub if (!Running) { @@ -30,17 +34,17 @@ public class NativeGLSurfaceView extends SurfaceView { } } - public void surfaceChanged(SurfaceHolder arg0, int arg1, - int arg2, int arg3) { + public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) + { // TODO Auto-generated method stub - } - public void surfaceDestroyed(SurfaceHolder arg0) { + public void surfaceDestroyed(SurfaceHolder arg0) + { // TODO Auto-generated method stub - } }); + Created = true; } } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java index f089362c38..14f7527c1d 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -1,14 +1,20 @@ +/* + * Copyright 2013 Dolphin Emulator Project + * Licensed under GPLv2 + * Refer to the license.txt file included. + */ + package org.dolphinemu.dolphinemu; import android.util.Log; import android.view.Surface; /** - * Copyright 2013 Dolphin Emulator Project - * Licensed under GPLv2 - * Refer to the license.txt file included. + * Class which contains methods that interact + * with the native side of the Dolphin code. */ -public class NativeLibrary { +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); diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/PrefsFragment.java b/Source/Android/src/org/dolphinemu/dolphinemu/PrefsFragment.java index 1263c03798..ad69a89a9d 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/PrefsFragment.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/PrefsFragment.java @@ -1,5 +1,7 @@ package org.dolphinemu.dolphinemu; +import java.util.HashMap; + import android.app.Activity; import android.os.Build; import android.os.Bundle; @@ -15,10 +17,12 @@ import javax.microedition.khronos.opengles.GL10; * Licensed under GPLv2 * Refer to the license.txt file included. */ -public class PrefsFragment extends PreferenceFragment { +public final class PrefsFragment extends PreferenceFragment +{ private Activity m_activity; - static public class VersionCheck { + static public class VersionCheck + { EGL10 mEGL; EGLDisplay mEGLDisplay; EGLConfig[] mEGLConfigs; @@ -29,8 +33,8 @@ public class PrefsFragment extends PreferenceFragment { String mThreadOwner; - public VersionCheck() { - + public VersionCheck() + { int[] version = new int[2]; int[] attribList = new int[] { EGL10.EGL_WIDTH, 1, @@ -38,13 +42,18 @@ public class PrefsFragment extends PreferenceFragment { EGL10.EGL_RENDERABLE_TYPE, 4, EGL10.EGL_NONE }; + int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + int[] ctx_attribs = new int[] { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL10.EGL_NONE + }; // No error checking performed, minimum required code to elucidate logic mEGL = (EGL10) EGLContext.getEGL(); mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); mEGL.eglInitialize(mEGLDisplay, version); mEGLConfig = chooseConfig(); // Choosing a config is a little more complicated - mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT, null); + mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT, ctx_attribs); mEGLSurface = mEGL.eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, attribList); mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext); mGL = (GL10) mEGLContext.getGL(); @@ -62,11 +71,14 @@ public class PrefsFragment extends PreferenceFragment { { return mGL.glGetString(GL10.GL_VENDOR); } + public String getRenderer() { return mGL.glGetString(GL10.GL_RENDERER); } - private EGLConfig chooseConfig() { + + private EGLConfig chooseConfig() + { int[] attribList = new int[] { EGL10.EGL_DEPTH_SIZE, 0, EGL10.EGL_STENCIL_SIZE, 0, @@ -88,35 +100,38 @@ public class PrefsFragment extends PreferenceFragment { return mEGLConfigs[0]; // Best match is probably the first configuration } } + static public boolean SupportsGLES3() { - String m_GLVersion; - String m_GLVendor; - String m_GLRenderer; - VersionCheck mbuffer = new VersionCheck(); - m_GLVersion = mbuffer.getVersion(); - m_GLVendor = mbuffer.getVendor(); - m_GLRenderer = mbuffer.getRenderer(); + String m_GLVersion = mbuffer.getVersion(); + String m_GLVendor = mbuffer.getVendor(); + String m_GLRenderer = mbuffer.getRenderer(); boolean mSupportsGLES3 = false; - if (m_GLVersion.contains("OpenGL ES 3.0") || - m_GLVersion.equals("OpenGL ES 3.0")) // 3.0 support + // Check for OpenGL ES 3 support (General case). + if (m_GLVersion.contains("OpenGL ES 3.0") || m_GLVersion.equals("OpenGL ES 3.0")) mSupportsGLES3 = true; + + // Checking for OpenGL ES 3 support for certain Qualcomm devices. if (!mSupportsGLES3 && m_GLVendor.equals("Qualcomm")) { if (m_GLRenderer.contains("Adreno (TM) 3")) { - int mVStart, mVEnd = 0; + int mVStart = m_GLVersion.indexOf("V@") + 2; + int mVEnd = 0; float mVersion; - mVStart = m_GLVersion.indexOf("V@") + 2; + for (int a = mVStart; a < m_GLVersion.length(); ++a) + { if (m_GLVersion.charAt(a) == ' ') { mVEnd = a; break; } + } + mVersion = Float.parseFloat(m_GLVersion.substring(mVStart, mVEnd)); if (mVersion >= 14.0f) @@ -125,47 +140,41 @@ public class PrefsFragment extends PreferenceFragment { } return mSupportsGLES3; } + @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) + { super.onCreate(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.layout.prefs); final ListPreference etp = new ListPreference(m_activity); - CharSequence[] _entries; - CharSequence[] _entryvalues; + final HashMap<CharSequence, CharSequence> entries = new HashMap<CharSequence, CharSequence>(); if (Build.CPU_ABI.contains("x86")) { - _entries = new CharSequence[] { - "Interpreter", - "JIT64 Recompiler", - "JITIL Recompiler", - }; - _entryvalues = new CharSequence[] {"0", "1", "2"}; + entries.put(getString(R.string.interpreter), "0"); + entries.put(getString(R.string.jit64_recompiler), "1"); + entries.put(getString(R.string.jitil_recompiler), "2"); } else if (Build.CPU_ABI.contains("arm")) { - _entries = new CharSequence[] { - "Interpreter", - "JIT ARM Recompiler", - }; - _entryvalues = new CharSequence[] {"0", "3"}; + entries.put(getString(R.string.interpreter), "0"); + entries.put(getString(R.string.jit_arm_recompiler), "3"); } else { - _entries = new CharSequence[] { - "Interpreter", - }; - _entryvalues = new CharSequence[] {"0"}; + entries.put(getString(R.string.interpreter), "0"); } - - etp.setEntries(_entries); - etp.setEntryValues(_entryvalues); + + // Convert the key/value sections to arrays respectively so the list can be set. + // If Java had proper generics it wouldn't look this disgusting. + etp.setEntries(entries.keySet().toArray(new CharSequence[entries.size()])); + etp.setEntryValues(entries.values().toArray(new CharSequence[entries.size()])); etp.setKey("cpupref"); - etp.setTitle("CPU Core"); - etp.setSummary("Emulation core to use"); + etp.setTitle(getString(R.string.cpu_core)); + etp.setSummary(getString(R.string.emu_core_to_use)); PreferenceCategory mCategory = (PreferenceCategory) findPreference("cpuprefcat"); mCategory.addPreference(etp); @@ -180,31 +189,34 @@ public class PrefsFragment extends PreferenceFragment { final ListPreference videobackend = new ListPreference(m_activity); - _entries = new CharSequence[] { - "Software Renderer", - }; - _entryvalues = new CharSequence[] {"Software Renderer"}; + // Add available graphics renderers to the hashmap to add to the list. + entries.clear(); + entries.put(getString(R.string.software_renderer), "Software Renderer"); videobackend.setKey("gpupref"); - videobackend.setTitle("Video Backend"); - videobackend.setSummary("Video backend to use"); + videobackend.setTitle(getString(R.string.video_backend)); + videobackend.setSummary(getString(R.string.video_backend_to_use)); - videobackend.setEntries(_entries); - videobackend.setEntryValues(_entryvalues); + videobackend.setEntries(entries.keySet().toArray(new CharSequence[entries.size()])); + videobackend.setEntryValues(entries.values().toArray(new CharSequence[entries.size()])); mCategory.addPreference(videobackend); } } @Override - public void onAttach(Activity activity) { + public void onAttach(Activity activity) + { super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception - try { + try + { m_activity = activity; - } catch (ClassCastException e) { + } + catch (ClassCastException e) + { throw new ClassCastException(activity.toString() + " must implement OnGameListZeroListener"); } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java b/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java index 599ce5007a..11c071b026 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java @@ -9,41 +9,45 @@ import android.widget.TextView; import java.util.List; -public class SideMenuAdapter extends ArrayAdapter<SideMenuItem>{ - - private Context c; - private int id; - private List<SideMenuItem>items; +public final class SideMenuAdapter extends ArrayAdapter<SideMenuItem> +{ + private final Context c; + private final int id; + private final List<SideMenuItem>items; - public SideMenuAdapter(Context context, int textViewResourceId, - List<SideMenuItem> objects) { + public SideMenuAdapter(Context context, int textViewResourceId, List<SideMenuItem> objects) + { super(context, textViewResourceId, objects); c = context; id = textViewResourceId; items = objects; } + public SideMenuItem getItem(int i) - { + { return items.get(i); - } - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (v == null) { - LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, null); - } - final SideMenuItem o = items.get(position); - if (o != null) { - TextView t1 = (TextView) v.findViewById(R.id.SideMenuTitle); - - if(t1!=null) - t1.setText(o.getName()); - } - return v; - } - - - + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) + { + View v = convertView; + if (v == null) + { + LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, null); + } + + final SideMenuItem item = items.get(position); + if (item != null) + { + TextView title = (TextView) v.findViewById(R.id.SideMenuTitle); + + if(title != null) + title.setText(item.getName()); + } + + return v; + } } diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java b/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java index e24842bed1..51ebc93c19 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/SideMenuItem.java @@ -1,25 +1,47 @@ -package org.dolphinemu.dolphinemu; - -/** +/* * Copyright 2013 Dolphin Emulator Project * Licensed under GPLv2 * Refer to the license.txt file included. */ -public class SideMenuItem implements Comparable<SideMenuItem>{ - private String m_name; - private int m_id; +package org.dolphinemu.dolphinemu; + - public SideMenuItem(String n, int id) +/** + * Represents an item that goes in the sidemenu of the app. + */ +public final class SideMenuItem implements Comparable<SideMenuItem> +{ + private final String m_name; + private final int m_id; + + /** + * Constructor + * + * @param name The name of the SideMenuItem. + * @param id ID number of this specific SideMenuItem. + */ + public SideMenuItem(String name, int id) { - m_name = n; + m_name = name; m_id = id; } + /** + * Gets the name of this SideMenuItem. + * + * @return the name of this SideMenuItem. + */ public String getName() { return m_name; } + + /** + * Gets the ID of this SideMenuItem. + * + * @return the ID of this SideMenuItem. + */ public int getID() { return m_id; diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 480a08a0fc..0a1a26e530 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -20,7 +20,6 @@ set(SRCS Src/BreakPoints.cpp Src/Thread.cpp Src/Timer.cpp Src/Version.cpp - Src/VideoBackendBase.cpp Src/x64ABI.cpp Src/x64Analyzer.cpp Src/x64Emitter.cpp diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 822fafe74b..2982a5c720 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -195,7 +195,6 @@ <ClCompile Include="Src\Thread.cpp" /> <ClCompile Include="Src\Timer.cpp" /> <ClCompile Include="Src\Version.cpp" /> - <ClCompile Include="Src\VideoBackendBase.cpp" /> <ClCompile Include="Src\x64ABI.cpp" /> <ClCompile Include="Src\x64Analyzer.cpp" /> <ClCompile Include="Src\x64CPUDetect.cpp" /> @@ -250,7 +249,6 @@ <ClInclude Include="Src\Thread.h" /> <ClInclude Include="Src\Thunk.h" /> <ClInclude Include="Src\Timer.h" /> - <ClInclude Include="Src\VideoBackendBase.h" /> <ClInclude Include="Src\x64ABI.h" /> <ClInclude Include="Src\x64Analyzer.h" /> <ClInclude Include="Src\x64Emitter.h" /> @@ -261,4 +259,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters index d427b70cdd..ae434219fd 100644 --- a/Source/Core/Common/Common.vcxproj.filters +++ b/Source/Core/Common/Common.vcxproj.filters @@ -23,7 +23,6 @@ <ClCompile Include="Src\Thread.cpp" /> <ClCompile Include="Src\Timer.cpp" /> <ClCompile Include="Src\Version.cpp" /> - <ClCompile Include="Src\VideoBackendBase.cpp" /> <ClCompile Include="Src\x64Analyzer.cpp" /> <ClCompile Include="Src\x64Emitter.cpp" /> <ClCompile Include="Src\LogManager.cpp"> @@ -92,7 +91,6 @@ <ClInclude Include="Src\Thread.h" /> <ClInclude Include="Src\Thunk.h" /> <ClInclude Include="Src\Timer.h" /> - <ClInclude Include="Src\VideoBackendBase.h" /> <ClInclude Include="Src\x64Analyzer.h" /> <ClInclude Include="Src\x64Emitter.h" /> <ClInclude Include="Src\Log.h"> @@ -134,4 +132,4 @@ <UniqueIdentifier>{f078f36e-a0ff-4cd0-95f8-476100d68e68}</UniqueIdentifier> </Filter> </ItemGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/Source/Core/Common/Src/ArmCPUDetect.cpp b/Source/Core/Common/Src/ArmCPUDetect.cpp index a04c88834f..ef49d6efb1 100644 --- a/Source/Core/Common/Src/ArmCPUDetect.cpp +++ b/Source/Core/Common/Src/ArmCPUDetect.cpp @@ -68,6 +68,9 @@ unsigned char GetCPUImplementer() sscanf(implementer_string, "0x%02hhx", &implementer); break; } + + free(implementer_string); + return implementer; } @@ -92,6 +95,9 @@ unsigned short GetCPUPart() sscanf(part_string, "0x%03hx", &part); break; } + + free(part_string); + return part; } diff --git a/Source/Core/Common/Src/ExtendedTrace.cpp b/Source/Core/Common/Src/ExtendedTrace.cpp index 85057639a5..08740c3c95 100644 --- a/Source/Core/Common/Src/ExtendedTrace.cpp +++ b/Source/Core/Common/Src/ExtendedTrace.cpp @@ -136,7 +136,6 @@ static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule ) static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol ) { BOOL ret = FALSE; - DWORD dwDisp = 0; DWORD dwSymSize = 10000; TCHAR lpszUnDSymbol[BUFFERSIZE]=_T("?"); CHAR lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; @@ -153,9 +152,11 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L // Get symbol info for IP #ifndef _M_X64 + DWORD dwDisp = 0; if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) ) #else //makes it compile but hell im not sure if this works... + DWORD64 dwDisp = 0; if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) ) #endif { diff --git a/Source/Core/Common/Src/IniFile.cpp b/Source/Core/Common/Src/IniFile.cpp index 0b265543de..2eca8df929 100644 --- a/Source/Core/Common/Src/IniFile.cpp +++ b/Source/Core/Common/Src/IniFile.cpp @@ -20,45 +20,30 @@ namespace { -static void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) +static void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut) { - int FirstEquals = (int)line.find("=", 0); - int FirstCommentChar = -1; - - // Comments - if (FirstCommentChar < 0) - FirstCommentChar = - (int)line.find("#", FirstEquals > 0 ? FirstEquals : 0); - if (FirstCommentChar < 0 && line[0] == ';') - FirstCommentChar = 0; + if (line[0] == '#') + return; - // Allow preservation of spacing before comment - if (FirstCommentChar > 0) - { - while (line[FirstCommentChar - 1] == ' ' || line[FirstCommentChar - 1] == 9) // 9 == tab - { - FirstCommentChar--; - } - } + int FirstEquals = (int)line.find("=", 0); - if ((FirstEquals >= 0) && ((FirstCommentChar < 0) || (FirstEquals < FirstCommentChar))) + if (FirstEquals >= 0) { // Yes, a valid line! *keyOut = StripSpaces(line.substr(0, FirstEquals)); - if (commentOut) *commentOut = FirstCommentChar > 0 ? line.substr(FirstCommentChar) : std::string(""); - if (valueOut) *valueOut = StripQuotes(StripSpaces(line.substr(FirstEquals + 1, FirstCommentChar - FirstEquals - 1))); + if (valueOut) *valueOut = StripQuotes(StripSpaces(line.substr(FirstEquals + 1, std::string::npos))); } } } -std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut, std::string* commentOut) +std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut) { for (std::vector<std::string>::iterator iter = lines.begin(); iter != lines.end(); ++iter) { std::string& line = *iter; std::string lineKey; - ParseLine(line, &lineKey, valueOut, commentOut); + ParseLine(line, &lineKey, valueOut); if (!strcasecmp(lineKey.c_str(), key)) return &line; } @@ -67,12 +52,12 @@ std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut, s void IniFile::Section::Set(const char* key, const char* newValue) { - std::string value, commented; - std::string* line = GetLine(key, &value, &commented); + std::string value; + std::string* line = GetLine(key, &value); if (line) { // Change the value - keep the key and comment - *line = StripSpaces(key) + " = " + newValue + commented; + *line = StripSpaces(key) + " = " + newValue; } else { @@ -91,7 +76,7 @@ void IniFile::Section::Set(const char* key, const std::string& newValue, const s bool IniFile::Section::Get(const char* key, std::string* value, const char* defaultValue) { - std::string* line = GetLine(key, value, 0); + std::string* line = GetLine(key, value); if (!line) { if (defaultValue) @@ -224,7 +209,7 @@ bool IniFile::Section::Exists(const char *key) const for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { std::string lineKey; - ParseLine(*iter, &lineKey, NULL, NULL); + ParseLine(*iter, &lineKey, NULL); if (!strcasecmp(lineKey.c_str(), key)) return true; } @@ -233,7 +218,7 @@ bool IniFile::Section::Exists(const char *key) const bool IniFile::Section::Delete(const char *key) { - std::string* line = GetLine(key, 0, 0); + std::string* line = GetLine(key, 0); for (std::vector<std::string>::iterator liter = lines.begin(); liter != lines.end(); ++liter) { if (line == &*liter) @@ -313,7 +298,7 @@ bool IniFile::DeleteKey(const char* sectionName, const char* key) Section* section = GetSection(sectionName); if (!section) return false; - std::string* line = section->GetLine(key, 0, 0); + std::string* line = section->GetLine(key, 0); for (std::vector<std::string>::iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) { if (line == &(*liter)) @@ -335,7 +320,7 @@ bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys) c for (std::vector<std::string>::const_iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) { std::string key; - ParseLine(*liter, &key, 0, 0); + ParseLine(*liter, &key, 0); keys.push_back(key); } return true; @@ -421,11 +406,6 @@ bool IniFile::Load(const char* filename) // New section! std::string sub = line.substr(1, endpos - 1); sections.push_back(Section(sub)); - - if (endpos + 1 < line.size()) - { - sections[sections.size() - 1].comment = line.substr(endpos + 1); - } } } else @@ -459,7 +439,7 @@ bool IniFile::Save(const char* filename) if (section.name != "") { - out << "[" << section.name << "]" << section.comment << std::endl; + out << "[" << section.name << "]" << std::endl; } for (std::vector<std::string>::const_iterator liter = section.lines.begin(); liter != section.lines.end(); ++liter) diff --git a/Source/Core/Common/Src/IniFile.h b/Source/Core/Common/Src/IniFile.h index 10e1cfdbb9..bad26ca090 100644 --- a/Source/Core/Common/Src/IniFile.h +++ b/Source/Core/Common/Src/IniFile.h @@ -25,7 +25,7 @@ public: bool Exists(const char *key) const; bool Delete(const char *key); - std::string* GetLine(const char* key, std::string* valueOut, std::string* commentOut); + std::string* GetLine(const char* key, std::string* valueOut); void Set(const char* key, const char* newValue); void Set(const char* key, const std::string& newValue, const std::string& defaultValue); @@ -70,7 +70,6 @@ public: protected: std::vector<std::string> lines; std::string name; - std::string comment; }; bool Load(const char* filename); diff --git a/Source/Core/Common/Src/MemArena.cpp b/Source/Core/Common/Src/MemArena.cpp index 487788dc45..7be7c98c89 100644 --- a/Source/Core/Common/Src/MemArena.cpp +++ b/Source/Core/Common/Src/MemArena.cpp @@ -20,6 +20,7 @@ #include <linux/ashmem.h> #endif #endif +#include <set> #if defined(__APPLE__) static const char* ram_temp_file = "/tmp/gc_mem.tmp"; @@ -214,27 +215,7 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 bail: // Argh! ERROR! Free what we grabbed so far so we can try again. - for (int j = 0; j <= i; j++) - { - SKIP(flags, views[i].flags); - if (views[j].out_ptr_low && *views[j].out_ptr_low) - { - arena->ReleaseView(*views[j].out_ptr_low, views[j].size); - *views[j].out_ptr_low = NULL; - } - if (*views[j].out_ptr) - { -#ifdef _M_X64 - arena->ReleaseView(*views[j].out_ptr, views[j].size); -#else - if (!(views[j].flags & MV_MIRROR_PREVIOUS)) - { - arena->ReleaseView(*views[j].out_ptr, views[j].size); - } -#endif - *views[j].out_ptr = NULL; - } - } + MemoryMap_Shutdown(views, i+1, flags, arena); return false; } @@ -300,15 +281,20 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena void MemoryMap_Shutdown(const MemoryView *views, int num_views, u32 flags, MemArena *arena) { + std::set<void*> freeset; for (int i = 0; i < num_views; i++) { - SKIP(flags, views[i].flags); - if (views[i].out_ptr_low && *views[i].out_ptr_low) - arena->ReleaseView(*views[i].out_ptr_low, views[i].size); - if (*views[i].out_ptr && (views[i].out_ptr_low && *views[i].out_ptr != *views[i].out_ptr_low)) - arena->ReleaseView(*views[i].out_ptr, views[i].size); - *views[i].out_ptr = NULL; - if (views[i].out_ptr_low) - *views[i].out_ptr_low = NULL; + const MemoryView* view = &views[i]; + u8** outptrs[2] = {view->out_ptr_low, view->out_ptr}; + for (int j = 0; j < 2; j++) + { + u8** outptr = outptrs[j]; + if (outptr && *outptr && !freeset.count(*outptr)) + { + arena->ReleaseView(*outptr, view->size); + freeset.insert(*outptr); + *outptr = NULL; + } + } } } diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index 99bc2ae6ca..25885552ef 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -34,7 +34,39 @@ bool AsciiToHex(const char* _szValue, u32& result) bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) { - int writtenCount = vsnprintf(out, outsize, format, args); + int writtenCount; + +#ifdef _WIN32 + // You would think *printf are simple, right? Iterate on each character, + // if it's a format specifier handle it properly, etc. + // + // Nooooo. Not according to the C standard. + // + // According to the C99 standard (7.19.6.1 "The fprintf function") + // The format shall be a multibyte character sequence + // + // Because some character encodings might have '%' signs in the middle of + // a multibyte sequence (SJIS for example only specifies that the first + // byte of a 2 byte sequence is "high", the second byte can be anything), + // printf functions have to decode the multibyte sequences and try their + // best to not screw up. + // + // Unfortunately, on Windows, the locale for most languages is not UTF-8 + // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the + // locale, and completely fails when trying to decode UTF-8 as EUC-CN. + // + // On the other hand, the fix is simple: because we use UTF-8, no such + // multibyte handling is required as we can simply assume that no '%' char + // will be present in the middle of a multibyte sequence. + // + // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l. + static locale_t c_locale = NULL; + if (!c_locale) + c_locale = _create_locale(LC_ALL, ".1252"); + writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); +#else + writtenCount = vsnprintf(out, outsize, format, args); +#endif if (writtenCount > 0 && writtenCount < outsize) { @@ -58,10 +90,9 @@ std::string StringFromFormat(const char* format, ...) va_start(args, format); required = _vscprintf(format, args); buf = new char[required + 1]; - vsnprintf(buf, required, format, args); + CharArrayFromFormatV(buf, required + 1, format, args); va_end(args); - buf[required] = '\0'; std::string temp = buf; delete[] buf; #else diff --git a/Source/Core/Common/make_scmrev.h.js b/Source/Core/Common/make_scmrev.h.js index 82f6394c2b..f2978987dc 100644 --- a/Source/Core/Common/make_scmrev.h.js +++ b/Source/Core/Common/make_scmrev.h.js @@ -58,8 +58,8 @@ var describe = GetFirstStdOutLine(gitexe + cmd_describe); var branch = GetFirstStdOutLine(gitexe + cmd_branch); var isMaster = +("master" == branch); -// remove hash from description -describe = describe.replace(/-[^-]+(-dirty)?$/, '$1'); +// remove hash (and trailing "-0" if needed) from description +describe = describe.replace(/(-0)?-[^-]+(-dirty)?$/, '$2'); var out_contents = "#define SCM_REV_STR \"" + revision + "\"\n" + diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index bf8d86494e..2e8744338d 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -210,6 +210,7 @@ if(_M_ARM) Src/PowerPC/JitArm32/JitArm_Integer.cpp Src/PowerPC/JitArm32/JitArm_LoadStore.cpp Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp + Src/PowerPC/JitArm32/JitArm_Paired.cpp Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp) endif() diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index 93b622b8de..78029ced2f 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -311,7 +311,10 @@ bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2) m_strSRAM = File::GetUserPath(F_GCSRAM_IDX); if (!bWii) { - m_strBootROM = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + Region + DIR_SEP GC_IPL; + m_strBootROM = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + Region + DIR_SEP GC_IPL; + if (!File::Exists(m_strBootROM)) + m_strBootROM = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + Region + DIR_SEP GC_IPL; + if (!bHLE_BS2) { if (!File::Exists(m_strBootROM)) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index a2d5768039..b043f6de5f 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -1255,8 +1255,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICom void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiry(u8* _Input) { // Inquiry should not be called normally - PanicAlertT("HCI_CMD_INQUIRY is called, please report!"); - hci_inquiry_cp* pInquiry = (hci_inquiry_cp*)_Input; INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_INQUIRY:"); @@ -1862,8 +1860,6 @@ CWII_IPC_HLE_WiiMote* CWII_IPC_HLE_Device_usb_oh1_57e_305::AccessWiiMote(const b } ERROR_LOG(WII_IPC_WIIMOTE,"Can't find WiiMote by bd: %02x:%02x:%02x:%02x:%02x:%02x", - _rAddr.b[0], _rAddr.b[1], _rAddr.b[2], _rAddr.b[3], _rAddr.b[4], _rAddr.b[5]); - PanicAlertT("Can't find WiiMote by bd: %02x:%02x:%02x:%02x:%02x:%02x", _rAddr.b[0], _rAddr.b[1], _rAddr.b[2], _rAddr.b[3], _rAddr.b[4], _rAddr.b[5]); return NULL; } diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index 0d68ac64ef..c5d77c0f23 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -703,6 +703,8 @@ bool NetPlayServer::StopGame() std::lock_guard<std::recursive_mutex> lks(m_crit.send); SendToClients(spac); + m_is_running = false; + return true; } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index 5ea96c8774..f3fded30e8 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -116,6 +116,11 @@ public: void GenerateRC(int cr = 0); void ComputeRC(int cr = 0); + void ComputeRC(s32 value, int cr); + + void ComputeCarry(); + void GetCarryAndClear(ARMReg reg); + void FinalizeCarry(ARMReg reg); // OPCODES void unknown_instruction(UGeckoInstruction _inst); @@ -143,6 +148,8 @@ public: void addi(UGeckoInstruction _inst); void addis(UGeckoInstruction _inst); void addx(UGeckoInstruction _inst); + void addcx(UGeckoInstruction _inst); + void addex(UGeckoInstruction _inst); void cmp (UGeckoInstruction _inst); void cmpi(UGeckoInstruction _inst); void cmpl(UGeckoInstruction _inst); @@ -153,6 +160,9 @@ public: void oris(UGeckoInstruction _inst); void orx(UGeckoInstruction _inst); void xorx(UGeckoInstruction _inst); + void andx(UGeckoInstruction _inst); + void andi_rc(UGeckoInstruction _inst); + void andis_rc(UGeckoInstruction _inst); void rlwimix(UGeckoInstruction _inst); void rlwinmx(UGeckoInstruction _inst); void subfx(UGeckoInstruction _inst); @@ -183,12 +193,22 @@ public: // Floating point void fabsx(UGeckoInstruction _inst); + void faddsx(UGeckoInstruction _inst); void faddx(UGeckoInstruction _inst); + void fsubsx(UGeckoInstruction _inst); + void fsubx(UGeckoInstruction _inst); + void fmulsx(UGeckoInstruction _inst); + void fmulx(UGeckoInstruction _inst); void fmrx(UGeckoInstruction _inst); // Floating point loadStore void lfs(UGeckoInstruction _inst); void lfd(UGeckoInstruction _inst); + + // Paired Singles + void ps_add(UGeckoInstruction _inst); + void ps_sub(UGeckoInstruction _inst); + void ps_mul(UGeckoInstruction _inst); }; #endif // _JIT64_H diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp index c82c7d3877..6dd1f80cd6 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp @@ -51,6 +51,21 @@ void JitArm::fabsx(UGeckoInstruction inst) if (inst.Rc) Helper_UpdateCR1(vD); } +void JitArm::faddsx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(FloatingPoint) + + ARMReg vD0 = fpr.R0(inst.FD); + ARMReg vD1 = fpr.R1(inst.FD); + ARMReg vA = fpr.R0(inst.FA); + ARMReg vB = fpr.R0(inst.FB); + + VADD(vD0, vA, vB); + VADD(vD1, vA, vB); + if (inst.Rc) Helper_UpdateCR1(vD0); +} + void JitArm::faddx(UGeckoInstruction inst) { INSTRUCTION_START @@ -64,6 +79,65 @@ void JitArm::faddx(UGeckoInstruction inst) if (inst.Rc) Helper_UpdateCR1(vD); } +// Breaks Animal crossing +void JitArm::fsubsx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(FloatingPoint) + + Default(inst); return; + + ARMReg vD0 = fpr.R0(inst.FD); + ARMReg vD1 = fpr.R1(inst.FD); + ARMReg vA = fpr.R0(inst.FA); + ARMReg vB = fpr.R0(inst.FB); + + VSUB(vD0, vA, vB); + VSUB(vD1, vA, vB); + if (inst.Rc) Helper_UpdateCR1(vD0); +} + +void JitArm::fsubx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(FloatingPoint) + + ARMReg vD = fpr.R0(inst.FD); + ARMReg vA = fpr.R0(inst.FA); + ARMReg vB = fpr.R0(inst.FB); + + VSUB(vD, vA, vB); + if (inst.Rc) Helper_UpdateCR1(vD); +} +// Breaks animal crossing +void JitArm::fmulsx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(FloatingPoint) + + Default(inst); return; + + ARMReg vD0 = fpr.R0(inst.FD); + ARMReg vD1 = fpr.R1(inst.FD); + ARMReg vA = fpr.R0(inst.FA); + ARMReg vC = fpr.R0(inst.FC); + + VMUL(vD0, vA, vC); + VMUL(vD1, vA, vC); + if (inst.Rc) Helper_UpdateCR1(vD0); +} +void JitArm::fmulx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(FloatingPoint) + + ARMReg vD0 = fpr.R0(inst.FD); + ARMReg vA = fpr.R0(inst.FA); + ARMReg vC = fpr.R0(inst.FC); + + VMUL(vD0, vA, vC); + if (inst.Rc) Helper_UpdateCR1(vD0); +} void JitArm::fmrx(UGeckoInstruction inst) { INSTRUCTION_START diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp index 4de3eaa471..d0c4f35fe3 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -54,6 +54,57 @@ void JitArm::ComputeRC(int cr) { STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr); gpr.Unlock(rB); } +void JitArm::ComputeRC(s32 value, int cr) { + ARMReg rB = gpr.GetReg(); + + if (value < 0) + MOV(rB, 0x8); + else if (value > 0) + MOV(rB, 0x4); + else + MOV(rB, 0x2); + + STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr); + gpr.Unlock(rB); +} + +void JitArm::ComputeCarry() +{ + ARMReg tmp = gpr.GetReg(); + Operand2 mask = Operand2(2, 2); // XER_CA_MASK + LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + SetCC(CC_CS); + ORR(tmp, tmp, mask); + SetCC(CC_CC); + BIC(tmp, tmp, mask); + SetCC(); + STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + gpr.Unlock(tmp); +} + +void JitArm::GetCarryAndClear(ARMReg reg) +{ + ARMReg tmp = gpr.GetReg(); + Operand2 mask = Operand2(2, 2); // XER_CA_MASK + LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + AND(reg, tmp, mask); + BIC(tmp, tmp, mask); + STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + gpr.Unlock(tmp); +} + +void JitArm::FinalizeCarry(ARMReg reg) +{ + ARMReg tmp = gpr.GetReg(); + Operand2 mask = Operand2(2, 2); // XER_CA_MASK + SetCC(CC_CS); + ORR(reg, reg, mask); + SetCC(); + LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + ORR(tmp, tmp, reg); + STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + gpr.Unlock(tmp); +} void JitArm::addi(UGeckoInstruction inst) { @@ -103,23 +154,70 @@ void JitArm::addx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) + u32 a = inst.RA, b = inst.RB, d = inst.RD; + + if (gpr.IsImm(a) && gpr.IsImm(b)) + { + gpr.SetImmediate(d, gpr.GetImm(a) + gpr.GetImm(b)); + if (inst.Rc) ComputeRC(gpr.GetImm(d), 0); + return; + } + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); + ARMReg RD = gpr.R(d); + ADDS(RD, RA, RB); + if (inst.Rc) ComputeRC(); +} - ARMReg RA = gpr.R(inst.RA); - ARMReg RB = gpr.R(inst.RB); - ARMReg RD = gpr.R(inst.RD); +void JitArm::addcx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + u32 a = inst.RA, b = inst.RB, d = inst.RD; + + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); + ARMReg RD = gpr.R(d); + ADDS(RD, RA, RB); + ComputeCarry(); + if (inst.Rc) ComputeRC(); +} +void JitArm::addex(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + u32 a = inst.RA, b = inst.RB, d = inst.RD; + Default(inst); return; + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); + ARMReg RD = gpr.R(d); + ARMReg rA = gpr.GetReg(); + GetCarryAndClear(rA); ADDS(RD, RA, RB); + FinalizeCarry(rA); if (inst.Rc) ComputeRC(); + gpr.Unlock(rA); } + void JitArm::subfx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) - ARMReg RA = gpr.R(inst.RA); - ARMReg RB = gpr.R(inst.RB); - ARMReg RD = gpr.R(inst.RD); - SUBS(RD, RB, RA); + u32 a = inst.RA, b = inst.RB, d = inst.RD; + if (inst.OE) PanicAlert("OE: subfx"); + + if (gpr.IsImm(a) && gpr.IsImm(b)) + { + gpr.SetImmediate(d, gpr.GetImm(b) - gpr.GetImm(a)); + if (inst.Rc) ComputeRC(gpr.GetImm(d), 0); + return; + } + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); + ARMReg RD = gpr.R(d); + SUBS(RD, RB, RA); if (inst.Rc) GenerateRC(); } void JitArm::mulli(UGeckoInstruction inst) @@ -149,7 +247,7 @@ void JitArm::ori(UGeckoInstruction inst) if (gpr.IsImm(s)) { - gpr.SetImmediate(s, gpr.GetImm(a) | inst.UIMM); + gpr.SetImmediate(a, gpr.GetImm(s) | inst.UIMM); return; } ARMReg RA = gpr.R(a); @@ -163,9 +261,15 @@ void JitArm::oris(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) + u32 a = inst.RA, s = inst.RS; - ARMReg RA = gpr.R(inst.RA); - ARMReg RS = gpr.R(inst.RS); + if (gpr.IsImm(s)) + { + gpr.SetImmediate(a, gpr.GetImm(s) | (inst.UIMM << 16)); + return; + } + ARMReg RA = gpr.R(a); + ARMReg RS = gpr.R(s); ARMReg rA = gpr.GetReg(); MOVI2R(rA, inst.UIMM << 16); ORR(RA, RS, rA); @@ -176,10 +280,17 @@ void JitArm::orx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) + u32 a = inst.RA, b = inst.RB, s = inst.RS; - ARMReg rA = gpr.R(inst.RA); - ARMReg rS = gpr.R(inst.RS); - ARMReg rB = gpr.R(inst.RB); + if (gpr.IsImm(b) && gpr.IsImm(s)) + { + gpr.SetImmediate(a, gpr.GetImm(s) | gpr.GetImm(b)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rB = gpr.R(b); + ARMReg rS = gpr.R(s); ORRS(rA, rS, rB); if (inst.Rc) ComputeRC(); @@ -190,23 +301,100 @@ void JitArm::xorx(UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(Integer) - ARMReg rA = gpr.R(inst.RA); - ARMReg rS = gpr.R(inst.RS); - ARMReg rB = gpr.R(inst.RB); + u32 a = inst.RA, b = inst.RB, s = inst.RS; + + if (gpr.IsImm(b) && gpr.IsImm(s)) + { + gpr.SetImmediate(a, gpr.GetImm(s) ^ gpr.GetImm(b)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rB = gpr.R(b); + ARMReg rS = gpr.R(s); EORS(rA, rS, rB); if (inst.Rc) ComputeRC(); } + +void JitArm::andx(UGeckoInstruction inst) +{ + u32 a = inst.RA, b = inst.RB, s = inst.RS; + + if (gpr.IsImm(s) && gpr.IsImm(b)) + { + gpr.SetImmediate(a, gpr.GetImm(s) & gpr.GetImm(b)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rB = gpr.R(b); + ARMReg rS = gpr.R(s); + + ANDS(rA, rS, rB); + + if (inst.Rc) ComputeRC(); +} + +void JitArm::andi_rc(UGeckoInstruction inst) +{ + u32 a = inst.RA, s = inst.RS; + + if (gpr.IsImm(s)) + { + gpr.SetImmediate(a, gpr.GetImm(s) & inst.UIMM); + ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rS = gpr.R(s); + ARMReg RA = gpr.GetReg(); + + MOVI2R(RA, inst.UIMM); + ANDS(rA, rS, RA); + + ComputeRC(); + gpr.Unlock(RA); +} + +void JitArm::andis_rc(UGeckoInstruction inst) +{ + u32 a = inst.RA, s = inst.RS; + + if (gpr.IsImm(s)) + { + gpr.SetImmediate(a, gpr.GetImm(s) & ((u32)inst.UIMM << 16)); + ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rS = gpr.R(s); + ARMReg RA = gpr.GetReg(); + + MOVI2R(RA, (u32)inst.UIMM << 16); + ANDS(rA, rS, RA); + + ComputeRC(); + gpr.Unlock(RA); +} + void JitArm::extshx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) - ARMReg RA, RS; - RA = gpr.R(inst.RA); - RS = gpr.R(inst.RS); - SXTH(RA, RS); + u32 a = inst.RA, s = inst.RS; + + if (gpr.IsImm(s)) + { + gpr.SetImmediate(a, (u32)(s32)(s16)gpr.GetImm(s)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rS = gpr.R(s); + SXTH(rA, rS); if (inst.Rc){ - CMP(RA, 0); + CMP(rA, 0); ComputeRC(); } } @@ -214,12 +402,19 @@ void JitArm::extsbx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) - ARMReg RA, RS; - RA = gpr.R(inst.RA); - RS = gpr.R(inst.RS); - SXTB(RA, RS); + u32 a = inst.RA, s = inst.RS; + + if (gpr.IsImm(s)) + { + gpr.SetImmediate(a, (u32)(s32)(s8)gpr.GetImm(s)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rS = gpr.R(s); + SXTB(rA, rS); if (inst.Rc){ - CMP(RA, 0); + CMP(rA, 0); ComputeRC(); } } @@ -228,31 +423,43 @@ void JitArm::cmp (UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(Integer) - ARMReg RA = gpr.R(inst.RA); - ARMReg RB = gpr.R(inst.RB); int crf = inst.CRFD; + u32 a = inst.RA, b = inst.RB; + + if (gpr.IsImm(a) && gpr.IsImm(b)) + { + ComputeRC((s32)gpr.GetImm(a) - (s32)gpr.GetImm(b), crf); + return; + } + + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); CMP(RA, RB); + ComputeRC(crf); } void JitArm::cmpi(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) - - ARMReg RA = gpr.R(inst.RA); + u32 a = inst.RA; int crf = inst.CRFD; - if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 256) - { - CMP(RA, inst.SIMM_16); - } + if (gpr.IsImm(a)) + ComputeRC((s32)gpr.GetImm(a) - inst.SIMM_16, crf); else { - ARMReg rA = gpr.GetReg(); - MOVI2R(rA, inst.SIMM_16); - CMP(RA, rA); - gpr.Unlock(rA); + ARMReg RA = gpr.R(a); + if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 256) + CMP(RA, inst.SIMM_16); + else + { + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, inst.SIMM_16); + CMP(RA, rA); + gpr.Unlock(rA); + } + ComputeRC(crf); } - ComputeRC(crf); } void JitArm::cmpl(UGeckoInstruction inst) { diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Paired.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Paired.cpp new file mode 100644 index 0000000000..39a8320389 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Paired.cpp @@ -0,0 +1,90 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#include "Common.h" +#include "Thunk.h" + +#include "../../Core.h" +#include "../PowerPC.h" +#include "../../CoreTiming.h" +#include "../PPCTables.h" +#include "ArmEmitter.h" + +#include "Jit.h" +#include "JitRegCache.h" +#include "JitAsm.h" + +// Wrong, THP videos like SMS and Ikaruga show artifacts +void JitArm::ps_add(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Paired) + + Default(inst); return; + + u32 a = inst.FA, b = inst.FB, d = inst.FD; + if (inst.Rc){ + Default(inst); return; + } + ARMReg vA0 = fpr.R0(a); + ARMReg vA1 = fpr.R1(a); + ARMReg vB0 = fpr.R0(b); + ARMReg vB1 = fpr.R1(b); + ARMReg vD0 = fpr.R0(d, false); + ARMReg vD1 = fpr.R1(d, false); + + VADD(vD0, vA0, vB0); + VADD(vD1, vA1, vB1); +} +void JitArm::ps_sub(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Paired) + + u32 a = inst.FA, b = inst.FB, d = inst.FD; + if (inst.Rc){ + Default(inst); return; + } + ARMReg vA0 = fpr.R0(a); + ARMReg vA1 = fpr.R1(a); + ARMReg vB0 = fpr.R0(b); + ARMReg vB1 = fpr.R1(b); + ARMReg vD0 = fpr.R0(d, false); + ARMReg vD1 = fpr.R1(d, false); + + VSUB(vD0, vA0, vB0); + VSUB(vD1, vA1, vB1); +} + +void JitArm::ps_mul(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Paired) + u32 a = inst.FA, c = inst.FC, d = inst.FD; + if (inst.Rc){ + Default(inst); return; + } + ARMReg vA0 = fpr.R0(a); + ARMReg vA1 = fpr.R1(a); + ARMReg vC0 = fpr.R0(c); + ARMReg vC1 = fpr.R1(c); + ARMReg vD0 = fpr.R0(d, false); + ARMReg vD1 = fpr.R1(d, false); + + VMUL(vD0, vA0, vC0); + VMUL(vD1, vA1, vC1); +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index 570bde105c..7d9ae6f47a 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -75,8 +75,8 @@ static GekkoOPTemplate primarytable[] = {25, &JitArm::oris}, //"oris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, {26, &JitArm::Default}, //"xori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, {27, &JitArm::Default}, //"xoris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, - {28, &JitArm::Default}, //"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, - {29, &JitArm::Default}, //"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, + {28, &JitArm::andi_rc}, //"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, + {29, &JitArm::andis_rc}, //"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, {32, &JitArm::lwz}, //"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, {33, &JitArm::Default}, //"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, @@ -150,11 +150,11 @@ static GekkoOPTemplate table4_2[] = {14, &JitArm::Default}, //"ps_madds0", OPTYPE_PS, 0}}, {15, &JitArm::Default}, //"ps_madds1", OPTYPE_PS, 0}}, {18, &JitArm::Default}, //"ps_div", OPTYPE_PS, 0, 16}}, - {20, &JitArm::Default}, //"ps_sub", OPTYPE_PS, 0}}, - {21, &JitArm::Default}, //"ps_add", OPTYPE_PS, 0}}, + {20, &JitArm::ps_sub}, //"ps_sub", OPTYPE_PS, 0}}, + {21, &JitArm::ps_add}, //"ps_add", OPTYPE_PS, 0}}, {23, &JitArm::Default}, //"ps_sel", OPTYPE_PS, 0}}, {24, &JitArm::Default}, //"ps_res", OPTYPE_PS, 0}}, - {25, &JitArm::Default}, //"ps_mul", OPTYPE_PS, 0}}, + {25, &JitArm::ps_mul}, //"ps_mul", OPTYPE_PS, 0}}, {26, &JitArm::Default}, //"ps_rsqrte", OPTYPE_PS, 0, 1}}, {28, &JitArm::Default}, //"ps_msub", OPTYPE_PS, 0}}, {29, &JitArm::Default}, //"ps_madd", OPTYPE_PS, 0}}, @@ -194,7 +194,7 @@ static GekkoOPTemplate table19[] = static GekkoOPTemplate table31[] = { - {28, &JitArm::Default}, //"andx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {28, &JitArm::andx}, //"andx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {60, &JitArm::Default}, //"andcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {444, &JitArm::orx}, //"orx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {124, &JitArm::Default}, //"norx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, @@ -309,8 +309,8 @@ static GekkoOPTemplate table31_2[] = { {266, &JitArm::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, {778, &JitArm::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, - {10, &JitArm::Default}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, - {138, &JitArm::Default}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {10, &JitArm::addcx}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {138, &JitArm::addex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {234, &JitArm::Default}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {202, &JitArm::Default}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {491, &JitArm::Default}, //"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, @@ -333,11 +333,11 @@ static GekkoOPTemplate table31_2[] = static GekkoOPTemplate table59[] = { {18, &JitArm::Default}, //{"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}}, - {20, &JitArm::Default}, //"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, - {21, &JitArm::Default}, //"faddsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {20, &JitArm::fsubsx}, //"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {21, &JitArm::faddsx}, //"faddsx", OPTYPE_FPU, FL_RC_BIT_F}}, // {22, &JitArm::Default}, //"fsqrtsx", OPTYPE_FPU, FL_RC_BIT_F}}, // Not implemented on gekko {24, &JitArm::Default}, //"fresx", OPTYPE_FPU, FL_RC_BIT_F}}, - {25, &JitArm::Default}, //"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {25, &JitArm::fmulsx}, //"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}}, {28, &JitArm::Default}, //"fmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, {29, &JitArm::Default}, //"fmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, {30, &JitArm::Default}, //"fnmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, @@ -367,11 +367,11 @@ static GekkoOPTemplate table63[] = static GekkoOPTemplate table63_2[] = { {18, &JitArm::Default}, //"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}}, - {20, &JitArm::Default}, //"fsubx", OPTYPE_FPU, FL_RC_BIT_F}}, + {20, &JitArm::fsubx}, //"fsubx", OPTYPE_FPU, FL_RC_BIT_F}}, {21, &JitArm::faddx}, //"faddx", OPTYPE_FPU, FL_RC_BIT_F}}, {22, &JitArm::Default}, //"fsqrtx", OPTYPE_FPU, FL_RC_BIT_F}}, {23, &JitArm::Default}, //"fselx", OPTYPE_FPU, FL_RC_BIT_F}}, - {25, &JitArm::Default}, //"fmulx", OPTYPE_FPU, FL_RC_BIT_F}}, + {25, &JitArm::fmulx}, //"fmulx", OPTYPE_FPU, FL_RC_BIT_F}}, {26, &JitArm::Default}, //"frsqrtex", OPTYPE_FPU, FL_RC_BIT_F}}, {28, &JitArm::Default}, //"fmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, {29, &JitArm::Default}, //"fmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index 4f45d08ede..b082960175 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -127,17 +127,6 @@ void Init(int cpu_core) ppcState.itlb_last = 0; memset(ppcState.itlb_va, 0, sizeof(ppcState.itlb_va)); memset(ppcState.itlb_pa, 0, sizeof(ppcState.itlb_pa)); - - memset(ppcState.mojs, 0, sizeof(ppcState.mojs)); - memset(ppcState.sr, 0, sizeof(ppcState.sr)); - ppcState.DebugCount = 0; - ppcState.dtlb_last = 0; - ppcState.dtlb_last = 0; - memset(ppcState.dtlb_va, 0, sizeof(ppcState.dtlb_va)); - memset(ppcState.dtlb_pa, 0, sizeof(ppcState.dtlb_pa)); - ppcState.itlb_last = 0; - memset(ppcState.itlb_va, 0, sizeof(ppcState.itlb_va)); - memset(ppcState.itlb_pa, 0, sizeof(ppcState.itlb_pa)); ppcState.pagetable_base = 0; ppcState.pagetable_hashmask = 0; diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 30d5cd7bb3..8a7e3bf1e3 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -1049,6 +1049,7 @@ void CFrame::DoStop() DoRecordingSave(); if(Movie::IsPlayingInput() || Movie::IsRecordingInput()) Movie::EndPlayInput(false); + NetPlay::StopGame(); wxBeginBusyCursor(); BootManager::Stop(); diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp index 0cbfab1031..be1f1b7802 100644 --- a/Source/Core/DolphinWX/Src/Main.cpp +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -263,6 +263,9 @@ bool DolphinApp::OnInit() File::CreateFullPath(File::GetUserPath(D_SCREENSHOTS_IDX)); File::CreateFullPath(File::GetUserPath(D_STATESAVES_IDX)); File::CreateFullPath(File::GetUserPath(D_MAILLOGS_IDX)); + File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + USA_DIR DIR_SEP); + File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + EUR_DIR DIR_SEP); + File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + JAP_DIR DIR_SEP); LogManager::Init(); SConfig::Init(); diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 86650b3588..adf8127e28 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -17,6 +17,7 @@ #include <string> #define NETPLAY_TITLEBAR "Dolphin NetPlay" +#define INITIAL_PAD_BUFFER_SIZE 20 BEGIN_EVENT_TABLE(NetPlayDiag, wxFrame) EVT_COMMAND(wxID_ANY, wxEVT_THREAD, NetPlayDiag::OnThread) @@ -246,6 +247,7 @@ void NetPlaySetupDiag::OnHost(wxCommandEvent&) m_host_port_text->GetValue().ToULong(&port); netplay_server = new NetPlayServer(u16(port)); netplay_server->ChangeGame(game); + netplay_server->AdjustPadBufferSize(INITIAL_PAD_BUFFER_SIZE); if (netplay_server->is_connected) { #ifdef USE_UPNP @@ -281,6 +283,7 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game : wxFrame(parent, wxID_ANY, wxT(NETPLAY_TITLEBAR), wxDefaultPosition, wxDefaultSize) , m_selected_game(game) , m_game_list(game_list) + , m_start_btn(NULL) { wxPanel* const panel = new wxPanel(this); @@ -338,15 +341,13 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game wxBoxSizer* const bottom_szr = new wxBoxSizer(wxHORIZONTAL); if (is_hosting) { - wxButton* const start_btn = new wxButton(panel, wxID_ANY, _("Start")); - start_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlayDiag::OnStart, this); - bottom_szr->Add(start_btn); - wxButton* const stop_btn = new wxButton(panel, wxID_ANY, _("Stop")); - stop_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlayDiag::OnStop, this); - bottom_szr->Add(stop_btn); + m_start_btn = new wxButton(panel, wxID_ANY, _("Start")); + m_start_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlayDiag::OnStart, this); + bottom_szr->Add(m_start_btn); + bottom_szr->Add(new wxStaticText(panel, wxID_ANY, _("Buffer:")), 0, wxLEFT | wxCENTER, 5 ); wxSpinCtrl* const padbuf_spin = new wxSpinCtrl(panel, wxID_ANY, wxT("20") - , wxDefaultPosition, wxSize(64, -1), wxSP_ARROW_KEYS, 0, 200, 20); + , wxDefaultPosition, wxSize(64, -1), wxSP_ARROW_KEYS, 0, 200, INITIAL_PAD_BUFFER_SIZE); padbuf_spin->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &NetPlayDiag::OnAdjustBuffer, this); bottom_szr->Add(padbuf_spin, 0, wxCENTER); } @@ -409,7 +410,7 @@ void NetPlayDiag::GetNetSettings(NetSettings &settings) settings.m_Controllers[i] = SConfig::GetInstance().m_SIDevice[i]; } -const std::string& NetPlayDiag::FindGame() +std::string NetPlayDiag::FindGame() { // find path for selected game, sloppy.. for (u32 i = 0 ; auto game = m_game_list->GetISO(i); ++i) @@ -428,11 +429,6 @@ void NetPlayDiag::OnStart(wxCommandEvent&) netplay_server->StartGame(FindGame()); } -void NetPlayDiag::OnStop(wxCommandEvent&) -{ - netplay_server->StopGame(); -} - void NetPlayDiag::BootGame(const std::string& filename) { main_frame->BootGame(filename); @@ -469,12 +465,16 @@ void NetPlayDiag::OnMsgStartGame() { wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_START_GAME); GetEventHandler()->AddPendingEvent(evt); + if (m_start_btn) + m_start_btn->Disable(); } void NetPlayDiag::OnMsgStopGame() { wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_STOP_GAME); GetEventHandler()->AddPendingEvent(evt); + if (m_start_btn) + m_start_btn->Enable(); } void NetPlayDiag::OnAdjustBuffer(wxCommandEvent& event) @@ -685,3 +685,11 @@ void PadMapDiag::OnAdjust(wxCommandEvent& event) m_wiimapping[i] = m_map_cbox[i+4]->GetSelection() - 1; } } + +void NetPlay::StopGame() +{ + if (netplay_server != NULL) + netplay_server->StopGame(); + + // TODO: allow non-hosting clients to close the window +} diff --git a/Source/Core/DolphinWX/Src/NetWindow.h b/Source/Core/DolphinWX/Src/NetWindow.h index 89bf66fee2..8812b1f8ea 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.h +++ b/Source/Core/DolphinWX/Src/NetWindow.h @@ -67,7 +67,6 @@ public: Common::FifoQueue<std::string> chat_msgs; void OnStart(wxCommandEvent& event); - void OnStop(wxCommandEvent& event); // implementation of NetPlayUI methods void BootGame(const std::string& filename); @@ -92,7 +91,7 @@ private: void OnAdjustBuffer(wxCommandEvent& event); void OnConfigPads(wxCommandEvent& event); void GetNetSettings(NetSettings &settings); - const std::string& FindGame(); + std::string FindGame(); wxListBox* m_player_lbox; wxTextCtrl* m_chat_text; @@ -101,6 +100,7 @@ private: std::string m_selected_game; wxButton* m_game_btn; + wxButton* m_start_btn; std::vector<int> m_playerids; @@ -134,5 +134,10 @@ private: int* const m_wiimapping; }; +namespace NetPlay +{ + void StopGame(); +} + #endif // _NETWINDOW_H_ diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index a4dad8293b..8503377779 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -33,6 +33,7 @@ set(SRCS Src/BPFunctions.cpp Src/VertexManagerBase.cpp Src/VertexShaderGen.cpp Src/VertexShaderManager.cpp + Src/VideoBackendBase.cpp Src/VideoConfig.cpp Src/VideoState.cpp Src/XFMemory.cpp diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index 77f2f6bab3..7272ed0993 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -299,38 +299,3 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size #undef SetRegName } } - -AlphaTest::TEST_RESULT AlphaTest::TestResult() -{ - switch(logic) - { - case 0: // AND - if (comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) - return PASS; - if (comp0 == ALPHACMP_NEVER || comp1 == ALPHACMP_NEVER) - return FAIL; - break; - - case 1: // OR - if (comp0 == ALPHACMP_ALWAYS || comp1 == ALPHACMP_ALWAYS) - return PASS; - if (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER) - return FAIL; - break; - - case 2: // XOR - if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS)) - return PASS; - if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)) - return FAIL; - break; - - case 3: // XNOR - if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS)) - return FAIL; - if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)) - return PASS; - break; - } - return UNDETERMINED; -} diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h index 90fffc6c6c..83dbefed50 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.h +++ b/Source/Core/VideoCommon/Src/BPMemory.h @@ -805,6 +805,7 @@ union PE_CONTROL u32 unused : 17; u32 rid : 8; }; + u32 hex; }; @@ -884,7 +885,40 @@ union AlphaTest PASS = 2, }; - TEST_RESULT TestResult(); + inline TEST_RESULT TestResult() const + { + switch(logic) + { + case 0: // AND + if (comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) + return PASS; + if (comp0 == ALPHACMP_NEVER || comp1 == ALPHACMP_NEVER) + return FAIL; + break; + + case 1: // OR + if (comp0 == ALPHACMP_ALWAYS || comp1 == ALPHACMP_ALWAYS) + return PASS; + if (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER) + return FAIL; + break; + + case 2: // XOR + if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS)) + return PASS; + if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)) + return FAIL; + break; + + case 3: // XNOR + if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS)) + return FAIL; + if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)) + return PASS; + break; + } + return UNDETERMINED; + } }; union UPE_Copy @@ -1005,6 +1039,9 @@ struct BPMemory TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd u32 bpMask; //0xFE u32 unknown18; //ff + + bool UseEarlyDepthTest() const { return zcontrol.early_ztest && zmode.testenable; } + bool UseLateDepthTest() const { return !zcontrol.early_ztest && zmode.testenable; } }; #pragma pack() diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index ce0346b523..00cecf0082 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -153,7 +153,10 @@ void BPWritten(const BPCmd& bp) bpmem.genMode.numtexgens, bpmem.genMode.numcolchans, bpmem.genMode.multisampling, bpmem.genMode.numtevstages+1, bpmem.genMode.cullmode, bpmem.genMode.numindstages, bpmem.genMode.zfreeze); - SetGenerationMode(); + + // Only call SetGenerationMode when cull mode changes. + if (bp.changes & 0xC000) + SetGenerationMode(); break; } case BPMEM_IND_MTXA: // Index Matrix Changed diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.h b/Source/Core/VideoCommon/Src/LightingShaderGen.h index 031dce44bd..fc107a2e2b 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.h +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.h @@ -9,40 +9,22 @@ #include "NativeVertexFormat.h" #include "XFMemory.h" -static const char* LightCol(const char* lightsName, unsigned int index, const char* swizzle) -{ - static char result[32]; - snprintf(result, sizeof(result), "%s[5*%d].%s", lightsName, index, swizzle); - return result; -} -static const char* LightCosAtt(const char* lightsName, unsigned int index) -{ - static char result[32]; - snprintf(result, sizeof(result), "%s[5*%d+1]", lightsName, index); - return result; -} +#define LIGHT_COL "%s[5*%d].%s" +#define LIGHT_COL_PARAMS(lightsName, index, swizzle) (lightsName), (index), (swizzle) -static const char* LightDistAtt(const char* lightsName, unsigned int index) -{ - static char result[32]; - snprintf(result, sizeof(result), "%s[5*%d+2]", lightsName, index); - return result; -} +#define LIGHT_COSATT "%s[5*%d+1]" +#define LIGHT_COSATT_PARAMS(lightsName, index) (lightsName), (index) -static const char* LightPos(const char* lightsName, unsigned int index) -{ - static char result[32]; - snprintf(result, sizeof(result), "%s[5*%d+3]", lightsName, index); - return result; -} +#define LIGHT_DISTATT "%s[5*%d+2]" +#define LIGHT_DISTATT_PARAMS(lightsName, index) (lightsName), (index) + +#define LIGHT_POS "%s[5*%d+3]" +#define LIGHT_POS_PARAMS(lightsName, index) (lightsName), (index) + +#define LIGHT_DIR "%s[5*%d+4]" +#define LIGHT_DIR_PARAMS(lightsName, index) (lightsName), (index) -static const char* LightDir(const char* lightsName, unsigned int index) -{ - static char result[32]; - snprintf(result, sizeof(result), "%s[5*%d+4]", lightsName, index); - return result; -} template<class T> static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha) @@ -62,13 +44,13 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, switch (chan.diffusefunc) { case LIGHTDIF_NONE: - object.Write("lacc.%s += %s;\n", swizzle, LightCol(lightsName, index, swizzle)); + object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsName, index, swizzle)); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: - object.Write("ldir = normalize(%s.xyz - pos.xyz);\n", LightPos(lightsName, index)); - object.Write("lacc.%s += %sdot(ldir, _norm0)) * %s;\n", - swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", LightCol(lightsName, index, swizzle)); + object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(lightsName, index)); + object.Write("lacc.%s += %sdot(ldir, _norm0)) * " LIGHT_COL";\n", + swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", LIGHT_COL_PARAMS(lightsName, index, swizzle)); break; default: _assert_(0); } @@ -77,31 +59,34 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, { if (chan.attnfunc == 3) { // spot - object.Write("ldir = %s.xyz - pos.xyz;\n", LightPos(lightsName, index)); + object.Write("ldir = " LIGHT_POS".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(lightsName, index)); object.Write("dist2 = dot(ldir, ldir);\n" "dist = sqrt(dist2);\n" "ldir = ldir / dist;\n" - "attn = max(0.0f, dot(ldir, %s.xyz));\n", LightDir(lightsName, index)); - object.Write("attn = max(0.0f, dot(%s.xyz, float3(1.0f, attn, attn*attn))) / dot(%s.xyz, float3(1.0f,dist,dist2));\n", LightCosAtt(lightsName, index), LightDistAtt(lightsName, index)); + "attn = max(0.0f, dot(ldir, " LIGHT_DIR".xyz));\n", + LIGHT_DIR_PARAMS(lightsName, index)); + object.Write("attn = max(0.0f, dot(" LIGHT_COSATT".xyz, float3(1.0f, attn, attn*attn))) / dot(" LIGHT_DISTATT".xyz, float3(1.0f,dist,dist2));\n", + LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index)); } else if (chan.attnfunc == 1) { // specular - object.Write("ldir = normalize(%s.xyz);\n", LightPos(lightsName, index)); - object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, %s.xyz)) : 0.0f;\n", LightDir(lightsName, index)); - object.Write("attn = max(0.0f, dot(%s.xyz, float3(1,attn,attn*attn))) / dot(%s.xyz, float3(1,attn,attn*attn));\n", LightCosAtt(lightsName, index), LightDistAtt(lightsName, index)); + object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(lightsName, index)); + object.Write("attn = (dot(_norm0,ldir) >= 0.0f) ? max(0.0f, dot(_norm0, " LIGHT_DIR".xyz)) : 0.0f;\n", LIGHT_DIR_PARAMS(lightsName, index)); + object.Write("attn = max(0.0f, dot(" LIGHT_COSATT".xyz, float3(1,attn,attn*attn))) / dot(" LIGHT_DISTATT".xyz, float3(1,attn,attn*attn));\n", + LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index)); } switch (chan.diffusefunc) { case LIGHTDIF_NONE: - object.Write("lacc.%s += attn * %s;\n", swizzle, LightCol(lightsName, index, swizzle)); + object.Write("lacc.%s += attn * " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsName, index, swizzle)); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: - object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * %s;\n", + object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * " LIGHT_COL";\n", swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", - LightCol(lightsName, index, swizzle)); + LIGHT_COL_PARAMS(lightsName, index, swizzle)); break; default: _assert_(0); } @@ -150,7 +135,10 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com else if (components & VB_HAS_COL0 ) object.Write("lacc = %s0;\n", inColorName); else - object.Write("lacc = float4(0.0f, 0.0f, 0.0f, 0.0f);\n"); + // TODO: this isn't verified. Here we want to read the ambient from the vertex, + // but the vertex itself has no color. So we don't know which value to read. + // Returing 1.0 is the same as disabled lightning, so this could be fine + object.Write("lacc = float4(1.0f, 1.0f, 1.0f, 1.0f);\n"); } else // from color { @@ -191,7 +179,8 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com else if (components & VB_HAS_COL0 ) object.Write("lacc.w = %s0.w;\n", inColorName); else - object.Write("lacc.w = 0.0f;\n"); + // TODO: The same for alpha: We want to read from vertex, but the vertex has no color + object.Write("lacc.w = 1.0f;\n"); } else // from color { diff --git a/Source/Core/VideoCommon/Src/PerfQueryBase.cpp b/Source/Core/VideoCommon/Src/PerfQueryBase.cpp index c537d176f6..af8bfa72e5 100644 --- a/Source/Core/VideoCommon/Src/PerfQueryBase.cpp +++ b/Source/Core/VideoCommon/Src/PerfQueryBase.cpp @@ -1,3 +1,9 @@ #include "PerfQueryBase.h" +#include "VideoConfig.h" PerfQueryBase* g_perf_query = 0; + +bool PerfQueryBase::ShouldEmulate() const +{ + return g_ActiveConfig.bPerfQueriesEnable; +} diff --git a/Source/Core/VideoCommon/Src/PerfQueryBase.h b/Source/Core/VideoCommon/Src/PerfQueryBase.h index b979449edb..bf5474b4db 100644 --- a/Source/Core/VideoCommon/Src/PerfQueryBase.h +++ b/Source/Core/VideoCommon/Src/PerfQueryBase.h @@ -25,9 +25,12 @@ enum PerfQueryGroup class PerfQueryBase { public: - PerfQueryBase() {}; + PerfQueryBase() {} virtual ~PerfQueryBase() {} + // Checks if performance queries are enabled in the gameini configuration. + bool ShouldEmulate() const; + // Begin querying the specified value for the following host GPU commands virtual void EnableQuery(PerfQueryGroup type) {} diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index f7ddec5477..7de5d12638 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -216,7 +216,7 @@ static char swapModeTable[4][5]; static char text[16384]; -static void BuildSwapModeTable() +static inline void BuildSwapModeTable() { static const char *swapColors = "rgba"; for (int i = 0; i < 4; i++) @@ -229,13 +229,13 @@ static void BuildSwapModeTable() } } -template<class T> static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4]); -template<class T> static void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); -template<class T> static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth); -template<class T> static void WriteFog(T& out, pixel_shader_uid_data& uid_data); +template<class T> static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4]); +template<class T> static inline void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); +template<class T> static inline void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth); +template<class T> static inline void WriteFog(T& out, pixel_shader_uid_data& uid_data); template<class T> -static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) +static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) { // Non-uid template parameters will write to the dummy data (=> gets optimized out) pixel_shader_uid_data dummy_data; @@ -243,23 +243,25 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api ? out.template GetUidData<pixel_shader_uid_data>() : dummy_data; out.SetBuffer(text); + const bool is_writing_shadercode = (out.GetBuffer() != NULL); #ifndef ANDROID locale_t locale; locale_t old_locale; - if (out.GetBuffer() != NULL) + if (is_writing_shadercode) { locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation old_locale = uselocale(locale); // Apply the locale for this thread } #endif - text[sizeof(text) - 1] = 0x7C; // canary + if (is_writing_shadercode) + text[sizeof(text) - 1] = 0x7C; // canary unsigned int numStages = bpmem.genMode.numtevstages + 1; unsigned int numTexgen = bpmem.genMode.numtexgens; - const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.zcontrol.early_ztest && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED); - const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) || (!g_ActiveConfig.bFastDepthCalc && !forced_early_z); + const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED); + const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z); out.Write("//Pixel Shader for TEV stages\n"); out.Write("//%i TEV stages, %i texgens, %i IND stages\n", @@ -331,7 +333,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api out.Write("VARYIN float4 colors_02;\n"); out.Write("VARYIN float4 colors_12;\n"); - + // compute window position if needed because binding semantic WPOS is not widely supported // Let's set up attributes if (xfregs.numTexGen.numTexGens < 7) @@ -365,18 +367,37 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api } out.Write("float4 clipPos;\n"); } - + if (forced_early_z) { // HACK: This doesn't force the driver to write to depth buffer if alpha test fails. // It just allows it, but it seems that all drivers do. out.Write("layout(early_fragment_tests) in;\n"); } - + else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) && is_writing_shadercode) + { + static bool warn_once = true; + if (warn_once) + WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current configuration. Make sure to use the D3D11 or OpenGL backend and enable fast depth calculations. If this message still shows up your hardware isn't able to emulate the feature properly (a GPU which supports D3D 11.0 / OGL 4.2 is required)."); + warn_once = false; + } + out.Write("void main()\n{\n"); } else { + if (forced_early_z) + { + out.Write("[earlydepthstencil]\n"); + } + else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) && is_writing_shadercode) + { + static bool warn_once = true; + if (warn_once) + WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current configuration. Make sure to use the D3D11 or OpenGL backend and enable fast depth calculations. If this message still shows up your hardware isn't able to emulate the feature properly (a GPU which supports D3D 11.0 / OGL 4.2 is required)."); + warn_once = false; + } + out.Write("void main(\n"); if(ApiType != API_D3D11) { @@ -481,7 +502,6 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { - uid_data.xfregs_numTexGen_numTexGens = xfregs.numTexGen.numTexGens; if (xfregs.numTexGen.numTexGens < 7) { out.Write("\tfloat3 _norm0 = normalize(Normal.xyz);\n\n"); @@ -630,11 +650,11 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api uid_data.per_pixel_depth = per_pixel_depth; uid_data.forced_early_z = forced_early_z; uid_data.fast_depth_calc = g_ActiveConfig.bFastDepthCalc; - uid_data.early_ztest = bpmem.zcontrol.early_ztest; + uid_data.early_ztest = bpmem.UseEarlyDepthTest(); uid_data.fog_fsel = bpmem.fog.c_proj_fsel.fsel; // Note: z-textures are not written to depth buffer if early depth test is used - if (per_pixel_depth && bpmem.zcontrol.early_ztest) + if (per_pixel_depth && bpmem.UseEarlyDepthTest()) out.Write("depth = zCoord;\n"); // Note: depth texture output is only written to depth buffer if late depth test is used @@ -652,7 +672,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api out.Write("zCoord = zCoord * (16777216.0f/16777215.0f);\n"); } - if (per_pixel_depth && !bpmem.zcontrol.early_ztest) + if (per_pixel_depth && bpmem.UseLateDepthTest()) out.Write("depth = zCoord;\n"); if (dstAlphaMode == DSTALPHA_ALPHA_PASS) @@ -687,16 +707,16 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api out.Write("}\n"); - if (text[sizeof(text) - 1] != 0x7C) - PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); + if (is_writing_shadercode) + { + if (text[sizeof(text) - 1] != 0x7C) + PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); #ifndef ANDROID - if (out.GetBuffer() != NULL) - { uselocale(old_locale); // restore locale freelocale(locale); - } #endif + } } @@ -744,7 +764,7 @@ static const char *TEVCMPAlphaOPTable[16] = }; template<class T> -static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4]) +static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4]) { int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1); bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens; @@ -887,7 +907,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap]; int texmap = bpmem.tevorders[n/2].getTexMap(n&1); uid_data.SetTevindrefTexmap(i, texmap); - + out.Write("textemp = "); SampleTexture<T>(out, "tevcoord", texswap, texmap, ApiType); } @@ -1114,7 +1134,7 @@ template<class T> void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType) { out.SetConstantsUsed(C_TEXDIMS+texmap,C_TEXDIMS+texmap); - + if (ApiType == API_D3D11) out.Write("Tex%d.Sample(samp%d,%s.xy * " I_TEXDIMS"[%d].xy).%s;\n", texmap,texmap, texcoords, texmap, texswap); else @@ -1142,7 +1162,7 @@ static const char *tevAlphaFunclogicTable[] = }; template<class T> -static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth) +static inline void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth) { static const char *alphaRef[2] = { @@ -1185,11 +1205,11 @@ static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE Api // We implement "depth test before texturing" by disabling alpha test when early-z is in use. // It seems to be less buggy than not to update the depth buffer if alpha test fails, // but both ways wouldn't be accurate. - + // OpenGL 4.2 has a flag which allows the driver to still update the depth buffer // if alpha test fails. The driver doesn't have to, but I assume they all do because // it's the much faster code path for the GPU. - uid_data.alpha_test_use_zcomploc_hack = bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable && !g_ActiveConfig.backend_info.bSupportsEarlyZ; + uid_data.alpha_test_use_zcomploc_hack = bpmem.UseEarlyDepthTest() && bpmem.zmode.updateenable && !g_ActiveConfig.backend_info.bSupportsEarlyZ; if (!uid_data.alpha_test_use_zcomploc_hack) { out.Write("\t\tdiscard;\n"); @@ -1213,7 +1233,7 @@ static const char *tevFogFuncsTable[] = }; template<class T> -static void WriteFog(T& out, pixel_shader_uid_data& uid_data) +static inline void WriteFog(T& out, pixel_shader_uid_data& uid_data) { uid_data.fog_fsel = bpmem.fog.c_proj_fsel.fsel; if(bpmem.fog.c_proj_fsel.fsel == 0) @@ -1255,7 +1275,7 @@ static void WriteFog(T& out, pixel_shader_uid_data& uid_data) } else { - if (bpmem.fog.c_proj_fsel.fsel != 2) + if (bpmem.fog.c_proj_fsel.fsel != 2 && out.GetBuffer() != NULL) WARN_LOG(VIDEO, "Unknown Fog Type! %08x", bpmem.fog.c_proj_fsel.fsel); } diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index c1ca009438..7763cbd574 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -63,18 +63,30 @@ struct pixel_shader_uid_data u32 num_values; // TODO: Shouldn't be a u32 u32 NumValues() const { return num_values; } - u32 components; + u32 components : 23; u32 dstAlphaMode : 2; u32 Pretest : 2; + u32 nIndirectStagesUsed : 4; + u32 pad0 : 1; u32 genMode_numtexgens : 4; u32 genMode_numtevstages : 4; u32 genMode_numindstages : 3; - - u32 nIndirectStagesUsed : 8; + u32 alpha_test_comp0 : 3; + u32 alpha_test_comp1 : 3; + u32 alpha_test_logic : 2; + u32 alpha_test_use_zcomploc_hack : 1; + u32 fog_proj : 1; + u32 fog_fsel : 3; + u32 fog_RangeBaseEnabled : 1; + u32 ztex_op : 2; + u32 fast_depth_calc : 1; + u32 per_pixel_depth : 1; + u32 forced_early_z : 1; + u32 early_ztest : 1; + u32 pad1 : 1; u32 texMtxInfo_n_projection : 8; // 8x1 bit - u32 tevindref_bi0 : 3; u32 tevindref_bc0 : 3; u32 tevindref_bi1 : 3; @@ -83,6 +95,7 @@ struct pixel_shader_uid_data u32 tevindref_bc3 : 3; u32 tevindref_bi4 : 3; u32 tevindref_bc4 : 3; + inline void SetTevindrefValues(int index, u32 texcoord, u32 texmap) { if (index == 0) { tevindref_bc0 = texcoord; tevindref_bi0 = texmap; } @@ -98,25 +111,6 @@ struct pixel_shader_uid_data else if (index == 3) { tevindref_bi4 = texmap; } } - u32 alpha_test_comp0 : 3; - u32 alpha_test_comp1 : 3; - u32 alpha_test_logic : 2; - - u32 alpha_test_use_zcomploc_hack : 1; - - u32 fog_proj : 1; - u32 fog_fsel : 3; - u32 fog_RangeBaseEnabled : 1; - - u32 ztex_op : 2; - - u32 fast_depth_calc : 1; - u32 per_pixel_depth : 1; - u32 forced_early_z : 1; - u32 early_ztest : 1; - - u32 xfregs_numTexGen_numTexGens : 4; - struct { // TODO: Can save a lot space by removing the padding bits u32 cc : 24; diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h index ec4fe27416..a804c08f13 100644 --- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h @@ -173,7 +173,7 @@ private: }; template<class T> -static void WriteRegister(T& object, API_TYPE ApiType, const char *prefix, const u32 num) +static inline void WriteRegister(T& object, API_TYPE ApiType, const char *prefix, const u32 num) { if (ApiType == API_OPENGL) return; // Nothing to do here @@ -182,7 +182,7 @@ static void WriteRegister(T& object, API_TYPE ApiType, const char *prefix, const } template<class T> -static void WriteLocation(T& object, API_TYPE ApiType, bool using_ubos) +static inline void WriteLocation(T& object, API_TYPE ApiType, bool using_ubos) { if (using_ubos) return; @@ -191,7 +191,7 @@ static void WriteLocation(T& object, API_TYPE ApiType, bool using_ubos) } template<class T> -static void DeclareUniform(T& object, API_TYPE api_type, bool using_ubos, const u32 num, const char* type, const char* name) +static inline void DeclareUniform(T& object, API_TYPE api_type, bool using_ubos, const u32 num, const char* type, const char* name) { WriteLocation(object, api_type, using_ubos); object.Write("%s %s ", type, name); diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index a682b4ea21..ad090fb839 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -38,7 +38,7 @@ static void DefineVSOutputStructMember(T& object, API_TYPE api_type, const char* } template<class T> -static void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) +static inline void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) { object.Write("struct VS_OUTPUT {\n"); DefineVSOutputStructMember(object, api_type, "float4", "pos", -1, "POSITION"); @@ -67,7 +67,7 @@ static void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type) } template<class T> -static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) +static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { // Non-uid template parameters will write to the dummy data (=> gets optimized out) vertex_shader_uid_data dummy_data; @@ -75,22 +75,23 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) ? out.template GetUidData<vertex_shader_uid_data>() : dummy_data; out.SetBuffer(text); + const bool is_writing_shadercode = (out.GetBuffer() != NULL); #ifndef ANDROID locale_t locale; locale_t old_locale; - if (out.GetBuffer() != NULL) + if (is_writing_shadercode) { locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation old_locale = uselocale(locale); // Apply the locale for this thread } #endif - text[sizeof(text) - 1] = 0x7C; // canary + + if (is_writing_shadercode) + text[sizeof(text) - 1] = 0x7C; // canary _assert_(bpmem.genMode.numtexgens == xfregs.numTexGen.numTexGens); _assert_(bpmem.genMode.numcolchans == xfregs.numChan.numColorChans); - bool is_d3d = (api_type & API_D3D9 || api_type == API_D3D11); - // uniforms if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) out.Write("layout(std140) uniform VSBlock {\n"); @@ -174,19 +175,9 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) if (components & VB_HAS_NRM0) out.Write(" float3 rawnorm0 : NORMAL0,\n"); if (components & VB_HAS_NRM1) - { - if (is_d3d) - out.Write(" float3 rawnorm1 : NORMAL1,\n"); - else - out.Write(" float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); - } + out.Write(" float3 rawnorm1 : NORMAL1,\n"); if (components & VB_HAS_NRM2) - { - if (is_d3d) - out.Write(" float3 rawnorm2 : NORMAL2,\n"); - else - out.Write(" float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); - } + out.Write(" float3 rawnorm2 : NORMAL2,\n"); if (components & VB_HAS_COL0) out.Write(" float4 color0 : COLOR0,\n"); if (components & VB_HAS_COL1) @@ -198,12 +189,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) out.Write(" float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i); } if (components & VB_HAS_POSMTXIDX) - { - if (is_d3d) - out.Write(" float4 blend_indices : BLENDINDICES,\n"); - else - out.Write(" float fposmtx : ATTR%d,\n", SHADER_POSMTX_ATTRIB); - } + out.Write(" float4 blend_indices : BLENDINDICES,\n"); out.Write(" float4 rawpos : POSITION) {\n"); } out.Write("VS_OUTPUT o;\n"); @@ -225,7 +211,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) out.Write("int posmtx = int(fposmtx);\n"); } - if (DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS)) + if (is_writing_shadercode && DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS)) { // This'll cause issues, but it can't be helped out.Write("float4 pos = float4(dot(" I_TRANSFORMMATRICES"[0], rawpos), dot(" I_TRANSFORMMATRICES"[1], rawpos), dot(" I_TRANSFORMMATRICES"[2], rawpos), 1);\n"); @@ -353,7 +339,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) // transform the light dir into tangent space uid_data.texMtxInfo[i].embosslightshift = xfregs.texMtxInfo[i].embosslightshift; uid_data.texMtxInfo[i].embosssourceshift = xfregs.texMtxInfo[i].embosssourceshift; - out.Write("ldir = normalize(%s.xyz - pos.xyz);\n", LightPos(I_LIGHTS, texinfo.embosslightshift)); + out.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(I_LIGHTS, texinfo.embosslightshift)); out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift); } else @@ -468,7 +454,7 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values //if not early z culling will improve speed - if (is_d3d) + if (api_type & API_D3D9 || api_type == API_D3D11) { out.Write("o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); } @@ -547,16 +533,16 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) out.Write("return o;\n}\n"); } - if (text[sizeof(text) - 1] != 0x7C) - PanicAlert("VertexShader generator - buffer too small, canary has been eaten!"); + if (is_writing_shadercode) + { + if (text[sizeof(text) - 1] != 0x7C) + PanicAlert("VertexShader generator - buffer too small, canary has been eaten!"); #ifndef ANDROID - if (out.GetBuffer() != NULL) - { uselocale(old_locale); // restore locale freelocale(locale); - } #endif + } } void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type) diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.h b/Source/Core/VideoCommon/Src/VertexShaderGen.h index eef0646e6f..ab9a378107 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.h +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.h @@ -69,12 +69,12 @@ struct vertex_shader_uid_data { u32 NumValues() const { return sizeof(vertex_shader_uid_data); } - u32 components; - u32 numColorChans : 2; + u32 components : 23; u32 numTexGens : 4; - + u32 numColorChans : 2; u32 dualTexTrans_enabled : 1; u32 pixel_lighting : 1; + u32 pad0 : 1; u32 texMtxInfo_n_projection : 16; // Stored separately to guarantee that the texMtxInfo struct is 8 bits wide struct { diff --git a/Source/Core/Common/Src/VideoBackendBase.cpp b/Source/Core/VideoCommon/Src/VideoBackendBase.cpp index 99bce01156..4769ede3a0 100644 --- a/Source/Core/Common/Src/VideoBackendBase.cpp +++ b/Source/Core/VideoCommon/Src/VideoBackendBase.cpp @@ -19,6 +19,8 @@ VideoBackend* g_video_backend = NULL; static VideoBackend* s_default_backend = NULL; #ifdef _WIN32 +#include <windows.h> + // http://msdn.microsoft.com/en-us/library/ms725491.aspx static bool IsGteVista() { diff --git a/Source/Core/Common/Src/VideoBackendBase.h b/Source/Core/VideoCommon/Src/VideoBackendBase.h index 9c591d05a5..9c591d05a5 100644 --- a/Source/Core/Common/Src/VideoBackendBase.h +++ b/Source/Core/VideoCommon/Src/VideoBackendBase.h diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index d422c3d01d..b3e9a8815f 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -181,6 +181,7 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.GetIfExists("Video", "PH_ZFar", &sPhackvalue[1]); iniFile.GetIfExists("Video", "ZTPSpeedupHack", &bZTPSpeedHack); iniFile.GetIfExists("Video", "UseBBox", &bUseBBox); + iniFile.GetIfExists("Video", "PerfQueriesEnable", &bPerfQueriesEnable); } void VideoConfig::VerifyValidity() diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index a0a5cabacf..b856683595 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -108,6 +108,7 @@ struct VideoConfig // Hacks bool bEFBAccessEnable; bool bDlistCachingEnable; + bool bPerfQueriesEnable; bool bEFBCopyEnable; bool bEFBCopyCacheEnable; diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj b/Source/Core/VideoCommon/VideoCommon.vcxproj index 1e7a56f578..c5896af1a6 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj @@ -213,6 +213,7 @@ <ClCompile Include="Src\VertexManagerBase.cpp" /> <ClCompile Include="Src\VertexShaderGen.cpp" /> <ClCompile Include="Src\VertexShaderManager.cpp" /> + <ClCompile Include="Src\VideoBackendBase.cpp" /> <ClCompile Include="Src\VideoConfig.cpp" /> <ClCompile Include="Src\VideoState.cpp" /> <ClCompile Include="Src\x64DLCache.cpp" /> @@ -266,6 +267,7 @@ <ClInclude Include="Src\VertexShaderGen.h" /> <ClInclude Include="Src\VertexShaderManager.h" /> <ClInclude Include="Src\VideoCommon.h" /> + <ClInclude Include="Src\VideoBackendBase.h" /> <ClInclude Include="Src\VideoConfig.h" /> <ClInclude Include="Src\VideoState.h" /> <ClInclude Include="Src\XFMemory.h" /> diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters index 785e55877f..3f864b0e7e 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters @@ -4,6 +4,7 @@ <ClCompile Include="Src\CommandProcessor.cpp" /> <ClCompile Include="Src\memcpy_amd.cpp" /> <ClCompile Include="Src\PixelEngine.cpp" /> + <ClCompile Include="Src\VideoBackendBase.cpp" /> <ClCompile Include="Src\VideoConfig.cpp" /> <ClCompile Include="Src\VertexLoader.cpp"> <Filter>Vertex Loading</Filter> @@ -128,6 +129,7 @@ <ClInclude Include="Src\NativeVertexFormat.h" /> <ClInclude Include="Src\PixelEngine.h" /> <ClInclude Include="Src\VideoCommon.h" /> + <ClInclude Include="Src\VideoBackendBase.h" /> <ClInclude Include="Src\VideoConfig.h" /> <ClInclude Include="Src\DataReader.h"> <Filter>Vertex Loading</Filter> diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp index 209bfdb73f..8ea7e88e3e 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp @@ -245,6 +245,13 @@ std::vector<DXGI_SAMPLE_DESC> EnumAAModes(IDXGIAdapter* adapter) return aa_modes; } +D3D_FEATURE_LEVEL GetFeatureLevel(IDXGIAdapter* adapter) +{ + D3D_FEATURE_LEVEL feat_level = D3D_FEATURE_LEVEL_9_1; + PD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, NULL, &feat_level, NULL); + return feat_level; +} + DXGI_SAMPLE_DESC GetAAMode(int index) { return aa_modes[index]; @@ -326,11 +333,7 @@ HRESULT Create(HWND wnd) swap_chain_desc.BufferDesc.Width = xres; swap_chain_desc.BufferDesc.Height = yres; -#if defined(_DEBUG) || defined(DEBUGFAST) - D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG|D3D11_CREATE_DEVICE_SINGLETHREADED); -#else D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED; -#endif hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, device_flags, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h index 6361e3a5fa..03c1ed9d13 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h @@ -31,6 +31,7 @@ void UnloadD3D(); void UnloadD3DX(); void UnloadD3DCompiler(); +D3D_FEATURE_LEVEL GetFeatureLevel(IDXGIAdapter* adapter); std::vector<DXGI_SAMPLE_DESC> EnumAAModes(IDXGIAdapter* adapter); DXGI_SAMPLE_DESC GetAAMode(int index); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp index c634593361..3ba5e098ef 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp @@ -28,6 +28,9 @@ PerfQuery::~PerfQuery() void PerfQuery::EnableQuery(PerfQueryGroup type) { + if (!ShouldEmulate()) + return; + // Is this sane? if (m_query_count > ARRAYSIZE(m_query_buffer) / 2) WeakFlush(); @@ -53,6 +56,9 @@ void PerfQuery::EnableQuery(PerfQueryGroup type) void PerfQuery::DisableQuery(PerfQueryGroup type) { + if (!ShouldEmulate()) + return; + // stop query if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) { @@ -69,6 +75,9 @@ 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) @@ -93,6 +102,9 @@ u32 PerfQuery::GetQueryResult(PerfQueryType type) void PerfQuery::FlushOne() { + if (!ShouldEmulate()) + return; + auto& entry = m_query_buffer[m_query_read_pos]; UINT64 result = 0; @@ -113,12 +125,18 @@ 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]; @@ -143,6 +161,9 @@ void PerfQuery::WeakFlush() bool PerfQuery::IsFlushed() const { + if (!ShouldEmulate()) + return true; + return 0 == m_query_count; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index 4e03dfb456..10369a1329 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -90,7 +90,6 @@ void InitBackendInfo() g_Config.backend_info.bSupportsFormatReinterpretation = true; g_Config.backend_info.bSupportsPixelLighting = true; g_Config.backend_info.bSupportsPrimitiveRestart = true; - g_Config.backend_info.bSupportsEarlyZ = false; IDXGIFactory* factory; IDXGIAdapter* ad; @@ -103,11 +102,13 @@ void InitBackendInfo() g_Config.backend_info.AAModes.clear(); while (factory->EnumAdapters((UINT)g_Config.backend_info.Adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND) { + const size_t adapter_index = g_Config.backend_info.Adapters.size(); + DXGI_ADAPTER_DESC desc; ad->GetDesc(&desc); // TODO: These don't get updated on adapter change, yet - if (g_Config.backend_info.Adapters.size() == g_Config.iAdapter) + if (adapter_index == g_Config.iAdapter) { char buf[32]; std::vector<DXGI_SAMPLE_DESC> modes; @@ -119,6 +120,9 @@ void InitBackendInfo() else sprintf_s(buf, 32, _trans("%d samples"), modes[i].Count); g_Config.backend_info.AAModes.push_back(buf); } + + // Requires the earlydepthstencil attribute (only available in shader model 5) + g_Config.backend_info.bSupportsEarlyZ = (DX11::D3D::GetFeatureLevel(ad) == D3D_FEATURE_LEVEL_11_0); } g_Config.backend_info.Adapters.push_back(UTF16ToUTF8(desc.Description)); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 19e6441bbd..1a4e1bf84d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -77,7 +77,7 @@ std::string VideoBackend::GetName() std::string VideoBackend::GetDisplayName() { - return "Direct3D9"; + return "Direct3D9 (deprecated)"; } void InitBackendInfo() diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index b381cd2375..140dbd4d78 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -226,8 +226,13 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms " ocol0 = float4(dst6) / 63.f;\n" "}"; - ProgramShaderCache::CompileShader(m_pixel_format_shaders[0], vs, ps_rgb8_to_rgba6); - ProgramShaderCache::CompileShader(m_pixel_format_shaders[1], vs, ps_rgba6_to_rgb8); + if(g_ogl_config.eSupportedGLSLVersion != GLSL_120) + { + // HACK: This shaders aren't glsl120 compatible as glsl120 don't support bit operations + // it could be workaround by floor + frac + tons off additions, but I think it isn't worth + ProgramShaderCache::CompileShader(m_pixel_format_shaders[0], vs, ps_rgb8_to_rgba6); + ProgramShaderCache::CompileShader(m_pixel_format_shaders[1], vs, ps_rgba6_to_rgb8); + } } @@ -359,6 +364,11 @@ GLuint FramebufferManager::ResolveAndGetDepthTarget(const EFBRectangle &source_r void FramebufferManager::ReinterpretPixelData(unsigned int convtype) { + if(g_ogl_config.eSupportedGLSLVersion == GLSL_120) { + // This feature isn't supported by glsl120 + return; + } + g_renderer->ResetAPIState(); GLuint src_texture = 0; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp index 31d2af6107..a1582c0c62 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp @@ -23,6 +23,9 @@ PerfQuery::~PerfQuery() void PerfQuery::EnableQuery(PerfQueryGroup type) { + if (!ShouldEmulate()) + return; + // Is this sane? if (m_query_count > ARRAYSIZE(m_query_buffer) / 2) WeakFlush(); @@ -47,6 +50,9 @@ void PerfQuery::EnableQuery(PerfQueryGroup type) void PerfQuery::DisableQuery(PerfQueryGroup type) { + if (!ShouldEmulate()) + return; + // stop query if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) { @@ -56,11 +62,17 @@ void PerfQuery::DisableQuery(PerfQueryGroup type) bool PerfQuery::IsFlushed() const { + if (!ShouldEmulate()) + return true; + return 0 == m_query_count; } void PerfQuery::FlushOne() { + if (!ShouldEmulate()) + return; + auto& entry = m_query_buffer[m_query_read_pos]; GLuint result = 0; @@ -76,12 +88,18 @@ 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]; @@ -108,6 +126,9 @@ 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) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 6b2e92c93a..1eb986fe74 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -250,6 +250,8 @@ void VideoBackend::Video_Cleanup() { ProgramShaderCache::Shutdown(); VertexShaderManager::Shutdown(); PixelShaderManager::Shutdown(); + delete g_perf_query; + g_perf_query = NULL; delete g_vertex_manager; g_vertex_manager = NULL; OpcodeDecoder_Shutdown(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp index f1fc5f5ac9..3c45ee7d25 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp @@ -135,7 +135,7 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi) if (z < 0 || z > 0x00ffffff) return; - if (bpmem.zcontrol.early_ztest && bpmem.zmode.testenable && g_SWVideoConfig.bZComploc) + if (bpmem.UseEarlyDepthTest() && g_SWVideoConfig.bZComploc) { // TODO: Test if perf regs are incremented even if test is disabled SWPixelEngine::pereg.IncZInputQuadCount(true); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp index 5f1f4aa2df..eea908edfc 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp @@ -51,7 +51,7 @@ VideoConfigDialog::VideoConfigDialog(wxWindow* parent, const std::string& title, it = g_available_video_backends.begin(), itend = g_available_video_backends.end(); for (; it != itend; ++it) - choice_backend->AppendString(StrToWxStr((*it)->GetName())); + choice_backend->AppendString(StrToWxStr((*it)->GetDisplayName())); // TODO: How to get the translated plugin name? choice_backend->SetStringSelection(StrToWxStr(g_video_backend->GetName())); |
