android: Remove obsolete AndroidTV mode and its resources

This commit is contained in:
FearlessTobi 2020-04-03 06:45:41 +02:00 committed by bunnei
parent 312dc5e821
commit ed32bfd28d
32 changed files with 0 additions and 1272 deletions

View File

@ -7,9 +7,6 @@
<uses-feature
android:name="android.hardware.gamepad"
android:required="false"/>
<uses-feature
android:name="android.software.leanback"
android:required="false"/>
<uses-feature android:glEsVersion="0x00030001" android:required="true" />
@ -41,18 +38,6 @@
</intent-filter>
</activity>
<activity
android:name="org.citra.citra_emu.ui.main.TvMainActivity"
android:theme="@style/CitraTv">
<!-- This intentfilter marks this Activity as the one that gets launched from Home screen. -->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="org.citra.citra_emu.features.settings.ui.SettingsActivity"
android:configChanges="orientation|screenSize"

View File

@ -1,67 +0,0 @@
package org.citra.citra_emu.adapters;
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.leanback.widget.ImageCardView;
import androidx.leanback.widget.Presenter;
import androidx.core.content.ContextCompat;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.citra.citra_emu.R;
import org.citra.citra_emu.model.Game;
import org.citra.citra_emu.utils.PicassoUtils;
import org.citra.citra_emu.viewholders.TvGameViewHolder;
/**
* The Leanback library / docs call this a Presenter, but it works very
* similarly to a RecyclerView.Adapter.
*/
public final class GameRowPresenter extends Presenter {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
// Create a new view.
ImageCardView gameCard = new ImageCardView(parent.getContext());
gameCard.setMainImageAdjustViewBounds(true);
gameCard.setMainImageDimensions(48, 48);
gameCard.setMainImageScaleType(ImageView.ScaleType.CENTER_CROP);
gameCard.setFocusable(true);
gameCard.setFocusableInTouchMode(true);
// Use that view to create a ViewHolder.
return new TvGameViewHolder(gameCard);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, Object item) {
TvGameViewHolder holder = (TvGameViewHolder) viewHolder;
Game game = (Game) item;
holder.imageScreenshot.setImageDrawable(null);
PicassoUtils.loadGameBanner(holder.imageScreenshot, game.getPath());
holder.cardParent.setTitleText(game.getTitle());
holder.cardParent.setContentText(game.getCompany());
// TODO These shouldn't be necessary once the move to a DB-based model is complete.
holder.gameId = game.getGameId();
holder.path = game.getPath();
holder.title = game.getTitle();
holder.description = game.getDescription();
holder.country = game.getCountry();
holder.company = game.getCompany();
holder.screenshotPath = game.getScreenshotPath();
// Set the platform-dependent background color of the card
Context context = holder.cardParent.getContext();
Drawable background = ContextCompat.getDrawable(context, R.drawable.tv_card_background_gamecube);
holder.cardParent.setInfoAreaBackground(background);
}
@Override
public void onUnbindViewHolder(ViewHolder viewHolder) {
// no op
}
}

View File

@ -1,42 +0,0 @@
package org.citra.citra_emu.adapters;
import android.content.res.Resources;
import androidx.leanback.widget.ImageCardView;
import androidx.leanback.widget.Presenter;
import android.view.ViewGroup;
import org.citra.citra_emu.model.TvSettingsItem;
import org.citra.citra_emu.viewholders.TvSettingsViewHolder;
public final class SettingsRowPresenter extends Presenter {
public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
// Create a new view.
ImageCardView settingsCard = new ImageCardView(parent.getContext());
settingsCard.setMainImageAdjustViewBounds(true);
settingsCard.setMainImageDimensions(192, 160);
settingsCard.setFocusable(true);
settingsCard.setFocusableInTouchMode(true);
// Use that view to create a ViewHolder.
return new TvSettingsViewHolder(settingsCard);
}
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
TvSettingsViewHolder holder = (TvSettingsViewHolder) viewHolder;
TvSettingsItem settingsItem = (TvSettingsItem) item;
Resources resources = holder.cardParent.getResources();
holder.itemId = settingsItem.getItemId();
holder.cardParent.setTitleText(resources.getString(settingsItem.getLabelId()));
holder.cardParent.setMainImage(resources.getDrawable(settingsItem.getIconId(), null));
}
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
// no op
}
}

View File

@ -69,11 +69,6 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return mPresenter.handleOptionsItem(item.getItemId());
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
// Critical: If super method is not called, rotations will be busted.

View File

@ -126,10 +126,6 @@ public final class SettingsActivityPresenter {
}
}
public boolean handleOptionsItem(int itemId) {
return false;
}
public void onSettingChanged() {
mShouldSave = true;
}

View File

@ -1,73 +0,0 @@
package org.citra.citra_emu.fragments;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.citra.citra_emu.R;
import org.citra.citra_emu.activities.EmulationActivity;
public final class MenuFragment extends Fragment implements View.OnClickListener {
private static final String KEY_TITLE = "title";
private static SparseIntArray buttonsActionsMap = new SparseIntArray();
static {
buttonsActionsMap.append(R.id.menu_emulation_show_fps,
EmulationActivity.MENU_ACTION_SHOW_FPS);
buttonsActionsMap.append(R.id.menu_exit, EmulationActivity.MENU_ACTION_EXIT);
buttonsActionsMap.append(R.id.menu_screen_layout_landscape,
EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_LANDSCAPE);
buttonsActionsMap.append(R.id.menu_screen_layout_portrait,
EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_PORTRAIT);
buttonsActionsMap.append(R.id.menu_screen_layout_single,
EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_SINGLE);
buttonsActionsMap.append(R.id.menu_screen_layout_sidebyside,
EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_SIDEBYSIDE);
buttonsActionsMap.append(R.id.menu_emulation_swap_screens,
EmulationActivity.MENU_ACTION_SWAP_SCREENS);
buttonsActionsMap.append(R.id.menu_emulation_show_overlay,
EmulationActivity.MENU_ACTION_SHOW_OVERLAY);
}
public static MenuFragment newInstance(String title) {
MenuFragment fragment = new MenuFragment();
Bundle arguments = new Bundle();
arguments.putSerializable(KEY_TITLE, title);
fragment.setArguments(arguments);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_ingame_menu, container, false);
LinearLayout options = rootView.findViewById(R.id.layout_options);
for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++) {
Button button = (Button) options.getChildAt(childIndex);
button.setOnClickListener(this);
}
TextView titleText = rootView.findViewById(R.id.text_game_title);
String title = getArguments().getString(KEY_TITLE);
if (title != null) {
titleText.setText(title);
}
return rootView;
}
@SuppressWarnings("WrongConstant")
@Override
public void onClick(View button) {
}
}

View File

@ -1,25 +0,0 @@
package org.citra.citra_emu.model;
public final class TvSettingsItem {
private final int mItemId;
private final int mIconId;
private final int mLabelId;
public TvSettingsItem(int itemId, int iconId, int labelId) {
mItemId = itemId;
mIconId = iconId;
mLabelId = labelId;
}
public int getItemId() {
return mItemId;
}
public int getIconId() {
return mIconId;
}
public int getLabelId() {
return mLabelId;
}
}

View File

@ -1,16 +0,0 @@
package org.citra.citra_emu.services;
import android.app.IntentService;
import android.content.Intent;
public final class USBPermService extends IntentService {
public USBPermService() {
super("USBPermService");
}
// Needed when extending IntentService.
// We don't care about the results of the intent handler for this.
@Override
protected void onHandleIntent(Intent intent) {
}
}

View File

@ -1,26 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.citra.citra_emu.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
/**
* Work around a bug with the nVidia Shield.
*
* Without this View, the emulation SurfaceView acts like it has the
* highest Z-value, blocking any other View, such as the menu fragments.
*/
public final class NvidiaShieldWorkaroundView extends View {
public NvidiaShieldWorkaroundView(Context context, AttributeSet attrs) {
super(context, attrs);
// Setting this seems to workaround the bug
setWillNotDraw(false);
}
}

View File

@ -1,69 +0,0 @@
package org.citra.citra_emu.ui.main;
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.leanback.widget.TitleViewAdapter;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.citra.citra_emu.R;
public class CustomTitleView extends LinearLayout implements TitleViewAdapter.Provider {
private final TextView mTitleView;
private final View mBadgeView;
private final TitleViewAdapter mTitleViewAdapter = new TitleViewAdapter() {
@Override
public View getSearchAffordanceView() {
return null;
}
@Override
public void setTitle(CharSequence titleText) {
CustomTitleView.this.setTitle(titleText);
}
@Override
public void setBadgeDrawable(Drawable drawable) {
CustomTitleView.this.setBadgeDrawable(drawable);
}
};
public CustomTitleView(Context context) {
this(context, null);
}
public CustomTitleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTitleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
View root = LayoutInflater.from(context).inflate(R.layout.tv_title, this);
mTitleView = root.findViewById(R.id.title);
mBadgeView = root.findViewById(R.id.badge);
}
public void setTitle(CharSequence title) {
if (title != null) {
mTitleView.setText(title);
mTitleView.setVisibility(View.VISIBLE);
mBadgeView.setVisibility(View.VISIBLE);
}
}
public void setBadgeDrawable(Drawable drawable) {
if (drawable != null) {
mTitleView.setVisibility(View.GONE);
mBadgeView.setVisibility(View.VISIBLE);
}
}
@Override
public TitleViewAdapter getTitleViewAdapter() {
return mTitleViewAdapter;
}
}

View File

@ -8,9 +8,6 @@ import org.citra.citra_emu.model.GameDatabase;
import org.citra.citra_emu.utils.AddDirectoryHelper;
import org.citra.citra_emu.features.settings.utils.SettingsFile;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public final class MainPresenter {
public static final int REQUEST_ADD_DIRECTORY = 1;
@ -27,10 +24,6 @@ public final class MainPresenter {
refeshGameList();
}
public void onFabClick() {
mView.launchFileListActivity();
}
public boolean handleOptionSelection(int itemId) {
switch (itemId) {
case R.id.menu_settings_core:
@ -57,14 +50,6 @@ public final class MainPresenter {
mDirToAdd = dir;
}
public void loadGames() {
GameDatabase databaseHelper = CitraApplication.databaseHelper;
databaseHelper.getGames()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(mView::showGames);
}
private void refeshGameList() {
GameDatabase databaseHelper = CitraApplication.databaseHelper;
databaseHelper.scanLibrary(databaseHelper.getWritableDatabase());

View File

@ -1,7 +1,5 @@
package org.citra.citra_emu.ui.main;
import android.database.Cursor;
/**
* Abstraction for the screen that shows on application launch.
* Implementations will differ primarily to target touch-screen
@ -24,12 +22,4 @@ public interface MainView {
void launchSettingsActivity(String menuTag);
void launchFileListActivity();
/**
* To be called when an asynchronous database read completes. Passes the
* result, in this case a {@link Cursor} to the view.
*
* @param games A Cursor containing the games read from the database.
*/
void showGames(Cursor games);
}

View File

@ -1,223 +0,0 @@
package org.citra.citra_emu.ui.main;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.leanback.app.BrowseSupportFragment;
import androidx.leanback.database.CursorMapper;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.CursorObjectAdapter;
import androidx.leanback.widget.HeaderItem;
import androidx.leanback.widget.ListRow;
import androidx.leanback.widget.ListRowPresenter;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.core.content.ContextCompat;
import android.widget.Toast;
import org.citra.citra_emu.R;
import org.citra.citra_emu.activities.EmulationActivity;
import org.citra.citra_emu.adapters.GameRowPresenter;
import org.citra.citra_emu.adapters.SettingsRowPresenter;
import org.citra.citra_emu.model.Game;
import org.citra.citra_emu.model.TvSettingsItem;
import org.citra.citra_emu.utils.DirectoryInitialization;
import org.citra.citra_emu.features.settings.ui.SettingsActivity;
import org.citra.citra_emu.utils.AddDirectoryHelper;
import org.citra.citra_emu.utils.FileBrowserHelper;
import org.citra.citra_emu.utils.PermissionsHandler;
import org.citra.citra_emu.utils.StartupHandler;
import org.citra.citra_emu.viewholders.TvGameViewHolder;
public final class TvMainActivity extends FragmentActivity implements MainView {
private MainPresenter mPresenter = new MainPresenter(this);
private BrowseSupportFragment mBrowseFragment;
private ArrayObjectAdapter mRowsAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tv_main);
setupUI();
mPresenter.onCreate();
// Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
if (savedInstanceState == null)
StartupHandler.HandleInit(this);
}
@Override
protected void onResume() {
super.onResume();
mPresenter.addDirIfNeeded(new AddDirectoryHelper(this));
}
void setupUI() {
final FragmentManager fragmentManager = getSupportFragmentManager();
mBrowseFragment = new BrowseSupportFragment();
fragmentManager
.beginTransaction()
.add(R.id.content, mBrowseFragment, "BrowseFragment")
.commit();
// Set display parameters for the BrowseFragment
mBrowseFragment.setHeadersState(BrowseSupportFragment.HEADERS_ENABLED);
mBrowseFragment.setBrandColor(ContextCompat.getColor(this, R.color.citra_orange_dark));
buildRowsAdapter();
mBrowseFragment.setOnItemViewClickedListener(
(itemViewHolder, item, rowViewHolder, row) ->
{
// Special case: user clicked on a settings row item.
if (item instanceof TvSettingsItem) {
TvSettingsItem settingsItem = (TvSettingsItem) item;
mPresenter.handleOptionSelection(settingsItem.getItemId());
} else {
TvGameViewHolder holder = (TvGameViewHolder) itemViewHolder;
// Start the emulation activity and send the path of the clicked ISO to it.
EmulationActivity.launch(TvMainActivity.this, holder.path, holder.title);
}
});
}
/**
* MainView
*/
@Override
public void setVersionString(String version) {
mBrowseFragment.setTitle(version);
}
@Override
public void refresh() {
recreate();
}
@Override
public void launchSettingsActivity(String menuTag) {
SettingsActivity.launch(this, menuTag, "");
}
@Override
public void launchFileListActivity() {
FileBrowserHelper.openDirectoryPicker(this, MainPresenter.REQUEST_ADD_DIRECTORY,
R.string.select_game_folder);
}
@Override
public void showGames(Cursor games) {
ListRow row = buildGamesRow(games);
// Add row to the adapter only if it is not empty.
if (row != null) {
mRowsAdapter.add(games);
}
}
/**
* Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity.
*
* @param requestCode An int describing whether the Activity that is returning did so successfully.
* @param resultCode An int describing what Activity is giving us this callback.
* @param result The information the returning Activity is providing us.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result) {
switch (requestCode) {
case MainPresenter.REQUEST_ADD_DIRECTORY:
// If the user picked a file, as opposed to just backing out.
if (resultCode == MainActivity.RESULT_OK) {
mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result));
}
break;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case PermissionsHandler.REQUEST_CODE_WRITE_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
DirectoryInitialization.start(this);
loadGames();
} else {
Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
private void buildRowsAdapter() {
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
if (PermissionsHandler.hasWriteAccess(this)) {
loadGames();
}
mRowsAdapter.add(buildSettingsRow());
mBrowseFragment.setAdapter(mRowsAdapter);
}
private void loadGames() {
mPresenter.loadGames();
}
private ListRow buildGamesRow(Cursor games) {
// Create an adapter for this row.
CursorObjectAdapter row = new CursorObjectAdapter(new GameRowPresenter());
// If cursor is empty, don't return a Row.
if (!games.moveToFirst()) {
return null;
}
row.changeCursor(games);
row.setMapper(new CursorMapper() {
@Override
protected void bindColumns(Cursor cursor) {
// No-op? Not sure what this does.
}
@Override
protected Object bind(Cursor cursor) {
return Game.fromCursor(cursor);
}
});
// Create the row, passing it the filled adapter and the header, and give it to the master adapter.
return new ListRow(null, row);
}
private ListRow buildSettingsRow() {
ArrayObjectAdapter rowItems = new ArrayObjectAdapter(new SettingsRowPresenter());
rowItems.add(new TvSettingsItem(R.id.menu_settings_core,
R.drawable.ic_settings_core_tv,
R.string.grid_menu_core_settings));
rowItems.add(new TvSettingsItem(R.id.button_add_directory,
R.drawable.ic_add_tv,
R.string.add_directory_title));
// Create a header for this row.
HeaderItem header =
new HeaderItem(R.string.preferences_settings, getString(R.string.preferences_settings));
return new ListRow(header, rowItems);
}
}

View File

@ -3,7 +3,6 @@ package org.citra.citra_emu.ui.platform;
import android.database.Cursor;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.recyclerview.widget.GridLayoutManager;
@ -60,11 +59,6 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam
});
}
@Override
public void refreshScreenshotAtPosition(int position) {
mAdapter.notifyItemChanged(position);
}
@Override
public void refresh() {
mPresenter.refresh();

View File

@ -11,14 +11,6 @@ public interface PlatformGamesView {
*/
void refresh();
/**
* Tell the view that a certain game's screenshot has been updated,
* and should be redrawn on-screen.
*
* @param position The index of the game that should be redrawn.
*/
void refreshScreenshotAtPosition(int position);
/**
* To be called when an asynchronous database read completes. Passes the
* result, in this case a {@link Cursor}, to the view.

View File

@ -1,25 +0,0 @@
package org.citra.citra_emu.utils;
import android.view.View;
import android.view.ViewPropertyAnimator;
public final class Animations {
private Animations() {
}
public static ViewPropertyAnimator fadeViewIn(View view) {
view.setVisibility(View.VISIBLE);
return view.animate()
.withLayer()
.setDuration(100)
.alpha(1.0f);
}
public static ViewPropertyAnimator fadeViewOut(View view) {
return view.animate()
.withLayer()
.setDuration(300)
.alpha(0.0f);
}
}

View File

@ -1,353 +0,0 @@
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2+
* Refer to the license.txt file included.
*/
package org.citra.citra_emu.utils;
import android.opengl.GLES30;
import org.citra.citra_emu.NativeLibrary;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;
/**
* Utility class that abstracts all the stuff about
* EGL initialization out of the way if all that is
* wanted is to query the underlying GL API for information.
*/
public final class EGLHelper {
// Renderable type bitmasks
public static final int EGL_OPENGL_ES_BIT = 0x0001;
public static final int EGL_OPENGL_ES2_BIT = 0x0004;
public static final int EGL_OPENGL_BIT = 0x0008;
public static final int EGL_OPENGL_ES3_BIT_KHR = 0x0040;
// API types
public static final int EGL_OPENGL_ES_API = 0x30A0;
public static final int EGL_OPENGL_API = 0x30A2;
private final EGL10 mEGL;
private final EGLDisplay mDisplay;
private EGLConfig[] mEGLConfigs;
private EGLContext mEGLContext;
private EGLSurface mEGLSurface;
private GL10 mGL;
// GL support flags
private boolean supportGL;
private boolean supportGLES2;
private boolean supportGLES3;
/**
* Constructor
* <p>
* Initializes the underlying {@link EGLSurface} with a width and height of 1.
* This is useful if all you need to use this class for is to query information
* from specific API contexts.
*
* @param renderableType Bitmask indicating which types of client API contexts
* the framebuffer config must support.
*/
public EGLHelper(int renderableType) {
this(1, 1, renderableType);
}
/**
* Constructor
*
* @param width Width of the underlying {@link EGLSurface}.
* @param height Height of the underlying {@link EGLSurface}.
* @param renderableType Bitmask indicating which types of client API contexts
* the framebuffer config must support.
*/
public EGLHelper(int width, int height, int renderableType) {
// Initialize handle to an EGL display.
mEGL = (EGL10) EGLContext.getEGL();
mDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
// If a display is present, initialize EGL.
if (mDisplay != EGL10.EGL_NO_DISPLAY) {
int[] version = new int[2];
if (mEGL.eglInitialize(mDisplay, version)) {
// Detect supported GL APIs, initialize configs, etc.
detect();
// Create context and surface
create(width, height, renderableType);
} else {
Log.error("[EGLHelper] Error initializing EGL.");
}
} else {
Log.error("[EGLHelper] Error initializing EGL display.");
}
}
/**
* Releases all resources associated with this helper.
* <p>
* This should be called whenever this helper is no longer needed.
*/
public void closeHelper() {
mEGL.eglTerminate(mDisplay);
}
/**
* Gets information through EGL.<br/>
* <p>
* Index 0: Vendor <br/>
* Index 1: Version <br/>
* Index 2: Renderer <br/>
* Index 3: Extensions <br/>
*
* @return information retrieved through EGL.
*/
public String[] getEGLInfo() {
return new String[]{
mGL.glGetString(GL10.GL_VENDOR),
mGL.glGetString(GL10.GL_VERSION),
mGL.glGetString(GL10.GL_RENDERER),
mGL.glGetString(GL10.GL_EXTENSIONS),
};
}
/**
* Whether or not this device supports OpenGL.
*
* @return true if this device supports OpenGL; false otherwise.
*/
public boolean supportsOpenGL() {
return supportGL;
}
/**
* Whether or not this device supports OpenGL ES 2.
* <br/>
* Note that if this returns true, then OpenGL ES 1 is also supported.
*
* @return true if this device supports OpenGL ES 2; false otherwise.
*/
public boolean supportsGLES2() {
return supportGLES2;
}
/**
* Whether or not this device supports OpenGL ES 3.
* <br/>
* Note that if this returns true, then OpenGL ES 1 and 2 are also supported.
*
* @return true if this device supports OpenGL ES 3; false otherwise.
*/
public boolean supportsGLES3() {
return supportGLES3;
}
/**
* Gets the underlying {@link EGL10} instance.
*
* @return the underlying {@link EGL10} instance.
*/
public EGL10 getEGL() {
return mEGL;
}
/**
* Gets the underlying {@link GL10} instance.
*
* @return the underlying {@link GL10} instance.
*/
public GL10 getGL() {
return mGL;
}
/**
* Gets the underlying {@link EGLDisplay}.
*
* @return the underlying {@link EGLDisplay}
*/
public EGLDisplay getDisplay() {
return mDisplay;
}
/**
* Gets all supported framebuffer configurations for this device.
*
* @return all supported framebuffer configurations for this device.
*/
public EGLConfig[] getConfigs() {
return mEGLConfigs;
}
/**
* Gets the underlying {@link EGLContext}.
*
* @return the underlying {@link EGLContext}.
*/
public EGLContext getContext() {
return mEGLContext;
}
/**
* Gets the underlying {@link EGLSurface}.
*
* @return the underlying {@link EGLSurface}.
*/
public EGLSurface getSurface() {
return mEGLSurface;
}
// Detects the specific kind of GL modes that are supported
private boolean detect() {
// Get total number of configs available.
int[] numConfigs = new int[1];
if (!mEGL.eglGetConfigs(mDisplay, null, 0, numConfigs)) {
Log.error("[EGLHelper] Error retrieving number of EGL configs available.");
return false;
}
// Now get all the configurations
mEGLConfigs = new EGLConfig[numConfigs[0]];
if (!mEGL.eglGetConfigs(mDisplay, mEGLConfigs, mEGLConfigs.length, numConfigs)) {
Log.error("[EGLHelper] Error retrieving all EGL configs.");
return false;
}
for (EGLConfig mEGLConfig : mEGLConfigs) {
int[] attribVal = new int[1];
boolean ret =
mEGL.eglGetConfigAttrib(mDisplay, mEGLConfig, EGL10.EGL_RENDERABLE_TYPE, attribVal);
if (ret) {
if ((attribVal[0] & EGL_OPENGL_BIT) != 0)
supportGL = true;
if ((attribVal[0] & EGL_OPENGL_ES2_BIT) != 0)
supportGLES2 = true;
if ((attribVal[0] & EGL_OPENGL_ES3_BIT_KHR) != 0)
supportGLES3 = true;
}
}
return true;
}
// Creates the context and surface.
private void create(int width, int height, int renderableType) {
int[] attribs = {
EGL10.EGL_WIDTH, width,
EGL10.EGL_HEIGHT, height,
EGL10.EGL_NONE
};
// Initially we just assume GLES2 will be the default context.
int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
int[] ctx_attribs = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL10.EGL_NONE
};
// Determine the type of context that will be created
// and change the attribute arrays accordingly.
switch (renderableType) {
case EGL_OPENGL_ES_BIT:
ctx_attribs[1] = 1;
break;
case EGL_OPENGL_BIT:
ctx_attribs[0] = EGL10.EGL_NONE;
break;
case EGL_OPENGL_ES3_BIT_KHR:
ctx_attribs[1] = 3;
break;
case EGL_OPENGL_ES2_BIT:
default: // Fall-back to GLES 2.
ctx_attribs[1] = 2;
break;
}
if (renderableType == EGL_OPENGL_BIT)
NativeLibrary.eglBindAPI(EGL_OPENGL_API);
else
NativeLibrary.eglBindAPI(EGL_OPENGL_ES_API);
mEGLContext =
mEGL.eglCreateContext(mDisplay, mEGLConfigs[0], EGL10.EGL_NO_CONTEXT, ctx_attribs);
mEGLSurface = mEGL.eglCreatePbufferSurface(mDisplay, mEGLConfigs[0], attribs);
mEGL.eglMakeCurrent(mDisplay, mEGLSurface, mEGLSurface, mEGLContext);
mGL = (GL10) mEGLContext.getGL();
}
/**
* Simplified call to {@link GL10#glGetString(int)}
* <p>
* Accepts the following constants:
* <ul>
* <li>GL_VENDOR - Company responsible for the GL implementation.</li>
* <li>GL_VERSION - Version or release number.</li>
* <li>GL_RENDERER - Name of the renderer</li>
* <li>GL_SHADING_LANGUAGE_VERSION - Version or release number of the shading language </li>
* </ul>
*
* @param glEnum A symbolic constant within {@link GL10}.
* @return the string information represented by {@code glEnum}.
*/
public String glGetString(int glEnum) {
return mGL.glGetString(glEnum);
}
/**
* Simplified call to {@link GLES30#glGetStringi(int, int)}
* <p>
* Accepts the following constants:
* <ul>
* <li>GL_VENDOR - Company responsible for the GL implementation.</li>
* <li>GL_VERSION - Version or release number.</li>
* <li>GL_RENDERER - Name of the renderer</li>
* <li>GL_SHADING_LANGUAGE_VERSION - Version or release number of the shading language </li>
* <li>GL_EXTENSIONS - Extension string supported by the implementation at {@code index}.</li>
* </ul>
*
* @param glEnum A symbolic GL constant
* @param index The index of the string to return.
* @return the string information represented by {@code glEnum} and {@code index}.
*/
public String glGetStringi(int glEnum, int index) {
return GLES30.glGetStringi(glEnum, index);
}
public boolean SupportsExtension(String extension) {
int[] num_ext = new int[1];
GLES30.glGetIntegerv(GLES30.GL_NUM_EXTENSIONS, num_ext, 0);
for (int i = 0; i < num_ext[0]; ++i) {
String ext = GLES30.glGetStringi(GLES30.GL_EXTENSIONS, i);
if (ext.equals(extension))
return true;
}
return false;
}
public int GetVersion() {
int[] major = new int[1];
int[] minor = new int[1];
GLES30.glGetIntegerv(GLES30.GL_MAJOR_VERSION, major, 0);
GLES30.glGetIntegerv(GLES30.GL_MINOR_VERSION, minor, 0);
return major[0] * 100 + minor[0] * 10;
}
/**
* Simplified call to {@link GL10#glGetIntegerv(int, int[], int)
*
* @param glEnum A symbolic GL constant.
* @return the integer information represented by {@code glEnum}.
*/
public int glGetInteger(int glEnum) {
int[] val = new int[1];
mGL.glGetIntegerv(glEnum, val, 0);
return val[0];
}
}

View File

@ -1,35 +0,0 @@
package org.citra.citra_emu.viewholders;
import androidx.leanback.widget.ImageCardView;
import androidx.leanback.widget.Presenter;
import android.view.View;
import android.widget.ImageView;
/**
* A simple class that stores references to views so that the GameAdapter doesn't need to
* keep calling findViewById(), which is expensive.
*/
public final class TvGameViewHolder extends Presenter.ViewHolder {
public ImageCardView cardParent;
public ImageView imageScreenshot;
public String gameId;
// TODO Not need any of this stuff. Currently only the properties dialog needs it.
public String path;
public String title;
public String description;
public int country;
public String company;
public String screenshotPath;
public TvGameViewHolder(View itemView) {
super(itemView);
itemView.setTag(this);
cardParent = (ImageCardView) itemView;
imageScreenshot = cardParent.getMainImageView();
}
}

View File

@ -1,20 +0,0 @@
package org.citra.citra_emu.viewholders;
import androidx.leanback.widget.ImageCardView;
import androidx.leanback.widget.Presenter;
import android.view.View;
public final class TvSettingsViewHolder extends Presenter.ViewHolder {
public ImageCardView cardParent;
// Determines what action to take when this item is clicked.
public int itemId;
public TvSettingsViewHolder(View itemView) {
super(itemView);
itemView.setTag(this);
cardParent = (ImageCardView) itemView;
}
}

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:propertyName="translationX"
android:valueType="floatType"
android:valueFrom="-1280dp"
android:valueTo="0"
android:interpolator="@android:interpolator/decelerate_quad"
android:duration="300"/>
<objectAnimator
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="1"
android:interpolator="@android:interpolator/accelerate_quad"
android:duration="300"/>
</set>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This animation is used ONLY when a submenu is replaced. -->
<objectAnimator
android:propertyName="translationX"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="-1280dp"
android:interpolator="@android:interpolator/decelerate_quad"
android:duration="200"/>
<objectAnimator
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="1"
android:valueTo="0"
android:interpolator="@android:interpolator/decelerate_quad"
android:duration="200"/>
</set>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="@color/citra_accent" />
<item
android:drawable="@color/tv_card_unselected" />
</selector>

View File

@ -1,39 +0,0 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/frame_content">
<FrameLayout
android:id="@+id/frame_emulation_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<org.citra.citra_emu.ui.NvidiaShieldWorkaroundView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/image_screenshot"
android:transitionName="image_game_screenshot"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false">
<FrameLayout
android:id="@+id/frame_menu"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".25"
tools:layout="@layout/fragment_ingame_menu"/>
</LinearLayout>
</FrameLayout>

View File

@ -1,7 +0,0 @@
<SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/surface_emulation"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="false"
android:focusableInTouchMode="false"
/>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/citra_orange_dark"
tools:layout_width="250dp">
<TextView
android:id="@+id/text_game_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="The Legend of Zelda: The Wind Waker"
android:textColor="@android:color/white"
android:textSize="20sp"
android:layout_margin="32dp"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:id="@+id/layout_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/menu_take_screenshot"
android:text="@string/emulation_screenshot"
style="@style/InGameMenuOption"/>
<Button
android:id="@+id/menu_exit"
android:text="@string/emulation_exit"
style="@style/InGameMenuOption"/>
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<org.citra.citra_emu.ui.main.CustomTitleView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/browse_title_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"/>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.leanback.widget.TitleView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:visibility="gone"
android:layout_alignTop="@+id/badge"
android:layout_alignBottom="@+id/badge"
android:layout_alignParentEnd="true"
android:id="@+id/title"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<ImageView
android:visibility="gone"
android:layout_toStartOf="@id/title"
android:id="@+id/badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
</androidx.leanback.widget.TitleView>

View File

@ -97,8 +97,6 @@
<string name="loader_error_invalid_format">Invalid ROM format</string>
<!-- Emulation Menu -->
<string name="emulation_screenshot">Take Screenshot</string>
<string name="emulation_exit">Exit</string>
<string name="emulation_show_fps">Show FPS</string>
<string name="emulation_configure_controls">Configure Controls</string>
<string name="emulation_edit_layout">Edit Layout</string>

View File

@ -52,55 +52,6 @@
<item name="colorAccent">@color/citra_accent</item>
</style>
<style name="CitraEmulationTvBase" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">@color/citra_orange</item>
<item name="colorPrimaryDark">@color/citra_orange_dark</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowBackground">@android:color/black</item>
<!-- Enable window content transitions -->
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
</style>
<!-- Inherit from the Base Citra Emulation Theme -->
<style name="CitraEmulationTv" parent="CitraEmulationTvBase">
<item name="colorAccent">@color/citra_accent</item>
</style>
<!-- Hax to make Tablayout render icons -->
<!-- Android TV Themes -->
<style name="CitraTvBase" parent="Theme.Leanback.Browse">
<item name="colorPrimary">@color/citra_orange</item>
<item name="colorPrimaryDark">@color/citra_orange_dark</item>
<!-- Enable window content transitions -->
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
</style>
<style name="CitraTv" parent="CitraTvBase">
<item name="colorAccent">@color/citra_accent</item>
<item name="browseTitleViewLayout">@layout/titleview</item>
</style>
<style name="InGameMenuOption" parent="Widget.AppCompat.Button.Borderless">
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textAllCaps">false</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">48dp</item>
<item name="android:gravity">center_vertical|left</item>
<item name="android:paddingLeft">32dp</item>
<item name="android:paddingRight">32dp</item>
<item name="android:layout_margin">0dp</item>
</style>
<!-- Inherit from a base file picker theme that handles day/night -->
<style name="FilePickerTheme" parent="FilePickerBaseTheme">
<item name="colorPrimary">@color/citra_orange</item>