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 zcmeAS@N?(olHy`uVBq!ia0y~yU@!w=4i*Lm1~s2WVGIlm3dtTpz6=aiY77hwEes65 z7#J8DUNA6}8Za=tN?>5Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*J~22IlFWE{-7)hu_YK_vs6iIqt7L>D2yD`C`S*k)N(bd+jjK?d%nL-G9qx z?WT{WqKgz0iv?$MKR(tfdF`0cSypkei+{3}&TWv9U6hwb&I0=5*z*@#q>8!)19@x)lQMy*X zRHON9aFX!EUbg0reYVb4f84aUNv_RnZHqF#)*q82wn~SacdJ)Rk4ui}Eg$*H%SW^K zxW6elI_ZLL>p|5e3;Vy6?eDn9t9*a(td^Cx3R6 z{eOK{M(C+Oj8CsRES~Z0_@q+7?~^|lpR%cHjNbpELd{nHlE$>GP1Do_?H7nxpIO_y zYwoSQn#!{?+>foiw7~L6@sy-nI|4e}r8cijyRwZ(KJx<8qnTbC-=^?S-l6}|>3nBu zuZz#@zRX>^$G@69n;d&D$SKA*d6iPLvB3{v`xPSEPp>iln5FVEC4AxhMb&r8y%+wE zJZ>D*S~ub4qIVDeY%L1hFMD#)x3FDRE6(*kjT5w9CAPWRRp(I7=bDFwE0;gB-a5@@ z^^{b{#foC>haPWq$$nvZJ4V#z{Rv&~2ggGvEBV%}-1H!G()D@&e9gJG7MNU&ShQUA zz44LUQ$czMV<%QQYXnV~ShiYta;NXYxqhp6DShZY7GE4Mcz%i0z0R^V54OyRV61$1 zQPxx$XS;cR9vh_v9bGLYv!d9S-9=JFVdQ&MBb@0LsVWoB#j- literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-hdpi/ic_date.png b/Source/Android/app/src/main/res/drawable-hdpi/ic_date.png new file mode 100644 index 0000000000000000000000000000000000000000..590def8b802c90bef08a5b9e40b058f3a86dc10b GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F~oi^1|^v_QUlgK|f(=z+)| zJ*82HzYF?(7n^Gyk@$;sossPBTW?n}@Ftioepj|pG6pWcwWll$(_o8!+c_;TjGSol@X!GEdT zX`iYbv&$mqLCS6&m^&?Z?U5^(>c{SwNdNNa@5LA zZt&rm&d>C13PU(g0K=R!Kl>Q3i0|dRusXgi;^p2Jaw<&QDb49O(6Q!he4AM#`2;p3Al z=R8mmUb8H4UrYbhtgVNcnVH#n9vl!%}mz=X_Cn>BASx9BcC*m4sjUx>MM^!(lU+H7`X zp0`Gp`-Z)FKW^tZ~d5Kb1!}CtooR4bk>Z4|61q-}pxxJfV zp3_?C&ZQb>L=$Avf3W1;Jo@>bNA3Rio($&te+xJM5jTimf4#qIXH>d-rgE>nwG*f6 flz=LId&V&CkB80$2WT-cFfe$!`njxgN@xNA5$~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!ia0y~yU{C>J4i*Lm25-&)VFm^Ug=CK)Uj~LMH3o);76yi2 z3=9knFBlj~4Hy_+B``2p&0t^#U&~PMjtQx#~Yn z6U3hQtMs4w=l$&5&UB`OmJeJ1acSvhJa*4=U@(?vXL@l`hC@t?ok`+^EJv7>5Hpj+ z2duIF@Wu;*L+wv|j9{w)n;({@UoD g`|aN{FObbO*?xTDk)>Z57#J8lUHx3vIVCg!00~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 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s76+K-XLn>~aowVDF*-@lz zvc|*;&ZI<@TsGHhI@PDw&CV5b5{OQm@1WzO@3{KG(hJ9|@?U>{%@J)8xLf9jrS2j&>{etdB`y6sNzktB+nbx) zm&`cq)cCk|L&sf~q)9RdOfCc(ykhXWbU;@p>Aw4CQ`^&xGb3868=oFndojk~6+_ij z=DiU|=JkXfUwrjrhMCOTKKFwf3Ze`w5)AooB$Ab@wR9O67#KWV{an^LB{Ts5j^;-b literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-mdpi/ic_country.png b/Source/Android/app/src/main/res/drawable-mdpi/ic_country.png new file mode 100644 index 0000000000000000000000000000000000000000..34ab76ac9e5caa373fe4cda33ef844ce75ef82e6 GIT binary patch literal 743 zcmeAS@N?(olHy`uVBq!ia0y~yU{C>J4i*Lm25-&)VFm^Ug=CK)Uj~LMH3o);76yi2 z3=9knFBlj~4Hy_+B``2p&0t^=Gi(`n#@vC8;*&>c2a>jmog*}!MAv}!!j~wfp-7W+^-qH8^;A#bq zL*>HL6(q!ClH3CQlP(CTF4Bl|5t#mDnfQAt-x(=iUKkyeh_C;99Tr2-8uZ(oL(qYpj;U+m*Nm#;(-%K%BI*{A%q4qM_pksw5|FtjL70&mY zAjD-XeD)~s=R@i~AAbt;|NPS`nEcw+s#BxavGh;F-A}RpzuU~VJZAs8_C|C6E5n4~ zn=aR{uH^S^YFjyf*;AXZ(-)-{hVSjV+VO4GVaY|ISN10>UQ7z<2p5PAIN#L0!ZqlP zWWM%0wOy%i{vL@H(`uFE>D*;v=G%2&c)jsAzenX=o1}gu7cO$E@${)Q)nr$d63AWG zeQa{CS>XE1nO<4yQ||lCKW%nVK>YfQjyo!L8KTD%*TtGv*nZ5Oed7ELrN>`7Eb;|& zpWk9`o-WjX+huYLPxe>Kk6GO-nzPR#a+6vWukn#NXGqMYve+Fv}>I{rdW! zgz_UzwI18#Pfd*2P`oZ7e&y~yy_+s`ONDbgws%x(xp7}goj)PI&-5*4?ybtO%g=gj z{r`krteH7q&hA(FcXRJQe;10$D%T#fbEuj0OXiNU)MU*E5;?4Q-&ro2dZm8R)Qrxs zTSb>xR^ANDy&`t?A>aNd(~m?(=>^pvoO^%!?W?wbn3oH_IqoOB?QMjb_2=sM3~pB! z%kz3350tv@<7W4|@C%E-Y4hTV4=);gX58t0IL`OjqK%$*o5Vc~cf8Ju5t_I5t~)4U6^;36z*y z{L1u=QmXjrH6pD$@6TZS>eAWPrP0G?d&Rj+=<4Jy@k8xZ846A=ZU1t!58gU_J*~y^ z_{sJeyz;;2Y~8>2+xGppEmwxre{mOI9HV!Bir3QnN0UCT30m1RcX|6)^(zbW?B>_s zTz$BmtMw3LM|?uu!9CMYKV4UDQNzIg-YH$Qn8k8U*lK>gsyc>8Cj7mNUSzEe+wGa0 za7E+#8o3^+i3^*r9NojechmCgUpXGWI(}n5^ULZ9vVyCxzrOzAkLV4nm^oXSa(K7f zEmL2iy_YwkvTfPLjF^|dN^*YmoVDNZQ~X)5kTrA33C<_#*EMU@*zV?^V|Y2&b9v|1 zx$AfX4sD$?p(oFG`DJsLJFiqCe)FBbyJ+2d_j5gJojb<`6!?~$A@yX>DpB+u_<3dMZN>?QY( zm@x#ItBS19YSV4Ieg7!qcb#SXK3++Bu1)u!2=5L5K7_}}tVc|Pwp-kX~wQiN}a z@715wtZS9Yacg@j$Di9(mI6Cu0yu6}|Ig$L(3y5JCGWT8f&4>D)fTQ&C|#)a;Q4gj zt2+u~j?}ldCK5Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*O)8m7Xq+Ar_~T|D1P_N=TCEle%W;@$l+LdD(ye|39ohR)6e2&kaR0UWI}m z`_(d~{{8>|bN@qoX-z4I2e<08FPZ%L|Ns5}FaK+nWH2-?|IaM=N#!_mqPnm0QBRf1 zU(f$n1vP#BP|y2F`Q73FB|(#p?fM_IL!?>ZvB#N343|ohn;m|n2r)1)FnGH9xvX{(JaZG%Q-e|yQz{EjrrIztFs$`-aSW-r_2%YA-a`fg4uQ>=3|ykbKIlcNL|;6_ z_>-F=-a|HhW ze)_(#_`R~+vs=IY9T*r{1RNL`t;&umY+-4ib9MpWmK}WO59WRdz5a0den*Hbi-1Ez z+qH-8wRf4G+p(1{I9ht+Z9$QBj(`wEe}muk#O;R}82&WIHZU?QXq6CKaQf6n1_lNO MPgg&ebxsLQ00#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 zcmeAS@N?(olHy`uVBq!ia0y~yVDJE84i*LmhW}5h&oD4BC?tCX`7$t6sWC7#v@kII zVqjosc)`F>YQVtoDuIE)Y6b&?c)^@qfi?^b3`|Mh?k)`f+xyS#XJBC9EbxddW?$}E#C-{>Iy&g<8%BsfGzYqEZH>k(S$a4|#J+m%xzSMxY~ zb!7IpHFg4S-`=`bF>0^RF^|Tg%uOu+CWrrYudzGU>hpBR z2bt%l|F$*x%W($C-T&=WwxP#IE@a>Fj~^ly)_gafdHl!W>-FO4{NftZ@49V}o2Sg( zU&6=r{=CnD!^+Kn5AB{FVzVjo{cW|foo**h%g?lLZIAqWYwoG~-wE@Rp6*|JKiXlo zU}pA*7%sM|yBtBZC~-m9fvn18C@DN`VM?@jZ)%1oltjHf(hujmDzl3jJ*)@ygg zh52q%1q%yB7I62}E{|EM&$V=}$x`13<_p(}dUZ9H9N8CotMOiFti90U#}g0fJ4L^I zy*p|}u9v5|T#RqT0@h<8*RmHmWYo@i|JrtH@S>xl$9COapLCv={mLq_UpmgQ*>ksD z+SV!NFL~=~mT(3avx)!THu0KY;ZCthtWkPVTYg;O)%v&fW22qq$83|Xt4Eow^qqc9 z<#=tn*-QAv#U+o9bZk7s`z7^K18{N}Q z^EAKQpF1;Td4{F!x!nn_1{c&W=Im5GQ?oF?oT*kf>K309$6hUojP{Ie2WGwDfBD|J zG0XL|Qg>bP1^>%uZ$0Mua_Ioi0h3CDiW7_CmA)_^bckIvQ}?Wn@UPE)3#PlA4$7{w zSyIl%eA0D(66fch3*pv{^F(#$Z+nrsif;nT0@F@Lsp5VgzgLortyZSD&At*i?Jv9E z0;|`CnJ2_rqrVj;*QlI3w&O78mtJko!;3>+Ozo^JEt&9c!{J3wO}tei?^G&DWF%g? z|8?KVg^fnXqkcWSIHzQRTlukwNhJ%~?>ba^`hBWClQpsa-*tD6>*;63ek-}G=&je= z9akFh+(tuh>pMr)bIp(3ME}n+aDSQm>Q2eh#~ODtSa0b?tufkiGwYAk;kj?WCRXX+ z^xErXyGe83z00BRPfsmt(_)>M#din7TTP0w%gX)f!Cjy2gpA^7PmZJ-l+P^e~$_7oM%g{1OF{;RDHMmu*?6eN|Rfs1o~>T zTl$!*zj(r+8xnM?My>b1WU5StOvW0fzwEvz*)JY@TD*gSfq}u()z4*}Q$iB}_YQpf literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/ic_date.png b/Source/Android/app/src/main/res/drawable-xhdpi/ic_date.png new file mode 100644 index 0000000000000000000000000000000000000000..9ecb630740378a6fc9d91f51119b90191285d49b GIT binary patch literal 1157 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hE~)jr!{?;wZ6i z>zn3%r|&P)->TC0JK+58C%+81yqFg|ylAgGaj8S$rE@p8rOVq3dV-vmfAXv6J)SEu zZSGCmz0u(_#pS-0%&#necJt=U@_REwPR%q>CMZ2ys6Fq z`{Kn5&yWm9)4GC!4}$AzU+mjn@OQ!9gI+F-HfQCJ{#M%e%gxPAE@SVSS$@m?-|uF4 zTJ)1gYpcrCD95FJE88CYXa1A7RMA_P<3sRQnFT9OUEKa{jcJem^Y5_?Ay4M464Bb% zmA!peyZN=<;fxm+7ri=muy&$3LoH( z{IZ8}+2Kd!KTdz(y%EyatMy7>c>mhwo08xvp(oyr z{~kP_8ugsrcJjUhGXq|?STHGur8O3BmfvB%zKZL9lt6nzWu%SaftltXTXyU5ZvGk7 zt1Xap*hpwf$+hI#?k5895Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*J~228L~(E{-7)hu>b?$lGin;P&wNh9!&IITKnZC>|0@VKZX1osy>~eM9Wo zbeWfX4yfPsf1b_rHdChHK%-QHx$JHs13tDiA9jW{HaDg)u&B8;@iE-U_^H8YkXGd< z%dp|{Mh(UWRr7nR8Fqe*V>f!N%WU*Wmvz#|dyFoR_p)~!`K{jYG37$+#4i(>l_%?6 zo;q!PUdWd{C5xS`-Yj`+C6w|tKF#RFrLC%xDJLII6;0W?dhz=Ad=>%rADH<$`WPRn T>)c>qU|{fc^>bP0l+XkKjb&|$ 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!ia0y~yU`POA4mJh`hDS5XEf^RWBuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFs$-)aSW-r_2$-Y&ISV!hl?6{Q%p;?tVx~DSRxp0 z?A$fsyrn`|qUPBwtZA(UNcSj)k{5YfL?Wb%hwECLP;ECLLSEDj8e lU}l5cnx$Yn5B#ZPWMfEo6jw8{)jtIi@^tlcS?83{1OSGSPQ(BJ 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 zcmeAS@N?(olHy`uVBq!ia0y~yV8{Vs4i*Lm2G#ueZVU_z3dtTpz6=aiY77hwEes65 z7#J8DUNA6}8Za=tN?>5Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*J~22KHJ{7srr_TW{xN=7hS69M3oB;s}|rwjp6;pUOWg=`x%ImxR`X2|MA4m-W$D2bB?)Q zStK^qqV?~I<7{V+MtpJWDL$}hVxQ%S1CQvmg|BY2>NxDa(7g3X($Tw1E}t?KKkLjc*63-G zY8_H*-B-Af(fiQ42FI)0^DnC2NDvMbE70M$vFJ8D$ei6}x=d}Su(j{YrwalN4p==( z55BDJ%(QFKohk3~w(y!naQ&O=w@_&H2ZhQddw7`H;uPn}9OlSz+PdYw^9wnT4Y!w; z9hE%ekS$TsUGXh>?nRN_c*z%j5ej#=t9tN?++diK+`iUHEb350qnL%ajeO14=_QX| z2AZ@nGQXYJD^=EW*($@Td&2+i+Z11}iedX$6Wct`Ojv00Iy>K^awqp+yPLP6@6Ekc z2aMy23^mmLon@JCzF^1vZ`G0qCZ0H;TDE@cR^c_8)k0!QI~$*5IH^Uy$hTDd+Hii8 z{h^*6>>Ix|7QSD*Uhui{O!X5nht4|Ha~`Sxw)27h6T`)I3F0?g(i*OIe4F^j(_^i| z?-<<^R~K!5(43#{PPygWL4gt8eYJesBUrl~^gidi z3dofhZj9JDuUvq=!*M~b;_?5-v~FDX*&ZU0W}#@=^tMt(@$UQy*=OEtRbSJv^@!)9 z(|>z@&-0b=zL<00&_eM<`lLy@Cxt)FxFb5XSyyH4L6NkJa-u2Ey{qfPGYzE-3?|g9 zKWoT+ZDPr<`N>Ou3vb%HG=Z73SFYzxb_&D7xt1H2F8O$*^~5sm|NpMflDIzWjECF9 z>LfGnGYxlLT;{D(*%r0#nUhIE!p38ox7rQ*^*an7?%FB)RxUjFu7qbAyBtpt`|P(G8_KU7{3OG= z%~^Dfpq4CanBz|=k%)N5tx{)~h#d)UI>z$!#r4fi@6=Y-NHgh%^1ks@x}!P&&ikfg z1*sdVS?|jK$q?a^>R;V>R{0Rar-es4lEYIs$Tj6{EX&B;CUrx-=@Iv(Mk&E=X^J%Dxz^g#r%>5-;S)E=J(=H(}Me6TK^{~?Dyt<)3D%%cd?;pW@Beu zxG$5dDsP5OUUjP9tu1nL z*1T`Bk2s@yA1K$E*om2>t!(VQY{yf#@oKK-hs7JuuerVGeMX&DhR>D<8F^RAO!9Zz zIWs?9wUAMnV`fL$wzsbWS4H+QRY%L_bSyr=wyN26V)^-pH@!-n?vw-tRBX%Hdwbe$ z8Rlv0*u@&1`wnPb*}rP;D~=7CzY^AV9C@N;7Tfr#d9zQ1a{^;rn_s4y5EB*JyocQ_=Ev<|#S9%O0<#lT8JS*>AqJIy9kE#c1!(V7>Vf9fB@5 z616S=O}`eLF5G!rfZry_Zusxv?z3M!# z%eR6>8#uNbDfe&Ew*9M|*6_Y1S!Fthwu%7f6;l_%IqxS1E=d12i!r-t?->PGyY~MY zPH8)xigx9H`=IdWaLRXPq2ZI< zy{_xRt#^y&rgVOu`Fd)seQU+OosRzV1%=L6%W7Avvaa-O)Y$yWUo7CNc$Lno-@3CW zhk83NofpSB>q@F(y~m%~U*C#k7ewmyyjJIxoa3%`Yx1)V?E9~(t~&mJ|JctLP2ZQK zK002y;fuHAn_VAQ>)+udcmwC;-Xoa4J zd|(CFQpRSjW62Buym6IzcKe5Jf41L$o;w1+_@^F8?(Cf(V$tsN*Vw=yA-t(HxbT9} z6+0g{?&`D@@f%ZZ&1Edr)*JUFYQEc0sK@xDCRl_mS*=Jk{%GorHgiLTJ@)sXR6o2e zoovYddP2L?92d*1fL^01kNlq`@unr21gR|TOXL=N1g`ZUm7ibUe@3aYh<}wOT4oFk O3=E#GelF{r5}E)uN3(|j 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 zcmeAS@N?(olHy`uVBq!ia0y~yU`POA4mJh`hDS5XEf^SB`#fD7Ln>~)o%=Rh#Z}zy8@)wV++!(ck&oCeJiyo;g1s6n=LUXi-p_7jI)9XA{tOSRv6|^4qso0TrEp z+ph^{Em=P!WmkIHUC-y58k25&mwvyJzijvNUAxNj`kWR9XozsN!l;>(boBK0O;9;G zJv%$w-^D*HJp6y#srSkk<6ZK7R_AH{-u2@ABIo7zgfH%2;v0YR{Pd)6wan*QA78(I zz5mOh<8B{sI(&Kf?Af#K$t`_GOYiNox_iyqZMMsQk-t2-z2|;QOH02$-TLlnY|Xr` z#dXn9QC0i0_TIjIJN!Y-{VG>$E=4&(^_Z#L)iMuSHkJwA57{Fv{pd`t=6j1Jc{ZF( z|EFd!Jm|Y*cW-Zi#nQOHmCc*HZLK7S z`lt85H}7KFV{*wlx?}--K=*>H}baIuQhmG8GWkeRnzga39_p{@SmN$Nm{t! zx0pkmyms)x^|}pO%!^nXmIs{rea%WNc?xTTr^6Nh2K@$4JI3jZ4u`dV-O%!H=n;+2 zsK3h*`tsSmsYX?)3<)+)x6f;ro)F_}rbY zT+$cq-(0yS-q0t`Uv%nkpt?YK_QRUOTh*5~+`n3=p8jG7Q^QBgr(!R6Fg1LBuT(+<@DAgKW{xLD;!rn=I-K-3|R=!XF*>+q1WlsddoL4%Ge~NE1 z9$;s2V0g%Ij>GlNY_o=j0GB-sCbxEEHWhN4Ntmm;mXs*27S9#XI6J3&>WcXdIjmXt zul_&y^WCEE==UoQmB#omY}8;BU;rT->jOVmbzYTkxiKpN)*1WEZ+Z) z!79SVUFNR)L=9Gs0=u{~HE$PaYiqB6U6s#Y_+KFUiHs(T#s1cn854cYQnw0Zu`={> zM{WpEfAsF{D{IGqRo!;1EA=*2cOQEH;>+i>2e0H9Ls%E+*ReP-pdbTFhR^%HeRBJi z#->nW%yuu$n89*&_C5WiS(Vp2m>Q0itvkHYwQG;>&L7cId@oL4{;;rLcFWzo{i>z9 zugcWkeE%i$^yjVQ?S0$6M!eehIJ>*5_|o0iqCJ;y_$_=j*S_dG(~n!L{vJ51$h&c? z=Ie~^<-SqBGgic=+4!GjEoI8x{jP7iK=kEa9`9RMi+L^_yrNxwvvP^`F42?LpDnvH zURf0A9=X<;#Wz_ca@OZF`_fFV2r|q*qN7p3%&~mooHikF7(zl4LWXd->+9?9pU8M& z&fg%0RV|AJJ$u<0jPA@j`|NbbTk)0il1iP;e=Tizm^}UFBax{(U7a6{>^^U0H{gAc z*za`vdf0i}SJ!N1Y9Fjlo1Q9_l-;LLArzD+#tF`Dl%>0|Cq5 zh3V(}x!vD-LBJn$uP!<%Jq21%-?+runV!zIbF!(8-T;uFh?)vs6wV=U{#@^K8KpUB*un`*r{EJ-5wHy87~>xyJeHVt&`R z&67*jvA6%2yV-VG?lOiCXN4^f?pS!Noa?I04BJmzgG+_0`M*OPa6SmV7nRd+Jla7lb#rhM-E<`iw8i>v))%G7__nun&!8CGRp vF`D)xDeUgmVqKLteyAnm!hkG=|4a+M&1BoYb)psn0|SGntDnm{r-UW|X}GwV 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!ia0y~yVDJE84i*LmhW}5h&oD4BC?tCX`7$t6sWC7#v@kII zVqjosc)`F>YQVtoDuIE)Y6b&?c)^@qfi?^b3`|Mh?k)`f+xyS#XJBC9EbxddW?x*=`5*@DvM`jx{d$O|_6efi+9XvIado>?N z!m_6;S(=VGoOfqu*>J&7tC7KNwb2Hq#89>}g~di2SS6=4ny%QvW8>hO`hZzWgW3MV zIinA(Z#9_n1Ii??Fr-d(lnro`yuzHT(>!Z|Z)!nCz@uZ4&nJ8Sy`n9?&T8ZQjLMg5 z`sVFE_i94ax}f9zzKr%S1kIEml&*7>Wc5Hn!&&zUNC1@pbY~915=W>y9>kr_Wm>b85kHi3p^r=85p>Q zL70(Y)*J~22Ci^V7srr_TW{x97hF9mdfZ%JXu-o?R-vvCx!l^TUJTAFN;BTdXZWsl zn6hzlgvSB*)i1(DR_lf?xxDi7#g)2SZ+LMzoz_2E)6f_66sJXZ0;*jW(37 z6=Dux412J~*hKcU<{!?=k31T@#v87So5-Gy)^PFq!{~L?=g;kOi?>Uq?)U3E+&}s| zu=#S_w}lFJ46$v!f$f*${&n4X$E(51|JdiuhZX@R=67Ygm3AI67Wf{7L9FD^Kjz;kTT$%)%+PrT%7P{s7)_{@5KC&!10%iLt8c%rOZRwwhW2>5f&s@-=7>*1MGv*a%=STLbaYtuPHo`Y{I zPA3#sC+jfYZA=R^w?8az$i~HWeqw3V$6oF#bpz?!tpNc)til$#-Y834!!UJ0=$6lM zRR?RNPp#44|9(leX7bA|yU)8NPd(v$p=VJ9!z|51n_1&uD}3gOd~d;4cBzhY^EI1$ z3*+RpTsycH^R5Um*x8p*r9SgthRW-6+}RHWH@yq|@+Lr^b#s9Jj0|%(;R`MYFYVcN z+IZoHhBeg+O=m9&x1ab`yz9!@gK7thYD>2;^j_I_DMbvWfR%V6@B#s=FHU*s*H<>kMMWU0X?TO5rO^Jf4n>I#X zK0LFINow)UjnjoEyCxcH7Te!e+WWR*O3&`ljIv+Tf3a%#K5o)?*Lu0o&Sh5Z&79eP z3%X)fXwKx>v*@Gv(jUw(6t~?heR6rRLF<&Nu-mVMg1$wiWqlHUn`h5ZJ9BPazH;}( z+KE%7SLc4$3i@`vC&X;?L*9o=?v(4YAF*kg zY=`@4XAfmZ+>f-pe4R#`X3{dFDaYZw*5AO|1flbgCVsCox@+igvK|$d5~!%C_V-fftYO8BE4GJt)t;{Uf5U3=l5;g(9YRW3ISjlimGPQy z{5G=7J3QGm`GSRS&4xCq;P_&P`%2~dD-XT1am$Fv;?0<8QK?pRQfYD-*BQn@$7ivR z9@_Y4R2-7JFjCD)u}#c8ajap*!;}5rg3oO;$#$^i=$+qfnj$FWH=B7;o4UN;iOp>vB*aVkT3DtlmGnxAE7bdQ;p5vh~1=NOUrtp z`B|lJw=C~#zW=Il;`X9j+MgIs*~-PQG(C6N?y;@i<*>y03I!4^^HdX+cN;`c*i%sV z{>}`MidVUp<0qwxM&-^=G*j1PxSPtKks+i~X!iMdVb0>kox%4$OjD1Yc1PHUe?@+i zylci0@jY^Bk<%_TY}x7cjgz@E@Yqg^fbF-ZGnc-eE3=~7SHSzW=ePI*o!Cn|Z_lWA zsDG^Lu|LS)a9+-*JD>fxY*O`kpI^kRA^Klww#6xV)D-+ro*YhTbpRvIv=$ob4*+l!-j8f0!CLCg3b8>5Aq4h=KlFn^c z?W27r`53Lb9d_!;Vl&1mt9FW&h)NoIA9Xa^y}|zWvjn5gwsSdWFVvJhcwZNLajAjV zfKJ+Ixh3rd+OUqmbTeFH%*K}7u~#_qwwZ&;FG<3OV2#*-&-(c zLY8XVO?Ts+PBRkCl0HAU>phF_jbhI0wPIx=f1B=0Z2VX7O=*RIQ^mcKJ)cS5wrAf4{!c5&5Ov)b@7jzgnZ&3?Ddh-Osu0=+K`VvtniXi@Ht!+y(V^ z&t1Rwz)msev+mjA%IAe^oEIzQthzYy)-H~)5VO7sU*B`jj*4b!-@kr?C9;{$DT?}aN5WbsC`O5M&G)Hld;5aarC(bG6jmyOV=8FGQC?j zC5}N;gwtO7Vo&N087{80)X+`;7#h=eUMBN)YV!9Vj2;V@Z~pKoE?vIx_uAR(f9+ztvaR>6 z-ODibJ$ttQVOnC~^+i(h|LHR0cDFAKnoAPndhDNs_g{MVTkyoTBF)$LzHgp$xJdl; zruz-IYA%EZ9^ZWXflBllM$IJ&QpxXj>b5$nl~rzw`ygUO&!nf9`nvx~N{Zw?}os4h_a8q?Q|~A-8~~fyu#c%712oF6~AZ^_jaF7#J8lUHx3vIVCg! E07Z}(#sB~S literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_play.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_play.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc0084756bfcb034ebd471394ef3c59c518de00 GIT binary patch literal 477 zcmeAS@N?(olHy`uVBq!ia0y~yU`POA4i*Lm29JsRH#0CWC?tCX`7$t6sWC7#v@kII zVqjosc)`F>YQVtoDuIE)Y6b&?c)^@qfi?^b3`|Mh?k)`f+xyS#XJBC9EbxddW?;mkSN+-?eId@8naAJ&12XY~bw}ZYwLB3&3LYI=#LZCg;jp(PgK@fAS}enX zZd?CU2Avp-PghwP_E;8#voYLR{b&~J0W8!)=i`Sz+n^nPdooU079oHBq zJ&NM?=*Tuzuvurzu(0qgGe=Lhy+c4uHIvh$ThbdW*C{iY9WCWK(6*zGIiu&bN5irm zeQXi3*FQ37KhAPEr2gf!=Xc>r|2osv&h3({-SFJMe2PWURaw;~?UpYKt5Oa2F6Fs< z#hj&B#v$3@I71G{GY*EAi(OwHzB?h|8?#4z0Snt^b_J6eR~tSgTw_|Izia7yDHXQO zObUPRsM*fg+0c~mjIpa}ChLUyvYVBX2@Q;F5=ex@<6rDSt#Sf)&)B|VU|?YIboFyt I=akR{0P;+(@&Et; literal 0 HcmV?d00001 diff --git a/Source/Android/app/src/main/res/drawable/oval_ripple.xml b/Source/Android/app/src/main/res/drawable/oval_ripple.xml new file mode 100644 index 0000000000..554d5f834a --- /dev/null +++ b/Source/Android/app/src/main/res/drawable/oval_ripple.xml @@ -0,0 +1,9 @@ + + + + + + + + \ 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); }