From b47835fc07371964816938c982c5aea3a9f564bb Mon Sep 17 00:00:00 2001 From: Eder Bastos Date: Wed, 6 May 2015 20:12:58 -0400 Subject: [PATCH] Implement first few screens of Android 5.0-based UI. --- Source/Android/app/build.gradle | 14 +- .../Android/app/src/main/AndroidManifest.xml | 17 +- .../dolphinemu/dolphinemu/NativeLibrary.java | 6 + .../activities/GameGridActivity.java | 131 ++++++++ .../dolphinemu/adapters/GameAdapter.java | 113 +++++++ .../dolphinemu/dialogs/GameDetailsDialog.java | 96 ++++++ .../org/dolphinemu/dolphinemu/model/Game.java | 23 ++ .../dolphinemu/dolphinemu/model/GcGame.java | 96 ++++++ .../dolphinemu/dolphinemu/model/WiiGame.java | 53 +++ .../viewholders/GameViewHolder.java | 83 +++++ .../src/main/res/anim/button_elevation.xml | 19 ++ .../src/main/res/drawable-hdpi/ic_country.png | Bin 0 -> 1055 bytes .../src/main/res/drawable-hdpi/ic_date.png | Bin 0 -> 917 bytes .../src/main/res/drawable-hdpi/ic_play.png | Bin 0 -> 282 bytes .../src/main/res/drawable-ldpi/ic_date.png | Bin 0 -> 346 bytes .../res/drawable-mdpi/ic_action_overflow.png | Bin 0 -> 197 bytes .../src/main/res/drawable-mdpi/ic_country.png | Bin 0 -> 743 bytes .../src/main/res/drawable-mdpi/ic_date.png | Bin 0 -> 717 bytes .../src/main/res/drawable-mdpi/ic_play.png | Bin 0 -> 257 bytes .../res/drawable-xhdpi/ic_action_overflow.png | Bin 0 -> 267 bytes .../main/res/drawable-xhdpi/ic_country.png | Bin 0 -> 1390 bytes .../src/main/res/drawable-xhdpi/ic_date.png | Bin 0 -> 1157 bytes .../src/main/res/drawable-xhdpi/ic_play.png | Bin 0 -> 318 bytes .../drawable-xxhdpi/ic_action_overflow.png | Bin 0 -> 264 bytes .../main/res/drawable-xxhdpi/ic_country.png | Bin 0 -> 2053 bytes .../src/main/res/drawable-xxhdpi/ic_date.png | Bin 0 -> 1479 bytes .../src/main/res/drawable-xxhdpi/ic_play.png | Bin 0 -> 399 bytes .../main/res/drawable-xxxhdpi/ic_country.png | Bin 0 -> 2783 bytes .../src/main/res/drawable-xxxhdpi/ic_play.png | Bin 0 -> 477 bytes .../app/src/main/res/drawable/oval_ripple.xml | 9 + .../main/res/layout/activity_game_grid.xml | 24 ++ .../app/src/main/res/layout/card_game.xml | 71 ++++ .../main/res/layout/dialog_game_details.xml | 135 ++++++++ .../app/src/main/res/values-w820dp/dimens.xml | 6 + .../app/src/main/res/values/colors.xml | 8 + .../app/src/main/res/values/dimens.xml | 10 + .../app/src/main/res/values/styles.xml | 27 ++ Source/Android/build.gradle | 2 +- Source/Core/DolphinWX/MainAndroid.cpp | 310 +++++++++++++----- 39 files changed, 1167 insertions(+), 86 deletions(-) create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/GameGridActivity.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GcGame.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/WiiGame.java create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java create mode 100644 Source/Android/app/src/main/res/anim/button_elevation.xml create mode 100644 Source/Android/app/src/main/res/drawable-hdpi/ic_country.png create mode 100644 Source/Android/app/src/main/res/drawable-hdpi/ic_date.png create mode 100644 Source/Android/app/src/main/res/drawable-hdpi/ic_play.png create mode 100644 Source/Android/app/src/main/res/drawable-ldpi/ic_date.png create mode 100644 Source/Android/app/src/main/res/drawable-mdpi/ic_action_overflow.png create mode 100644 Source/Android/app/src/main/res/drawable-mdpi/ic_country.png create mode 100644 Source/Android/app/src/main/res/drawable-mdpi/ic_date.png create mode 100644 Source/Android/app/src/main/res/drawable-mdpi/ic_play.png create mode 100644 Source/Android/app/src/main/res/drawable-xhdpi/ic_action_overflow.png create mode 100644 Source/Android/app/src/main/res/drawable-xhdpi/ic_country.png create mode 100644 Source/Android/app/src/main/res/drawable-xhdpi/ic_date.png create mode 100644 Source/Android/app/src/main/res/drawable-xhdpi/ic_play.png create mode 100644 Source/Android/app/src/main/res/drawable-xxhdpi/ic_action_overflow.png create mode 100644 Source/Android/app/src/main/res/drawable-xxhdpi/ic_country.png create mode 100644 Source/Android/app/src/main/res/drawable-xxhdpi/ic_date.png create mode 100644 Source/Android/app/src/main/res/drawable-xxhdpi/ic_play.png create mode 100644 Source/Android/app/src/main/res/drawable-xxxhdpi/ic_country.png create mode 100644 Source/Android/app/src/main/res/drawable-xxxhdpi/ic_play.png create mode 100644 Source/Android/app/src/main/res/drawable/oval_ripple.xml create mode 100644 Source/Android/app/src/main/res/layout/activity_game_grid.xml create mode 100644 Source/Android/app/src/main/res/layout/card_game.xml create mode 100644 Source/Android/app/src/main/res/layout/dialog_game_details.xml create mode 100644 Source/Android/app/src/main/res/values-w820dp/dimens.xml create mode 100644 Source/Android/app/src/main/res/values/colors.xml create mode 100644 Source/Android/app/src/main/res/values/dimens.xml create mode 100644 Source/Android/app/src/main/res/values/styles.xml diff --git a/Source/Android/app/build.gradle b/Source/Android/app/build.gradle index 50ec628d1d..0fd64d013c 100644 --- a/Source/Android/app/build.gradle +++ b/Source/Android/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 21 - buildToolsVersion "20.0.0" + buildToolsVersion "20.0.0" lintOptions { // This is important as it will run lint but not abort on error @@ -47,6 +47,14 @@ android { dependencies { - compile 'com.android.support:support-v4:22.0.0' - compile 'com.android.support:support-v13:22.0.0' + compile 'com.android.support:support-v4:22.1.1' + compile 'com.android.support:support-v13:22.0.0' + compile 'com.android.support:cardview-v7:21.0.3' + compile 'com.android.support:recyclerview-v7:21.0.3' + + // For showing the banner as a circle a-la Material Design Guidelines + compile 'de.hdodenhof:circleimageview:1.2.2' + + // For loading huge screenshots from the disk. + compile "com.squareup.picasso:picasso:2.4.0" } diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml index 5187f65691..981d4117e9 100644 --- a/Source/Android/app/src/main/AndroidManifest.xml +++ b/Source/Android/app/src/main/AndroidManifest.xml @@ -9,15 +9,28 @@ + + + + + + + + + + + - + diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java index ab9f25b306..e7d2e2b328 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -130,6 +130,12 @@ public final class NativeLibrary */ public static native String GetTitle(String filename); + public static native String GetDescription(String filename); + public static native String GetGameId(String filename); + public static native String GetDate(String filename); + public static native long GetFilesize(String filename); + public static native boolean IsWiiTitle(String filename); + /** * Gets the Dolphin version string. * diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/GameGridActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/GameGridActivity.java new file mode 100644 index 0000000000..be0fbbed1a --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/GameGridActivity.java @@ -0,0 +1,131 @@ +package org.dolphinemu.dolphinemu.activities; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Environment; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.widget.Toolbar; + +import org.dolphinemu.dolphinemu.AssetCopyService; +import org.dolphinemu.dolphinemu.NativeLibrary; +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.adapters.GameAdapter; +import org.dolphinemu.dolphinemu.model.Game; +import org.dolphinemu.dolphinemu.model.GcGame; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class GameGridActivity extends Activity +{ + private RecyclerView mRecyclerView; + private RecyclerView.Adapter mAdapter; + private RecyclerView.LayoutManager mLayoutManager; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_game_grid); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_game_list); + setActionBar(toolbar); + + mRecyclerView = (RecyclerView) findViewById(R.id.grid_games); + + // use this setting to improve performance if you know that changes + // in content do not change the layout size of the RecyclerView + //mRecyclerView.setHasFixedSize(true); + + // Specifying the LayoutManager determines how the RecyclerView arranges views. + mLayoutManager = new GridLayoutManager(this, 4); + mRecyclerView.setLayoutManager(mLayoutManager); + + mRecyclerView.addItemDecoration(new GameAdapter.SpacesItemDecoration(8)); + + // Create an adapter that will relate the dataset to the views on-screen. + mAdapter = new GameAdapter(getGameList()); + mRecyclerView.setAdapter(mAdapter); + + // Stuff in this block only happens when this activity is newly created (i.e. not a rotation) + if (savedInstanceState == null) + { + // Copy assets into appropriate locations. + Intent copyAssets = new Intent(this, AssetCopyService.class); + startService(copyAssets); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) + { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.gamelist_menu, menu); + return true; + + } + + // TODO Replace all of this with a SQLite database + private ArrayList getGameList() + { + ArrayList gameList = new ArrayList(); + + final String DefaultDir = Environment.getExternalStorageDirectory() + File.separator + "dolphin-emu"; + + NativeLibrary.SetUserDirectory(DefaultDir); + + String Directories = NativeLibrary.GetConfig("Dolphin.ini", "General", "ISOPaths", "0"); + Log.v("DolphinEmu", "Directories: " + Directories); + int intDirectories = Integer.parseInt(Directories); + + // Extensions to filter by. + Set exts = new HashSet(Arrays.asList(".dff", ".dol", ".elf", ".gcm", ".gcz", ".iso", ".wad", ".wbfs")); + + for (int a = 0; a < intDirectories; ++a) + { + String BrowseDir = NativeLibrary.GetConfig("Dolphin.ini", "General", "ISOPath" + a, ""); + Log.v("DolphinEmu", "Directory " + a + ": " + BrowseDir); + + File currentDir = new File(BrowseDir); + File[] dirs = currentDir.listFiles(); + try + { + for (File entry : dirs) + { + if (!entry.isHidden() && !entry.isDirectory()) + { + String entryName = entry.getName(); + + // Check that the file has an appropriate extension before trying to read out of it. + if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) + { + GcGame game = new GcGame(NativeLibrary.GetTitle(entry.getAbsolutePath()), + NativeLibrary.GetDescription(entry.getAbsolutePath()).replace("\n", " "), + // TODO Some games might actually not be from this region, believe it or not. + "United States", + entry.getAbsolutePath(), + NativeLibrary.GetGameId(entry.getAbsolutePath()), + NativeLibrary.GetDate(entry.getAbsolutePath())); + + gameList.add(game); + } + + } + + } + } catch (Exception ignored) + { + } + } + + return gameList; + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java new file mode 100644 index 0000000000..30bc9daad6 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java @@ -0,0 +1,113 @@ +package org.dolphinemu.dolphinemu.adapters; + +import android.graphics.Rect; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.squareup.picasso.Picasso; + +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.model.Game; +import org.dolphinemu.dolphinemu.viewholders.GameViewHolder; + +import java.util.ArrayList; + +public class GameAdapter extends RecyclerView.Adapter +{ + private ArrayList mGameList; + + /** + * Mostly just initializes the dataset to be displayed. + * + * @param gameList + */ + public GameAdapter(ArrayList gameList) + { + mGameList = gameList; + } + + /** + * Called by the LayoutManager when it is necessary to create a new view. + * + * @param parent The RecyclerView (I think?) the created view will be thrown into. + * @param viewType Not used here, but useful when more than one type of child will be used in the RecyclerView. + * @return The created ViewHolder with references to all the child view's members. + */ + @Override + public GameViewHolder onCreateViewHolder(ViewGroup parent, int viewType) + { + // Create a new view. + View gameCard = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.card_game, parent, false); + + // Use that view to create a ViewHolder. + GameViewHolder holder = new GameViewHolder(gameCard); + return holder; + } + + /** + * Called by the LayoutManager when a new view is not necessary because we can recycle + * an existing one (for example, if a view just scrolled onto the screen from the bottom, we + * can use the view that just scrolled off the top instead of inflating a new one.) + * + * @param holder A ViewHolder representing the view we're recycling. + * @param position The position of the 'new' view in the dataset. + */ + @Override + public void onBindViewHolder(GameViewHolder holder, int position) + { + // Get a reference to the item from the dataset; we'll use this to fill in the view contents. + final Game game = mGameList.get(position); + + // Fill in the view contents. + Picasso.with(holder.imageScreenshot.getContext()) + .load(game.getScreenPath()) + .error(R.drawable.no_banner) + .into(holder.imageScreenshot); + + holder.textGameTitle.setText(game.getTitle()); + if (game.getDescription() != null) + { + holder.textDescription.setText(game.getDescription()); + } + holder.buttonDetails.setTag(game.getGameId()); + + holder.path = game.getPath(); + holder.screenshotPath = game.getScreenPath(); + holder.game = game; + + } + + /** + * Called by the LayoutManager to find out how much data we have. + * + * @return Size of the dataset. + */ + @Override + public int getItemCount() + { + return mGameList.size(); + } + + public static class SpacesItemDecoration extends RecyclerView.ItemDecoration + { + private int space; + + public SpacesItemDecoration(int space) + { + this.space = space; + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) + { + outRect.left = space; + outRect.right = space; + outRect.bottom = space; + outRect.top = space; + + } + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java new file mode 100644 index 0000000000..19c6621345 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java @@ -0,0 +1,96 @@ +package org.dolphinemu.dolphinemu.dialogs; + + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; + +import com.squareup.picasso.Picasso; + +import org.dolphinemu.dolphinemu.BuildConfig; +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.emulation.EmulationActivity; +import org.dolphinemu.dolphinemu.model.Game; + +import de.hdodenhof.circleimageview.CircleImageView; + +public class GameDetailsDialog extends DialogFragment +{ + public static final String ARGUMENT_GAME_TITLE = BuildConfig.APPLICATION_ID + ".game_title"; + public static final String ARGUMENT_GAME_DESCRIPTION = BuildConfig.APPLICATION_ID + ".game_description"; + public static final String ARGUMENT_GAME_COUNTRY = BuildConfig.APPLICATION_ID + ".game_country"; + public static final String ARGUMENT_GAME_DATE = BuildConfig.APPLICATION_ID + ".game_date"; + public static final String ARGUMENT_GAME_PATH = BuildConfig.APPLICATION_ID + ".game_path"; + public static final String ARGUMENT_GAME_SCREENSHOT_PATH = BuildConfig.APPLICATION_ID + ".game_screenshot_path"; + + + public static GameDetailsDialog newInstance(Game game) + { + GameDetailsDialog fragment = new GameDetailsDialog(); + + Bundle arguments = new Bundle(); + arguments.putString(ARGUMENT_GAME_TITLE, game.getTitle()); + arguments.putString(ARGUMENT_GAME_DESCRIPTION, game.getDescription()); + arguments.putString(ARGUMENT_GAME_COUNTRY, game.getCountry()); + arguments.putString(ARGUMENT_GAME_DATE, game.getDate()); + arguments.putString(ARGUMENT_GAME_PATH, game.getPath()); + arguments.putString(ARGUMENT_GAME_SCREENSHOT_PATH, game.getScreenPath()); + fragment.setArguments(arguments); + + return fragment; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) + { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + ViewGroup contents = (ViewGroup) getActivity().getLayoutInflater().inflate(R.layout.dialog_game_details, null); + + final ImageView imageGameScreen = (ImageView) contents.findViewById(R.id.image_game_screen); + CircleImageView circleBanner = (CircleImageView) contents.findViewById(R.id.circle_banner); + + TextView textTitle = (TextView) contents.findViewById(R.id.text_game_title); + TextView textDescription = (TextView) contents.findViewById(R.id.text_game_description); + + TextView textCountry = (TextView) contents.findViewById(R.id.text_country); + TextView textDate = (TextView) contents.findViewById(R.id.text_date); + + ImageButton buttonLaunch = (ImageButton) contents.findViewById(R.id.button_launch); + + textTitle.setText(getArguments().getString(ARGUMENT_GAME_TITLE)); + textDescription.setText(getArguments().getString(ARGUMENT_GAME_DESCRIPTION)); + textCountry.setText(getArguments().getString(ARGUMENT_GAME_COUNTRY)); + textDate.setText(getArguments().getString(ARGUMENT_GAME_DATE)); + buttonLaunch.setOnClickListener(new View.OnClickListener() + { + @Override + public void onClick(View view) + { + // Start the emulation activity and send the path of the clicked ROM to it. + Intent intent = new Intent(view.getContext(), EmulationActivity.class); + + intent.putExtra("SelectedGame", getArguments().getString(ARGUMENT_GAME_PATH)); + startActivity(intent); + } + }); + + // Fill in the view contents. + Picasso.with(imageGameScreen.getContext()) + .load(getArguments().getString(ARGUMENT_GAME_SCREENSHOT_PATH)) + .noFade() + .noPlaceholder() + .into(imageGameScreen); + + circleBanner.setImageResource(R.drawable.no_banner); + + builder.setView(contents); + return builder.create(); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java new file mode 100644 index 0000000000..9d3e736841 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java @@ -0,0 +1,23 @@ +package org.dolphinemu.dolphinemu.model; + +public interface Game +{ + public static final int PLATFORM_GC = 0; + public static final int PLATFORM_WII = 1; + + public int getPlatform(); + + public String getDate(); + + public String getTitle(); + + public String getDescription(); + + public String getCountry(); + + public String getPath(); + + public String getGameId(); + + public String getScreenPath(); +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GcGame.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GcGame.java new file mode 100644 index 0000000000..d682bee0b6 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GcGame.java @@ -0,0 +1,96 @@ +package org.dolphinemu.dolphinemu.model; + + +import java.io.File; + +public final class GcGame implements Game +{ + private String mTitle; + private String mDescription; + private String mCountry; + private String mPath; + private String mGameId; + + private String mScreenshotFolderPath; + + private String mDate; + private int mPlatform = PLATFORM_GC; + + private static final String PATH_SCREENSHOT_FOLDER = "file:///sdcard/dolphin-emu/ScreenShots/"; + + public GcGame(String title, String description, String country, String path, String gameId, String date) + { + mTitle = title; + mDescription = description; + mCountry = country; + mPath = path; + mGameId = gameId; + mDate = date; + mScreenshotFolderPath = PATH_SCREENSHOT_FOLDER + getGameId() + "/"; + } + + @Override + public int getPlatform() + { + return mPlatform; + } + + @Override + public String getTitle() + { + return mTitle; + } + + @Override + public String getDescription() + { + return mDescription; + } + + @Override + public String getDate() + { + return mDate; + } + + @Override + public String getCountry() + { + return mCountry; + } + + @Override + public String getPath() + { + return mPath; + } + + public String getGameId() + { + return mGameId; + } + + public String getScreenshotFolderPath() + { + return mScreenshotFolderPath; + } + + @Override + public String getScreenPath() + { + // Count how many screenshots are available, so we can use the most recent one. + File screenshotFolder = new File(mScreenshotFolderPath.substring(mScreenshotFolderPath.indexOf('s') - 1)); + int screenCount = 0; + + if (screenshotFolder.isDirectory()) + { + screenCount = screenshotFolder.list().length; + } + + String screenPath = mScreenshotFolderPath + + getGameId() + "-" + + screenCount + ".png"; + + return screenPath; + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/WiiGame.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/WiiGame.java new file mode 100644 index 0000000000..c64de8d582 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/WiiGame.java @@ -0,0 +1,53 @@ +package org.dolphinemu.dolphinemu.model; + + +public final class WiiGame implements Game +{ + @Override + public int getPlatform() + { + return 0; + } + + @Override + public String getDate() + { + return null; + } + + @Override + public String getTitle() + { + return null; + } + + @Override + public String getDescription() + { + return null; + } + + @Override + public String getCountry() + { + return null; + } + + @Override + public String getPath() + { + return null; + } + + @Override + public String getGameId() + { + return null; + } + + @Override + public String getScreenPath() + { + return null; + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java new file mode 100644 index 0000000000..47acf588de --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java @@ -0,0 +1,83 @@ +package org.dolphinemu.dolphinemu.viewholders; + +import android.app.Activity; +import android.content.Intent; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; + +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog; +import org.dolphinemu.dolphinemu.emulation.EmulationActivity; +import org.dolphinemu.dolphinemu.model.Game; + + +public class GameViewHolder extends RecyclerView.ViewHolder +{ + public ImageView imageScreenshot; + public TextView textGameTitle; + public TextView textDescription; + public ImageButton buttonDetails; + + // Used to handle onClick(). Set this in onBindViewHolder(). + public String path; + public String screenshotPath; + public Game game; + + public GameViewHolder(View itemView) + { + super(itemView); + + itemView.setOnClickListener(mCardClickListener); + + imageScreenshot = (ImageView) itemView.findViewById(R.id.image_game_screen); + textGameTitle = (TextView) itemView.findViewById(R.id.text_game_title); + textDescription = (TextView) itemView.findViewById(R.id.text_game_description); + buttonDetails = (ImageButton) itemView.findViewById(R.id.button_details); + + buttonDetails.setOnClickListener(mDetailsButtonListener); + } + + private View.OnClickListener mCardClickListener = new View.OnClickListener() + { + /** + * Launches the game that was clicked on. + * + * @param view The card representing the game the user wants to play. + */ + @Override + public void onClick(View view) + { + // Start the emulation activity and send the path of the clicked ROM to it. + Intent intent = new Intent(view.getContext(), EmulationActivity.class); + + intent.putExtra("SelectedGame", path); + + view.getContext().startActivity(intent); + } + }; + + private View.OnClickListener mDetailsButtonListener = new View.OnClickListener() + { + + /** + * Launches the details activity for this Game, using an ID stored in the + * details button's Tag. + * + * @param view The Details button that was clicked on. + */ + @Override + public void onClick(View view) + { + // Get the ID of the game we want to look at. + // TODO This should be all we need to pass in, eventually. + // String gameId = (String) view.getTag(); + + Activity activity = (Activity) view.getContext(); + GameDetailsDialog.newInstance(game).show(activity.getFragmentManager(), "game_details"); + } + }; + +} diff --git a/Source/Android/app/src/main/res/anim/button_elevation.xml b/Source/Android/app/src/main/res/anim/button_elevation.xml new file mode 100644 index 0000000000..d96b299541 --- /dev/null +++ b/Source/Android/app/src/main/res/anim/button_elevation.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/drawable-hdpi/ic_country.png b/Source/Android/app/src/main/res/drawable-hdpi/ic_country.png new file mode 100644 index 0000000000000000000000000000000000000000..2eec57e591dab910a469227028b5ed73dc2b1b66 GIT binary patch literal 1055 zcmV+)1mOFLP)004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_00WmvL_t(o!|j+~OpZ|;$4@Jg%D?h&7ITAH^442QxHoNy zjS}mR+Dxso@ii5qAz^b7n+xN{g&Eey63qn{7Sa4`BFzdBiSa7^eO);Ho^zh(Jn#Ed z@7sm7b9Fwy-+8{zbDrP%o!>bOZ0s5v7aM!AV8kF5`6xmW@~{PV1bIU&1}9OE0XTK7 zA9W~$%~N6%k&Om}h`v2TI{Zc}wi&H%g@#%)){k6l7OE@@4Yf*yj6`fT+DspL)5UAN zN9=ILlF%)M!6l@jkN19I9>U<@y&k0EiWEA(v2HkGN$3{_S7R|4E>eFl7#NDEUjc@2 z+!aRjA;GHH8sV$DkPQZgx#;Dj75-pg2*5}3nE?ido%kbsU7QuM+4w|5+7Zp^eqy=g zxr^9tPU7%Y_;(@h#cl~wi-(Dw z6ecs#mDmKdkYl#M%ZY|d{!zqB1ezl(b3b#jEONUo@#mbrGE90Cx712hi_A20v4&x1 z4EH(HL@e6lQcgIrTrGCOD`LmgVo$sx_DCfbO!@5|4oR((^F|&2*P3Wm%KQQ4)j*?| z_Q#TS5%-hxbILq=fm^@mcqTnB(kPZ{vX&+hKcEyl%&mjEo!V}EdCizd#;MYvImC06 zV%oS+iH91qsbZ%|5?W~T!ns+>7wr7{IzmXza7b<_Ex%j zsLqY$UJ*O07PEUrEW&K_eBp7ar{+7gmOQJJWkI7M7Kg&)u|#X=Ion(nJnzUYOW?;< zlOj!gsj}c{lGmR8O*aa)a5T|aqNgSAGsJDmQZB(=k$OWYQkNK}s}qxnO`)AmtGXia zjmBSdUlGrw8s3R^tl+emSOIzN(H%7yRtZuqm~Q1@5icApy0L?&;~q}hcmW=WcAD@I zF!-Q=e4KC~#_EwNQ93f!U?~{RQ@=v;O$ULxjN>?7k3VAVeVrxhTXw#pidR3p{N!8i%%G zo6F@6mdoYGvZMV%wOT!sn)5?LLuWDQA_s>ftAreR1@!+xct6^|g!uJ{?IQX;pN9V# z40=z4E*A=g>lkFOu;Wa#+1!W0UegH06Fnn5N}6-BZyNKz*+c=by~ys5l;6Ooi|uv z`US2s9lP4?ssIgOHlyx#u@zgN0ycJC8zvs&IKwA!YcAd_M_&Ti*>gBLj3rYx(DZ*| zETCP*<_K_Aa3A;?<=7tFZSKPC$L2T=Y@X<$^)5h9r5=-$8GxNirE<}cugSL*teZAQ zIDP_7zKG#@v0?s9zeOj)~2z?%tfJ_XR4+8d-09Oo90G!PEjsesc zy$R5++fvr48c-BBAs!>Nq1ha>%rLVIzY{jk_Ncp~O>D&GI1Y~*-m;MPfj8)M0>8&C zOe$x$l@e`kTy?81j<2D5%99apLPz$lwFUQ%IH<|!cGJX4h|l73BY()e5O&pgpbu~wZj7g0|yM?z!7E(o?CdS zWpf1UC@_xW9s0y3LE)4W|~w30Hz43k3mtX&)GM1u@S; zI|<@^K7U%7YEuyF1lzj+ooFak2atFki3N rk9xUUXGduxjXyg=2_=+JdM`f#RtxdM&Qnk-00000NkvXXu0mjf5$~oB literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-hdpi/ic_play.png b/Source/Android/app/src/main/res/drawable-hdpi/ic_play.png new file mode 100644 index 0000000000000000000000000000000000000000..164385d047ab7a9a86438c8abed5c3d570e72bdc GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;Lb6AYF9SoB8UsT^3j@P1pisjL z28L1t28LG&3=CE?7#PG0=Ijcz0ZK3>dAqwX{BQ3+vmeOgEbxddW?vh&p4JS^Mgk1HXrU_zC{8jqT z{PTWxZf82vLCc4&|G2btGakEVIWQQ@vopOoDZ?SA#m*#gLY5;;N{E?B;_*TYc0vB5 zks4B6+7}Wv);Y~(^gVXfEGqeia;xBpTO3O^DRIXqXId|IQ(Jsv5r1v;&;9mqnHR|B YnruHl@yODzK-V#Ny85}Sb4q9e00~rBB>(^b literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-ldpi/ic_date.png b/Source/Android/app/src/main/res/drawable-ldpi/ic_date.png new file mode 100644 index 0000000000000000000000000000000000000000..e6339193eafdcc1d66a698bdd1d30f46686a56cd GIT binary patch literal 346 zcmV-g0j2(lP)j+yoQM(-Y zIXma_apvqa8tZ1QIF9e5D7xXhX=BYKNv?@KR8_U%>{N1u0f^9$rn4{%`-D6ca1Mc- zJ0TP-(F;mxOn^Mn@QQy@qvAHdTm@LrFhjTcM(?%Q%*K8O=85 sUAO=ST`=NQ0y4p0T0i}koobEj147+mv)O1v+W-In07*qoM6N<$f}h-%@Bjb+ literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-mdpi/ic_action_overflow.png b/Source/Android/app/src/main/res/drawable-mdpi/ic_action_overflow.png new file mode 100644 index 0000000000000000000000000000000000000000..6f0fb23f4d9a2bad32b82ee41e079395e27f51a3 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G>7Fi*Ar-fh5+qm`CoExhD>9Xmmj0b2Xjk^_&CTsgW*l~E zd|bPs<1S0mB$)#y7Xl4lF?d}%psSN~-~F?x?disu5iQk?PYf(7 ru;Yube#|hFS=;A+P(wkKfklEL|BXbla?P)004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_00Li0L_t(Y$JJIzYZO5g9y3lZaf~?_R15)6;z56dM$l2? zxQ^?=s~`x%cN3Q&7#Cb(Mo~{<&=4h}C|*Pmm*l1w?;1^*Wc27V!5CkE{kpoVt?4*} zm+%h#zIv~}u6|op3aS4isaZtSh&+lIMj4YL6Bt4dHX&0RQ43DtE2bS%#&I8wBrZ$t=NN)>M>wb z*+kdXsSizphN+*XO6X>=|z> z?k2ir?ES=D7Al1q42illHcg7(6R$J&PU3fpvKshfaiT_iNlbY)DF-DQ5N)oD#*>XU zQLoc!N@^#R-%g*)Hqj6l*O-XhBtB>r$6>BrHF!PoYn#Z=*dpWfh&XQ%ZRgqpgO?JI z+eDLG3~Ti{@oI~xgKN(s?d0J~?L=#1L>U*6``5NuL_4@PXmFeB*Zg32#DaZDwjauo zSg>=hU|*@bjxO0moplp!h_{G)Dn<*^WuK5=jy3HGZQ6NO)8>plPyANVe3_pfKKgg} zH%t8ep%xt@ea1dOe3JSc+#?#3Dc~4v1>NpBqLtKtqLpZgR@!pX1gY6pZPXUk;SRs# zm&93GE>eHNo!__H)jj+JrxEPOP93)GSSCC3d+z{7)uSH`Nykwd*Gxt}>v8l1Pc?(1 zk>SxW^8vX_!(L6sqOnOnvKL4(xa(?M5}vK?5|NQBLl54_s}+e*39qCXazXjc?)y=V Z@&|UiLCu&m1+4%8002ovPDHLkV1nPLLy7^g}L9D2K7XVhKeYR20he6iW1e6iWkC%dT1a*M27xtYr)#X z*Jgw{$H|A74IlfQwZFagx4+vtsZ@XTM;D`9F3*%orQgM3@vKs*jGd>4^(WM!Za$xX z*{j2c3WdS}h+kk{!MvBt<*s))d;kaULT43o1Ual$s}C-EegNV$4~?SeYOPkgNn>Et zDA%kWj2e-lgVe>m552Od*YybD>c`lh1L=E^9TBV7>(}u771%mloV5aM4Yxj~C#WmE z4PbeOrqO6z>H2hR_>9dzu=y9}QxZD^bjS(hC)X)_CI;Pa&H(A1NvDamovsZ~!nK@` zjBZV*(>Fxi>LghE4$s}9uCGVV#0Kzo2*)en%esB*9HAFhSpo7)as%Z0rW1vvX+_4I z__(htuGj{=#Z4Y%v)TJBCt$O@8J``d{t#IV`=%gs4kHJ2-o!QlQa2?Os49jnhTGr8 z0rxDXzVXyz;Htzn07TDi4YSVu#=^sBgvFq9hh^vSB{E<}wHv4}jHv;I4x>kK*h7N_ z3d4lM$U$!=se*lGJ;)XzOL+f;`6HhVwhh^`7-SRJ7rif%gDpB~2->%02>jc6IS{xU zPzc(4|7i|TESAY+Zu>dFZ^ES}p{gKtp(^0#mo3$}aa_cIg@s}Gug z38SvVDCAO=~G=WkKR z>FMGaVsSe8&v^%_gd~YRscVKF53hcdm;Lwu|HJxY^~e76+)y;*RVeteUoBG#DEM># zLwjjWDTfEQ>a#DI{Q3X?{r@ljYnEg%G%o+oEci*~ICG-9ukuk(mC9ew|5pVyef?0+ v`$+lS;r}H;laB5BAGAZHS>dtAnMDkjN|Ku$exwKi9l_w~>gTe~DWM4fU&vtH literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/ic_action_overflow.png b/Source/Android/app/src/main/res/drawable-xhdpi/ic_action_overflow.png new file mode 100644 index 0000000000000000000000000000000000000000..7ba4e10ea218fd516a1106a72e709b91c6bd359a GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X)_S@)hE&{ob8{o_Ap-%2z~)N^E>U71^deQFFCOCYe9Cx; z?~TCbgQhAc>inHdrg6kO-8rer$iPtYqUa0zvpLIunX&chEuHf9`g!9y0)Kx$ecxF8 zURmzht>69*42&!SK*Fl*n8Fs8_Bm%4@NL<_cm81RhtTT}m+yCk$O4r#v|W4XUVE46 zxgA^Sf}^E3-WC*D=LiTv^f&ljPuzZ(f#FYMYy%_1f>sH!1*cDK1Uj6-)78&qol`;+ E00#tR2mk;8 literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/ic_country.png b/Source/Android/app/src/main/res/drawable-xhdpi/ic_country.png new file mode 100644 index 0000000000000000000000000000000000000000..e5cc9bc28b3826946cc85a32393c17d168f593f1 GIT binary patch literal 1390 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 IbxsLQ0F7mBiU0rr literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/ic_action_overflow.png b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_action_overflow.png new file mode 100644 index 0000000000000000000000000000000000000000..5a603b6bc32763878eb8c5b952d25dd3d4b61cdf GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGok|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XR(ZNOhE&{ob89zegMo;{MUA{ErX^d}q)uln5sWr=?wWAk zQX#DI#Ma6WPC(TlkPvoTL%i28?rCY5Tz&DmmB-)T`rFLJ(ZIl@(7?c3MAy|>gTe~DWM4fhLKLh literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/ic_country.png b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_country.png new file mode 100644 index 0000000000000000000000000000000000000000..6fa2c3b33c37c236dd4eb8022d39b9280399e79e GIT binary patch literal 2053 zcmV+g2>SPlP)004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_00(_ZL_t(|+U=ZaY*j@R$8R?Z2vm@*fMBU*NvUNOidY~< z;}Rn=3K0|}g2CM&|0*Ib?4@B-XsiN3WD^3x822Dh+JXkxXrxd;)B-I#bfL86`GFQ* z-<&gV=HC03i#PM}o-;GQ_h#mvbLO0Dz_>n};exqfE|?4Eg1KNW7|~+U595)Ejo6JM zoW@1eq861nh5g9K2F%4+^hS(xz@m|kImpLFcobR%c47w75E;&3k+=sdaasw;x0NCX z!w?aEV68C?f0;t^ZU+F|7(QT~unZNJq3YWOEI_-^gSEtB#oeUS$}tzsLkAXtNjPOY zRDC;+aiIZA!mfZp)wgfaCD>pSQ5JA44?H-FF~I|CiZ!Mtxf450>E)nNFu*$EXH(NF zLjt;@+?4Kav<);^3jUQ&p%Sa`AbF&`3=oR zH=wwm_Inw?k;uR$cCWRy6RatF5*8x4f#hgHCR^xlIU)6c&$2(ljJOA}_JMKlt*;U1 zBbg`2T*A#le+k5Y_PO9MDd#W`Na*_L1yKNUb3ITrJ4eqO;(GZ)QdwV+U9g za|q`UZef-nbs0U$UQ>x4rwdY1SWAw54!2kZi$E^(Z$%IubTP45xt@0r2Z%wSZ6U}1 z#wys;Ot(}JW;h`^g6(-EA>E&lYs~DmC#-;d^2>3(SDsL`0sdB(_?v=0Y@JV6nz2+J`WY zFYv)Se$dy0;`&={&;^UcVMl-+;I;+_cDEz2Jn&$s9@q-UfW5B+79GGqsNJoUzNw+X z?sN>62ObPk2b=9Euy@qK@*D-WLlvwMDjfw@LHQaKSYJW48qK5@#8-mG1m)=0vx4p> zseBs(EmaNdNg~`SpWN?)#&Bh@dj;Je{Ad&k8jq`i%_G79@}b0tV^?Lc9)fPMc4%p~ z8rUa-;tSG&8WD>lRvE0Bpj+c7hu~E~W33ukfuMMwbfEUct(H#c{DPq0N-F=5Aiqlu z?0}%yOLH+5X@QAeS)x?Fk08HK4NNqrTBbDzU$e&OHtJK^vq5+nt z1-4sqH$w;9#UOzaSgoKapV%-pTR_A2PWO`mBpx^aZ!q1ZI7E=ox40D3r1DM7F2&Fv z9`c*Zc(aFx_2d4a7MK|4O$f|!FTSAfmk!j<;tN{5&4~-l3tBX(Ui6cCdD&Kzs>+W> zhFOzpp7tH$30sZeBYreK7Bpt5fsNBX41TfIZ7J}hvCpjAqVH&aDrii!;An2tb~JCh zK0^cLs-XcR2$_g>w(aUss#%T#ds`iBh@-#;s)I$5chBM3N_0ZpbW%`wwrsuImb)AS zmaYdDfkTeKD%8KKo$3g%Df(coh{WV7HeG@8gR@Lru5V*ydl4CP=XpOsHtZ7eWyqyN zykQ~;CwgKTY&f8Rm`#?sJdX~fX~ji_`w_BzrC4c%MhYVfvb?8_*_5L!GUX_hIc~(< zw}sN)mkIKR+3ayDL~NBr?7EQ!bxah!I5CVJkWQm)28f6N%dp z4?I{&pv_lv0-2*`CV{nqsmbVUN3!#H=H<9vSdcx)BwMP_4Mg^EqOb_JG9!<&D?R-q zW`OU6V`{$+U}yAWQp^c>y=$Ug?PTX zK~J9%63=@bD|;mcsY!t-v+7S4P}LWDEUNo0o0C;bL#3Wx37XVpA%95xoAvD!Yj9aE zjO!;28JtHZ+LPw62fx)Ns>k3D#`)-i_oQXw$91suOBs{dDxvy+Zap3*lLDu(+1RCc z6k8+(aaZ{Om;>=G*u!k84i<4BQa<50%7Y ziH)CBIEPIAGcYh??yzw#0r-4V6b54^ zaur|2W!Q!{F(AA@-{gDY+Z$ss2kVfBLYzc7YEX?bl;Th1Vhv_uG*Tp`j$sQH;^u<6 jU@n*o=7PCkPHz7J8g^Lzd2}i^00000NkvXXu0mjfHb=9E literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/ic_date.png b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_date.png new file mode 100644 index 0000000000000000000000000000000000000000..076602cca305d7f8a789d610d9fdbe18165530ae GIT binary patch literal 1479 zcmY+EdpOez9L9gc15su_u zt|L!9E_2CT*WAi&*xbT6a&&smA3e|eeLw%c&-;CzHx6TKDJm>43;=*A`V!LqfSx~2 zNbta?(}@NE0H&gmW)649mY*%-)liTRRjc`Pi@aD;?n9WFoyBG)8fPJr&6^C`GJ`~` zoXGJoG;ue?P~WTE&_BAl83R$%{$4jEEqd3LA>*>xuqU z^E?dnh;YpR$Vk>ceY*LHT1OflkGDhGIXOG;$98g6`#q2W)}{U$yY=(E`4&avQvEFj zHXa?lY1qw3{+^gG!^6Xg8*Lviu8x{+OwG>DQc|L+x-Z9@FR+FX7qgK2NA^Sr2|c?C z3JTn=7|zV~h@8hS?z_3VlA8URm`tYgWW)psg%CcjB%yvS^>Dc2WOPNC#Dqhmg2Hq+ zL4#{h;BWXF-+rnOFiHJnJl=#cc$rdcuuBWG!qz2nUQDxE(!NYu)cG$Xtn1@G$;iJD$*cz7-+lY<@cuQMq-vv|*~GlCuUk?wh{bVZz=QmG(C-jy+R zSJt}HTCPLZJ$xRpgd7)U z$5VAl-hii}IkOkq;C@2XoyIKF+c^}OwP!bzul%)}904-jDv0+Wyh8~q^qVX(hGfZ9 zS@AoadzaNA&iJW_pt0~zZzcwV)Njqd5;sG!5=<@8UYLPCz0$`T+@dNwij)pPP~u;0Ysek+fYPjTbEY74z)4OBou5a5Rl z5j0*&+@NywNT#nBtlg=4afBM8vRNG5!T~P0AT1SHmPt^sP@u7Ucf@k8mX=oeA}K&T zXdmMCRZ&C0pe3f*C&}i#cMZf33?v-B`Uayu%~@t6%rGSsV{q~5%5X{>cYb3XH_284 zIe>Fv_YZ>qqBC${y?Jx(;tozwCFHE&IPNR}FU60;u$lLUAMuetguQ-WfqL9%^KRQs zUTnT=U?nf{ST)PP$Rh68hvE>A@%5G368m5Tj*szSJ zv~8+eP(yt@NL<#cjW*0^(TQrp!uh^<&^&RzwJBT^+=p8K81^+HQ4LIiOoa6 z6W>^ba9k}aQ?28p5dVAzJ+NH|w3d{p^IdGt2#+0H=+}q#4$IgM*XAgBYnzy?5~_>} z35CE4T?*d%Htz#bcu+CjXszZ-s8o0&AK~FC_;6j*UZWQg#}lYt>gT2{Wj|7l_}1}R z1ngl|86F2R6qZ{rRPEWSx~XN|Uuvrurp`0ccl1{Jo#e~VeY%ZxVhslCs4dz4x{P@k cKb3vH+|3NZx|$@-gMkLnC|l%fbI+)M0cp6nnE(I) literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/ic_play.png b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_play.png new file mode 100644 index 0000000000000000000000000000000000000000..043acd808ec133c8353be75d77ce9afeea456c9b GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw6p}rHd>I(3)EF2VS{N990fib~ zFff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9;eUJonf*W>XMsm#F#`j)FbFd;%$g&? zz`)4v>EalYaqsPoje<=M0<90{CmAXo=i0)$kt35S`vBJoQx(f%<-Xf{E0uSP));@d zcQ1DGg;{D2j9dW?Od<;ySYM>emFRdaI5OLq*^`~cpfD+n>ENlU+^hLG5|%w($pi(>HJTxmOdS z)&(8!_hqzyA!w%jpmd$1B;)t}8fk2Q9KthK9&c-EsBTyyx2B6ZkK2f2hwKTB2Vn|3 l+l!xbLVcj&@SpD&lWxp4#x1KBYXifH!PC{xWt~$(69D^8i*^72 literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_country.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_country.png new file mode 100644 index 0000000000000000000000000000000000000000..f11d5351f3742c1fb2df91a358274ab259cdc6e8 GIT binary patch literal 2783 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 + + + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/layout/activity_game_grid.xml b/Source/Android/app/src/main/res/layout/activity_game_grid.xml new file mode 100644 index 0000000000..f026322f3d --- /dev/null +++ b/Source/Android/app/src/main/res/layout/activity_game_grid.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/layout/card_game.xml b/Source/Android/app/src/main/res/layout/card_game.xml new file mode 100644 index 0000000000..a89e5bdb21 --- /dev/null +++ b/Source/Android/app/src/main/res/layout/card_game.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Android/app/src/main/res/layout/dialog_game_details.xml b/Source/Android/app/src/main/res/layout/dialog_game_details.xml new file mode 100644 index 0000000000..885dc91676 --- /dev/null +++ b/Source/Android/app/src/main/res/layout/dialog_game_details.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Android/app/src/main/res/values-w820dp/dimens.xml b/Source/Android/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 0000000000..63fc816444 --- /dev/null +++ b/Source/Android/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/Source/Android/app/src/main/res/values/colors.xml b/Source/Android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000000..608cc9afd7 --- /dev/null +++ b/Source/Android/app/src/main/res/values/colors.xml @@ -0,0 +1,8 @@ + + + #5bc0de + #428bca + + #663399 + #311b92 + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/values/dimens.xml b/Source/Android/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000000..72b7d0fcaf --- /dev/null +++ b/Source/Android/app/src/main/res/values/dimens.xml @@ -0,0 +1,10 @@ + + + 16dp + 16dp + + 48dp + 1dp + 4dp + 16dp + diff --git a/Source/Android/app/src/main/res/values/styles.xml b/Source/Android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000000..40d406b20f --- /dev/null +++ b/Source/Android/app/src/main/res/values/styles.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/Source/Android/build.gradle b/Source/Android/build.gradle index e553a87d2e..9405f3fd18 100644 --- a/Source/Android/build.gradle +++ b/Source/Android/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.2.0' + classpath 'com.android.tools.build:gradle:1.2.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/Source/Core/DolphinWX/MainAndroid.cpp b/Source/Core/DolphinWX/MainAndroid.cpp index 0d5f71dc99..a38f312f49 100644 --- a/Source/Core/DolphinWX/MainAndroid.cpp +++ b/Source/Core/DolphinWX/MainAndroid.cpp @@ -48,7 +48,7 @@ ANativeWindow* surf; std::string g_filename; std::string g_set_userpath = ""; -#define DOLPHIN_TAG "Dolphinemu" +#define DOLPHIN_TAG "DolphinEmuNative" void Host_NotifyMapLoaded() {} void Host_RefreshDSPDebuggerWindow() {} @@ -111,8 +111,6 @@ static bool MsgAlert(const char* caption, const char* text, bool /*yes_no*/, int #define DVD_BANNER_WIDTH 96 #define DVD_BANNER_HEIGHT 32 -std::map m_names; -bool m_is_wii_title; static inline u32 Average32(u32 a, u32 b) { return ((a >> 1) & 0x7f7f7f7f) + ((b >> 1) & 0x7f7f7f7f); @@ -131,9 +129,6 @@ static bool LoadBanner(std::string filename, u32 *Banner) if (pVolume != nullptr) { - m_names = pVolume->GetNames(); - m_is_wii_title = pVolume->IsWiiDisc() || pVolume->IsWadFile(); - int Width, Height; std::vector BannerVec = pVolume->GetBanner(&Width, &Height); // This code (along with above inlines) is moved from @@ -166,31 +161,148 @@ static bool LoadBanner(std::string filename, u32 *Banner) return false; } -static std::string GetName(std::string filename) +static bool IsWiiTitle(std::string filename) { - DiscIO::IVolume::ELanguage language = SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_is_wii_title); + std::unique_ptr pVolume(DiscIO::CreateVolumeFromFilename(filename)); - auto end = m_names.end(); - auto it = m_names.find(language); - if (it != end) - return it->second; - - // English tends to be a good fallback when the requested language isn't available - if (language != IVolume::ELanguage::LANGUAGE_ENGLISH) + if (pVolume != nullptr) { - it = m_names.find(IVolume::ELanguage::LANGUAGE_ENGLISH); - if (it != end) - return it->second; + bool is_wii_title = pVolume->IsWiiDisc() || pVolume->IsWadFile(); + + __android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Is %s a Wii Disc: %s", filename.c_str(), is_wii_title ? "Yes" : "No" ); + + return is_wii_title; } - // If English isn't available either, just pick something - if (!m_names.empty()) - return m_names.cbegin()->second; + // Technically correct. + return false; +} - // No usable name, return filename (better than nothing) - std::string name; - SplitPath(filename, nullptr, &name, nullptr); - return name; +static std::string GetTitle(std::string filename) +{ + __android_log_print(ANDROID_LOG_WARN, DOLPHIN_TAG, "Getting Title for file: %s", filename.c_str()); + + std::unique_ptr pVolume(DiscIO::CreateVolumeFromFilename(filename)); + + if (pVolume != nullptr) { + std::map titles = pVolume->GetNames(); + + + /*bool is_wii_title = IsWiiTitle(filename); + + DiscIO::IVolume::ELanguage language = SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage( + is_wii_title); + + + + auto it = titles.find(language); + if (it != end) + return it->second;*/ + + auto end = titles.end(); + + // English tends to be a good fallback when the requested language isn't available + //if (language != IVolume::ELanguage::LANGUAGE_ENGLISH) { + auto it = titles.find(IVolume::ELanguage::LANGUAGE_ENGLISH); + if (it != end) + return it->second; + //} + + + // If English isn't available either, just pick something + if (!titles.empty()) + return titles.cbegin()->second; + + // No usable name, return filename (better than nothing) + std::string name; + SplitPath(filename, nullptr, &name, nullptr); + return name; + } + + return std::string ("Error"); +} + +static std::string GetDescription(std::string filename) +{ + __android_log_print(ANDROID_LOG_WARN, DOLPHIN_TAG, "Getting Description for file: %s", filename.c_str()); + + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(filename); + + if (pVolume != nullptr) + { + std::map descriptions = pVolume->GetDescriptions(); + + /* + bool is_wii_title = IsWiiTitle(filename); + + DiscIO::IVolume::ELanguage language = SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage( + is_wii_title); + + auto it = descriptions.find(language); + if (it != end) + return it->second;*/ + + auto end = descriptions.end(); + + // English tends to be a good fallback when the requested language isn't available + //if (language != IVolume::ELanguage::LANGUAGE_ENGLISH) { + auto it = descriptions.find(IVolume::ELanguage::LANGUAGE_ENGLISH); + if (it != end) + return it->second; + //} + + // If English isn't available either, just pick something + if (!descriptions.empty()) + return descriptions.cbegin()->second; + } + + return std::string ("Error"); +} + +static std::string GetGameId(std::string filename) +{ + __android_log_print(ANDROID_LOG_WARN, DOLPHIN_TAG, "Getting ID for file: %s", filename.c_str()); + + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(filename); + if (pVolume != nullptr) + { + std::string id = pVolume->GetUniqueID(); + __android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Game ID: %s", id.c_str()); + + return id; + } + return std::string ("Error"); +} + +static std::string GetApploaderDate(std::string filename) +{ + __android_log_print(ANDROID_LOG_WARN, DOLPHIN_TAG, "Getting Date for file: %s", filename.c_str()); + + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(filename); + if (pVolume != nullptr) + { + std::string date = pVolume->GetApploaderDate(); + __android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Date: %s", date.c_str()); + + return date; + } + return std::string ("Error"); +} + +static u64 GetFileSize(std::string filename) +{ + __android_log_print(ANDROID_LOG_WARN, DOLPHIN_TAG, "Getting size of file: %s", filename.c_str()); + + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(filename); + if (pVolume != nullptr) + { + u64 size = pVolume->GetSize(); + __android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Size: %lu", size); + + return size; + } + + return -1; } static std::string GetJString(JNIEnv *env, jstring jstr) @@ -215,8 +327,12 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulati JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv *env, jobject obj); JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Button, jint Action); JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadMoveEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Axis, jfloat Value); -JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetBanner(JNIEnv *env, jobject obj, jstring jFile); -JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetTitle(JNIEnv *env, jobject obj, jstring jFile); +JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetBanner(JNIEnv *env, jobject obj, jstring jFile);JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetTitle(JNIEnv *env, jobject obj, jstring jFilename); +JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetDescription(JNIEnv *env, jobject obj, jstring jFilename); +JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGameId(JNIEnv *env, jobject obj, jstring jFilename); +JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetDate(JNIEnv *env, jobject obj, jstring jFilename); +JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetFilesize(JNIEnv *env, jobject obj, jstring jFilename); +JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_IsWiiTitle(JNIEnv *env, jobject obj, jstring jFilename); JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetVersionString(JNIEnv *env, jobject obj); JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SupportsNEON(JNIEnv *env, jobject obj); JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveScreenShot(JNIEnv *env, jobject obj); @@ -233,17 +349,17 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv * JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv *env, jobject obj) { - PowerPC::Start(); +PowerPC::Start(); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv *env, jobject obj) { - PowerPC::Pause(); +PowerPC::Pause(); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv *env, jobject obj) { - Core::Stop(); - updateMainFrameEvent.Set(); // Kick the waiting event +Core::Stop(); +updateMainFrameEvent.Set(); // Kick the waiting event } JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Button, jint Action) { @@ -251,7 +367,7 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePa } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadMoveEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Axis, jfloat Value) { - ButtonManager::GamepadAxisEvent(GetJString(env, jDevice), Axis, Value); +ButtonManager::GamepadAxisEvent(GetJString(env, jDevice), Axis, Value); } JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetBanner(JNIEnv *env, jobject obj, jstring jFile) @@ -266,15 +382,49 @@ JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetBann } return Banner; } -JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetTitle(JNIEnv *env, jobject obj, jstring jFile) -{ - std::string file = GetJString(env, jFile); - std::string name = GetName(file); - m_names.clear(); +JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetTitle(JNIEnv *env, jobject obj, jstring jFilename) +{ + std::string filename = GetJString(env, jFilename); + std::string name = GetTitle(filename); return env->NewStringUTF(name.c_str()); } +JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetDescription(JNIEnv *env, jobject obj, jstring jFilename) +{ + std::string filename = GetJString(env, jFilename); + std::string description = GetDescription(filename); + return env->NewStringUTF(description.c_str()); +} + +JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGameId(JNIEnv *env, jobject obj, jstring jFilename) +{ + std::string filename = GetJString(env, jFilename); + std::string id = GetGameId(filename); + return env->NewStringUTF(id.c_str()); +} + +JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetDate(JNIEnv *env, jobject obj, jstring jFilename) +{ + std::string filename = GetJString(env, jFilename); + std::string date = GetApploaderDate(filename); + return env->NewStringUTF(date.c_str()); +} + +JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetFilesize(JNIEnv *env, jobject obj, jstring jFilename) +{ + std::string filename = GetJString(env, jFilename); + u64 size = GetFileSize(filename); + return size; +} + +JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_IsWiiTitle(JNIEnv *env, jobject obj, jstring jFilename) +{ + std::string filename = GetJString(env, jFilename); + bool wiiDisc = IsWiiTitle(filename); + return wiiDisc; +} + JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetVersionString(JNIEnv *env, jobject obj) { return env->NewStringUTF(scm_rev_str); @@ -287,12 +437,12 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Supports JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveScreenShot(JNIEnv *env, jobject obj) { - Core::SaveScreenShot(); +Core::SaveScreenShot(); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_eglBindAPI(JNIEnv *env, jobject obj, jint api) { - eglBindAPI(api); +eglBindAPI(api); } JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig(JNIEnv *env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jDefault) @@ -313,56 +463,56 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetConfig(JNIEnv *env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jValue) { - IniFile ini; - std::string file = GetJString(env, jFile); - std::string section = GetJString(env, jSection); - std::string key = GetJString(env, jKey); - std::string value = GetJString(env, jValue); +IniFile ini; +std::string file = GetJString(env, jFile); +std::string section = GetJString(env, jSection); +std::string key = GetJString(env, jKey); +std::string value = GetJString(env, jValue); - ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string(file)); +ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string(file)); - ini.GetOrCreateSection(section)->Set(key, value); - ini.Save(File::GetUserPath(D_CONFIG_IDX) + std::string(file)); +ini.GetOrCreateSection(section)->Set(key, value); +ini.Save(File::GetUserPath(D_CONFIG_IDX) + std::string(file)); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetFilename(JNIEnv *env, jobject obj, jstring jFile) { - g_filename = GetJString(env, jFile); +g_filename = GetJString(env, jFile); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JNIEnv *env, jobject obj, jint slot) { - State::Save(slot); +State::Save(slot); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadState(JNIEnv *env, jobject obj, jint slot) { - State::Load(slot); +State::Load(slot); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CreateUserFolders(JNIEnv *env, jobject obj) { - File::CreateFullPath(File::GetUserPath(D_CONFIG_IDX)); - File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX)); - File::CreateFullPath(File::GetUserPath(D_WIIUSER_IDX)); - File::CreateFullPath(File::GetUserPath(D_CACHE_IDX)); - File::CreateFullPath(File::GetUserPath(D_DUMPDSP_IDX)); - File::CreateFullPath(File::GetUserPath(D_DUMPTEXTURES_IDX)); - File::CreateFullPath(File::GetUserPath(D_HIRESTEXTURES_IDX)); - 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_SHADERS_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); +File::CreateFullPath(File::GetUserPath(D_CONFIG_IDX)); +File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX)); +File::CreateFullPath(File::GetUserPath(D_WIIUSER_IDX)); +File::CreateFullPath(File::GetUserPath(D_CACHE_IDX)); +File::CreateFullPath(File::GetUserPath(D_DUMPDSP_IDX)); +File::CreateFullPath(File::GetUserPath(D_DUMPTEXTURES_IDX)); +File::CreateFullPath(File::GetUserPath(D_HIRESTEXTURES_IDX)); +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_SHADERS_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); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(JNIEnv *env, jobject obj, jstring jDirectory) { - std::string directory = GetJString(env, jDirectory); - g_set_userpath = directory; - UICommon::SetUserDirectory(directory); +std::string directory = GetJString(env, jDirectory); +g_set_userpath = directory; +UICommon::SetUserDirectory(directory); } JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDirectory(JNIEnv *env, jobject obj) @@ -372,24 +522,24 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDi JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj, jobject _surf) { - surf = ANativeWindow_fromSurface(env, _surf); +surf = ANativeWindow_fromSurface(env, _surf); - // Install our callbacks - OSD::AddCallback(OSD::OSD_INIT, ButtonManager::Init); - OSD::AddCallback(OSD::OSD_SHUTDOWN, ButtonManager::Shutdown); +// Install our callbacks +OSD::AddCallback(OSD::OSD_INIT, ButtonManager::Init); +OSD::AddCallback(OSD::OSD_SHUTDOWN, ButtonManager::Shutdown); - RegisterMsgAlertHandler(&MsgAlert); +RegisterMsgAlertHandler(&MsgAlert); - UICommon::SetUserDirectory(g_set_userpath); - UICommon::Init(); +UICommon::SetUserDirectory(g_set_userpath); +UICommon::Init(); - // No use running the loop when booting fails - if ( BootManager::BootCore( g_filename.c_str() ) ) - while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) - updateMainFrameEvent.Wait(); +// No use running the loop when booting fails +if ( BootManager::BootCore( g_filename.c_str() ) ) +while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) +updateMainFrameEvent.Wait(); - UICommon::Shutdown(); - ANativeWindow_release(surf); +UICommon::Shutdown(); +ANativeWindow_release(surf); }