Update NDK, Gradle and dependencies + Improve Settings API + Migrate to PugiXML

This commit is contained in:
◱ PixelyIon 2021-01-22 08:32:01 +05:30 committed by ◱ Mark
parent 1f48fdd4a5
commit 80302cf1ad
30 changed files with 173 additions and 195 deletions

6
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[submodule "app/libraries/tinyxml2"]
path = app/libraries/tinyxml2
url = https://github.com/leethomason/tinyxml2
[submodule "app/libraries/fmt"]
path = app/libraries/fmt
url = https://github.com/fmtlib/fmt
@ -17,3 +14,6 @@
[submodule "app/libraries/frozen"]
path = app/libraries/frozen
url = https://github.com/serge-sans-paille/frozen
[submodule "app/libraries/pugixml"]
path = app/libraries/pugixml
url = https://github.com/zeux/pugixml.git

View File

@ -26,5 +26,15 @@
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="file:/$PROJECT_DIR$/app/libraries/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:/$USER_HOME$/.m2/repository/" />
</remote-repository>
</component>
</project>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Kotlin2JvmCompilerArguments">
<option name="jvmTarget" value="14" />
<option name="jvmTarget" value="15" />
</component>
</project>

View File

@ -1,3 +1,3 @@
<component name="DependencyValidationManager">
<scope name="SkylineKotlin" pattern="file[app]:src/main/java//*.kt" />
<scope name="SkylineKotlin" pattern="file[Skyline.app]:src/main/java//*.kt" />
</component>

View File

@ -6,6 +6,7 @@
<mapping directory="$PROJECT_DIR$/app/libraries/frozen" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/lz4" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/oboe" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/pugixml" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/tinyxml2" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/vkhpp" vcs="Git" />
</component>

View File

@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.8)
cmake_minimum_required(VERSION 3.16)
project(Skyline LANGUAGES CXX ASM VERSION 0.3)
set(BUILD_TESTS OFF)
set(BUILD_TESTING OFF)
set(BUILD_TESTS OFF CACHE BOOL "Build Tests" FORCE)
set(BUILD_TESTING OFF CACHE BOOL "Build Testing" FORCE)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Shared Libraries" FORCE)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(source_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp)
@ -13,18 +13,21 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -flto=full -fno-stack-protector -Wno-unused-command-line-argument")
if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
add_compile_definitions(NDEBUG)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif ()
set(CMAKE_POLICY_DEFAULT_CMP0048 OLD)
add_subdirectory("libraries/tinyxml2")
add_subdirectory("libraries/fmt")
add_subdirectory("libraries/oboe")
add_subdirectory("libraries/lz4/contrib/cmake_unofficial")
include_directories("libraries/lz4/lib")
include_directories("libraries/oboe/include")
set(LZ4_BUILD_CLI OFF CACHE BOOL "Build LZ4 CLI" FORCE)
add_subdirectory("libraries/lz4/build/cmake")
include_directories("libraries/lz4/lib")
include_directories("libraries/vkhpp/include")
include_directories("libraries/pugixml/src") # We use PugiXML in header-only mode
include_directories("libraries/frozen/include")
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
find_package(mbedtls REQUIRED CONFIG)
@ -163,7 +166,5 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/ssl/ISslContext.cpp
${source_DIR}/skyline/services/prepo/IPrepoService.cpp
)
target_link_libraries(skyline vulkan android fmt tinyxml2 oboe lz4_static mbedtls::mbedcrypto)
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=c++2a")
target_compile_options(skyline PRIVATE -Wno-c++17-extensions -Wall -Wno-reorder -Wno-missing-braces -Wno-unused-variable -Wno-unused-private-field)
target_link_libraries(skyline vulkan android fmt lz4_static oboe mbedtls::mbedcrypto)
target_compile_options(skyline PRIVATE -Wall -Wno-unknown-attributes -Wno-c++20-extensions -Wno-c++17-extensions -Wno-c99-designator -Wno-reorder -Wno-missing-braces -Wno-unused-variable -Wno-unused-private-field)

View File

@ -4,23 +4,32 @@ apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion '30.0.2'
buildToolsVersion '30.0.3'
defaultConfig {
applicationId "skyline.emu"
minSdkVersion 26
targetSdkVersion 30
versionCode 3
versionName "0.3"
ndk {
abiFilters "arm64-v8a"
}
}
lintOptions {
disable 'IconLocation'
/* JVM Bytecode Options */
def javaVersion = JavaVersion.VERSION_11
compileOptions {
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = javaVersion.toString()
}
/* Build Options */
buildTypes {
release {
debuggable true
@ -34,43 +43,57 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
debug {
debuggable true
minifyEnabled false
shrinkResources false
}
}
buildFeatures {
prefab true
viewBinding false
}
/* Android Extensions */
androidExtensions {
/* TODO: Remove this after migrating to View Bindings */
experimental = true
}
/* Linting */
lintOptions {
disable 'IconLocation'
}
/* NDK */
ndkVersion '22.0.7026061'
externalNativeBuild {
cmake {
version "3.10.2+"
version '3.18.1+'
path "CMakeLists.txt"
}
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
ndkVersion '21.3.6528147'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
/* Filetrees */
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
/* Google */
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.preference:preference:1.1.1'
implementation 'com.google.android.material:material:1.3.0-alpha02'
implementation "androidx.core:core-ktx:1.3.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.android.material:material:1.3.0-rc01'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'info.debatty:java-string-similarity:1.2.1'
implementation(name: 'mbedtls', ext: 'aar')
}
repositories {
mavenCentral()
flatDir {
dirs 'libraries'
}
/* Kotlin */
implementation "androidx.core:core-ktx:1.3.2"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
/* Other Java */
implementation 'info.debatty:java-string-similarity:2.0.0'
/* NDK */
implementation files("libraries/mbedtls.aar")
}

@ -1 +1 @@
Subproject commit 6a497e1d061993cce54c2d71506a90155a3725e6
Subproject commit 9c418bc468baf434a848010bff74663e1f820e79

@ -1 +1 @@
Subproject commit 30b475274c044f456c37b6d15de3d04c85112698
Subproject commit e6ddc432d0ba4e42542b5867bdc932b5f6d1e08d

@ -1 +1 @@
Subproject commit c7ad96e299545330617e95eebc1369edd4e5fdf0
Subproject commit 416bc96faca629abcef42e56ecd2e20d26b79934

@ -1 +1 @@
Subproject commit 56854b88dd54a8bf7c511800ecf9f991e02cf3de
Subproject commit 5eb2ea6899367f9cdc5a262f340c06e1a7c284b2

1
app/libraries/pugixml Submodule

@ -0,0 +1 @@
Subproject commit 08b3433180727ea2f78fe02e860a08471db1e03c

@ -1 +0,0 @@
Subproject commit 61a4c7d507322c9f494f5880d4c94b60e4ce9590

View File

@ -12,9 +12,10 @@
<application
android:name=".SkylineApplication"
android:allowBackup="true"
android:extractNativeLibs="true"
android:extractNativeLibs="false"
android:fullBackupContent="@xml/backup_descriptor"
android:icon="@drawable/logo_skyline"
android:isGame="true"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"

View File

@ -32,8 +32,7 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
close(preferenceFd);
auto appFilesPath{env->GetStringUTFChars(appFilesPathJstring, nullptr)};
auto logger{std::make_shared<skyline::Logger>(std::string(appFilesPath) + "skyline.log", static_cast<skyline::Logger::LogLevel>(std::stoi(settings->GetString("log_level"))))};
//settings->List(logger); // (Uncomment when you want to print out all settings strings)
auto logger{std::make_shared<skyline::Logger>(std::string(appFilesPath) + "skyline.log", static_cast<skyline::Logger::LogLevel>(settings->logLevel))};
auto start{std::chrono::steady_clock::now()};

View File

@ -8,6 +8,7 @@
#include <span>
#include <list>
#include <vector>
#include <span>
#include <fstream>
#include <mutex>
#include <shared_mutex>
@ -292,8 +293,8 @@ namespace skyline {
using std::span<T, Extent>::span;
using std::span<T, Extent>::operator=;
typedef typename std::span<T, Extent>::element_type elementType;
typedef typename std::span<T, Extent>::index_type indexType;
typedef typename std::span<T, Extent>::element_type element_type;
typedef typename std::span<T, Extent>::size_type size_type;
constexpr span(const std::span<T, Extent> &spn) : std::span<T, Extent>(spn) {}
@ -329,7 +330,7 @@ namespace skyline {
* @param amount The amount of elements that need to be copied (in terms of the supplied span), 0 will try to copy the entirety of the other span
*/
template<typename In, size_t InExtent>
constexpr void copy_from(const span<In, InExtent> spn, indexType amount = 0) {
constexpr void copy_from(const span<In, InExtent> spn, size_type amount = 0) {
auto size{amount ? amount * sizeof(In) : spn.size_bytes()};
if (span::size_bytes() < size)
throw exception("Data being copied is larger than this span");
@ -340,7 +341,7 @@ namespace skyline {
* @brief Implicit type conversion for copy_from, this allows passing in std::vector/std::array in directly is automatically passed by reference which is important for any containers
*/
template<typename In>
constexpr void copy_from(const In &in, indexType amount = 0) {
constexpr void copy_from(const In &in, size_type amount = 0) {
copy_from(span<typename std::add_const<typename In::value_type>::type>(in), amount);
}
@ -355,11 +356,11 @@ namespace skyline {
return std::span<T, Extent>::template last<Count>();
}
constexpr span<elementType, std::dynamic_extent> first(indexType count) const noexcept {
constexpr span<element_type, std::dynamic_extent> first(size_type count) const noexcept {
return std::span<T, Extent>::first(count);
}
constexpr span<elementType, std::dynamic_extent> last(indexType count) const noexcept {
constexpr span<element_type, std::dynamic_extent> last(size_type count) const noexcept {
return std::span<T, Extent>::last(count);
}
@ -368,7 +369,7 @@ namespace skyline {
return std::span<T, Extent>::template subspan<Offset, Count>();
}
constexpr span<T, std::dynamic_extent> subspan(indexType offset, indexType count = std::dynamic_extent) const noexcept {
constexpr span<T, std::dynamic_extent> subspan(size_type offset, size_type count = std::dynamic_extent) const noexcept {
return std::span<T, Extent>::subspan(offset, count);
}
};

View File

@ -1,65 +1,52 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <android/log.h>
#include <tinyxml2.h>
#define PUGIXML_HEADER_ONLY
#include <pugixml.hpp>
#include "settings.h"
namespace skyline {
Settings::Settings(int fd) {
tinyxml2::XMLDocument pref;
pugi::xml_document document;
auto result{document.load_file(fmt::format("/proc/self/fd/{}", fd).c_str())};
if (!result)
throw exception("PugiXML Error: {} at {}", result.description(), result.offset);
auto fileDeleter = [](FILE *file) { fclose(file); };
std::unique_ptr<FILE, decltype(fileDeleter)> file{fdopen(fd, "r"), fileDeleter};
if (pref.LoadFile(file.get()))
throw exception("TinyXML2 Error: " + std::string(pref.ErrorStr()));
#define PREF_ELEM(name, memberName, rhs) std::make_pair(std::string(name), [](Settings &settings, const pugi::xml_node &element) { settings.memberName = rhs; })
tinyxml2::XMLElement *elem{pref.LastChild()->FirstChild()->ToElement()};
while (elem) {
switch (elem->Value()[0]) {
case 's':
stringMap[elem->FindAttribute("name")->Value()] = elem->GetText();
break;
case 'b':
boolMap[elem->FindAttribute("name")->Value()] = elem->FindAttribute("value")->BoolValue();
break;
case 'i':
intMap[elem->FindAttribute("name")->Value()] = elem->FindAttribute("value")->IntValue();
break;
default:
__android_log_print(ANDROID_LOG_WARN, "emu-cpp", "Settings type is missing: %s for %s", elem->Value(), elem->FindAttribute("name")->Value());
break;
std::tuple preferences{
PREF_ELEM("operation_mode", operationMode, element.attribute("value").as_bool()),
PREF_ELEM("username_value", username, element.text().as_string()),
PREF_ELEM("log_level", logLevel, element.attribute("value").as_int()),
};
if (elem->NextSibling())
elem = elem->NextSibling()->ToElement();
else
break;
std::bitset<std::tuple_size_v<typeof(preferences)>> preferencesSet{}; // A bitfield to keep track of all the preferences we've set
for (auto element{document.last_child().first_child()}; element; element = element.next_sibling()) {
std::string_view name{element.attribute("name").value()};
std::apply([&](auto... preferences) {
size_t index{};
([&](auto preference) {
if (name.size() == preference.first.size() && name.starts_with(preference.first)) {
preference.second(*this, element);
preferencesSet.set(index);
}
index++;
}(preferences), ...);
}, preferences);
}
pref.Clear();
if (!preferencesSet.all()) {
std::string unsetPreferences;
std::apply([&](auto... preferences) {
size_t index{};
([&](auto preference) {
if (!preferencesSet.test(index))
unsetPreferences += std::string("\n* ") + preference.first;
index++;
}(preferences), ...);
}, preferences);
throw exception("Cannot find the following preferences:{}", unsetPreferences);
}
std::string Settings::GetString(const std::string &key) {
return stringMap.at(key);
}
bool Settings::GetBool(const std::string &key) {
return boolMap.at(key);
}
int Settings::GetInt(const std::string &key) {
return intMap.at(key);
}
void Settings::List(const std::shared_ptr<Logger> &logger) {
for (auto &iter : stringMap)
logger->Info("{} = \"{}\"", iter.first, GetString(iter.first));
for (auto &iter : boolMap)
logger->Info("{} = {}", iter.first, GetBool(iter.first));
}
}

View File

@ -10,41 +10,14 @@ namespace skyline {
* @brief The Settings class is used to access preferences set in the Kotlin component of Skyline
*/
class Settings {
private:
std::unordered_map<std::string, std::string> stringMap; //!< A mapping from all keys to their corresponding string value
std::unordered_map<std::string, bool> boolMap; //!< A mapping from all keys to their corresponding boolean value
std::unordered_map<std::string, int> intMap; //!< A mapping from all keys to their corresponding integer value
public:
int logLevel; //!< The minimum level that logs need to be for them to be printed
bool operationMode; //!< If the emulated Switch should be handheld or docked
std::string username; //!< The name set by the user to be supplied to the guest
/**
* @param fd An FD to the preference XML file
*/
Settings(int fd);
/**
* @brief Retrieves a particular setting as a string
* @param key The key of the setting
* @return The string value of the setting
*/
std::string GetString(const std::string &key);
/**
* @brief Retrieves a particular setting as a boolean
* @param key The key of the setting
* @return The boolean value of the setting
*/
bool GetBool(const std::string &key);
/**
* @brief Retrieves a particular setting as a integer
* @param key The key of the setting
* @return The integer value of the setting
*/
int GetInt(const std::string &key);
/**
* @brief Writes all settings keys and values to syslog, this function is for development purposes
*/
void List(const std::shared_ptr<Logger> &logger);
};
}

View File

@ -23,13 +23,7 @@ namespace skyline {
constexpr Dimensions(u32 width, u32 height, u32 depth) : width(width), height(height), depth(depth) {}
constexpr bool operator==(const Dimensions &dimensions) {
return (width == dimensions.width) && (height == dimensions.height) && (depth == dimensions.depth);
}
constexpr bool operator!=(const Dimensions &dimensions) {
return (width != dimensions.width) || (height != dimensions.height) || (depth != dimensions.depth);
}
auto operator<=>(const Dimensions &) const = default;
};
/**

View File

@ -106,12 +106,7 @@ namespace skyline::input {
float amplitudeHigh;
float frequencyHigh;
bool operator==(const NpadVibrationValue &other) const {
return (amplitudeLow == other.amplitudeLow) &&
(frequencyLow == other.frequencyLow) &&
(amplitudeHigh == other.amplitudeHigh) &&
(frequencyHigh == other.frequencyHigh);
}
constexpr bool operator==(const NpadVibrationValue &) const = default;
};
static_assert(sizeof(NpadVibrationValue) == 0x10);

View File

@ -44,7 +44,7 @@ namespace skyline::kernel::type {
void KProcess::InitializeHeapTls() {
constexpr size_t DefaultHeapSize{0x200000};
heap = heap.make_shared(state, reinterpret_cast<u8 *>(state.process->memory.heap.address), DefaultHeapSize, memory::Permission{true, true, false}, memory::states::Heap);
heap = std::make_shared<KPrivateMemory>(state, reinterpret_cast<u8 *>(state.process->memory.heap.address), DefaultHeapSize, memory::Permission{true, true, false}, memory::states::Heap);
InsertItem(heap); // Insert it into the handle table so GetMemoryObject will contain it
tlsExceptionContext = AllocateTlsSlot();
}
@ -67,7 +67,7 @@ namespace skyline::kernel::type {
if (disableThreadCreation)
return nullptr;
if (!stackTop && threads.empty()) { //!< Main thread stack is created by the kernel and owned by the process
mainThreadStack = mainThreadStack.make_shared(state, reinterpret_cast<u8 *>(state.process->memory.stack.address), state.process->npdm.meta.mainThreadStackSize, memory::Permission{true, true, false}, memory::states::Stack);
mainThreadStack = std::make_shared<KPrivateMemory>(state, reinterpret_cast<u8 *>(state.process->memory.stack.address), state.process->npdm.meta.mainThreadStackSize, memory::Permission{true, true, false}, memory::states::Stack);
if (mprotect(mainThreadStack->ptr, PAGE_SIZE, PROT_NONE))
throw exception("Failed to create guard page for thread stack at 0x{:X}", mainThreadStack->ptr);
stackTop = mainThreadStack->ptr + mainThreadStack->size;

View File

@ -21,13 +21,9 @@ namespace skyline {
u64 upper; //!< The upper 64 bits of the user ID
u64 lower; //!< The lower 64 bits of the user ID
constexpr bool operator==(const UserId &userId) {
return upper == userId.upper && lower == userId.lower;
}
constexpr bool operator==(const UserId &userId) const = default;
constexpr bool operator!=(const UserId &userId) {
return !(*this == userId);
}
constexpr bool operator!=(const UserId &userId) const = default;
};
/**
@ -39,7 +35,7 @@ namespace skyline {
/**
* @brief Writes a vector of 128-bit user IDs to an output buffer
*/
Result WriteUserList(span <u8> buffer, std::vector<UserId> userIds);
Result WriteUserList(span <u8> buffer, std::vector <UserId> userIds);
public:
IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager);
@ -80,8 +76,10 @@ namespace skyline {
*/
Result GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
SERVICE_DECL(
SFUNC(0x1, IAccountServiceForApplication, GetUserExistence),
SERVICE_DECL (
SFUNC(
0x1, IAccountServiceForApplication, GetUserExistence),
SFUNC(0x2, IAccountServiceForApplication, ListAllUsers),
SFUNC(0x3, IAccountServiceForApplication, ListOpenUsers),
SFUNC(0x4, IAccountServiceForApplication, GetLastOpenedUser),

View File

@ -31,9 +31,8 @@ namespace skyline::service::account {
.uid = userId,
};
auto username{state.settings->GetString("username_value")};
size_t usernameSize{std::min(accountProfileBase.nickname.size() - 1, username.size())};
std::memcpy(accountProfileBase.nickname.data(), username.c_str(), usernameSize);
size_t usernameSize{std::min(accountProfileBase.nickname.size() - 1, state.settings->username.size())};
std::memcpy(accountProfileBase.nickname.data(), state.settings->username.c_str(), usernameSize);
response.Push(accountProfileBase);

View File

@ -12,7 +12,7 @@ namespace skyline::service::am {
}
ICommonStateGetter::ICommonStateGetter(const DeviceState &state, ServiceManager &manager) : messageEvent(std::make_shared<type::KEvent>(state, false)), BaseService(state, manager) {
operationMode = static_cast<OperationMode>(state.settings->GetBool("operation_mode"));
operationMode = static_cast<OperationMode>(state.settings->operationMode);
state.logger->Info("Switch to mode: {}", static_cast<bool>(operationMode) ? "Docked" : "Handheld");
QueueMessage(Message::FocusStateChange);
}

View File

@ -19,7 +19,7 @@ namespace skyline::service::nvdrv {
case util::Hash(devicePath): { \
std::shared_ptr<device::type> device{}; \
if (name.expired()) { \
device = device.make_shared(state); \
device = std::make_shared<device::type>(state); \
name = device; \
} else { \
device = name.lock(); \

View File

@ -7,7 +7,7 @@ namespace skyline::service::settings {
ISystemSettingsServer::ISystemSettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
Result ISystemSettingsServer::GetFirmwareVersion(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
request.outputBuf.at(0).as<SysVerTitle>() = {.major=9, .minor=0, .micro=0, .revMajor=4, .revMinor=0, .platform="NX", .verHash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .dispVer="9.0.0", .dispTitle="NintendoSDK Firmware for NX 9.0.0-4.0"};
request.outputBuf.at(0).as<SysVerTitle>() = {.major=5, .minor=0, .micro=0, .revMajor=4, .revMinor=0, .platform="NX", .verHash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .dispVer="9.0.0", .dispTitle="NintendoSDK Firmware for NX 9.0.0-4.0"};
return {};
}
}

View File

@ -213,7 +213,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
}
@Suppress("DEPRECATION") val display = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) display!! else windowManager.defaultDisplay
display?.supportedModes?.maxBy { it.refreshRate + (it.physicalHeight * it.physicalWidth) }?.let { window.attributes.preferredDisplayModeId = it.modeId }
display?.supportedModes?.maxByOrNull { it.refreshRate + (it.physicalHeight * it.physicalWidth) }?.let { window.attributes.preferredDisplayModeId = it.modeId }
game_view.setOnTouchListener(this)

View File

@ -1,14 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.61'
ext.kotlin_version = '1.4.21'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.android.tools.build:gradle:7.0.0-alpha04'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
@ -17,7 +16,7 @@ buildscript {
}
plugins {
id "com.github.ben-manes.versions" version "0.28.0"
id "com.github.ben-manes.versions" version "0.36.0"
}
allprojects {

View File

@ -19,7 +19,3 @@ org.gradle.daemon=true
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
# Enables Prefab
android.enablePrefab=true
android.prefabVersion=1.1.0

View File

@ -1,5 +1,6 @@
#Thu Jan 21 04:22:50 IST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-all.zip
zipStoreBase=GRADLE_USER_HOME