mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
(Android) Updated the game launching logic
This commit is contained in:
parent
d87bb4e3a4
commit
3ae7bc6b5b
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -34,7 +34,7 @@ emulationstation.worker.js
|
||||||
/ROMs
|
/ROMs
|
||||||
|
|
||||||
# Android build
|
# Android build
|
||||||
android
|
/android
|
||||||
|
|
||||||
# AppImage
|
# AppImage
|
||||||
AppDir
|
AppDir
|
||||||
|
|
|
@ -882,6 +882,7 @@ void FileData::launchGame()
|
||||||
std::string commandRaw {command};
|
std::string commandRaw {command};
|
||||||
std::string romPath {Utils::FileSystem::getEscapedPath(mPath)};
|
std::string romPath {Utils::FileSystem::getEscapedPath(mPath)};
|
||||||
std::string baseName {Utils::FileSystem::getStem(mPath)};
|
std::string baseName {Utils::FileSystem::getStem(mPath)};
|
||||||
|
std::string romRaw {Utils::FileSystem::getPreferredPath(mPath)};
|
||||||
|
|
||||||
// For the special case where a directory has a supported file extension and is therefore
|
// For the special case where a directory has a supported file extension and is therefore
|
||||||
// interpreted as a file, check if there is a matching filename inside the directory.
|
// interpreted as a file, check if there is a matching filename inside the directory.
|
||||||
|
@ -890,7 +891,11 @@ void FileData::launchGame()
|
||||||
for (std::string& file : Utils::FileSystem::getDirContent(mPath)) {
|
for (std::string& file : Utils::FileSystem::getDirContent(mPath)) {
|
||||||
if (Utils::FileSystem::getFileName(file) == Utils::FileSystem::getFileName(mPath) &&
|
if (Utils::FileSystem::getFileName(file) == Utils::FileSystem::getFileName(mPath) &&
|
||||||
(Utils::FileSystem::isRegularFile(file) || Utils::FileSystem::isSymlink(file))) {
|
(Utils::FileSystem::isRegularFile(file) || Utils::FileSystem::isSymlink(file))) {
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
romRaw = file;
|
||||||
|
#else
|
||||||
romPath = Utils::FileSystem::getEscapedPath(file);
|
romPath = Utils::FileSystem::getEscapedPath(file);
|
||||||
|
#endif
|
||||||
baseName = baseName.substr(0, baseName.find("."));
|
baseName = baseName.substr(0, baseName.find("."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -898,7 +903,6 @@ void FileData::launchGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string fileName {baseName + Utils::FileSystem::getExtension(romPath)};
|
const std::string fileName {baseName + Utils::FileSystem::getExtension(romPath)};
|
||||||
const std::string romRaw {Utils::FileSystem::getPreferredPath(mPath)};
|
|
||||||
const std::string esPath {Utils::FileSystem::getExePath()};
|
const std::string esPath {Utils::FileSystem::getExePath()};
|
||||||
bool runInBackground {false};
|
bool runInBackground {false};
|
||||||
|
|
||||||
|
@ -951,8 +955,12 @@ void FileData::launchGame()
|
||||||
std::string androidPackage;
|
std::string androidPackage;
|
||||||
std::string androidActivity;
|
std::string androidActivity;
|
||||||
std::string androidAction;
|
std::string androidAction;
|
||||||
std::string androidFileAsURI;
|
std::string androidCategory;
|
||||||
std::vector<std::pair<std::string, std::string>> androidExtras;
|
std::string androidMimeType;
|
||||||
|
std::string androidData;
|
||||||
|
std::map<std::string, std::string> androidExtrasString;
|
||||||
|
std::map<std::string, std::string> androidExtrasBool;
|
||||||
|
std::vector<std::string> androidActivityFlags;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
|
@ -1119,18 +1127,6 @@ void FileData::launchGame()
|
||||||
androidPackage = androidPackage.substr(0, separatorPos);
|
androidPackage = androidPackage.substr(0, separatorPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
separatorPos = androidPackage.find('|');
|
|
||||||
if (separatorPos != std::string::npos) {
|
|
||||||
androidAction = androidPackage.substr(separatorPos + 1);
|
|
||||||
androidPackage = androidPackage.substr(0, separatorPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
separatorPos = androidActivity.find('|');
|
|
||||||
if (separatorPos != std::string::npos) {
|
|
||||||
androidAction = androidActivity.substr(separatorPos + 1);
|
|
||||||
androidActivity = androidActivity.substr(0, separatorPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(LogDebug) << "FileData::launchGame(): Found emulator package \"" << androidPackage
|
LOG(LogDebug) << "FileData::launchGame(): Found emulator package \"" << androidPackage
|
||||||
<< "\"";
|
<< "\"";
|
||||||
}
|
}
|
||||||
|
@ -1609,6 +1605,7 @@ void FileData::launchGame()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__ANDROID__)
|
||||||
// Replace the remaining variables with their actual values.
|
// Replace the remaining variables with their actual values.
|
||||||
command = Utils::String::replace(command, "%ROM%", romPath);
|
command = Utils::String::replace(command, "%ROM%", romPath);
|
||||||
command = Utils::String::replace(command, "%BASENAME%", baseName);
|
command = Utils::String::replace(command, "%BASENAME%", baseName);
|
||||||
|
@ -1616,12 +1613,64 @@ void FileData::launchGame()
|
||||||
command = Utils::String::replace(command, "%ROMRAW%", romRaw);
|
command = Utils::String::replace(command, "%ROMRAW%", romRaw);
|
||||||
command = Utils::String::replace(command, "%ROMPATH%",
|
command = Utils::String::replace(command, "%ROMPATH%",
|
||||||
Utils::FileSystem::getEscapedPath(getROMDirectory()));
|
Utils::FileSystem::getEscapedPath(getROMDirectory()));
|
||||||
#if defined(__ANDROID__)
|
#else
|
||||||
if (command.find("%ROMURI%") != std::string::npos)
|
|
||||||
androidFileAsURI = romRaw;
|
|
||||||
command = Utils::String::replace(command, "%ANDROIDPACKAGE%", androidPackage);
|
command = Utils::String::replace(command, "%ANDROIDPACKAGE%", androidPackage);
|
||||||
size_t extraPos {command.find("%EXTRA_")};
|
|
||||||
|
|
||||||
|
const std::vector<std::string> androidVariabels {
|
||||||
|
"%ACTION%=", "%CATEGORY%=", "%MIMETYPE%=", "%DATA%="};
|
||||||
|
|
||||||
|
for (std::string variable : androidVariabels) {
|
||||||
|
size_t dataPos {command.find(variable)};
|
||||||
|
if (dataPos != std::string::npos) {
|
||||||
|
bool invalidEntry {false};
|
||||||
|
bool isQuoted {(command.length() > dataPos + variable.length() &&
|
||||||
|
command[dataPos + variable.length()] == '\"')};
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
if (isQuoted) {
|
||||||
|
const size_t closeQuotePos {command.find("\"", dataPos + variable.length() + 1)};
|
||||||
|
if (closeQuotePos != std::string::npos)
|
||||||
|
value = command.substr(dataPos + variable.length() + 1,
|
||||||
|
closeQuotePos - (dataPos + variable.length() + 1));
|
||||||
|
else
|
||||||
|
invalidEntry = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const size_t spacePos {command.find(" ", dataPos)};
|
||||||
|
if (spacePos != std::string::npos)
|
||||||
|
value = command.substr(dataPos + variable.length(),
|
||||||
|
spacePos - (dataPos + variable.length()));
|
||||||
|
else
|
||||||
|
value = command.substr(dataPos + variable.length(),
|
||||||
|
command.size() - dataPos + variable.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invalidEntry) {
|
||||||
|
LOG(LogError) << "Invalid entry in systems configuration file es_systems.xml";
|
||||||
|
LOG(LogError) << "Raw emulator launch command:";
|
||||||
|
LOG(LogError) << commandRaw;
|
||||||
|
|
||||||
|
window->queueInfoPopup("ERROR: INVALID ENTRY IN SYSTEMS CONFIGURATION FILE", 6000);
|
||||||
|
window->setAllowTextScrolling(true);
|
||||||
|
window->setAllowFileAnimation(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variable == "%ACTION%=")
|
||||||
|
androidAction = value;
|
||||||
|
else if (variable == "%DATA%=")
|
||||||
|
androidData = value;
|
||||||
|
else if (variable == "%CATEGORY%=")
|
||||||
|
androidCategory = value;
|
||||||
|
else if (variable == "%MIMETYPE%=")
|
||||||
|
androidMimeType = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> extraVariabels {"%EXTRA_", "%EXTRABOOL_"};
|
||||||
|
|
||||||
|
for (std::string variable : extraVariabels) {
|
||||||
|
size_t extraPos {command.find(variable)};
|
||||||
while (extraPos != std::string::npos) {
|
while (extraPos != std::string::npos) {
|
||||||
if (extraPos != std::string::npos) {
|
if (extraPos != std::string::npos) {
|
||||||
bool invalidEntry {false};
|
bool invalidEntry {false};
|
||||||
|
@ -1633,19 +1682,21 @@ void FileData::launchGame()
|
||||||
if (equalPos == std::string::npos)
|
if (equalPos == std::string::npos)
|
||||||
invalidEntry = true;
|
invalidEntry = true;
|
||||||
|
|
||||||
if (!invalidEntry && extraPos + 8 >= command.size())
|
if (!invalidEntry && extraPos + variable.length() + 1 >= command.size())
|
||||||
invalidEntry = true;
|
invalidEntry = true;
|
||||||
|
|
||||||
if (!invalidEntry) {
|
if (!invalidEntry) {
|
||||||
if (command.length() > equalPos && command[equalPos + 1] == '\"')
|
if (command.length() > equalPos && command[equalPos + 1] == '\"')
|
||||||
isQuoted = true;
|
isQuoted = true;
|
||||||
|
|
||||||
extraName = command.substr(extraPos + 7, equalPos - (extraPos + 8));
|
extraName = command.substr(extraPos + variable.length(),
|
||||||
|
equalPos - (extraPos + variable.length() + 1));
|
||||||
|
|
||||||
if (isQuoted) {
|
if (isQuoted) {
|
||||||
const size_t closeQuotePos {command.find("\"", equalPos + 2)};
|
const size_t closeQuotePos {command.find("\"", equalPos + 2)};
|
||||||
if (closeQuotePos != std::string::npos)
|
if (closeQuotePos != std::string::npos)
|
||||||
extraValue = command.substr(equalPos + 2, closeQuotePos - (equalPos + 2));
|
extraValue =
|
||||||
|
command.substr(equalPos + 2, closeQuotePos - (equalPos + 2));
|
||||||
else
|
else
|
||||||
invalidEntry = true;
|
invalidEntry = true;
|
||||||
}
|
}
|
||||||
|
@ -1658,7 +1709,8 @@ void FileData::launchGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidEntry) {
|
if (invalidEntry) {
|
||||||
LOG(LogError) << "Invalid entry in systems configuration file es_systems.xml";
|
LOG(LogError)
|
||||||
|
<< "Invalid entry in systems configuration file es_systems.xml";
|
||||||
LOG(LogError) << "Raw emulator launch command:";
|
LOG(LogError) << "Raw emulator launch command:";
|
||||||
LOG(LogError) << commandRaw;
|
LOG(LogError) << commandRaw;
|
||||||
|
|
||||||
|
@ -1669,12 +1721,24 @@ void FileData::launchGame()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extraName != "" && extraValue != "")
|
if (extraName != "" && extraValue != "") {
|
||||||
androidExtras.emplace_back(make_pair(extraName, extraValue));
|
if (variable == "%EXTRA_")
|
||||||
|
androidExtrasString[extraName] = extraValue;
|
||||||
|
else if (variable == "%EXTRABOOL_")
|
||||||
|
androidExtrasBool[extraName] = extraValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extraPos = command.find("%EXTRA_", extraPos + 1);
|
|
||||||
}
|
}
|
||||||
|
extraPos = command.find(variable, extraPos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.find("%ACTIVITY_CLEAR_TASK%") != std::string::npos)
|
||||||
|
androidActivityFlags.emplace_back("%ACTIVITY_CLEAR_TASK%");
|
||||||
|
if (command.find("%ACTIVITY_CLEAR_TOP%") != std::string::npos)
|
||||||
|
androidActivityFlags.emplace_back("%ACTIVITY_CLEAR_TOP%");
|
||||||
|
if (command.find("%ACTIVITY_NO_HISTORY%") != std::string::npos)
|
||||||
|
androidActivityFlags.emplace_back("%ACTIVITY_NO_HISTORY%");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
|
@ -1722,15 +1786,29 @@ void FileData::launchGame()
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
LOG(LogInfo) << "Expanded emulator launch arguments:";
|
LOG(LogInfo) << "Expanded emulator launch arguments:";
|
||||||
LOG(LogInfo) << "Package: " << androidPackage;
|
LOG(LogInfo) << "Package: " << androidPackage;
|
||||||
LOG(LogInfo) << "Activity: " << (androidActivity == "" ? "<package default>" : androidActivity);
|
if (androidActivity != "") {
|
||||||
LOG(LogInfo) << "Action: " << (androidAction == "" ? "<package default>" : androidAction);
|
LOG(LogInfo) << "Activity: " << androidActivity;
|
||||||
if (androidFileAsURI != "") {
|
|
||||||
LOG(LogInfo) << "File (URI): " << androidFileAsURI;
|
|
||||||
}
|
}
|
||||||
for (auto& extra : androidExtras) {
|
if (androidAction != "") {
|
||||||
|
LOG(LogInfo) << "Action: " << androidAction;
|
||||||
|
}
|
||||||
|
if (androidCategory != "") {
|
||||||
|
LOG(LogInfo) << "Category: " << androidCategory;
|
||||||
|
}
|
||||||
|
if (androidMimeType != "") {
|
||||||
|
LOG(LogInfo) << "MIME type: " << androidMimeType;
|
||||||
|
}
|
||||||
|
if (androidData != "") {
|
||||||
|
LOG(LogInfo) << "Data: " << androidData;
|
||||||
|
}
|
||||||
|
for (auto& extra : androidExtrasString) {
|
||||||
LOG(LogInfo) << "Extra name: " << extra.first;
|
LOG(LogInfo) << "Extra name: " << extra.first;
|
||||||
LOG(LogInfo) << "Extra value: " << extra.second;
|
LOG(LogInfo) << "Extra value: " << extra.second;
|
||||||
}
|
}
|
||||||
|
for (auto& extra : androidExtrasBool) {
|
||||||
|
LOG(LogInfo) << "Extra bool name: " << extra.first;
|
||||||
|
LOG(LogInfo) << "Extra bool value: " << extra.second;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
LOG(LogInfo) << "Expanded emulator launch command:";
|
LOG(LogInfo) << "Expanded emulator launch command:";
|
||||||
LOG(LogInfo) << command;
|
LOG(LogInfo) << command;
|
||||||
|
@ -1755,13 +1833,14 @@ void FileData::launchGame()
|
||||||
Utils::String::stringToWideString(startDirectory), runInBackground, hideWindow);
|
Utils::String::stringToWideString(startDirectory), runInBackground, hideWindow);
|
||||||
#elif defined(__ANDROID__)
|
#elif defined(__ANDROID__)
|
||||||
returnValue = Utils::Platform::Android::launchGame(
|
returnValue = Utils::Platform::Android::launchGame(
|
||||||
androidPackage, androidActivity, androidAction, androidFileAsURI, androidExtras);
|
androidPackage, androidActivity, androidAction, androidCategory, androidMimeType,
|
||||||
|
androidData, romRaw, androidExtrasString, androidExtrasBool, androidActivityFlags);
|
||||||
#else
|
#else
|
||||||
returnValue = Utils::Platform::launchGameUnix(command, startDirectory, runInBackground);
|
returnValue = Utils::Platform::launchGameUnix(command, startDirectory, runInBackground);
|
||||||
#endif
|
#endif
|
||||||
// Notify the user in case of a failed game launch using a popup window.
|
// Notify the user in case of a failed game launch using a popup window.
|
||||||
if (returnValue != 0) {
|
if (returnValue != 0) {
|
||||||
LOG(LogWarning) << "...launch terminated with nonzero return value " << returnValue;
|
LOG(LogWarning) << "Launch terminated with nonzero return value " << returnValue;
|
||||||
|
|
||||||
window->queueInfoPopup("ERROR LAUNCHING GAME '" +
|
window->queueInfoPopup("ERROR LAUNCHING GAME '" +
|
||||||
Utils::String::toUpper(metadata.get("name")) + "' (ERROR CODE " +
|
Utils::String::toUpper(metadata.get("name")) + "' (ERROR CODE " +
|
||||||
|
@ -2051,13 +2130,10 @@ const std::pair<std::string, FileData::findEmulatorResult> FileData::findEmulato
|
||||||
for (std::string& androidpackage : emulatorAndroidPackages) {
|
for (std::string& androidpackage : emulatorAndroidPackages) {
|
||||||
// If a forward slash character is present in the androidpackage entry it means an explicit
|
// If a forward slash character is present in the androidpackage entry it means an explicit
|
||||||
// Intent activity should be used rather than the default one. The checkEmulatorInstalled()
|
// Intent activity should be used rather than the default one. The checkEmulatorInstalled()
|
||||||
// Java function will check for the activity as well and if it's not found it flags
|
// Java function will check for the activity as well and if it's not found it flags the
|
||||||
// the overall emulator entry as not found. It's also possible to define an explicit
|
// overall emulator entry as not found.
|
||||||
// Intent action using the pipe character but this is not checked for in the Java
|
|
||||||
// function as invalid actions will not lead to crashes.
|
|
||||||
std::string packageName {androidpackage};
|
std::string packageName {androidpackage};
|
||||||
std::string activity;
|
std::string activity;
|
||||||
std::string action;
|
|
||||||
size_t separatorPos {packageName.find('/')};
|
size_t separatorPos {packageName.find('/')};
|
||||||
|
|
||||||
if (separatorPos != std::string::npos) {
|
if (separatorPos != std::string::npos) {
|
||||||
|
@ -2065,18 +2141,6 @@ const std::pair<std::string, FileData::findEmulatorResult> FileData::findEmulato
|
||||||
packageName = packageName.substr(0, separatorPos);
|
packageName = packageName.substr(0, separatorPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
separatorPos = packageName.find('|');
|
|
||||||
if (separatorPos != std::string::npos) {
|
|
||||||
action = packageName.substr(separatorPos + 1);
|
|
||||||
packageName = packageName.substr(0, separatorPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
separatorPos = activity.find('|');
|
|
||||||
if (separatorPos != std::string::npos) {
|
|
||||||
action = activity.substr(separatorPos + 1);
|
|
||||||
activity = activity.substr(0, separatorPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Utils::Platform::Android::checkEmulatorInstalled(packageName, activity)) {
|
if (Utils::Platform::Android::checkEmulatorInstalled(packageName, activity)) {
|
||||||
return std::make_pair(androidpackage,
|
return std::make_pair(androidpackage,
|
||||||
FileData::findEmulatorResult::FOUND_ANDROID_PACKAGE);
|
FileData::findEmulatorResult::FOUND_ANDROID_PACKAGE);
|
||||||
|
|
|
@ -31,6 +31,18 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
JNIEXPORT void JNICALL Java_org_es_1de_frontend_MainActivity_nativeLogOutput(JNIEnv* jniEnv,
|
||||||
|
jclass jniClass,
|
||||||
|
jstring output,
|
||||||
|
jint logLevel)
|
||||||
|
{
|
||||||
|
const char* outputUtf {jniEnv->GetStringUTFChars(output, nullptr)};
|
||||||
|
LOG(static_cast<LogLevel>(logLevel)) << outputUtf;
|
||||||
|
jniEnv->ReleaseStringUTFChars(output, outputUtf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils
|
||||||
{
|
{
|
||||||
namespace Platform
|
namespace Platform
|
||||||
|
@ -380,10 +392,9 @@ namespace Utils
|
||||||
JNIEnv* jniEnv {reinterpret_cast<JNIEnv*>(SDL_AndroidGetJNIEnv())};
|
JNIEnv* jniEnv {reinterpret_cast<JNIEnv*>(SDL_AndroidGetJNIEnv())};
|
||||||
jclass jniClass {jniEnv->FindClass("org/es_de/frontend/MainActivity")};
|
jclass jniClass {jniEnv->FindClass("org/es_de/frontend/MainActivity")};
|
||||||
jmethodID methodID {
|
jmethodID methodID {
|
||||||
jniEnv->GetStaticMethodID(jniClass, "requestStoragePermissions", "()Z")};
|
jniEnv->GetStaticMethodID(jniClass, "requestStoragePermissions", "()V")};
|
||||||
const bool result {
|
jniEnv->CallStaticVoidMethod(jniClass, methodID);
|
||||||
static_cast<bool>(jniEnv->CallStaticBooleanMethod(jniClass, methodID))};
|
bool result {false};
|
||||||
// jniEnv->DeleteLocalRef(jniClass);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,33 +472,61 @@ namespace Utils
|
||||||
int launchGame(const std::string& packageName,
|
int launchGame(const std::string& packageName,
|
||||||
const std::string& activity,
|
const std::string& activity,
|
||||||
const std::string& action,
|
const std::string& action,
|
||||||
const std::string& fileAsURI,
|
const std::string& category,
|
||||||
std::vector<std::pair<std::string, std::string>>& extras)
|
const std::string& mimeType,
|
||||||
|
const std::string& data,
|
||||||
|
const std::string& romRaw,
|
||||||
|
const std::map<std::string, std::string>& extrasString,
|
||||||
|
const std::map<std::string, std::string>& extrasBool,
|
||||||
|
const std::vector<std::string>& activityFlags)
|
||||||
{
|
{
|
||||||
JNIEnv* jniEnv {reinterpret_cast<JNIEnv*>(SDL_AndroidGetJNIEnv())};
|
JNIEnv* jniEnv {reinterpret_cast<JNIEnv*>(SDL_AndroidGetJNIEnv())};
|
||||||
jclass jniClass {jniEnv->FindClass("org/es_de/frontend/MainActivity")};
|
jclass jniClass {jniEnv->FindClass("org/es_de/frontend/MainActivity")};
|
||||||
jmethodID methodID {jniEnv->GetStaticMethodID(
|
jmethodID methodID {jniEnv->GetStaticMethodID(
|
||||||
jniClass, "launchGame",
|
jniClass, "launchGame",
|
||||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
|
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
|
||||||
"String;Ljava/util/Vector;Ljava/util/Vector;)Z")};
|
"String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/"
|
||||||
jclass vectorClass {jniEnv->FindClass("java/util/Vector")};
|
"HashMap;Ljava/util/HashMap;Ljava/util/List;)Z")};
|
||||||
jmethodID vectorMID {jniEnv->GetMethodID(vectorClass, "<init>", "()V")};
|
|
||||||
jmethodID addMethodID {
|
jclass hashMapClass {jniEnv->FindClass("java/util/HashMap")};
|
||||||
jniEnv->GetMethodID(vectorClass, "add", "(Ljava/lang/Object;)Z")};
|
jmethodID hashMapInit {jniEnv->GetMethodID(hashMapClass, "<init>", "(I)V")};
|
||||||
jobject extrasNames {jniEnv->NewObject(vectorClass, vectorMID)};
|
|
||||||
jobject extrasValues {jniEnv->NewObject(vectorClass, vectorMID)};
|
jobject hashMapString {
|
||||||
for (auto& extra : extras) {
|
jniEnv->NewObject(hashMapClass, hashMapInit, extrasString.size())};
|
||||||
jniEnv->CallBooleanMethod(extrasNames, addMethodID,
|
jobject hashMapBool {
|
||||||
jniEnv->NewStringUTF(extra.first.c_str()));
|
jniEnv->NewObject(hashMapClass, hashMapInit, extrasBool.size())};
|
||||||
jniEnv->CallBooleanMethod(extrasValues, addMethodID,
|
|
||||||
jniEnv->NewStringUTF(extra.second.c_str()));
|
jmethodID hashMapPutMethodString {jniEnv->GetMethodID(
|
||||||
|
hashMapClass, "put",
|
||||||
|
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")};
|
||||||
|
|
||||||
|
for (auto it : extrasString) {
|
||||||
|
jniEnv->CallObjectMethod(hashMapString, hashMapPutMethodString,
|
||||||
|
jniEnv->NewStringUTF(it.first.c_str()),
|
||||||
|
jniEnv->NewStringUTF(it.second.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto it : extrasBool) {
|
||||||
|
jniEnv->CallObjectMethod(hashMapBool, hashMapPutMethodString,
|
||||||
|
jniEnv->NewStringUTF(it.first.c_str()),
|
||||||
|
jniEnv->NewStringUTF(it.second.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass arrayListClass {jniEnv->FindClass("java/util/ArrayList")};
|
||||||
|
jmethodID arrayListInit {jniEnv->GetMethodID(arrayListClass, "<init>", "()V")};
|
||||||
|
jmethodID addMethod {
|
||||||
|
jniEnv->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z")};
|
||||||
|
jobject flags {jniEnv->NewObject(arrayListClass, arrayListInit)};
|
||||||
|
|
||||||
|
for (auto& flag : activityFlags)
|
||||||
|
jniEnv->CallBooleanMethod(flags, addMethod, jniEnv->NewStringUTF(flag.c_str()));
|
||||||
|
|
||||||
const bool returnValue {static_cast<bool>(jniEnv->CallStaticBooleanMethod(
|
const bool returnValue {static_cast<bool>(jniEnv->CallStaticBooleanMethod(
|
||||||
jniClass, methodID, jniEnv->NewStringUTF(packageName.c_str()),
|
jniClass, methodID, jniEnv->NewStringUTF(packageName.c_str()),
|
||||||
jniEnv->NewStringUTF(activity.c_str()), jniEnv->NewStringUTF(action.c_str()),
|
jniEnv->NewStringUTF(activity.c_str()), jniEnv->NewStringUTF(action.c_str()),
|
||||||
jniEnv->NewStringUTF(fileAsURI.c_str()), extrasNames, extrasValues))};
|
jniEnv->NewStringUTF(category.c_str()), jniEnv->NewStringUTF(mimeType.c_str()),
|
||||||
// jniEnv->DeleteLocalRef(vectorClass);
|
jniEnv->NewStringUTF(data.c_str()), jniEnv->NewStringUTF(romRaw.c_str()),
|
||||||
// jniEnv->DeleteLocalRef(jniClass);
|
hashMapString, hashMapBool, flags))};
|
||||||
if (returnValue)
|
if (returnValue)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
extern "C" void Java_org_es_1de_frontend_MainActivity_nativeLogOutput(JNIEnv* jniEnv,
|
||||||
|
jclass jniClass,
|
||||||
|
jstring output,
|
||||||
|
jint logLevel);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils
|
||||||
|
@ -68,8 +74,14 @@ namespace Utils
|
||||||
int launchGame(const std::string& packageName,
|
int launchGame(const std::string& packageName,
|
||||||
const std::string& activity,
|
const std::string& activity,
|
||||||
const std::string& action,
|
const std::string& action,
|
||||||
const std::string& fileAsURI,
|
const std::string& category,
|
||||||
std::vector<std::pair<std::string, std::string>>& extras);
|
const std::string& mimeType,
|
||||||
|
const std::string& data,
|
||||||
|
const std::string& romRaw,
|
||||||
|
const std::map<std::string, std::string>& extrasString,
|
||||||
|
const std::map<std::string, std::string>& extrasBool,
|
||||||
|
const std::vector<std::string>& activityFlags);
|
||||||
|
|
||||||
} // namespace Android
|
} // namespace Android
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue