mirror of
https://github.com/Lorenzooone/cc3dsfs.git
synced 2025-06-18 08:35:33 -04:00
Implement proper saving on Android
This commit is contained in:
parent
77872ecf56
commit
405bba1cb8
@ -4,9 +4,6 @@
|
||||
<uses-feature android:glEsVersion="0x00010001" />
|
||||
<uses-feature android:name="android.hardware.usb.host" />
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application android:label="@string/app_name"
|
||||
android:icon="@drawable/sfml_logo"
|
||||
android:hasCode="false"
|
||||
|
@ -5,6 +5,20 @@
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
#define ANDROID_COMPILATION
|
||||
#else
|
||||
// Possible to add more stuff here...
|
||||
#ifdef ANDROID_COMPILATION
|
||||
#undef ANDROID_COMPILATION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID_COMPILATION
|
||||
// These headers are needed for direct NDK/JDK interaction
|
||||
#include <android/native_activity.h>
|
||||
#endif
|
||||
|
||||
#if _MSC_VER && !__INTEL_COMPILER
|
||||
#define PACKED
|
||||
#define ALIGNED(x) alignas(x)
|
||||
@ -17,6 +31,12 @@
|
||||
|
||||
#define NAME "cc3dsfs"
|
||||
|
||||
#ifdef ANDROID_COMPILATION
|
||||
#define PRINT_FUNCTION(...) __android_log_print(ANDROID_LOG_INFO, NAME, __VA_ARGS__)
|
||||
#else
|
||||
#define PRINT_FUNCTION(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// This isn't precise, however we can use it...
|
||||
// Use these to properly sleep, with small wakes to check if data is ready
|
||||
#define USB_FPS 60
|
||||
@ -28,7 +48,12 @@
|
||||
#define SIMPLE_RESET_DATA_INDEX -2
|
||||
#define CREATE_NEW_FILE_INDEX -3
|
||||
|
||||
#ifdef ANDROID_COMPILATION
|
||||
ANativeActivity* getAndroidNativeActivity();
|
||||
#endif
|
||||
std::string get_version_string(bool get_letter = true);
|
||||
void ActualConsoleOutTextError(std::string out_string);
|
||||
void ActualConsoleOutText(std::string out_string);
|
||||
std::string LayoutNameGenerator(int index);
|
||||
std::string LayoutPathGenerator(int index, bool created_proper_folder);
|
||||
std::string load_layout_name(int index, bool created_proper_folder, bool &success);
|
||||
|
@ -1,16 +1,8 @@
|
||||
#include "usb_generic.hpp"
|
||||
#include "utils.hpp"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
// These headers are only needed for direct NDK/JDK interaction
|
||||
#include <android/native_activity.h>
|
||||
#include <jni.h>
|
||||
// Since we want to get the native activity from SFML, we'll have to use an
|
||||
// extra header here:
|
||||
#include <SFML/System/NativeActivity.hpp>
|
||||
#endif
|
||||
|
||||
static bool usb_initialized = false;
|
||||
static libusb_context* usb_ctx = NULL; // libusb session context
|
||||
static int usb_thread_registered = 0;
|
||||
@ -20,13 +12,13 @@ std::mutex usb_thread_mutex;
|
||||
void usb_init() {
|
||||
if(usb_initialized)
|
||||
return;
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
// First we'll need the native activity handle
|
||||
ANativeActivity& activity = *sf::getNativeActivity();
|
||||
// Retrieve the JVM and JNI environment
|
||||
JavaVM& vm = *activity.vm;
|
||||
JNIEnv& env = *activity.env;
|
||||
libusb_set_option(usb_ctx, LIBUSB_OPTION_ANDROID_JAVAVM, &vm);
|
||||
#ifdef ANDROID_COMPILATION
|
||||
ANativeActivity* native_activity_ptr = getAndroidNativeActivity();
|
||||
if(native_activity_ptr) {
|
||||
// Retrieve the JVM environment
|
||||
JavaVM* vm = native_activity_ptr->vm;
|
||||
libusb_set_option(usb_ctx, LIBUSB_OPTION_ANDROID_JAVAVM, vm);
|
||||
}
|
||||
#endif
|
||||
int result = libusb_init(&usb_ctx); // open session
|
||||
if (result < 0) {
|
||||
|
@ -6,7 +6,6 @@
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
@ -720,7 +719,7 @@ static bool create_folder(const std::string path) {
|
||||
return true;
|
||||
}
|
||||
catch(...) {
|
||||
std::cerr << "Error creating folder " << path << std::endl;
|
||||
ActualConsoleOutTextError("Error creating folder " + path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -749,7 +748,7 @@ static bool parse_int_arg(int &index, int argc, char **argv, int &target, std::s
|
||||
target = std::stoi(argv[index]);
|
||||
}
|
||||
catch(...) {
|
||||
std::cerr << "Error with input for: " << to_check << std::endl;
|
||||
ActualConsoleOutTextError("Error with input for: " + to_check);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -763,7 +762,7 @@ static bool parse_double_arg(int &index, int argc, char **argv, double &target,
|
||||
target = std::stod(argv[index]);
|
||||
}
|
||||
catch(...) {
|
||||
std::cerr << "Error with input for: " << to_check << std::endl;
|
||||
ActualConsoleOutTextError("Error with input for: " + to_check);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -778,7 +777,7 @@ int main(int argc, char **argv) {
|
||||
bool use_pud_up = true;
|
||||
bool created_proper_folder = create_out_folder();
|
||||
bool mono_app_default_value = false;
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
#ifdef ANDROID_COMPILATION
|
||||
mono_app_default_value = true;
|
||||
#endif
|
||||
override_all_data override_data;
|
||||
@ -846,44 +845,44 @@ int main(int argc, char **argv) {
|
||||
mono_app_action_str = "Disables";
|
||||
default_mono_app_strn = "Enabled";
|
||||
}
|
||||
std::cout << "Help:" << std::endl;
|
||||
std::cout << " --mono_app "<< mono_app_action_str << " special mode for when only this application" << std::endl;
|
||||
std::cout << " should run on the system. " << default_mono_app_strn << " by default." << std::endl;
|
||||
std::cout << " --recovery_mode Resets to the defaults." << std::endl;
|
||||
std::cout << " --pos_x_both Set default x position for the window with both screens." << std::endl;
|
||||
std::cout << " --pos_y_both Set default y position for the window with both screens." << std::endl;
|
||||
std::cout << " --scaling_both Overrides the scale factor for the window with both screens." << std::endl;
|
||||
std::cout << " --enabled_both Overrides the presence of the window with both screens." << std::endl;
|
||||
std::cout << " 1 On, 0 Off." << std::endl;
|
||||
std::cout << " --pos_x_top Set default x position for the top screen's window." << std::endl;
|
||||
std::cout << " --pos_y_top Set default y position for the top screen's window." << std::endl;
|
||||
std::cout << " --scaling_top Overrides the top screen window's scale factor." << std::endl;
|
||||
std::cout << " --enabled_top Overrides the presence of the top screen's window." << std::endl;
|
||||
std::cout << " 1 On, 0 Off." << std::endl;
|
||||
std::cout << " --pos_x_bot Set default x position for the bottom screen's window." << std::endl;
|
||||
std::cout << " --pos_y_bot Set default y position for the bottom screen's window." << std::endl;
|
||||
std::cout << " --scaling_bot Overrides the bottom screen window's scale factor." << std::endl;
|
||||
std::cout << " --enabled_bot Overrides the presence of the bottom screen's window." << std::endl;
|
||||
std::cout << " 1 On, 0 Off." << std::endl;
|
||||
std::cout << " --no_frame_blend Disables support for frame blending shader." << std::endl;
|
||||
std::cout << " May improve compatibility with lower end hardware." << std::endl;
|
||||
std::cout << " --volume Overrides the saved volume for the audio. 0 - 200" << std::endl;
|
||||
std::cout << " --no_audio Disables audio output and processing completely." << std::endl;
|
||||
std::cout << " --no_cursor Prevents the mouse cursor from showing, unless moved." << std::endl;
|
||||
std::cout << " --auto_connect Automatically connects to the first available device," << std::endl;
|
||||
std::cout << " even if multiple are present." << std::endl;
|
||||
std::cout << " --failure_close Automatically closes the software if the first connection" << std::endl;
|
||||
std::cout << " doesn't succeed." << std::endl;
|
||||
std::cout << " --auto_close Automatically closes the software on disconnect." << std::endl;
|
||||
std::cout << " --profile Loads the profile with the specified ID at startup" << std::endl;
|
||||
std::cout << " instead of the default one. When the program closes," << std::endl;
|
||||
std::cout << " the data is also saved to the specified profile." << std::endl;
|
||||
ActualConsoleOutText("Help:");
|
||||
ActualConsoleOutText(" --mono_app " + mono_app_action_str + " special mode for when only this application");
|
||||
ActualConsoleOutText(" should run on the system. " + default_mono_app_strn + " by default.");
|
||||
ActualConsoleOutText(" --recovery_mode Resets to the defaults.");
|
||||
ActualConsoleOutText(" --pos_x_both Set default x position for the window with both screens.");
|
||||
ActualConsoleOutText(" --pos_y_both Set default y position for the window with both screens.");
|
||||
ActualConsoleOutText(" --scaling_both Overrides the scale factor for the window with both screens.");
|
||||
ActualConsoleOutText(" --enabled_both Overrides the presence of the window with both screens.");
|
||||
ActualConsoleOutText(" 1 On, 0 Off.");
|
||||
ActualConsoleOutText(" --pos_x_top Set default x position for the top screen's window.");
|
||||
ActualConsoleOutText(" --pos_y_top Set default y position for the top screen's window.");
|
||||
ActualConsoleOutText(" --scaling_top Overrides the top screen window's scale factor.");
|
||||
ActualConsoleOutText(" --enabled_top Overrides the presence of the top screen's window.");
|
||||
ActualConsoleOutText(" 1 On, 0 Off.");
|
||||
ActualConsoleOutText(" --pos_x_bot Set default x position for the bottom screen's window.");
|
||||
ActualConsoleOutText(" --pos_y_bot Set default y position for the bottom screen's window.");
|
||||
ActualConsoleOutText(" --scaling_bot Overrides the bottom screen window's scale factor.");
|
||||
ActualConsoleOutText(" --enabled_bot Overrides the presence of the bottom screen's window.");
|
||||
ActualConsoleOutText(" 1 On, 0 Off.");
|
||||
ActualConsoleOutText(" --no_frame_blend Disables support for frame blending shader.");
|
||||
ActualConsoleOutText(" May improve compatibility with lower end hardware.");
|
||||
ActualConsoleOutText(" --volume Overrides the saved volume for the audio. 0 - 200");
|
||||
ActualConsoleOutText(" --no_audio Disables audio output and processing completely.");
|
||||
ActualConsoleOutText(" --no_cursor Prevents the mouse cursor from showing, unless moved.");
|
||||
ActualConsoleOutText(" --auto_connect Automatically connects to the first available device,");
|
||||
ActualConsoleOutText(" even if multiple are present.");
|
||||
ActualConsoleOutText(" --failure_close Automatically closes the software if the first connection");
|
||||
ActualConsoleOutText(" doesn't succeed.");
|
||||
ActualConsoleOutText(" --auto_close Automatically closes the software on disconnect.");
|
||||
ActualConsoleOutText(" --profile Loads the profile with the specified ID at startup");
|
||||
ActualConsoleOutText(" instead of the default one. When the program closes,");
|
||||
ActualConsoleOutText(" the data is also saved to the specified profile.");
|
||||
#ifdef RASPI
|
||||
std::cout << " --pi_select ID Specifies ID for the select GPIO button." << std::endl;
|
||||
std::cout << " --pi_menu ID Specifies ID for the menu GPIO button." << std::endl;
|
||||
std::cout << " --pi_enter ID Specifies ID for the enter GPIO button." << std::endl;
|
||||
std::cout << " --pi_power ID Specifies ID for the poweroff GPIO button." << std::endl;
|
||||
std::cout << " --pi_pud_down Sets the pull-up GPIO mode to down. Default is up." << std::endl;
|
||||
ActualConsoleOutText(" --pi_select ID Specifies ID for the select GPIO button.");
|
||||
ActualConsoleOutText(" --pi_menu ID Specifies ID for the menu GPIO button.");
|
||||
ActualConsoleOutText(" --pi_enter ID Specifies ID for the enter GPIO button.");
|
||||
ActualConsoleOutText(" --pi_power ID Specifies ID for the poweroff GPIO button.");
|
||||
ActualConsoleOutText(" --pi_pud_down Sets the pull-up GPIO mode to down. Default is up.");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "frontend.hpp"
|
||||
#include <cmath>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include <SFML/System.hpp>
|
||||
|
||||
const CropData default_3ds_crop = {
|
||||
@ -1181,7 +1180,7 @@ std::string get_name_input_colorspace_mode(InputColorspaceMode input) {
|
||||
|
||||
static void ConsoleOutText(std::string full_text, std::string preamble_name) {
|
||||
if(full_text != "")
|
||||
std::cout << "[" << preamble_name << "] " << full_text << std::endl;
|
||||
ActualConsoleOutText("[" + preamble_name + "] " + full_text);
|
||||
}
|
||||
|
||||
void ConsumeOutText(OutTextData &out_text_data, bool update_consumed) {
|
||||
|
@ -16,6 +16,17 @@
|
||||
#include <queue>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
// Since we want to get the native activity from SFML, we'll have to use an
|
||||
// extra header here:
|
||||
#include <SFML/System/NativeActivity.hpp>
|
||||
#endif
|
||||
#ifdef ANDROID_COMPILATION
|
||||
#include <android/log.h>
|
||||
// These headers are only needed for direct NDK/JDK interaction
|
||||
#include <android/native_activity.h>
|
||||
#endif
|
||||
|
||||
#define xstr(a) str(a)
|
||||
#define str(a) #a
|
||||
|
||||
@ -276,24 +287,59 @@ std::string get_float_str_decimals(float value, int decimals) {
|
||||
return return_text;
|
||||
}
|
||||
|
||||
void ActualConsoleOutTextError(std::string out_string) {
|
||||
#ifdef ANDROID_COMPILATION
|
||||
__android_log_print(ANDROID_LOG_ERROR, NAME, "%s", out_string.c_str());
|
||||
#else
|
||||
std::cerr << out_string << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ActualConsoleOutText(std::string out_string) {
|
||||
#ifdef ANDROID_COMPILATION
|
||||
__android_log_print(ANDROID_LOG_INFO, NAME, "%s", out_string.c_str());
|
||||
#else
|
||||
std::cout << out_string << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string LayoutNameGenerator(int index) {
|
||||
if(index == STARTUP_FILE_INDEX)
|
||||
return std::string(NAME) + ".cfg";
|
||||
return "layout" + std::to_string(index) + ".cfg";
|
||||
}
|
||||
|
||||
#ifdef ANDROID_COMPILATION
|
||||
ANativeActivity* getAndroidNativeActivity() {
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
return sf::getNativeActivity();
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string LayoutPathGenerator(int index, bool created_proper_folder) {
|
||||
bool success = false;
|
||||
std::string cfg_dir;
|
||||
#if !(defined(_WIN32) || defined(_WIN64))
|
||||
const char* env_p = std::getenv("HOME");
|
||||
if(created_proper_folder && env_p) {
|
||||
cfg_dir = std::string(env_p) + "/.config/" + std::string(NAME);
|
||||
success = true;
|
||||
}
|
||||
const char* env_p = NULL;
|
||||
|
||||
#ifdef ANDROID_COMPILATION
|
||||
ANativeActivity* native_activity_ptr = getAndroidNativeActivity();
|
||||
if(native_activity_ptr)
|
||||
env_p = native_activity_ptr->internalDataPath;
|
||||
#elif !(defined(_WIN32) || defined(_WIN64))
|
||||
env_p = std::getenv("HOME");
|
||||
#endif
|
||||
if(!success)
|
||||
cfg_dir = ".config/" + std::string(NAME);
|
||||
|
||||
if(!created_proper_folder)
|
||||
env_p = NULL;
|
||||
|
||||
if(env_p != NULL)
|
||||
cfg_dir = std::string(env_p) + "/";
|
||||
|
||||
cfg_dir += ".config/" + std::string(NAME);
|
||||
|
||||
if(index == STARTUP_FILE_INDEX)
|
||||
return cfg_dir + "/";
|
||||
return cfg_dir + "/presets/";
|
||||
|
Loading…
Reference in New Issue
Block a user