mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-05-04 11:14:48 +12:00
Initial commit
This commit is contained in:
parent
61ba0f2d35
commit
b214d6d194
18 changed files with 402 additions and 1 deletions
|
@ -46,5 +46,7 @@
|
||||||
|
|
||||||
<activity android:name=".app.preferences.InputMapActivity"
|
<activity android:name=".app.preferences.InputMapActivity"
|
||||||
android:configChanges="density|orientation|screenSize"/>
|
android:configChanges="density|orientation|screenSize"/>
|
||||||
|
|
||||||
|
<service android:name=".app.services.LoggerService" android:process=":logger_service"/>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -21,6 +21,7 @@ import com.panda3ds.pandroid.input.InputMap;
|
||||||
import com.panda3ds.pandroid.utils.Constants;
|
import com.panda3ds.pandroid.utils.Constants;
|
||||||
import com.panda3ds.pandroid.view.PandaGlSurfaceView;
|
import com.panda3ds.pandroid.view.PandaGlSurfaceView;
|
||||||
import com.panda3ds.pandroid.view.PandaLayoutController;
|
import com.panda3ds.pandroid.view.PandaLayoutController;
|
||||||
|
import com.panda3ds.pandroid.view.utils.PerformanceView;
|
||||||
|
|
||||||
public class GameActivity extends BaseActivity {
|
public class GameActivity extends BaseActivity {
|
||||||
private final DrawerFragment drawerFragment = new DrawerFragment();
|
private final DrawerFragment drawerFragment = new DrawerFragment();
|
||||||
|
@ -56,6 +57,11 @@ public class GameActivity extends BaseActivity {
|
||||||
((CheckBox) findViewById(R.id.hide_screen_controller)).setChecked(GlobalConfig.get(GlobalConfig.KEY_SCREEN_GAMEPAD_VISIBLE));
|
((CheckBox) findViewById(R.id.hide_screen_controller)).setChecked(GlobalConfig.get(GlobalConfig.KEY_SCREEN_GAMEPAD_VISIBLE));
|
||||||
|
|
||||||
getSupportFragmentManager().beginTransaction().replace(R.id.drawer_fragment, drawerFragment).commitNow();
|
getSupportFragmentManager().beginTransaction().replace(R.id.drawer_fragment, drawerFragment).commitNow();
|
||||||
|
|
||||||
|
if (GlobalConfig.get(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY)) {
|
||||||
|
PerformanceView view = new PerformanceView(this);
|
||||||
|
((FrameLayout) findViewById(R.id.panda_gl_frame)).addView(view, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,11 +2,13 @@ package com.panda3ds.pandroid.app;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
|
||||||
import com.panda3ds.pandroid.AlberDriver;
|
import com.panda3ds.pandroid.AlberDriver;
|
||||||
import com.panda3ds.pandroid.R;
|
import com.panda3ds.pandroid.R;
|
||||||
|
import com.panda3ds.pandroid.app.services.LoggerService;
|
||||||
import com.panda3ds.pandroid.data.config.GlobalConfig;
|
import com.panda3ds.pandroid.data.config.GlobalConfig;
|
||||||
import com.panda3ds.pandroid.input.InputMap;
|
import com.panda3ds.pandroid.input.InputMap;
|
||||||
import com.panda3ds.pandroid.utils.GameUtils;
|
import com.panda3ds.pandroid.utils.GameUtils;
|
||||||
|
@ -24,6 +26,10 @@ public class PandroidApplication extends Application {
|
||||||
GameUtils.initialize();
|
GameUtils.initialize();
|
||||||
InputMap.initialize();
|
InputMap.initialize();
|
||||||
AlberDriver.Setup();
|
AlberDriver.Setup();
|
||||||
|
|
||||||
|
if (GlobalConfig.get(GlobalConfig.KEY_LOGGER_SERVICE)) {
|
||||||
|
startService(new Intent(this, LoggerService.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getThemeId() {
|
public static int getThemeId() {
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
package com.panda3ds.pandroid.app.base;
|
package com.panda3ds.pandroid.app.base;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceFragmentCompat;
|
import androidx.preference.PreferenceFragmentCompat;
|
||||||
|
import androidx.preference.SwitchPreference;
|
||||||
|
|
||||||
import com.panda3ds.pandroid.lang.Function;
|
import com.panda3ds.pandroid.lang.Function;
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,4 +20,8 @@ public abstract class BasePreferenceFragment extends PreferenceFragmentCompat {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setActivityTitle(@StringRes int titleId) {
|
||||||
|
((AppCompatActivity) requireActivity()).getSupportActionBar().setTitle(titleId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.panda3ds.pandroid.R;
|
||||||
import com.panda3ds.pandroid.app.PreferenceActivity;
|
import com.panda3ds.pandroid.app.PreferenceActivity;
|
||||||
import com.panda3ds.pandroid.app.base.BasePreferenceFragment;
|
import com.panda3ds.pandroid.app.base.BasePreferenceFragment;
|
||||||
import com.panda3ds.pandroid.app.preferences.AppearancePreferences;
|
import com.panda3ds.pandroid.app.preferences.AppearancePreferences;
|
||||||
|
import com.panda3ds.pandroid.app.preferences.DeveloperPreferences;
|
||||||
import com.panda3ds.pandroid.app.preferences.InputPreferences;
|
import com.panda3ds.pandroid.app.preferences.InputPreferences;
|
||||||
|
|
||||||
public class SettingsFragment extends BasePreferenceFragment {
|
public class SettingsFragment extends BasePreferenceFragment {
|
||||||
|
@ -16,5 +17,6 @@ public class SettingsFragment extends BasePreferenceFragment {
|
||||||
setPreferencesFromResource(R.xml.start_preferences, rootKey);
|
setPreferencesFromResource(R.xml.start_preferences, rootKey);
|
||||||
setItemClick("input", (item) -> PreferenceActivity.launch(requireContext(), InputPreferences.class));
|
setItemClick("input", (item) -> PreferenceActivity.launch(requireContext(), InputPreferences.class));
|
||||||
setItemClick("appearance", (item)-> PreferenceActivity.launch(requireContext(), AppearancePreferences.class));
|
setItemClick("appearance", (item)-> PreferenceActivity.launch(requireContext(), AppearancePreferences.class));
|
||||||
|
setItemClick("developer", (item)-> PreferenceActivity.launch(requireContext(), DeveloperPreferences.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.panda3ds.pandroid.app.preferences;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.preference.SwitchPreference;
|
||||||
|
|
||||||
|
import com.panda3ds.pandroid.R;
|
||||||
|
import com.panda3ds.pandroid.app.PandroidApplication;
|
||||||
|
import com.panda3ds.pandroid.app.base.BasePreferenceFragment;
|
||||||
|
import com.panda3ds.pandroid.app.services.LoggerService;
|
||||||
|
import com.panda3ds.pandroid.data.config.GlobalConfig;
|
||||||
|
|
||||||
|
public class DeveloperPreferences extends BasePreferenceFragment {
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
|
||||||
|
setPreferencesFromResource(R.xml.developer_preferences, rootKey);
|
||||||
|
setActivityTitle(R.string.developer_options);
|
||||||
|
|
||||||
|
setItemClick("performanceMonitor", pref -> GlobalConfig.set(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY, ((SwitchPreference) pref).isChecked()));
|
||||||
|
setItemClick("loggerService", pref -> {
|
||||||
|
boolean checked = ((SwitchPreference) pref).isChecked();
|
||||||
|
Context ctx = PandroidApplication.getAppContext();
|
||||||
|
if (checked) {
|
||||||
|
ctx.startService(new Intent(ctx, LoggerService.class));
|
||||||
|
} else {
|
||||||
|
ctx.stopService(new Intent(ctx, LoggerService.class));
|
||||||
|
}
|
||||||
|
GlobalConfig.set(GlobalConfig.KEY_LOGGER_SERVICE, checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refresh() {
|
||||||
|
((SwitchPreference) findPreference("performanceMonitor")).setChecked(GlobalConfig.get(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY));
|
||||||
|
((SwitchPreference) findPreference("loggerService")).setChecked(GlobalConfig.get(GlobalConfig.KEY_LOGGER_SERVICE));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.panda3ds.pandroid.app.services;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.panda3ds.pandroid.lang.PipeStreamTask;
|
||||||
|
import com.panda3ds.pandroid.lang.Task;
|
||||||
|
import com.panda3ds.pandroid.utils.Constants;
|
||||||
|
import com.panda3ds.pandroid.utils.FileUtils;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class LoggerService extends Service {
|
||||||
|
private static final long MAX_LOG_SIZE = 1024 * 1024 * 4; // 4MB
|
||||||
|
|
||||||
|
private PipeStreamTask errorTask;
|
||||||
|
private PipeStreamTask outputTask;
|
||||||
|
private Process logcat;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
try {
|
||||||
|
Runtime.getRuntime().exec(new String[]{"logcat", "-c"}).waitFor();
|
||||||
|
logcat = Runtime.getRuntime().exec(new String[]{"logcat"});
|
||||||
|
String logPath = getExternalMediaDirs()[0].getAbsolutePath();
|
||||||
|
FileUtils.createDir(logPath, "logs");
|
||||||
|
logPath = logPath + "/logs";
|
||||||
|
|
||||||
|
if (FileUtils.exists(logPath + "/last.txt")) {
|
||||||
|
FileUtils.delete(logPath + "/last.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileUtils.exists(logPath + "/current.txt")) {
|
||||||
|
FileUtils.rename(logPath + "/current.txt", "last.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputStream stream = FileUtils.getOutputStream(logPath + "/current.txt");
|
||||||
|
errorTask = new PipeStreamTask(logcat.getErrorStream(), stream, MAX_LOG_SIZE);
|
||||||
|
outputTask = new PipeStreamTask(logcat.getInputStream(), stream, MAX_LOG_SIZE);
|
||||||
|
|
||||||
|
errorTask.start();
|
||||||
|
outputTask.start();
|
||||||
|
|
||||||
|
Log.i(Constants.LOG_TAG, "STARTED LOGGER SERVICE");
|
||||||
|
printDeviceAbout();
|
||||||
|
} catch (Exception e) {
|
||||||
|
stopSelf();
|
||||||
|
Log.e(Constants.LOG_TAG, "Failed to start LoggerService!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printDeviceAbout() {
|
||||||
|
Log.i(Constants.LOG_TAG, "----------------------");
|
||||||
|
Log.i(Constants.LOG_TAG, "Android SDK: " + Build.VERSION.SDK_INT);
|
||||||
|
Log.i(Constants.LOG_TAG, "Device: " + Build.DEVICE);
|
||||||
|
Log.i(Constants.LOG_TAG, "Model: " + Build.MANUFACTURER + " " + Build.MODEL);
|
||||||
|
Log.i(Constants.LOG_TAG, "ABIs: " + Arrays.toString(Build.SUPPORTED_ABIS));
|
||||||
|
try {
|
||||||
|
PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||||
|
Log.i(Constants.LOG_TAG, "");
|
||||||
|
Log.i(Constants.LOG_TAG, "Package: " + info.packageName);
|
||||||
|
Log.i(Constants.LOG_TAG, "Install location: " + info.installLocation);
|
||||||
|
Log.i(Constants.LOG_TAG, "App version: " + info.versionName + " (" + info.versionCode + ")");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(Constants.LOG_TAG, "Error on obtain package info: " + e);
|
||||||
|
}
|
||||||
|
Log.i(Constants.LOG_TAG, "----------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskRemoved(Intent rootIntent) {
|
||||||
|
stopSelf();
|
||||||
|
//This is a time for app save save log file
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (Exception e) {}
|
||||||
|
super.onTaskRemoved(rootIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
Log.i(Constants.LOG_TAG, "FINISHED LOGGER SERVICE");
|
||||||
|
errorTask.close();
|
||||||
|
outputTask.close();
|
||||||
|
try {
|
||||||
|
logcat.destroy();
|
||||||
|
} catch (Throwable t) {}
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ import com.panda3ds.pandroid.data.GsonConfigParser;
|
||||||
import com.panda3ds.pandroid.utils.Constants;
|
import com.panda3ds.pandroid.utils.Constants;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class GlobalConfig {
|
public class GlobalConfig {
|
||||||
|
@ -19,6 +18,8 @@ public class GlobalConfig {
|
||||||
|
|
||||||
public static DataModel data;
|
public static DataModel data;
|
||||||
|
|
||||||
|
public static final Key<Boolean> KEY_SHOW_PERFORMANCE_OVERLAY = new Key<>("dev.performanceOverlay", false);
|
||||||
|
public static final Key<Boolean> KEY_LOGGER_SERVICE = new Key<>("dev.loggerService", false);
|
||||||
public static final Key<Integer> KEY_APP_THEME = new Key<>("app.theme", THEME_ANDROID);
|
public static final Key<Integer> KEY_APP_THEME = new Key<>("app.theme", THEME_ANDROID);
|
||||||
public static final Key<Boolean> KEY_SCREEN_GAMEPAD_VISIBLE = new Key<>("app.screen_gamepad.visible", true);
|
public static final Key<Boolean> KEY_SCREEN_GAMEPAD_VISIBLE = new Key<>("app.screen_gamepad.visible", true);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.panda3ds.pandroid.lang;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class PipeStreamTask extends Task {
|
||||||
|
private final InputStream input;
|
||||||
|
private final OutputStream output;
|
||||||
|
private final long limit;
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
public PipeStreamTask(InputStream input, OutputStream output, long limit) {
|
||||||
|
this.input = input;
|
||||||
|
this.output = output;
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
super.run();
|
||||||
|
int data;
|
||||||
|
try {
|
||||||
|
while ((data = input.read()) != -1) {
|
||||||
|
output.write(data);
|
||||||
|
if (++size > limit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {}
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
input.close();
|
||||||
|
} catch (Exception e) {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,8 @@ public class Task extends Thread {
|
||||||
super(runnable);
|
super(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Task() {}
|
||||||
|
|
||||||
public void runSync() {
|
public void runSync() {
|
||||||
start();
|
start();
|
||||||
waitFinish();
|
waitFinish();
|
||||||
|
|
|
@ -70,6 +70,23 @@ public class FileUtils {
|
||||||
return parseFile(path).exists();
|
return parseFile(path).exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void rename(String path, String newName){
|
||||||
|
parseFile(path).renameTo(newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void delete(String path){
|
||||||
|
DocumentFile file = parseFile(path);
|
||||||
|
if (file.exists()){
|
||||||
|
if (file.isDirectory()){
|
||||||
|
String[] children = listFiles(path);
|
||||||
|
for (String child: children){
|
||||||
|
delete(path+"/"+child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean createDir(String path, String name) {
|
public static boolean createDir(String path, String name) {
|
||||||
DocumentFile folder = parseFile(path);
|
DocumentFile folder = parseFile(path);
|
||||||
if (folder.findFile(name) != null) {
|
if (folder.findFile(name) != null) {
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.panda3ds.pandroid.utils;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Debug;
|
||||||
|
import android.os.Process;
|
||||||
|
|
||||||
|
import com.panda3ds.pandroid.app.PandroidApplication;
|
||||||
|
import com.panda3ds.pandroid.data.config.GlobalConfig;
|
||||||
|
|
||||||
|
public class PerformanceMonitor {
|
||||||
|
private static int fps = 1;
|
||||||
|
private static String backend = "";
|
||||||
|
private static int frames = 0;
|
||||||
|
private static long lastUpdate = 0;
|
||||||
|
private static long totalMemory = 1;
|
||||||
|
private static long availMemory = 0;
|
||||||
|
|
||||||
|
public static void initialize(String backendName) {
|
||||||
|
fps = 1;
|
||||||
|
backend = backendName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runFrame() {
|
||||||
|
if (GlobalConfig.get(GlobalConfig.KEY_SHOW_PERFORMANCE_OVERLAY)) {
|
||||||
|
frames++;
|
||||||
|
if (System.currentTimeMillis() - lastUpdate > 1000) {
|
||||||
|
lastUpdate = System.currentTimeMillis();
|
||||||
|
fps = frames;
|
||||||
|
frames = 0;
|
||||||
|
try {
|
||||||
|
Context ctx = PandroidApplication.getAppContext();
|
||||||
|
ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
|
||||||
|
manager.getMemoryInfo(info);
|
||||||
|
totalMemory = info.totalMem;
|
||||||
|
availMemory = info.availMem;
|
||||||
|
} catch (Exception e) {/**/}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getUsageMemory() {
|
||||||
|
return Math.max(1, totalMemory - availMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getTotalMemory() {
|
||||||
|
return totalMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getAvailMemory() {
|
||||||
|
return availMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getFps() {
|
||||||
|
return fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getBackend() {
|
||||||
|
return backend;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void destroy() {}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import android.util.Log;
|
||||||
import com.panda3ds.pandroid.AlberDriver;
|
import com.panda3ds.pandroid.AlberDriver;
|
||||||
import com.panda3ds.pandroid.utils.Constants;
|
import com.panda3ds.pandroid.utils.Constants;
|
||||||
import com.panda3ds.pandroid.utils.GameUtils;
|
import com.panda3ds.pandroid.utils.GameUtils;
|
||||||
|
import com.panda3ds.pandroid.utils.PerformanceMonitor;
|
||||||
import com.panda3ds.pandroid.view.renderer.ConsoleRenderer;
|
import com.panda3ds.pandroid.view.renderer.ConsoleRenderer;
|
||||||
import com.panda3ds.pandroid.view.renderer.layout.ConsoleLayout;
|
import com.panda3ds.pandroid.view.renderer.layout.ConsoleLayout;
|
||||||
import com.panda3ds.pandroid.view.renderer.layout.DefaultScreenLayout;
|
import com.panda3ds.pandroid.view.renderer.layout.DefaultScreenLayout;
|
||||||
|
@ -41,6 +42,7 @@ public class PandaGlRenderer implements GLSurfaceView.Renderer, ConsoleRenderer
|
||||||
if (screenFbo != 0) {
|
if (screenFbo != 0) {
|
||||||
glDeleteFramebuffers(1, new int[] {screenFbo}, 0);
|
glDeleteFramebuffers(1, new int[] {screenFbo}, 0);
|
||||||
}
|
}
|
||||||
|
PerformanceMonitor.destroy();
|
||||||
super.finalize();
|
super.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +94,7 @@ public class PandaGlRenderer implements GLSurfaceView.Renderer, ConsoleRenderer
|
||||||
GameUtils.removeGame(game);
|
GameUtils.removeGame(game);
|
||||||
GameUtils.addGame(GameMetadata.applySMDH(game, smdh));
|
GameUtils.addGame(GameMetadata.applySMDH(game, smdh));
|
||||||
}
|
}
|
||||||
|
PerformanceMonitor.initialize(getBackendName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDrawFrame(GL10 unused) {
|
public void onDrawFrame(GL10 unused) {
|
||||||
|
@ -114,6 +117,7 @@ public class PandaGlRenderer implements GLSurfaceView.Renderer, ConsoleRenderer
|
||||||
screenHeight - bottomScreen.bottom, GL_COLOR_BUFFER_BIT, GL_LINEAR
|
screenHeight - bottomScreen.bottom, GL_COLOR_BUFFER_BIT, GL_LINEAR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
PerformanceMonitor.runFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSurfaceChanged(GL10 unused, int width, int height) {
|
public void onSurfaceChanged(GL10 unused, int width, int height) {
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.panda3ds.pandroid.view.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.AppCompatTextView;
|
||||||
|
|
||||||
|
import com.panda3ds.pandroid.utils.PerformanceMonitor;
|
||||||
|
|
||||||
|
public class PerformanceView extends AppCompatTextView {
|
||||||
|
private boolean running = false;
|
||||||
|
|
||||||
|
public PerformanceView(@NonNull Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PerformanceView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
this(context, attrs,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PerformanceView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
|
||||||
|
int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
|
||||||
|
setPadding(padding,padding,padding,padding);
|
||||||
|
setTextColor(Color.WHITE);
|
||||||
|
setShadowLayer(padding,0,0,Color.BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh(){
|
||||||
|
running = isShown();
|
||||||
|
if (!running){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String debug = "";
|
||||||
|
|
||||||
|
int memoryTotalMb = (int) Math.round((PerformanceMonitor.getTotalMemory()/1024.0)/1024.0);
|
||||||
|
int memoryUsageMb = (int) Math.round((PerformanceMonitor.getUsageMemory()/1024.0)/1024.0);
|
||||||
|
|
||||||
|
debug += "<b>FPS: </b>"+PerformanceMonitor.getFps()+"<br>";
|
||||||
|
debug += "<b>RAM: </b>"+Math.round(((float) memoryUsageMb / memoryTotalMb)*100)+"% ("+memoryUsageMb+"MB/"+memoryTotalMb+"MB)<br>";
|
||||||
|
debug += "<b>BACKEND: </b>"+PerformanceMonitor.getBackend()+"<br>";
|
||||||
|
setText(Html.fromHtml(debug, Html.FROM_HTML_MODE_COMPACT));
|
||||||
|
postDelayed(this::refresh, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
if (!running){
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,4 +45,10 @@
|
||||||
<string name="open_file">Abrir arquivo</string>
|
<string name="open_file">Abrir arquivo</string>
|
||||||
<string name="create_new">Criar novo</string>
|
<string name="create_new">Criar novo</string>
|
||||||
<string name="running_ff">Executando \"%s\" ...</string>
|
<string name="running_ff">Executando \"%s\" ...</string>
|
||||||
|
<string name="developer_options">Opções de desenvolvedor</string>
|
||||||
|
<string name="pref_developer_summary">Depuração, mostrar fps, etc.</string>
|
||||||
|
<string name="pref_performance_monitor_title">Monitor de desempenho</string>
|
||||||
|
<string name="pref_performance_monitor_summary">Mostrar um overlay com fps, memoria, etc.</string>
|
||||||
|
<string name="pref_logger_service_title">Depuração</string>
|
||||||
|
<string name="pref_logger_service_summary">Grave os registros para um arquivo.</string>
|
||||||
</resources>
|
</resources>
|
|
@ -46,4 +46,10 @@
|
||||||
<string name="open_file">Open file</string>
|
<string name="open_file">Open file</string>
|
||||||
<string name="create_new">Create new</string>
|
<string name="create_new">Create new</string>
|
||||||
<string name="running_ff">Running \"%s\" ...</string>
|
<string name="running_ff">Running \"%s\" ...</string>
|
||||||
|
<string name="developer_options">Developer options</string>
|
||||||
|
<string name="pref_developer_summary">Logger, FPS Counter, etc.</string>
|
||||||
|
<string name="pref_performance_monitor_title">Performance monitor</string>
|
||||||
|
<string name="pref_performance_monitor_summary">Show overlay with fps, memory, etc.</string>
|
||||||
|
<string name="pref_logger_service_title">Logger</string>
|
||||||
|
<string name="pref_logger_service_summary">Store application logs to file.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
17
src/pandroid/app/src/main/res/xml/developer_preferences.xml
Normal file
17
src/pandroid/app/src/main/res/xml/developer_preferences.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="performanceMonitor"
|
||||||
|
app:title="@string/pref_performance_monitor_title"
|
||||||
|
app:summary="@string/pref_performance_monitor_summary"
|
||||||
|
app:iconSpaceReserved="false"/>
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="loggerService"
|
||||||
|
app:iconSpaceReserved="false"
|
||||||
|
app:title="@string/pref_logger_service_title"
|
||||||
|
android:summary="@string/pref_logger_service_summary"/>
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
|
@ -23,4 +23,11 @@
|
||||||
app:summary="@string/pref_appearance_summary"
|
app:summary="@string/pref_appearance_summary"
|
||||||
app:layout="@layout/preference_start_item"/>
|
app:layout="@layout/preference_start_item"/>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
app:key="developer"
|
||||||
|
app:icon="@drawable/ic_code"
|
||||||
|
app:title="@string/developer_options"
|
||||||
|
app:summary="@string/pref_developer_summary"
|
||||||
|
app:layout="@layout/preference_start_item"/>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
Loading…
Add table
Add a link
Reference in a new issue