This commit is contained in:
SSimco
2025-06-25 17:10:37 +03:00
parent f14536635c
commit b20a0a1374
13 changed files with 96 additions and 49 deletions
@@ -68,6 +68,7 @@ class AArch64Allocator : public Allocator
#else
inline static Allocator s_allocator;
#endif
inline static std::mutex s_allocatorMutex;
Allocator* m_allocatorImpl;
bool m_freeDisabled = false;
@@ -77,6 +78,7 @@ class AArch64Allocator : public Allocator
uint32* alloc(size_t size) override
{
std::lock_guard lock{s_allocatorMutex};
return m_allocatorImpl->alloc(size);
}
@@ -87,8 +89,11 @@ class AArch64Allocator : public Allocator
void free(uint32* p) override
{
if (!m_freeDisabled)
m_allocatorImpl->free(p);
if (m_freeDisabled)
return;
std::lock_guard lock{s_allocatorMutex};
m_allocatorImpl->free(p);
}
[[nodiscard]] bool useProtect() const override
@@ -2097,10 +2097,10 @@ void VulkanRenderer::SubmitCommandBuffer(VkSemaphore signalSemaphore, VkSemaphor
const VkPipelineStageFlags semWaitStageMask[2] = { VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
VkSemaphore waitSemArray[2];
submitInfo.waitSemaphoreCount = 0;
if (m_numSubmittedCmdBuffers > 0)
waitSemArray[submitInfo.waitSemaphoreCount++] = prevSem; // wait on semaphore from previous submit
if (waitSemaphore != VK_NULL_HANDLE)
waitSemArray[submitInfo.waitSemaphoreCount++] = waitSemaphore;
if (m_numSubmittedCmdBuffers > 0)
waitSemArray[submitInfo.waitSemaphoreCount++] = prevSem; // wait on semaphore from previous submit
submitInfo.pWaitDstStageMask = semWaitStageMask;
submitInfo.pWaitSemaphores = waitSemArray;
+1 -1
View File
@@ -7,7 +7,7 @@
#define _XSTRINGFY(s) _STRINGFY(s)
#define _STRINGFY(s) #s
#if EMULATOR_VERSION_MAJOR != 0
#if EMULATOR_VERSION_MAJOR != 0 || EMULATOR_VERSION_MINOR != 0
#define BUILD_VERSION_WITH_NAME_STRING (EMULATOR_NAME " " _XSTRINGFY(EMULATOR_VERSION_MAJOR) "." _XSTRINGFY(EMULATOR_VERSION_MINOR) EMULATOR_VERSION_SUFFIX)
#define BUILD_VERSION_STRING (_XSTRINGFY(EMULATOR_VERSION_MAJOR) "." _XSTRINGFY(EMULATOR_VERSION_MINOR) EMULATOR_VERSION_SUFFIX)
#else
+6 -6
View File
@@ -90,7 +90,7 @@ android {
debug {
applicationIdSuffix = ".debug"
}
create("githubRelease") {
create("github") {
if (keystoreFilePath != null) {
initWith(getByName("release"))
isMinifyEnabled = true
@@ -177,16 +177,16 @@ abstract class ComputeCemuDataFilesHashTask : DefaultTask() {
assetDir.mkdirs()
}
val cemuDataFilesFile = File(project.projectDir, cemuDataFolder.get())
val cemuDataFilesDir = File(project.projectDir, cemuDataFolder.get())
val hashFile = File(assetDir, "hash.txt")
val md = MessageDigest.getInstance("SHA-256")
if (!cemuDataFilesFile.isDirectory) {
if (!cemuDataFilesDir.isDirectory) {
hashFile.writeText("invalid")
return
}
val fileHashes = cemuDataFilesFile.walkTopDown()
val fileHashes = cemuDataFilesDir.walkTopDown()
.filter { it.isFile && !isFileIgnored(it) }
.sortedBy { it.path }
.map {
@@ -204,10 +204,10 @@ abstract class ComputeCemuDataFilesHashTask : DefaultTask() {
}
}
tasks.register<ComputeCemuDataFilesHashTask>("computeCemuDataFilesHash") {
val computeCemuDataFilesHashTask =tasks.register<ComputeCemuDataFilesHashTask>("computeCemuDataFilesHash") {
cemuDataFolder = cemuDataFilesFolder
}
tasks.preBuild.dependsOn("computeCemuDataFilesHash")
tasks.preBuild.dependsOn(computeCemuDataFilesHashTask)
dependencies {
implementation(libs.androidx.lifecycle.runtime.ktx)
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application tools:remove="android:icon,android:roundIcon" />
</manifest>
@@ -87,11 +87,3 @@ jobject JNIUtils::createJavaStringArrayList(JNIEnv* env, const std::vector<std::
}
return arrayListObject;
}
void JNIUtils::fiberSafeJNICall(const std::function<void(JNIEnv*)>& func)
{
std::thread([&]() {
ScopedJNIENV env;
func(*env);
}).join();
}
+7 -1
View File
@@ -191,5 +191,11 @@ namespace JNIUtils
return obj;
}
void fiberSafeJNICall(const std::function<void(JNIEnv*)>& func);
inline void fiberSafeJNICall(const std::function<void(JNIEnv*)>& func)
{
std::thread([&]() {
ScopedJNIENV env;
func(*env);
}).join();
}
} // namespace JNIUtils
@@ -348,7 +348,6 @@ Java_info_cemu_cemu_nativeinterface_NativeSettings_getCustomDriverPath(JNIEnv* e
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
Java_info_cemu_cemu_nativeinterface_NativeSettings_setCustomDriverPath(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring custom_driver_path)
{
throw std::runtime_error("todo");
g_config.data().custom_driver_path = JNIUtils::toString(env, custom_driver_path);
}
@@ -21,15 +21,7 @@ void WuaConverter::startConversion(int fd, std::unique_ptr<CompressTitleCallback
callbacks->onError();
return;
}
struct ScopedFd
{
int fd;
~ScopedFd()
{
close(fd);
}
} scopedFd{.fd = fd};
stdx::scope_exit fdCleanup([fd](){ close(fd); });
if (m_started)
return;
@@ -27,23 +27,26 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.documentfile.provider.DocumentFile
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
import info.cemu.cemu.about.AboutCemuRoute
import info.cemu.cemu.about.aboutCemuNavigation
import info.cemu.cemu.emulation.EmulationActivity
import info.cemu.cemu.provider.DocumentsProvider
import info.cemu.cemu.gamelist.GameListRoute
import info.cemu.cemu.gamelist.gameListNavigation
import info.cemu.cemu.graphicpacks.GraphicPacksRoute
import info.cemu.cemu.graphicpacks.graphicPacksNavigation
import info.cemu.cemu.guicore.components.ActivityContent
import info.cemu.cemu.nativeinterface.NativeActiveSettings
import info.cemu.cemu.nativeinterface.NativeGameTitles.Game
import info.cemu.cemu.nativeinterface.NativeSettings
import info.cemu.cemu.provider.DocumentsProvider
import info.cemu.cemu.settings.SettingsRoute
import info.cemu.cemu.settings.settingsNavigation
import info.cemu.cemu.titlemanager.TitleManagerRoute
import info.cemu.cemu.titlemanager.titleManagerNavigation
import java.io.File
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -55,6 +58,11 @@ class MainActivity : ComponentActivity() {
}
}
override fun onDestroy() {
super.onDestroy()
NativeSettings.saveSettings()
}
override fun onPause() {
super.onPause()
NativeSettings.saveSettings()
@@ -123,7 +131,7 @@ private fun GameListToolBarActionsMenu(
) {
Icon(
imageVector = Icons.Filled.MoreVert,
contentDescription = "More options"
contentDescription = stringResource(R.string.more_options)
)
}
DropdownMenu(
@@ -146,6 +154,10 @@ private fun GameListToolBarActionsMenu(
onClick = { openCemuFolder(context) },
text = stringResource(R.string.open_cemu_folder)
)
DropdownMenuItem(
onClick = { shareLogFile(context) },
text = stringResource(R.string.log_file_share_label),
)
DropdownMenuItem(
onClick = goToAboutCemu,
text = stringResource(R.string.about_cemu),
@@ -153,22 +165,45 @@ private fun GameListToolBarActionsMenu(
}
}
private fun shareLogFile(context: Context) {
val logFileName = "log.txt"
val logFile = File(NativeActiveSettings.getUserDataPath()).resolve(logFileName)
if (!logFile.isFile) {
Toast.makeText(context, R.string.log_file_not_available, Toast.LENGTH_LONG).show()
return
}
val fileUri = DocumentsContract.buildDocumentUri(
DocumentsProvider.AUTHORITY,
DocumentsProvider.ROOT_ID + "/$logFileName"
)
val documentFile = DocumentFile.fromSingleUri(context, fileUri) ?: return
val intent = Intent(Intent.ACTION_SEND)
.setDataAndType(documentFile.uri, "text/plain")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
.putExtra(Intent.EXTRA_STREAM, documentFile.uri)
context.startActivity(Intent.createChooser(intent, null))
}
private fun openCemuFolder(context: Context) {
try {
Intent(Intent.ACTION_VIEW).apply {
addCategory(Intent.CATEGORY_DEFAULT)
data = DocumentsContract.buildRootUri(
DocumentsProvider.AUTHORITY,
DocumentsProvider.ROOT_ID
)
addFlags(
val intent = Intent(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_DEFAULT)
.addFlags(
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
or Intent.FLAG_GRANT_READ_URI_PERMISSION
or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
context.startActivity(this@apply)
}
intent.data = DocumentsContract.buildRootUri(
DocumentsProvider.AUTHORITY,
DocumentsProvider.ROOT_ID
)
context.startActivity(intent)
} catch (activityNotFoundException: ActivityNotFoundException) {
Toast.makeText(context, R.string.failed_to_open_cemu_folder, Toast.LENGTH_LONG).show()
}
@@ -12,6 +12,7 @@ import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.LinearLayout
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
@@ -119,6 +120,9 @@ class EmulationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
emulationActivityInstance = WeakReference(this)
overlaySettings = InputOverlaySettingsManager(this).overlaySettings
@@ -189,7 +193,9 @@ class EmulationActivity : AppCompatActivity() {
}
}
private fun LayoutSideMenuEmulationBinding.configureSideMenu(isInputOverlayEnabled: Boolean) {
private fun LayoutSideMenuEmulationBinding.configureSideMenu() {
val isInputOverlayEnabled = overlaySettings.isOverlayEnabled
enableMotionCheckbox.configure(onCheckChanged = ::setMotionEnabled)
replaceTvWithPadCheckbox.configure(onCheckChanged = NativeEmulation::setReplaceTVWithPadView)
showPadCheckbox.configure(onCheckChanged = ::setPadViewVisibility)
@@ -217,7 +223,9 @@ class EmulationActivity : AppCompatActivity() {
binding = ActivityEmulationBinding.inflate(layoutInflater)
inputOverlaySurfaceView = binding.inputOverlay
binding.sideMenu.configureSideMenu(overlaySettings.isOverlayEnabled)
inputOverlaySurfaceView.setVisible(overlaySettings.isOverlayEnabled)
binding.sideMenu.configureSideMenu()
binding.moveInputsButton.setOnClickListener { _ ->
if (inputOverlaySurfaceView.getInputMode() == InputOverlaySurfaceView.InputMode.EDIT_POSITION) {
@@ -416,6 +424,7 @@ class EmulationActivity : AppCompatActivity() {
}
val parentTextInputLayout =
inputEditTextLayout.requireViewById<TextInputLayout>(R.id.emulation_input_layout)
if (maxLength > 0) {
parentTextInputLayout.isCounterEnabled = true
parentTextInputLayout.counterMaxLength = maxLength
@@ -423,6 +432,7 @@ class EmulationActivity : AppCompatActivity() {
} else {
parentTextInputLayout.isCounterEnabled = false
}
emulationActivity.emulationTextInputDialog = dialog
}
}
@@ -30,12 +30,12 @@ fun GraphicsSettingsScreen(navigateBack: () -> Unit, goToCustomDriversSettings:
appBarText = stringResource(R.string.general_settings),
navigateBack = navigateBack,
) {
// if (supportsLoadingCustomDrivers) {
// Button(
// label = stringResource(R.string.custom_drivers),
// onClick = goToCustomDriversSettings
// )
// }
if (supportsLoadingCustomDrivers) {
Button(
label = stringResource(R.string.custom_drivers),
onClick = goToCustomDriversSettings
)
}
Toggle(
label = stringResource(R.string.async_shader_compile),
description = stringResource(R.string.async_shader_compile_description),
@@ -337,4 +337,6 @@
<string name="controller_select_dialog_title">Select a controller</string>
<string name="side_menu_button">Side menu button</string>
<string name="side_menu_button_description">Show the emulation side menu button</string>
<string name="log_file_not_available">Log file doesn\'t exist</string>
<string name="log_file_share_label">Share log file</string>
</resources>