Compare commits

..

14 Commits

Author SHA1 Message Date
yuzubot
82359e986c Android 216 2024-01-28 05:28:41 +00:00
yuzubot
5862b1df55 Merge yuzu-emu#12827 2024-01-28 05:28:41 +00:00
yuzubot
0da5c3912d Merge yuzu-emu#12826 2024-01-28 05:28:41 +00:00
yuzubot
fcae200396 Merge yuzu-emu#12802 2024-01-28 05:28:41 +00:00
yuzubot
ad63c5dc0e Merge yuzu-emu#12760 2024-01-28 05:28:41 +00:00
yuzubot
386bbc6495 Merge yuzu-emu#12749 2024-01-28 05:28:40 +00:00
liamwhite
d5e8c9d04f Merge pull request #12824 from t895/multi-boot
android: Multi-program app switching
2024-01-27 21:48:54 -05:00
t895
3f1290cee3 android: Multi-program app switching 2024-01-27 20:05:51 -05:00
liamwhite
ce2eb6e8ee Merge pull request #12818 from K900/small-fixes
A few small fixes
2024-01-27 12:13:46 -05:00
K900
8b47465586 input: add a missing null pointer check
There's a few other places where the result of GetAruidData is accessed without a null check,
but I couldn't find a code path that hits those.
2024-01-27 17:32:49 +03:00
K900
3065ab0fd8 nx_tzdb: add another safety assertion 2024-01-27 17:28:04 +03:00
K900
a2407a2964 nx_tzdb: check for unpacked directory
Otherwise things get funny if the archive is downloaded, but the unpacking was interrupted.
2024-01-27 17:25:52 +03:00
liamwhite
16b79df836 Merge pull request #12815 from t895/visual-driver-silly
android: Reload global settings on closing emulation
2024-01-27 01:36:26 -05:00
t895
6a4b25699d android: Reload global settings on closing emulation
UI like the driver manager expects the global settings to be loaded when in the MainActivity so we reload global config to properly reset state on exit.
2024-01-26 23:05:02 -05:00
21 changed files with 210 additions and 65 deletions

View File

@@ -1,8 +1,10 @@
| Pull Request | Commit | Title | Author | Merged? |
|----|----|----|----|----|
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`e3171486d`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12760](https://github.com/yuzu-emu/yuzu-android//pull/12760) | [`eb46f21c5`](https://github.com/yuzu-emu/yuzu-android//pull/12760/files) | am: rewrite for multiprocess support | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12760](https://github.com/yuzu-emu/yuzu-android//pull/12760) | [`53f17ede1`](https://github.com/yuzu-emu/yuzu-android//pull/12760/files) | am: rewrite for multiprocess support | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12802](https://github.com/yuzu-emu/yuzu-android//pull/12802) | [`c5e88c654`](https://github.com/yuzu-emu/yuzu-android//pull/12802/files) | service: mii: Migrate service to new interface | [german77](https://github.com/german77/) | Yes |
| [12826](https://github.com/yuzu-emu/yuzu-android//pull/12826) | [`2d8f80b65`](https://github.com/yuzu-emu/yuzu-android//pull/12826/files) | android: Show system driver information | [t895](https://github.com/t895/) | Yes |
| [12827](https://github.com/yuzu-emu/yuzu-android//pull/12827) | [`c770af9b1`](https://github.com/yuzu-emu/yuzu-android//pull/12827/files) | android: Disable focus on loading card | [t895](https://github.com/t895/) | Yes |
End of merge log. You can find the original README.md below the break.

View File

@@ -32,7 +32,7 @@ set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip")
set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb")
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ARCHIVE})
if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ROMFS_DIR})
set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip")
message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...")

View File

@@ -11,6 +11,10 @@ execute_process(
WORKING_DIRECTORY ${ZONE_PATH}
OUTPUT_VARIABLE FILE_LIST)
if (NOT FILE_LIST)
message(FATAL_ERROR "No timezone files found in directory ${ZONE_PATH}, did the download fail?")
endif()
set(DIRECTORY_NAME ${HEADER_NAME})
set(FILE_DATA "")

View File

@@ -261,7 +261,7 @@ object NativeLibrary {
/**
* Begins emulation.
*/
external fun run(path: String?)
external fun run(path: String?, programIndex: Int = 0)
// Surface Handling
external fun surfaceChanged(surf: Surface?)
@@ -489,6 +489,12 @@ object NativeLibrary {
sEmulationActivity.get()!!.onEmulationStopped(status)
}
@Keep
@JvmStatic
fun onProgramChanged(programIndex: Int) {
sEmulationActivity.get()!!.onProgramChanged(programIndex)
}
/**
* Logs the Yuzu version, Android version and, CPU.
*/

View File

@@ -76,7 +76,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
override fun onDestroy() {
stopForegroundService(this)
emulationViewModel.clear()
super.onDestroy()
}
@@ -446,9 +445,14 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
}
fun onEmulationStopped(status: Int) {
if (status == 0) {
if (status == 0 && emulationViewModel.programChanged.value == -1) {
finish()
}
emulationViewModel.setEmulationStopped(true)
}
fun onProgramChanged(programIndex: Int) {
emulationViewModel.setProgramChanged(programIndex)
}
private fun startMotionSensorListener() {

View File

@@ -301,6 +301,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
R.id.menu_exit -> {
emulationState.stop()
NativeConfig.reloadGlobalConfig()
emulationViewModel.setIsEmulationStopping(true)
binding.drawerLayout.close()
binding.inGameMenu.requestFocus()
@@ -423,10 +424,38 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
}
launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
emulationViewModel.programChanged.collect {
if (it != 0) {
emulationViewModel.setEmulationStarted(false)
binding.drawerLayout.close()
binding.drawerLayout
.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
ViewUtils.hideView(binding.surfaceInputOverlay)
ViewUtils.showView(binding.loadingIndicator)
}
}
}
}
launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
emulationViewModel.emulationStopped.collect {
if (it && emulationViewModel.programChanged.value != -1) {
if (perfStatsUpdater != null) {
perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!)
}
emulationState.changeProgram(emulationViewModel.programChanged.value)
emulationViewModel.setProgramChanged(-1)
emulationViewModel.setEmulationStopped(false)
}
}
}
}
}
}
private fun startEmulation() {
private fun startEmulation(programIndex: Int = 0) {
if (!NativeLibrary.isRunning() && !NativeLibrary.isPaused()) {
if (!DirectoryInitialization.areDirectoriesReady) {
DirectoryInitialization.start()
@@ -434,7 +463,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
updateScreenLayout()
emulationState.run(emulationActivity!!.isActivityRecreated)
emulationState.run(emulationActivity!!.isActivityRecreated, programIndex)
}
}
@@ -832,6 +861,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
) {
private var state: State
private var surface: Surface? = null
lateinit var emulationThread: Thread
init {
// Starting state is stopped.
@@ -877,7 +907,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
@Synchronized
fun run(isActivityRecreated: Boolean) {
fun run(isActivityRecreated: Boolean, programIndex: Int = 0) {
if (isActivityRecreated) {
if (NativeLibrary.isRunning()) {
state = State.PAUSED
@@ -888,10 +918,20 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
// If the surface is set, run now. Otherwise, wait for it to get set.
if (surface != null) {
runWithValidSurface()
runWithValidSurface(programIndex)
}
}
@Synchronized
fun changeProgram(programIndex: Int) {
emulationThread.join()
emulationThread = Thread({
Log.debug("[EmulationFragment] Starting emulation thread.")
NativeLibrary.run(gamePath, programIndex)
}, "NativeEmulation")
emulationThread.start()
}
// Surface callbacks
@Synchronized
fun newSurface(surface: Surface?) {
@@ -931,7 +971,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
}
private fun runWithValidSurface() {
private fun runWithValidSurface(programIndex: Int = 0) {
NativeLibrary.surfaceChanged(surface)
if (!emulationCanStart.invoke()) {
return
@@ -939,9 +979,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
when (state) {
State.STOPPED -> {
val emulationThread = Thread({
emulationThread = Thread({
Log.debug("[EmulationFragment] Starting emulation thread.")
NativeLibrary.run(gamePath)
NativeLibrary.run(gamePath, programIndex)
}, "NativeEmulation")
emulationThread.start()
}

View File

@@ -66,10 +66,13 @@ class DriverViewModel : ViewModel() {
fun updateDriverList() {
val selectedDriver = GpuDriverHelper.customDriverSettingData
val systemDriverData = GpuDriverHelper.getSystemDriverInfo()
val newDriverList = mutableListOf(
Driver(
selectedDriver == GpuDriverMetadata(),
YuzuApplication.appContext.getString(R.string.system_gpu_driver)
YuzuApplication.appContext.getString(R.string.system_gpu_driver),
systemDriverData?.get(0) ?: "",
systemDriverData?.get(1) ?: ""
)
)
driverData.forEach {

View File

@@ -15,6 +15,12 @@ class EmulationViewModel : ViewModel() {
val isEmulationStopping: StateFlow<Boolean> get() = _isEmulationStopping
private val _isEmulationStopping = MutableStateFlow(false)
private val _emulationStopped = MutableStateFlow(false)
val emulationStopped = _emulationStopped.asStateFlow()
private val _programChanged = MutableStateFlow(-1)
val programChanged = _programChanged.asStateFlow()
val shaderProgress: StateFlow<Int> get() = _shaderProgress
private val _shaderProgress = MutableStateFlow(0)
@@ -35,6 +41,17 @@ class EmulationViewModel : ViewModel() {
_isEmulationStopping.value = value
}
fun setEmulationStopped(value: Boolean) {
if (value) {
_emulationStarted.value = false
}
_emulationStopped.value = value
}
fun setProgramChanged(programIndex: Int) {
_programChanged.value = programIndex
}
fun setShaderProgress(progress: Int) {
_shaderProgress.value = progress
}
@@ -56,20 +73,4 @@ class EmulationViewModel : ViewModel() {
fun setDrawerOpen(value: Boolean) {
_drawerOpen.value = value
}
fun clear() {
setEmulationStarted(false)
setIsEmulationStopping(false)
setShaderProgress(0)
setTotalShaders(0)
setShaderMessage("")
}
companion object {
const val KEY_EMULATION_STARTED = "EmulationStarted"
const val KEY_IS_EMULATION_STOPPING = "IsEmulationStarting"
const val KEY_SHADER_PROGRESS = "ShaderProgress"
const val KEY_TOTAL_SHADERS = "TotalShaders"
const val KEY_SHADER_MESSAGE = "ShaderMessage"
}
}

View File

@@ -3,8 +3,10 @@
package org.yuzu.yuzu_emu.utils
import android.graphics.SurfaceTexture
import android.net.Uri
import android.os.Build
import android.view.Surface
import java.io.File
import java.io.IOException
import org.yuzu.yuzu_emu.NativeLibrary
@@ -195,6 +197,11 @@ object GpuDriverHelper {
external fun supportsCustomDriverLoading(): Boolean
external fun getSystemDriverInfo(
surface: Surface = Surface(SurfaceTexture(true)),
hookLibPath: String = GpuDriverHelper.hookLibPath!!
): Array<String>?
// Parse the custom driver metadata to retrieve the name.
val installedCustomDriverData: GpuDriverMetadata
get() = GpuDriverMetadata(File(driverInstallationPath + META_JSON_FILENAME))

View File

@@ -22,7 +22,7 @@ add_library(yuzu-android SHARED
set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common)
target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common Vulkan::Headers)
target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad jnigraphics log)
if (ARCHITECTURE_arm64)
target_link_libraries(yuzu-android PRIVATE adrenotools)

View File

@@ -19,6 +19,7 @@ static jmethodID s_exit_emulation_activity;
static jmethodID s_disk_cache_load_progress;
static jmethodID s_on_emulation_started;
static jmethodID s_on_emulation_stopped;
static jmethodID s_on_program_changed;
static jclass s_game_class;
static jmethodID s_game_constructor;
@@ -123,6 +124,10 @@ jmethodID GetOnEmulationStopped() {
return s_on_emulation_stopped;
}
jmethodID GetOnProgramChanged() {
return s_on_program_changed;
}
jclass GetGameClass() {
return s_game_class;
}
@@ -306,6 +311,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V");
s_on_emulation_stopped =
env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V");
s_on_program_changed =
env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V");
const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game");
s_game_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_class));

View File

@@ -19,6 +19,7 @@ jmethodID GetExitEmulationActivity();
jmethodID GetDiskCacheLoadProgress();
jmethodID GetOnEmulationStarted();
jmethodID GetOnEmulationStopped();
jmethodID GetOnProgramChanged();
jclass GetGameClass();
jmethodID GetGameConstructor();

View File

@@ -61,6 +61,9 @@
#include "jni/id_cache.h"
#include "jni/native.h"
#include "video_core/renderer_base.h"
#include "video_core/renderer_vulkan/renderer_vulkan.h"
#include "video_core/vulkan_common/vulkan_instance.h"
#include "video_core/vulkan_common/vulkan_surface.h"
#define jconst [[maybe_unused]] const auto
#define jauto [[maybe_unused]] auto
@@ -209,7 +212,14 @@ void EmulationSession::InitializeSystem(bool reload) {
m_system.GetFileSystemController().CreateFactories(*m_vfs);
}
Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath) {
void EmulationSession::SetAppletId(int applet_id) {
m_applet_id = applet_id;
m_system.GetFrontendAppletHolder().SetCurrentAppletId(
static_cast<Service::AM::AppletId>(m_applet_id));
}
Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath,
const std::size_t program_index) {
std::scoped_lock lock(m_mutex);
// Create the render window.
@@ -240,7 +250,8 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
// Load the ROM.
Service::AM::FrontendAppletParameters params{
.applet_id = Service::AM::AppletId::Application,
.applet_id = static_cast<Service::AM::AppletId>(m_applet_id),
.program_index = static_cast<s32>(program_index),
};
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath, params);
if (m_load_result != Core::SystemResultStatus::Success) {
@@ -252,6 +263,12 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
m_system.GetCpuManager().OnGpuReady();
m_system.RegisterExitCallback([&] { HaltEmulation(); });
// Register an ExecuteProgram callback such that Core can execute a sub-program
m_system.RegisterExecuteProgramCallback([&](std::size_t program_index_) {
m_next_program_index = program_index_;
EmulationSession::GetInstance().HaltEmulation();
});
OnEmulationStarted();
return Core::SystemResultStatus::Success;
}
@@ -259,6 +276,11 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
void EmulationSession::ShutdownEmulation() {
std::scoped_lock lock(m_mutex);
if (m_next_program_index != -1) {
ChangeProgram(m_next_program_index);
m_next_program_index = -1;
}
m_is_running = false;
// Unload user input.
@@ -327,6 +349,9 @@ void EmulationSession::RunEmulation() {
}
}
}
// Reset current applet ID.
m_applet_id = static_cast<int>(Service::AM::AppletId::Application);
}
bool EmulationSession::IsHandheldOnly() {
@@ -406,6 +431,12 @@ void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
static_cast<jint>(result));
}
void EmulationSession::ChangeProgram(std::size_t program_index) {
JNIEnv* env = IDCache::GetEnvForThread();
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnProgramChanged(),
static_cast<jint>(program_index));
}
u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
auto program_id_string = GetJString(env, jprogramId);
try {
@@ -415,7 +446,8 @@ u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
}
}
static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
static Core::SystemResultStatus RunEmulation(const std::string& filepath,
const size_t program_index = 0) {
MicroProfileOnThreadCreate("EmuThread");
SCOPE_EXIT({ MicroProfileShutdown(); });
@@ -428,7 +460,7 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); });
jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath);
jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index);
if (result != Core::SystemResultStatus::Success) {
return result;
}
@@ -525,6 +557,37 @@ jboolean JNICALL Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_supportsCustomDri
#endif
}
jobjectArray Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getSystemDriverInfo(
JNIEnv* env, jobject j_obj, jobject j_surf, jstring j_hook_lib_dir) {
const char* file_redirect_dir_{};
int featureFlags{};
std::string hook_lib_dir = GetJString(env, j_hook_lib_dir);
auto handle = adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
nullptr, nullptr, file_redirect_dir_, nullptr);
auto driver_library = std::make_shared<Common::DynamicLibrary>(handle);
InputCommon::InputSubsystem input_subsystem;
auto m_window = std::make_unique<EmuWindow_Android>(
&input_subsystem, ANativeWindow_fromSurface(env, j_surf), driver_library);
Vulkan::vk::InstanceDispatch dld;
Vulkan::vk::Instance vk_instance = Vulkan::CreateInstance(
*driver_library, dld, VK_API_VERSION_1_1, Core::Frontend::WindowSystemType::Android);
auto surface = Vulkan::CreateSurface(vk_instance, m_window->GetWindowInfo());
auto device = Vulkan::CreateDevice(vk_instance, dld, *surface);
auto driver_version = device.GetDriverVersion();
auto version_string =
fmt::format("{}.{}.{}", VK_API_VERSION_MAJOR(driver_version),
VK_API_VERSION_MINOR(driver_version), VK_API_VERSION_PATCH(driver_version));
jobjectArray j_driver_info =
env->NewObjectArray(2, IDCache::GetStringClass(), ToJString(env, version_string));
env->SetObjectArrayElement(j_driver_info, 1, ToJString(env, device.GetDriverName()));
return j_driver_info;
}
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env, jclass clazz) {
Core::Crypto::KeyManager::Instance().ReloadKeys();
return static_cast<jboolean>(Core::Crypto::KeyManager::Instance().AreKeysLoaded());
@@ -693,11 +756,11 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_logSettings(JNIEnv* env, jobject jobj
Settings::LogSettings();
}
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2(JNIEnv* env, jclass clazz,
jstring j_path) {
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run(JNIEnv* env, jobject jobj, jstring j_path,
jint j_program_index) {
const std::string path = GetJString(env, j_path);
const Core::SystemResultStatus result{RunEmulation(path)};
const Core::SystemResultStatus result{RunEmulation(path, j_program_index)};
if (result != Core::SystemResultStatus::Success) {
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
IDCache::GetExitEmulationActivity(), static_cast<int>(result));
@@ -759,8 +822,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletLaunchPath(JNIEnv* env, j
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentAppletId(JNIEnv* env, jclass clazz,
jint jappletId) {
EmulationSession::GetInstance().System().GetFrontendAppletHolder().SetCurrentAppletId(
static_cast<Service::AM::AppletId>(jappletId));
EmulationSession::GetInstance().SetAppletId(jappletId);
}
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass clazz,

View File

@@ -45,7 +45,9 @@ public:
const Core::PerfStatsResults& PerfStats();
void ConfigureFilesystemProvider(const std::string& filepath);
void InitializeSystem(bool reload);
Core::SystemResultStatus InitializeEmulation(const std::string& filepath);
void SetAppletId(int applet_id);
Core::SystemResultStatus InitializeEmulation(const std::string& filepath,
const std::size_t program_index = 0);
bool IsHandheldOnly();
void SetDeviceType([[maybe_unused]] int index, int type);
@@ -60,6 +62,7 @@ public:
private:
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max);
static void OnEmulationStopped(Core::SystemResultStatus result);
static void ChangeProgram(std::size_t program_index);
private:
// Window management
@@ -77,6 +80,7 @@ private:
std::atomic<bool> m_is_paused = false;
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
int m_applet_id{1};
// GPU driver parameters
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
@@ -84,4 +88,7 @@ private:
// Synchronization
std::condition_variable_any m_cv;
mutable std::mutex m_mutex;
// Program index for next boot
std::atomic<s32> m_next_program_index = -1;
};

View File

@@ -34,8 +34,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:focusable="false"
android:defaultFocusHighlightEnabled="false"
android:clickable="false">
android:clickable="false"
app:rippleColor="@android:color/transparent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/loading_layout"

View File

@@ -221,6 +221,7 @@ void AppletManager::InsertApplet(std::shared_ptr<Applet> applet) {
void AppletManager::TerminateAndRemoveApplet(AppletResourceUserId aruid) {
std::shared_ptr<Applet> applet;
bool should_stop = false;
{
std::scoped_lock lk{m_lock};
@@ -231,10 +232,17 @@ void AppletManager::TerminateAndRemoveApplet(AppletResourceUserId aruid) {
applet = it->second;
m_applets.erase(it);
should_stop = m_applets.empty();
}
// Terminate process.
applet->process->Terminate();
// If there were no applets left, stop emulation.
if (should_stop) {
m_system.Exit();
}
}
void AppletManager::CreateAndInsertByFrontendAppletParameters(

View File

@@ -60,13 +60,12 @@ void IDisplayController::GetCallerAppletCaptureImageEx(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
OutputParameters params{};
const auto res = applet->system_buffer_manager.WriteApplicationCaptureBuffer(
const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer(
&params.was_written, &params.fbshare_layer_index);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(res);
rb.Push(params.was_written);
rb.Push(params.fbshare_layer_index);
rb.PushRaw(params);
}
void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
@@ -80,13 +79,12 @@ void IDisplayController::AcquireLastApplicationCaptureSharedBuffer(HLERequestCon
LOG_WARNING(Service_AM, "(STUBBED) called");
OutputParameters params{};
const auto res = applet->system_buffer_manager.WriteApplicationCaptureBuffer(
const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer(
&params.was_written, &params.fbshare_layer_index);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(res);
rb.Push(params.was_written);
rb.Push(params.fbshare_layer_index);
rb.PushRaw(params);
}
void IDisplayController::ReleaseLastApplicationCaptureSharedBuffer(HLERequestContext& ctx) {
@@ -100,13 +98,12 @@ void IDisplayController::AcquireLastForegroundCaptureSharedBuffer(HLERequestCont
LOG_WARNING(Service_AM, "(STUBBED) called");
OutputParameters params{};
const auto res = applet->system_buffer_manager.WriteApplicationCaptureBuffer(
const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer(
&params.was_written, &params.fbshare_layer_index);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(res);
rb.Push(params.was_written);
rb.Push(params.fbshare_layer_index);
rb.PushRaw(params);
}
void IDisplayController::ReleaseLastForegroundCaptureSharedBuffer(HLERequestContext& ctx) {
@@ -120,13 +117,12 @@ void IDisplayController::AcquireCallerAppletCaptureSharedBuffer(HLERequestContex
LOG_WARNING(Service_AM, "(STUBBED) called");
OutputParameters params{};
const auto res = applet->system_buffer_manager.WriteApplicationCaptureBuffer(
const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer(
&params.was_written, &params.fbshare_layer_index);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(res);
rb.Push(params.was_written);
rb.Push(params.fbshare_layer_index);
rb.PushRaw(params);
}
void IDisplayController::ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) {

View File

@@ -115,15 +115,10 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
}
std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system,
std::shared_ptr<Applet> caller_applet,
AppletId applet_id,
LibraryAppletMode mode) {
[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(
Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id,
LibraryAppletMode mode) {
const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
if (program_id == 0) {
// Unknown applet
return {};
}
auto process = std::make_unique<Process>(system);
auto applet = std::make_shared<Applet>(system, std::move(process));

View File

@@ -60,8 +60,8 @@ void SystemBufferManager::SetWindowVisibility(bool visible) {
}
}
Result SystemBufferManager::WriteApplicationCaptureBuffer(bool* out_was_written,
s32* out_fbshare_layer_index) {
Result SystemBufferManager::WriteAppletCaptureBuffer(bool* out_was_written,
s32* out_fbshare_layer_index) {
// TODO
R_SUCCEED();
}

View File

@@ -37,7 +37,7 @@ public:
void SetWindowVisibility(bool visible);
Result WriteApplicationCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index);
Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index);
private:
Kernel::KProcess* m_process{};

View File

@@ -137,7 +137,7 @@ void NpadAbstractPropertiesHandler::UpdateAllDeviceProperties() {
const auto npad_index = NpadIdTypeToIndex(npad_id_type);
for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) {
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid_index);
if (!data->flag.is_assigned) {
if (data == nullptr || !data->flag.is_assigned) {
continue;
}
auto& npad_entry = data->shared_memory_format->npad.npad_entry[npad_index];