From bb003c2bd46043c71b7287940a576029de2b7bd1 Mon Sep 17 00:00:00 2001 From: SachinVin <26602104+SachinVin@users.noreply.github.com> Date: Sat, 17 Feb 2024 06:42:54 +0530 Subject: [PATCH 1/5] audio_core\hle\source.cpp: Improve accuracy of SourceStatus (#7432) --- src/audio_core/hle/source.cpp | 30 ++++++++++++++++++++---------- src/audio_core/hle/source.h | 6 ++---- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/audio_core/hle/source.cpp b/src/audio_core/hle/source.cpp index 54a28bee3..d3fbfd0cb 100644 --- a/src/audio_core/hle/source.cpp +++ b/src/audio_core/hle/source.cpp @@ -298,9 +298,9 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config, b.buffer_id, state.mono_or_stereo, state.format, - true, - {}, // 0 in u32_dsp - false, + true, // from_queue + 0, // play_position + false, // has_played }); } LOG_TRACE(Audio_DSP, "enqueuing queued {} addr={:#010x} len={} id={}", i, @@ -321,7 +321,11 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config, void Source::GenerateFrame() { current_frame.fill({}); - if (state.current_buffer.empty() && !DequeueBuffer()) { + if (state.current_buffer.empty()) { + // TODO(SachinV): Should dequeue happen at the end of the frame generation? + if (DequeueBuffer()) { + return; + } state.enabled = false; state.buffer_update = true; state.last_buffer_id = state.current_buffer_id; @@ -330,8 +334,6 @@ void Source::GenerateFrame() { } std::size_t frame_position = 0; - - state.current_sample_number = state.next_sample_number; while (frame_position < current_frame.size()) { if (state.current_buffer.empty() && !DequeueBuffer()) { break; @@ -358,7 +360,7 @@ void Source::GenerateFrame() { } // TODO(jroweboy): Keep track of frame_position independently so that it doesn't lose precision // over time - state.next_sample_number += static_cast(frame_position * state.rate_multiplier); + state.current_sample_number += static_cast(frame_position * state.rate_multiplier); state.filters.ProcessFrame(current_frame); } @@ -409,7 +411,6 @@ bool Source::DequeueBuffer() { // the first playthrough starts at play_position, loops start at the beginning of the buffer state.current_sample_number = (!buf.has_played) ? buf.play_position : 0; - state.next_sample_number = state.current_sample_number; state.current_buffer_physical_address = buf.physical_address; state.current_buffer_id = buf.buffer_id; state.last_buffer_id = 0; @@ -420,8 +421,17 @@ bool Source::DequeueBuffer() { state.input_queue.push(buf); } - LOG_TRACE(Audio_DSP, "source_id={} buffer_id={} from_queue={} current_buffer.size()={}", - source_id, buf.buffer_id, buf.from_queue, state.current_buffer.size()); + // Because our interpolation consumes samples instead of using an index, + // let's just consume the samples up to the current sample number. + state.current_buffer.erase( + state.current_buffer.begin(), + std::next(state.current_buffer.begin(), state.current_sample_number)); + + LOG_TRACE(Audio_DSP, + "source_id={} buffer_id={} from_queue={} current_buffer.size()={}, " + "buf.has_played={}, buf.play_position={}", + source_id, buf.buffer_id, buf.from_queue, state.current_buffer.size(), buf.has_played, + buf.play_position); return true; } diff --git a/src/audio_core/hle/source.h b/src/audio_core/hle/source.h index a3af06d27..d7114952b 100644 --- a/src/audio_core/hle/source.h +++ b/src/audio_core/hle/source.h @@ -87,8 +87,8 @@ private: Format format; bool from_queue; - u32_dsp play_position; // = 0; - bool has_played; // = false; + u32 play_position; // = 0; + bool has_played; // = false; private: template @@ -136,7 +136,6 @@ private: // Current buffer u32 current_sample_number = 0; - u32 next_sample_number = 0; PAddr current_buffer_physical_address = 0; AudioInterp::StereoBuffer16 current_buffer = {}; @@ -171,7 +170,6 @@ private: ar& mono_or_stereo; ar& format; ar& current_sample_number; - ar& next_sample_number; ar& current_buffer_physical_address; ar& current_buffer; ar& buffer_update; From 749a721aa28ed0aa3aba85ff014324ba824cdc8c Mon Sep 17 00:00:00 2001 From: Castor215 <132155746+Castor215@users.noreply.github.com> Date: Sat, 17 Feb 2024 14:39:38 +0000 Subject: [PATCH 2/5] externals: disable system cpp-httplib if it is a shared object (#7446) Co-authored-by: Castor216 --- externals/CMakeLists.txt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 5f4c23ad3..fc45473b6 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -294,11 +294,20 @@ endif() add_library(httplib INTERFACE) if(USE_SYSTEM_CPP_HTTPLIB) find_package(CppHttp 0.14.1) - if(CppHttp_FOUND) - target_link_libraries(httplib INTERFACE httplib::httplib) - else() - message(STATUS "Cpp-httplib not found or not suitable version! Falling back to bundled...") + # Detect if system cpphttplib is a shared library + # this breaks building as Citra relies on functions that are moved + # into the shared object. + get_target_property(HTTP_LIBS httplib::httplib INTERFACE_LINK_LIBRARIES) + if(HTTP_LIBS) + message(WARNING "Shared cpp-http (${HTTP_LIBS}) not supported. Falling back to bundled...") target_include_directories(httplib SYSTEM INTERFACE ./httplib) + else() + if(CppHttp_FOUND) + target_link_libraries(httplib INTERFACE httplib::httplib) + else() + message(STATUS "Cpp-httplib not found or not suitable version! Falling back to bundled...") + target_include_directories(httplib SYSTEM INTERFACE ./httplib) + endif() endif() else() target_include_directories(httplib SYSTEM INTERFACE ./httplib) From da5aa70fc940c3f0feec3bf83acab233c84966d7 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Sat, 17 Feb 2024 23:10:10 -0500 Subject: [PATCH 3/5] android: Port yuzu system info logging (#7431) --- .../org/citra/citra_emu/CitraApplication.kt | 14 +++ .../java/org/citra/citra_emu/NativeLibrary.kt | 4 +- .../utils/DirectoryInitialization.kt | 6 +- .../java/org/citra/citra_emu/utils/Log.kt | 27 +---- .../org/citra/citra_emu/utils/MemoryUtil.kt | 108 ++++++++++++++++++ src/android/app/src/main/jni/CMakeLists.txt | 1 + src/android/app/src/main/jni/native_log.cpp | 30 +++++ .../app/src/main/res/values/strings.xml | 11 ++ 8 files changed, 174 insertions(+), 27 deletions(-) create mode 100644 src/android/app/src/main/java/org/citra/citra_emu/utils/MemoryUtil.kt create mode 100644 src/android/app/src/main/jni/native_log.cpp diff --git a/src/android/app/src/main/java/org/citra/citra_emu/CitraApplication.kt b/src/android/app/src/main/java/org/citra/citra_emu/CitraApplication.kt index c414d4246..75a88baf1 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/CitraApplication.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/CitraApplication.kt @@ -9,10 +9,13 @@ import android.app.Application import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context +import android.os.Build import org.citra.citra_emu.utils.DirectoryInitialization import org.citra.citra_emu.utils.DocumentsTree import org.citra.citra_emu.utils.GpuDriverHelper import org.citra.citra_emu.utils.PermissionsHandler +import org.citra.citra_emu.utils.Log +import org.citra.citra_emu.utils.MemoryUtil class CitraApplication : Application() { private fun createNotificationChannel() { @@ -53,9 +56,20 @@ class CitraApplication : Application() { } NativeLibrary.logDeviceInfo() + logDeviceInfo() createNotificationChannel() } + fun logDeviceInfo() { + Log.info("Device Manufacturer - ${Build.MANUFACTURER}") + Log.info("Device Model - ${Build.MODEL}") + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) { + Log.info("SoC Manufacturer - ${Build.SOC_MANUFACTURER}") + Log.info("SoC Model - ${Build.SOC_MODEL}") + } + Log.info("Total System Memory - ${MemoryUtil.getDeviceRAM()}") + } + companion object { private var application: CitraApplication? = null diff --git a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt index 75150fd16..bfbe658f8 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt @@ -413,12 +413,12 @@ object NativeLibrary { } fun setEmulationActivity(emulationActivity: EmulationActivity?) { - Log.verbose("[NativeLibrary] Registering EmulationActivity.") + Log.debug("[NativeLibrary] Registering EmulationActivity.") sEmulationActivity = WeakReference(emulationActivity) } fun clearEmulationActivity() { - Log.verbose("[NativeLibrary] Unregistering EmulationActivity.") + Log.debug("[NativeLibrary] Unregistering EmulationActivity.") sEmulationActivity.clear() } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/DirectoryInitialization.kt index 10e509f23..c48f9d22e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/DirectoryInitialization.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/DirectoryInitialization.kt @@ -94,14 +94,14 @@ object DirectoryInitialization { val dataPath = PermissionsHandler.citraDirectory if (dataPath.toString().isNotEmpty()) { userPath = dataPath.toString() - Log.debug("[DirectoryInitialization] User Dir: $userPath") + android.util.Log.d("[Citra Frontend]", "[DirectoryInitialization] User Dir: $userPath") return true } return false } private fun copyAsset(asset: String, output: File, overwrite: Boolean, context: Context) { - Log.verbose("[DirectoryInitialization] Copying File $asset to $output") + Log.debug("[DirectoryInitialization] Copying File $asset to $output") try { if (!output.exists() || overwrite) { val inputStream = context.assets.open(asset) @@ -121,7 +121,7 @@ object DirectoryInitialization { overwrite: Boolean, context: Context ) { - Log.verbose("[DirectoryInitialization] Copying Folder $assetFolder to $outputFolder") + Log.debug("[DirectoryInitialization] Copying Folder $assetFolder to $outputFolder") try { var createdFolder = false for (file in context.assets.list(assetFolder)!!) { diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/Log.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/Log.kt index 26c41bc98..f691d51b0 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/Log.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/Log.kt @@ -4,34 +4,17 @@ package org.citra.citra_emu.utils -import android.util.Log -import org.citra.citra_emu.BuildConfig - -/** - * Contains methods that call through to [android.util.Log], but - * with the same TAG automatically provided. Also no-ops VERBOSE and DEBUG log - * levels in release builds. - */ object Log { // Tracks whether we should share the old log or the current log var gameLaunched = false - private const val TAG = "Citra Frontend" - fun verbose(message: String?) { - if (BuildConfig.DEBUG) { - Log.v(TAG, message!!) - } - } + external fun debug(message: String) - fun debug(message: String?) { - if (BuildConfig.DEBUG) { - Log.d(TAG, message!!) - } - } + external fun warning(message: String) - fun info(message: String?) = Log.i(TAG, message!!) + external fun info(message: String) - fun warning(message: String?) = Log.w(TAG, message!!) + external fun error(message: String) - fun error(message: String?) = Log.e(TAG, message!!) + external fun critical(message: String) } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/MemoryUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/MemoryUtil.kt new file mode 100644 index 000000000..4bf1d88c7 --- /dev/null +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/MemoryUtil.kt @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.citra.citra_emu.utils + +import android.app.ActivityManager +import android.content.Context +import android.os.Build +import org.citra.citra_emu.CitraApplication +import org.citra.citra_emu.R +import java.util.Locale +import kotlin.math.ceil + +object MemoryUtil { + private val context get() = CitraApplication.appContext + + private val Float.hundredths: String + get() = String.format(Locale.ROOT, "%.2f", this) + + const val Kb: Float = 1024F + const val Mb = Kb * 1024 + const val Gb = Mb * 1024 + const val Tb = Gb * 1024 + const val Pb = Tb * 1024 + const val Eb = Pb * 1024 + + fun bytesToSizeUnit(size: Float, roundUp: Boolean = false): String = + when { + size < Kb -> { + context.getString( + R.string.memory_formatted, + size.hundredths, + context.getString(R.string.memory_byte_shorthand) + ) + } + size < Mb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Kb) else (size / Kb).hundredths, + context.getString(R.string.memory_kilobyte) + ) + } + size < Gb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Mb) else (size / Mb).hundredths, + context.getString(R.string.memory_megabyte) + ) + } + size < Tb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Gb) else (size / Gb).hundredths, + context.getString(R.string.memory_gigabyte) + ) + } + size < Pb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Tb) else (size / Tb).hundredths, + context.getString(R.string.memory_terabyte) + ) + } + size < Eb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Pb) else (size / Pb).hundredths, + context.getString(R.string.memory_petabyte) + ) + } + else -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Eb) else (size / Eb).hundredths, + context.getString(R.string.memory_exabyte) + ) + } + } + + val totalMemory: Float + get() { + val memInfo = ActivityManager.MemoryInfo() + with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) { + getMemoryInfo(memInfo) + } + + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + memInfo.advertisedMem.toFloat() + } else { + memInfo.totalMem.toFloat() + } + } + + fun isLessThan(minimum: Int, size: Float): Boolean = + when (size) { + Kb -> totalMemory < Mb && totalMemory < minimum + Mb -> totalMemory < Gb && (totalMemory / Mb) < minimum + Gb -> totalMemory < Tb && (totalMemory / Gb) < minimum + Tb -> totalMemory < Pb && (totalMemory / Tb) < minimum + Pb -> totalMemory < Eb && (totalMemory / Pb) < minimum + Eb -> totalMemory / Eb < minimum + else -> totalMemory < Kb && totalMemory < minimum + } + + // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for + // the potential error created by memInfo.totalMem + fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory, true) +} diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt index 84a34441a..233d568ed 100644 --- a/src/android/app/src/main/jni/CMakeLists.txt +++ b/src/android/app/src/main/jni/CMakeLists.txt @@ -28,6 +28,7 @@ add_library(citra-android SHARED ndk_motion.cpp ndk_motion.h system_save_game.cpp + native_log.cpp ) target_link_libraries(citra-android PRIVATE audio_core citra_common citra_core input_common network) diff --git a/src/android/app/src/main/jni/native_log.cpp b/src/android/app/src/main/jni/native_log.cpp new file mode 100644 index 000000000..86a57b99f --- /dev/null +++ b/src/android/app/src/main/jni/native_log.cpp @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "android_common/android_common.h" + +extern "C" { + +void Java_org_citra_citra_1emu_utils_Log_debug(JNIEnv* env, jobject obj, jstring jmessage) { + LOG_DEBUG(Frontend, "{}", GetJString(env, jmessage)); +} + +void Java_org_citra_citra_1emu_utils_Log_warning(JNIEnv* env, jobject obj, jstring jmessage) { + LOG_WARNING(Frontend, "{}", GetJString(env, jmessage)); +} + +void Java_org_citra_citra_1emu_utils_Log_info(JNIEnv* env, jobject obj, jstring jmessage) { + LOG_INFO(Frontend, "{}", GetJString(env, jmessage)); +} + +void Java_org_citra_citra_1emu_utils_Log_error(JNIEnv* env, jobject obj, jstring jmessage) { + LOG_ERROR(Frontend, "{}", GetJString(env, jmessage)); +} + +void Java_org_citra_citra_1emu_utils_Log_critical(JNIEnv* env, jobject obj, jstring jmessage) { + LOG_CRITICAL(Frontend, "{}", GetJString(env, jmessage)); +} + +} // extern "C" diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 303632162..781e78da1 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -442,6 +442,17 @@ \"%s\" must be decrypted before being used with Citra.\n A real 3DS is required An unknown error occurred while installing \"%s\".\n Please see the log for more details + + %1$s %2$s + Byte + B + KB + MB + GB + TB + PB + EB + Change Theme Mode Follow System From cbe898703631b404dfc430a60050fd8d0956a62f Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Sun, 18 Feb 2024 08:23:15 -0800 Subject: [PATCH 4/5] ci: Update action versions. (#7449) --- .github/workflows/build.yml | 42 ++++++++++++++++----------------- .github/workflows/format.yml | 2 +- .github/workflows/publish.yml | 16 ++++++------- .github/workflows/transifex.yml | 2 +- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad0665c5b..b848e93d5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,13 +12,13 @@ jobs: if: ${{ !github.head_ref }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - name: Pack run: ./.ci/source.sh - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: source path: artifacts/ @@ -37,11 +37,11 @@ jobs: OS: linux TARGET: ${{ matrix.target }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - name: Set up cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ env.CCACHE_DIR }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} @@ -53,7 +53,7 @@ jobs: run: ./.ci/pack.sh if: ${{ matrix.target == 'appimage' }} - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ matrix.target == 'appimage' }} with: name: ${{ env.OS }}-${{ env.TARGET }} @@ -70,11 +70,11 @@ jobs: OS: macos TARGET: ${{ matrix.target }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - name: Set up cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ env.CCACHE_DIR }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} @@ -87,7 +87,7 @@ jobs: - name: Prepare outputs for caching run: mv build/bundle $OS-$TARGET - name: Cache outputs for universal build - uses: actions/cache/save@v3 + uses: actions/cache/save@v4 with: path: ${{ env.OS }}-${{ env.TARGET }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} @@ -98,15 +98,15 @@ jobs: OS: macos TARGET: universal steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Download x86_64 build from cache - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: ${{ env.OS }}-x86_64 key: ${{ runner.os }}-x86_64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} fail-on-cache-miss: true - name: Download ARM64 build from cache - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: ${{ env.OS }}-arm64 key: ${{ runner.os }}-arm64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} @@ -118,7 +118,7 @@ jobs: - name: Pack run: ./.ci/pack.sh - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ env.OS }}-${{ env.TARGET }} path: artifacts/ @@ -137,11 +137,11 @@ jobs: OS: windows TARGET: ${{ matrix.target }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - name: Set up cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ env.CCACHE_DIR }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} @@ -179,7 +179,7 @@ jobs: - name: Pack run: ./.ci/pack.sh - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ env.OS }}-${{ env.TARGET }} path: artifacts/ @@ -192,11 +192,11 @@ jobs: OS: android TARGET: universal steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - name: Set up cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.gradle/caches @@ -228,7 +228,7 @@ jobs: env: UNPACKED: 1 - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ env.OS }}-${{ env.TARGET }} path: src/android/app/artifacts/ @@ -242,11 +242,11 @@ jobs: OS: ios TARGET: arm64 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - name: Set up cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ env.CCACHE_DIR }} key: ${{ runner.os }}-ios-${{ github.sha }} @@ -261,7 +261,7 @@ jobs: needs: [windows, linux, macos-universal, android, source] if: ${{ startsWith(github.ref, 'refs/tags/') }} steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 - name: Create release uses: actions/create-release@v1 env: diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 574a24e62..0d9a30caf 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -13,7 +13,7 @@ jobs: image: citraemu/build-environments:linux-fresh options: -u 1001 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Build diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4c46597f4..8c63dc6bf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,11 +20,11 @@ jobs: if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }} steps: # this checkout is required to make sure the GitHub Actions scripts are available - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Pre-checkout with: submodules: false - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 id: check-changes name: 'Check for new changes' env: @@ -38,7 +38,7 @@ jobs: return checkBaseChanges(github, context); - run: npm install execa@5 if: ${{ steps.check-changes.outputs.result == 'true' }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout if: ${{ steps.check-changes.outputs.result == 'true' }} with: @@ -46,7 +46,7 @@ jobs: fetch-depth: 0 submodules: true token: ${{ secrets.ALT_GITHUB_TOKEN }} - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 name: 'Update and tag new commits' if: ${{ steps.check-changes.outputs.result == 'true' }} env: @@ -62,11 +62,11 @@ jobs: if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }} steps: # this checkout is required to make sure the GitHub Actions scripts are available - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Pre-checkout with: submodules: false - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 id: check-changes name: 'Check for new changes' env: @@ -79,7 +79,7 @@ jobs: return checkCanaryChanges(github, context); - run: npm install execa@5 if: ${{ steps.check-changes.outputs.result == 'true' }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout if: ${{ steps.check-changes.outputs.result == 'true' }} with: @@ -87,7 +87,7 @@ jobs: fetch-depth: 0 submodules: true token: ${{ secrets.ALT_GITHUB_TOKEN }} - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 name: 'Check and merge canary changes' if: ${{ steps.check-changes.outputs.result == 'true' }} env: diff --git a/.github/workflows/transifex.yml b/.github/workflows/transifex.yml index 64d6e5866..b7a695f2b 100644 --- a/.github/workflows/transifex.yml +++ b/.github/workflows/transifex.yml @@ -10,7 +10,7 @@ jobs: container: citraemu/build-environments:linux-fresh if: ${{ github.repository == 'citra-emu/citra' }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 From 3a4ebb1413cb4767bb03cd11263eb188ea2d97f0 Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Sun, 18 Feb 2024 15:21:53 -0800 Subject: [PATCH 5/5] file_util: Make sure portable user path is absolute. (#7448) --- src/citra_qt/main.cpp | 6 ++-- src/common/common_paths.h | 1 - src/common/file_util.cpp | 63 ++++++++++++++++++++++----------------- src/common/file_util.h | 5 +--- 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 4f179a35c..5d8b4204b 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -3197,8 +3197,10 @@ int main(int argc, char* argv[]) { QApplication::setHighDpiScaleFactorRoundingPolicy(rounding_policy); #ifdef __APPLE__ - std::string bin_path = FileUtil::GetBundleDirectory() + DIR_SEP + ".."; - chdir(bin_path.c_str()); + auto bundle_dir = FileUtil::GetBundleDirectory(); + if (bundle_dir) { + FileUtil::SetCurrentDir(bundle_dir.value() + ".."); + } #endif #ifdef ENABLE_OPENGL diff --git a/src/common/common_paths.h b/src/common/common_paths.h index da9c04f2f..f12eedb0c 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -13,7 +13,6 @@ #endif // The user data dir -#define ROOT_DIR "." #define USERDATA_DIR "user" #ifdef USER_DIR #define EMU_DATA_DIR USER_DIR diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 1acbb2724..cda752e5f 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -634,6 +634,10 @@ std::optional GetCurrentDir() { std::string strDir = dir; #endif free(dir); + + if (!strDir.ends_with(DIR_SEP)) { + strDir += DIR_SEP; + } return strDir; } // namespace FileUtil @@ -646,17 +650,36 @@ bool SetCurrentDir(const std::string& directory) { } #if defined(__APPLE__) -std::string GetBundleDirectory() { - CFURLRef BundleRef; - char AppBundlePath[MAXPATHLEN]; +std::optional GetBundleDirectory() { // Get the main bundle for the app - BundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFStringRef BundlePath = CFURLCopyFileSystemPath(BundleRef, kCFURLPOSIXPathStyle); - CFStringGetFileSystemRepresentation(BundlePath, AppBundlePath, sizeof(AppBundlePath)); - CFRelease(BundleRef); - CFRelease(BundlePath); + CFBundleRef bundle_ref = CFBundleGetMainBundle(); + if (!bundle_ref) { + return {}; + } - return AppBundlePath; + CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref); + if (!bundle_url_ref) { + return {}; + } + SCOPE_EXIT({ CFRelease(bundle_url_ref); }); + + CFStringRef bundle_path_ref = CFURLCopyFileSystemPath(bundle_url_ref, kCFURLPOSIXPathStyle); + if (!bundle_path_ref) { + return {}; + } + SCOPE_EXIT({ CFRelease(bundle_path_ref); }); + + char app_bundle_path[MAXPATHLEN]; + if (!CFStringGetFileSystemRepresentation(bundle_path_ref, app_bundle_path, + sizeof(app_bundle_path))) { + return {}; + } + + std::string path_str(app_bundle_path); + if (!path_str.ends_with(DIR_SEP)) { + path_str += DIR_SEP; + } + return path_str; } #endif @@ -732,22 +755,6 @@ static const std::string& GetHomeDirectory() { } #endif -std::string GetSysDirectory() { - std::string sysDir; - -#if defined(__APPLE__) - sysDir = GetBundleDirectory(); - sysDir += DIR_SEP; - sysDir += SYSDATA_DIR; -#else - sysDir = SYSDATA_DIR; -#endif - sysDir += DIR_SEP; - - LOG_DEBUG(Common_Filesystem, "Setting to {}:", sysDir); - return sysDir; -} - namespace { std::unordered_map g_paths; std::unordered_map g_default_paths; @@ -777,8 +784,10 @@ void SetUserPath(const std::string& path) { g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); #else - if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { - user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; + auto current_dir = FileUtil::GetCurrentDir(); + if (current_dir.has_value() && + FileUtil::Exists(current_dir.value() + USERDATA_DIR DIR_SEP)) { + user_path = current_dir.value() + USERDATA_DIR DIR_SEP; g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); } else { diff --git a/src/common/file_util.h b/src/common/file_util.h index 2a4cc70ef..6595fead9 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -193,11 +193,8 @@ void SetCurrentRomPath(const std::string& path); // Update the Global Path with the new value void UpdateUserPath(UserPath path, const std::string& filename); -// Returns the path to where the sys file are -[[nodiscard]] std::string GetSysDirectory(); - #ifdef __APPLE__ -[[nodiscard]] std::string GetBundleDirectory(); +[[nodiscard]] std::optional GetBundleDirectory(); #endif #ifdef _WIN32