Merge remote-tracking branch 'origin/master' into wiimote-netplay
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 510 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 487 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 580 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
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(t1!=null)
|
||||
t1.setText(o.getName());
|
||||
if(t2!=null)
|
||||
t2.setText(o.getData());
|
||||
if(v1!=null)
|
||||
v1.setImageBitmap(o.getImage());
|
||||
}
|
||||
if(title != null)
|
||||
title.setText(item.getName());
|
||||
if(subtitle != null)
|
||||
subtitle.setText(item.getData());
|
||||
if(icon != null)
|
||||
icon.setImageBitmap(item.getImage());
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
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(t1!=null)
|
||||
t1.setText(o.getName());
|
||||
if(t2!=null)
|
||||
t2.setText(o.getBind());
|
||||
if(title != null)
|
||||
title.setText(item.getName());
|
||||
|
||||
if(subtitle != null)
|
||||
subtitle.setText(item.getBind());
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
</Project>
|
||||
|
||||
@@ -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>
|
||||
</Project>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
if (line[0] == '#')
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
// Allow preservation of spacing before comment
|
||||
if (FirstCommentChar > 0)
|
||||
{
|
||||
while (line[FirstCommentChar - 1] == ' ' || line[FirstCommentChar - 1] == 9) // 9 == tab
|
||||
{
|
||||
FirstCommentChar--;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" +
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
ARMReg RA = gpr.R(inst.RA);
|
||||
ARMReg RB = gpr.R(inst.RB);
|
||||
ARMReg RD = gpr.R(inst.RD);
|
||||
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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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}},
|
||||
|
||||
@@ -117,17 +117,6 @@ void Init(int cpu_core)
|
||||
{
|
||||
FPURoundMode::SetPrecisionMode(FPURoundMode::PREC_53);
|
||||
|
||||
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));
|
||||
|
||||
memset(ppcState.mojs, 0, sizeof(ppcState.mojs));
|
||||
memset(ppcState.sr, 0, sizeof(ppcState.sr));
|
||||
ppcState.DebugCount = 0;
|
||||
|
||||
@@ -1049,6 +1049,7 @@ void CFrame::DoStop()
|
||||
DoRecordingSave();
|
||||
if(Movie::IsPlayingInput() || Movie::IsRecordingInput())
|
||||
Movie::EndPlayInput(false);
|
||||
NetPlay::StopGame();
|
||||
|
||||
wxBeginBusyCursor();
|
||||
BootManager::Stop();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#include "PerfQueryBase.h"
|
||||
#include "VideoConfig.h"
|
||||
|
||||
PerfQueryBase* g_perf_query = 0;
|
||||
|
||||
bool PerfQueryBase::ShouldEmulate() const
|
||||
{
|
||||
return g_ActiveConfig.bPerfQueriesEnable;
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+2
@@ -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()
|
||||
{
|
||||
@@ -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()
|
||||
|
||||
@@ -108,6 +108,7 @@ struct VideoConfig
|
||||
// Hacks
|
||||
bool bEFBAccessEnable;
|
||||
bool bDlistCachingEnable;
|
||||
bool bPerfQueriesEnable;
|
||||
|
||||
bool bEFBCopyEnable;
|
||||
bool bEFBCopyCacheEnable;
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -77,7 +77,7 @@ std::string VideoBackend::GetName()
|
||||
|
||||
std::string VideoBackend::GetDisplayName()
|
||||
{
|
||||
return "Direct3D9";
|
||||
return "Direct3D9 (deprecated)";
|
||||
}
|
||||
|
||||
void InitBackendInfo()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()));
|
||||
|
||||
Reference in New Issue
Block a user