Compare commits
64 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
00e3bbbdf2 | ||
![]() |
13e200ce77 | ||
![]() |
e6847cbf82 | ||
![]() |
d8e4c15d31 | ||
![]() |
5b5ba0ea67 | ||
![]() |
0d8d5bc91c | ||
![]() |
97528ec262 | ||
![]() |
3b7511bc31 | ||
![]() |
91e14ad6c5 | ||
![]() |
9906618edc | ||
![]() |
a80549dc09 | ||
![]() |
eee5377325 | ||
![]() |
3c7e583f6d | ||
![]() |
a4b8664fd3 | ||
![]() |
f0291df007 | ||
![]() |
310a519722 | ||
![]() |
4b5b4a21b8 | ||
![]() |
32bb14f0d2 | ||
![]() |
f7c284c7a9 | ||
![]() |
63ce52d0db | ||
![]() |
553955e251 | ||
![]() |
ce124c3360 | ||
![]() |
0830b98b35 | ||
![]() |
8de2a95b23 | ||
![]() |
b625401e64 | ||
![]() |
6ecee968ea | ||
![]() |
5a4c19e01e | ||
![]() |
96d678a7ee | ||
![]() |
7c88951845 | ||
![]() |
cc7625e87c | ||
![]() |
9ee1801d32 | ||
![]() |
eb95a30176 | ||
![]() |
50e7ffe1a4 | ||
![]() |
da7388a5d7 | ||
![]() |
1df5db9128 | ||
![]() |
c411c1ef96 | ||
![]() |
d2a58ea277 | ||
![]() |
5d1b0bef2e | ||
![]() |
3d989b6d3e | ||
![]() |
9112dbd56d | ||
![]() |
22b9c547fc | ||
![]() |
afa0cdfe9f | ||
![]() |
1a73739fd8 | ||
![]() |
67890f59fd | ||
![]() |
bf3eb08b71 | ||
![]() |
3587303222 | ||
![]() |
9480f269c0 | ||
![]() |
9c87fdf711 | ||
![]() |
b0831cf453 | ||
![]() |
06c00a9319 | ||
![]() |
2fbfb8159c | ||
![]() |
dd0fc33e27 | ||
![]() |
0f8765eb3e | ||
![]() |
0e89ee7367 | ||
![]() |
54b997473d | ||
![]() |
643f53f5f2 | ||
![]() |
411abde5d1 | ||
![]() |
2a33d1f91b | ||
![]() |
d33a2cbf02 | ||
![]() |
8888143931 | ||
![]() |
ae26f8e8d5 | ||
![]() |
dd66e3b4a3 | ||
![]() |
89d74d5763 | ||
![]() |
5e0797b112 |
|
@ -2,10 +2,7 @@
|
|||
|
||||
if [ "$TARGET" = "appimage" ]; then
|
||||
# Compile the AppImage we distribute with Clang.
|
||||
export EXTRA_CMAKE_FLAGS=(-DCMAKE_CXX_COMPILER=clang++
|
||||
-DCMAKE_C_COMPILER=clang
|
||||
-DCMAKE_LINKER=/etc/bin/ld.lld
|
||||
-DENABLE_ROOM_STANDALONE=OFF)
|
||||
export EXTRA_CMAKE_FLAGS=(-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_LINKER=/etc/bin/ld.lld)
|
||||
# Bundle required QT wayland libraries
|
||||
export EXTRA_QT_PLUGINS="waylandcompositor"
|
||||
export EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so"
|
||||
|
|
|
@ -11,7 +11,7 @@ BASE_ARTIFACT_ARCH="${BASE_ARTIFACT##*-}"
|
|||
mv $BASE_ARTIFACT $BUNDLE_DIR
|
||||
|
||||
# Executable binary paths that need to be combined.
|
||||
BIN_PATHS=(Azahar.app/Contents/MacOS/azahar)
|
||||
BIN_PATHS=(azahar-room Azahar.app/Contents/MacOS/azahar)
|
||||
|
||||
# Dylib paths that need to be combined.
|
||||
IFS=$'\n'
|
||||
|
@ -36,11 +36,8 @@ for OTHER_ARTIFACT in "${ARTIFACTS_LIST[@]:1}"; do
|
|||
done
|
||||
done
|
||||
|
||||
# Remove leftover libs so that they aren't distributed
|
||||
rm -rf "${BUNDLE_DIR}/libs"
|
||||
|
||||
# Re-sign executables and bundles after combining.
|
||||
APP_PATHS=(Azahar.app)
|
||||
APP_PATHS=(azahar-room Azahar.app)
|
||||
for APP_PATH in "${APP_PATHS[@]}"; do
|
||||
codesign --deep -fs - $BUNDLE_DIR/$APP_PATH
|
||||
done
|
||||
|
|
|
@ -11,7 +11,6 @@ cmake .. -GNinja \
|
|||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DENABLE_QT_TRANSLATION=ON \
|
||||
-DENABLE_ROOM_STANDALONE=OFF \
|
||||
-DUSE_DISCORD_PRESENCE=ON \
|
||||
"${EXTRA_CMAKE_FLAGS[@]}"
|
||||
ninja
|
||||
|
|
|
@ -14,7 +14,7 @@ else
|
|||
fi
|
||||
|
||||
# Archive and upload the artifacts.
|
||||
mkdir -p artifacts
|
||||
mkdir artifacts
|
||||
|
||||
function pack_artifacts() {
|
||||
ARTIFACTS_PATH="$1"
|
||||
|
@ -50,6 +50,11 @@ function pack_artifacts() {
|
|||
rm -rf "$REV_NAME"
|
||||
}
|
||||
|
||||
if [ "$OS" = "windows" ] && [ "$GITHUB_REF_TYPE" = "tag" ]; then
|
||||
# Move the installer to the artifacts directory
|
||||
mv src/installer/bin/*.exe artifacts/
|
||||
fi
|
||||
|
||||
if [ -n "$UNPACKED" ]; then
|
||||
# Copy the artifacts to be uploaded unpacked.
|
||||
for ARTIFACT in build/bundle/*; do
|
||||
|
|
|
@ -4,10 +4,6 @@ GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
|||
GITREV="`git show -s --format='%h'`"
|
||||
REV_NAME="azahar-unified-source-${GITDATE}-${GITREV}"
|
||||
|
||||
if [ "$GITHUB_REF_TYPE" = "tag" ]; then
|
||||
REV_NAME="azahar-unified-source-$GITHUB_REF_NAME"
|
||||
fi
|
||||
|
||||
COMPAT_LIST='dist/compatibility_list/compatibility_list.json'
|
||||
|
||||
mkdir artifacts
|
||||
|
|
10
.github/workflows/build.yml
vendored
|
@ -49,11 +49,9 @@ jobs:
|
|||
${{ runner.os }}-${{ matrix.target }}-
|
||||
- name: Build
|
||||
run: ./.ci/linux.sh
|
||||
- name: Move AppImage to artifacts directory
|
||||
- name: Pack
|
||||
if: ${{ matrix.target == 'appimage' }}
|
||||
run: |
|
||||
mkdir -p artifacts
|
||||
mv build/bundle/*.AppImage artifacts/
|
||||
run: ./.ci/pack.sh
|
||||
- name: Upload
|
||||
if: ${{ matrix.target == 'appimage' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -190,8 +188,8 @@ jobs:
|
|||
run: |
|
||||
cd src\installer
|
||||
"C:\Program Files (x86)\NSIS\makensis.exe" /DPRODUCT_VARIANT=${{ matrix.target }} /DPRODUCT_VERSION=${{ github.ref_name }} citra.nsi
|
||||
mkdir ..\..\artifacts 2> NUL
|
||||
move /y *.exe ..\..\artifacts\
|
||||
mkdir bin
|
||||
move /y *.exe bin\
|
||||
shell: cmd
|
||||
- name: Pack
|
||||
run: ./.ci/pack.sh
|
||||
|
|
23
.github/workflows/stale.yml
vendored
|
@ -1,23 +0,0 @@
|
|||
name: azahar-stale
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
stale-issues:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/stale@v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-issue-stale: 90
|
||||
days-before-issue-close: 10
|
||||
stale-issue-message: "This issue has been marked as stale. If there is no activity within the next 10 days, this issue will be closed."
|
||||
close-issue-message: "This issue has been closed as stale."
|
||||
days-before-pr-stale: -1
|
||||
days-before-pr-close: -1
|
||||
remove-issue-stale-when-updated: true
|
||||
exempt-issue-labels: "priority - low,priority - medium,priority - high,priority - urgent,documentation,enhancement,miscellaneous,task,refactor"
|
|
@ -41,8 +41,8 @@ if (APPLE)
|
|||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
|
||||
else()
|
||||
# Minimum macOS 13
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.4")
|
||||
# Minimum macOS 11
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -86,8 +86,7 @@ option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
|||
option(ENABLE_QT_UPDATE_CHECKER "Enable built-in update checker for the Qt frontend" OFF)
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_TESTS "Enable generating tests executable" ON "NOT IOS" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_ROOM "Enable dedicated room functionality" ON "NOT ANDROID AND NOT IOS" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_ROOM_STANDALONE "Enable generating a standalone dedicated room executable" ON "ENABLE_ROOM" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_ROOM "Enable generating dedicated room executable" ON "NOT ANDROID AND NOT IOS" OFF)
|
||||
|
||||
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
||||
option(ENABLE_SCRIPTING "Enable RPC server for scripting" ON)
|
||||
|
@ -119,9 +118,6 @@ endif()
|
|||
if (ENABLE_QT_TRANSLATION)
|
||||
add_definitions(-DENABLE_QT_TRANSLATION)
|
||||
endif()
|
||||
if (ENABLE_ROOM)
|
||||
add_definitions(-DENABLE_ROOM)
|
||||
endif()
|
||||
if (ENABLE_SDL2_FRONTEND)
|
||||
add_definitions(-DENABLE_SDL2_FRONTEND)
|
||||
endif()
|
||||
|
@ -488,8 +484,9 @@ if (NOT ANDROID AND NOT IOS)
|
|||
elseif (ENABLE_SDL2_FRONTEND)
|
||||
bundle_target(citra_meta)
|
||||
endif()
|
||||
if (ENABLE_ROOM_STANDALONE)
|
||||
bundle_target(citra_room_standalone)
|
||||
|
||||
if (ENABLE_ROOM)
|
||||
bundle_target(citra_room)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -279,12 +279,22 @@ else()
|
|||
add_custom_target(bundle)
|
||||
add_custom_command(
|
||||
TARGET bundle
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/"
|
||||
POST_BUILD)
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/")
|
||||
add_custom_command(
|
||||
TARGET bundle
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/dist/scripting" "${CMAKE_BINARY_DIR}/bundle/scripting"
|
||||
POST_BUILD)
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/dist/")
|
||||
add_custom_command(
|
||||
TARGET bundle
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/dist/azahar.png" "${CMAKE_BINARY_DIR}/bundle/dist/azahar.png")
|
||||
add_custom_command(
|
||||
TARGET bundle
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/license.txt" "${CMAKE_BINARY_DIR}/bundle/")
|
||||
add_custom_command(
|
||||
TARGET bundle
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/README.md" "${CMAKE_BINARY_DIR}/bundle/")
|
||||
add_custom_command(
|
||||
TARGET bundle
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/dist/scripting" "${CMAKE_BINARY_DIR}/bundle/scripting")
|
||||
|
||||
# On Linux, add a command to prepare linuxdeploy and any required plugins before any bundling occurs.
|
||||
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
|
@ -295,8 +305,7 @@ else()
|
|||
"-DLINUXDEPLOY_PATH=${CMAKE_BINARY_DIR}/externals/linuxdeploy"
|
||||
"-DLINUXDEPLOY_ARCH=${CMAKE_HOST_SYSTEM_PROCESSOR}"
|
||||
-P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
POST_BUILD)
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
|
24
README.md
|
@ -10,20 +10,20 @@ It was created from the merging of PabloMK7's Citra fork and the Lime3DS project
|
|||
|
||||
The goal of this project is to be the de-facto platform for future development.
|
||||
|
||||
> [!NOTE]
|
||||
> Azahar has not fully released yet. For this reason, there are no compiled binaries available for download.
|
||||
>
|
||||
> It is recommended that only developers and early adopters should use the emulator until our first stable release.
|
||||
>
|
||||
> Here be dragons.
|
||||
|
||||
<!--
|
||||
# Installation
|
||||
|
||||
### Windows
|
||||
### Windows & MacOS
|
||||
|
||||
Download the latest release from [Releases](https://github.com/azahar-emu/azahar/releases).
|
||||
|
||||
If you are unsure of whether you want to use MSYS2 or MSVC, use MSYS2.
|
||||
|
||||
### MacOS
|
||||
|
||||
Download the latest release from [Releases](https://github.com/azahar-emu/azahar/releases).
|
||||
|
||||
The `macos-universal` download will work on both Intel and Apple Silicon Macs.
|
||||
|
||||
---
|
||||
### Android
|
||||
The recommended method of downloading Azahar on Android is via the [Google Play store](https://play.google.com/store/apps/details?id=io.github.lime3ds.android).
|
||||
|
@ -44,8 +44,6 @@ Keep in mind that you will not recieve automatic updates when installing via the
|
|||
|
||||
Azahar is available as an AppImage on the [Releases](https://github.com/azahar-emu/azahar/releases) page.
|
||||
|
||||
A Flatpak distribution is currently being worked on.
|
||||
<!--
|
||||
We are also on Flathub:
|
||||
|
||||
<a href=https://flathub.org/apps/org.azahar-emu.azahar><img width='180' alt='Download on Flathub' src='https://dl.flathub.org/assets/badges/flathub-badge-en.png'/></a>
|
||||
|
@ -86,13 +84,13 @@ Below are the minimum requirements to run Azahar:
|
|||
### Desktop
|
||||
```
|
||||
Operating System: Windows 10 (64-bit), MacOS 13 (Ventura), or modern 64-bit Linux
|
||||
CPU: x86-64/ARM64 CPU (Windows for ARM not supported). Single core performance higher than 1,800 on Passmark
|
||||
CPU: x86-64 (64-bit) CPU. Single core performance higher than 1,800 on Passmark
|
||||
GPU: OpenGL 4.3 or Vulkan 1.1 support
|
||||
Memory: 2GB of RAM. 4GB is recommended
|
||||
```
|
||||
### Android
|
||||
```
|
||||
Operating System: Android 9.0+ (64-bit)
|
||||
Operating System: Android 9.0+
|
||||
CPU: Snapdragon 835 SoC or better
|
||||
GPU: OpenGL ES 3.2 or Vulkan 1.1 support
|
||||
Memory: 2GB of RAM. 4GB is recommended
|
||||
|
|
847
dist/languages/ca_ES_valencia.ts
vendored
2523
dist/languages/da_DK.ts
vendored
894
dist/languages/de.ts
vendored
1973
dist/languages/el.ts
vendored
847
dist/languages/es_ES.ts
vendored
2603
dist/languages/fi.ts
vendored
885
dist/languages/fr.ts
vendored
2085
dist/languages/hu_HU.ts
vendored
2309
dist/languages/id.ts
vendored
905
dist/languages/it.ts
vendored
1629
dist/languages/ja_JP.ts
vendored
1611
dist/languages/ko_KR.ts
vendored
2419
dist/languages/lt_LT.ts
vendored
2141
dist/languages/nb.ts
vendored
1359
dist/languages/nl.ts
vendored
863
dist/languages/pl_PL.ts
vendored
857
dist/languages/pt_BR.ts
vendored
1421
dist/languages/ro_RO.ts
vendored
2093
dist/languages/ru_RU.ts
vendored
851
dist/languages/sv.ts
vendored
1795
dist/languages/tr_TR.ts
vendored
2275
dist/languages/vi_VN.ts
vendored
851
dist/languages/zh_CN.ts
vendored
2163
dist/languages/zh_TW.ts
vendored
61
dist/scripting/citra.py
vendored
|
@ -1,21 +1,15 @@
|
|||
# Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
# Licensed under GPLv2 or any later version
|
||||
# Refer to the license.txt file included.
|
||||
|
||||
import struct
|
||||
import random
|
||||
import enum
|
||||
import socket
|
||||
|
||||
CURRENT_REQUEST_VERSION = 1
|
||||
MAX_REQUEST_DATA_SIZE = 1024
|
||||
MAX_PACKET_SIZE = 1024 + 0x10
|
||||
MAX_REQUEST_DATA_SIZE = 32
|
||||
MAX_PACKET_SIZE = 48
|
||||
|
||||
class RequestType(enum.IntEnum):
|
||||
ReadMemory = 1,
|
||||
WriteMemory = 2,
|
||||
ProcessList = 3,
|
||||
SetGetProcess = 4,
|
||||
WriteMemory = 2
|
||||
|
||||
CITRA_PORT = 45987
|
||||
|
||||
|
@ -40,55 +34,6 @@ class Citra:
|
|||
return raw_reply[4*4:]
|
||||
return None
|
||||
|
||||
def process_list(self):
|
||||
processes = {}
|
||||
read_processes = 0
|
||||
while True:
|
||||
request_data = struct.pack("II", read_processes, 0x7FFFFFFF)
|
||||
request, request_id = self._generate_header(RequestType.ProcessList, len(request_data))
|
||||
request += request_data
|
||||
self.socket.sendto(request, (self.address, CITRA_PORT))
|
||||
|
||||
raw_reply = self.socket.recv(MAX_PACKET_SIZE)
|
||||
reply_data = self._read_and_validate_header(raw_reply, request_id, RequestType.ProcessList)
|
||||
|
||||
if reply_data:
|
||||
read_count = struct.unpack("I", reply_data[0:4])[0]
|
||||
reply_data = reply_data[4:]
|
||||
if read_count == 0:
|
||||
break
|
||||
read_processes += read_count
|
||||
for i in range(read_count):
|
||||
proc_data = reply_data[i * 0x14 : (i + 1) * 0x14]
|
||||
proc_id, title_id, proc_name = struct.unpack("<IQ8s", proc_data)
|
||||
proc_name = proc_name.rstrip(b"\x00").decode("ascii")
|
||||
processes[proc_id] = (title_id, proc_name)
|
||||
else:
|
||||
break
|
||||
return processes
|
||||
|
||||
def get_process(self):
|
||||
request_data = struct.pack("II", 0, 0)
|
||||
request, request_id = self._generate_header(RequestType.SetGetProcess, len(request_data))
|
||||
request += request_data
|
||||
self.socket.sendto(request, (self.address, CITRA_PORT))
|
||||
|
||||
raw_reply = self.socket.recv(MAX_PACKET_SIZE)
|
||||
reply_data = self._read_and_validate_header(raw_reply, request_id, RequestType.SetGetProcess)
|
||||
|
||||
if reply_data:
|
||||
return struct.unpack("I", reply_data)[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def set_process(self, process_id):
|
||||
request_data = struct.pack("II", 1, process_id)
|
||||
request, request_id = self._generate_header(RequestType.SetGetProcess, len(request_data))
|
||||
request += request_data
|
||||
self.socket.sendto(request, (self.address, CITRA_PORT))
|
||||
|
||||
self.socket.recv(MAX_PACKET_SIZE)
|
||||
|
||||
def read_memory(self, read_address, read_size):
|
||||
"""
|
||||
>>> c.read_memory(0x100000, 4)
|
||||
|
|
|
@ -199,10 +199,6 @@ if (ENABLE_ROOM)
|
|||
add_subdirectory(citra_room)
|
||||
endif()
|
||||
|
||||
if (ENABLE_ROOM_STANDALONE)
|
||||
add_subdirectory(citra_room_standalone)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
add_subdirectory(android/app/src/main/jni)
|
||||
target_include_directories(citra-android PRIVATE android/app/src/main)
|
||||
|
|
|
@ -186,10 +186,6 @@ object NativeLibrary {
|
|||
|
||||
external fun unlinkConsole()
|
||||
|
||||
external fun setTemporaryFrameLimit(speed: Double)
|
||||
|
||||
external fun disableTemporaryFrameLimit()
|
||||
|
||||
private var coreErrorAlertResult = false
|
||||
private val coreErrorAlertLock = Object()
|
||||
|
||||
|
@ -777,7 +773,6 @@ object NativeLibrary {
|
|||
const val BUTTON_DEBUG = 781
|
||||
const val BUTTON_GPIO14 = 782
|
||||
const val BUTTON_SWAP = 800
|
||||
const val BUTTON_TURBO = 801
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright Citra Emulator Project / Lime3DS Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -15,7 +15,6 @@ import android.os.Bundle
|
|||
import android.view.InputDevice
|
||||
import android.view.KeyEvent
|
||||
import android.view.MotionEvent
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
|
@ -45,7 +44,6 @@ import org.citra.citra_emu.utils.FileBrowserHelper
|
|||
import org.citra.citra_emu.utils.EmulationLifecycleUtil
|
||||
import org.citra.citra_emu.utils.EmulationMenuSettings
|
||||
import org.citra.citra_emu.utils.ThemeUtil
|
||||
import org.citra.citra_emu.utils.TurboHelper
|
||||
import org.citra.citra_emu.viewmodel.EmulationViewModel
|
||||
|
||||
class EmulationActivity : AppCompatActivity() {
|
||||
|
@ -53,7 +51,7 @@ class EmulationActivity : AppCompatActivity() {
|
|||
get() = PreferenceManager.getDefaultSharedPreferences(CitraApplication.appContext)
|
||||
var isActivityRecreated = false
|
||||
private val emulationViewModel: EmulationViewModel by viewModels()
|
||||
val settingsViewModel: SettingsViewModel by viewModels()
|
||||
private val settingsViewModel: SettingsViewModel by viewModels()
|
||||
|
||||
private lateinit var binding: ActivityEmulationBinding
|
||||
private lateinit var screenAdjustmentUtil: ScreenAdjustmentUtil
|
||||
|
@ -69,8 +67,6 @@ class EmulationActivity : AppCompatActivity() {
|
|||
private var isEmulationRunning: Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
|
||||
ThemeUtil.setTheme(this)
|
||||
|
||||
settingsViewModel.settings.loadSettings()
|
||||
|
@ -196,16 +192,9 @@ class EmulationActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun enableFullscreenImmersive() {
|
||||
val attributes = window.attributes
|
||||
|
||||
attributes.layoutInDisplayCutoutMode =
|
||||
if (BooleanSetting.EXPAND_TO_CUTOUT_AREA.boolean) {
|
||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||
} else {
|
||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
|
||||
}
|
||||
|
||||
window.attributes = attributes
|
||||
// TODO: Remove this once we properly account for display insets in the input overlay
|
||||
window.attributes.layoutInDisplayCutoutMode =
|
||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
|
||||
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright Citra Emulator Project / Lime3DS Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
package org.citra.citra_emu.adapters
|
||||
|
||||
import android.graphics.drawable.Icon
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.SystemClock
|
||||
import android.text.TextUtils
|
||||
|
@ -29,7 +28,6 @@ import androidx.recyclerview.widget.AsyncDifferConfig
|
|||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import android.widget.PopupMenu
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.button.MaterialButton
|
||||
|
@ -46,9 +44,7 @@ import org.citra.citra_emu.databinding.CardGameBinding
|
|||
import org.citra.citra_emu.features.cheats.ui.CheatsFragmentDirections
|
||||
import org.citra.citra_emu.features.settings.ui.SettingsActivity
|
||||
import org.citra.citra_emu.features.settings.utils.SettingsFile
|
||||
import org.citra.citra_emu.fragments.IndeterminateProgressDialogFragment
|
||||
import org.citra.citra_emu.model.Game
|
||||
import org.citra.citra_emu.utils.FileUtil
|
||||
import org.citra.citra_emu.utils.GameIconUtils
|
||||
import org.citra.citra_emu.viewmodel.GamesViewModel
|
||||
|
||||
|
@ -207,117 +203,6 @@ class GameAdapter(private val activity: AppCompatActivity, private val inflater:
|
|||
}
|
||||
}
|
||||
|
||||
private data class GameDirectories(
|
||||
val gameDir: String,
|
||||
val saveDir: String,
|
||||
val modsDir: String,
|
||||
val texturesDir: String,
|
||||
val appDir: String,
|
||||
val dlcDir: String,
|
||||
val updatesDir: String,
|
||||
val extraDir: String
|
||||
)
|
||||
private fun getGameDirectories(game: Game): GameDirectories {
|
||||
val basePath = "sdmc/Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000"
|
||||
return GameDirectories(
|
||||
gameDir = game.path.substringBeforeLast("/"),
|
||||
saveDir = basePath + "/title/${String.format("%016x", game.titleId).lowercase().substring(0, 8)}/${String.format("%016x", game.titleId).lowercase().substring(8)}/data/00000001",
|
||||
modsDir = "load/mods/${String.format("%016X", game.titleId)}",
|
||||
texturesDir = "load/textures/${String.format("%016X", game.titleId)}",
|
||||
appDir = game.path.substringBeforeLast("/").split("/").filter { it.isNotEmpty() }.joinToString("/"),
|
||||
dlcDir = basePath + "/title/0004008c/${String.format("%016x", game.titleId).lowercase().substring(8)}/content",
|
||||
updatesDir = basePath + "/title/0004000e/${String.format("%016x", game.titleId).lowercase().substring(8)}/content",
|
||||
extraDir = basePath + "/extdata/00000000/${String.format("%016X", game.titleId).substring(8, 14).padStart(8, '0')}"
|
||||
)
|
||||
}
|
||||
|
||||
private fun showOpenContextMenu(view: View, game: Game) {
|
||||
val dirs = getGameDirectories(game)
|
||||
|
||||
val popup = PopupMenu(view.context, view).apply {
|
||||
menuInflater.inflate(R.menu.game_context_menu_open, menu)
|
||||
listOf(
|
||||
R.id.game_context_open_app to dirs.appDir,
|
||||
R.id.game_context_open_save_dir to dirs.saveDir,
|
||||
R.id.game_context_open_updates to dirs.updatesDir,
|
||||
R.id.game_context_open_dlc to dirs.dlcDir,
|
||||
R.id.game_context_open_extra to dirs.extraDir
|
||||
).forEach { (id, dir) ->
|
||||
menu.findItem(id)?.isEnabled =
|
||||
CitraApplication.documentsTree.folderUriHelper(dir)?.let {
|
||||
DocumentFile.fromTreeUri(view.context, it)?.exists()
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener { menuItem ->
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.setType("*/*")
|
||||
|
||||
val uri = when (menuItem.itemId) {
|
||||
R.id.game_context_open_app -> CitraApplication.documentsTree.folderUriHelper(dirs.appDir)
|
||||
R.id.game_context_open_save_dir -> CitraApplication.documentsTree.folderUriHelper(dirs.saveDir)
|
||||
R.id.game_context_open_updates -> CitraApplication.documentsTree.folderUriHelper(dirs.updatesDir)
|
||||
R.id.game_context_open_dlc -> CitraApplication.documentsTree.folderUriHelper(dirs.dlcDir)
|
||||
R.id.game_context_open_extra -> CitraApplication.documentsTree.folderUriHelper(dirs.extraDir)
|
||||
R.id.game_context_open_textures -> CitraApplication.documentsTree.folderUriHelper(dirs.texturesDir, true)
|
||||
R.id.game_context_open_mods -> CitraApplication.documentsTree.folderUriHelper(dirs.modsDir, true)
|
||||
else -> null
|
||||
}
|
||||
|
||||
uri?.let {
|
||||
intent.data = it
|
||||
view.context.startActivity(intent)
|
||||
true
|
||||
} ?: false
|
||||
}
|
||||
|
||||
popup.show()
|
||||
}
|
||||
|
||||
private fun showUninstallContextMenu(view: View, game: Game, bottomSheetDialog: BottomSheetDialog) {
|
||||
val dirs = getGameDirectories(game)
|
||||
val popup = PopupMenu(view.context, view).apply {
|
||||
menuInflater.inflate(R.menu.game_context_menu_uninstall, menu)
|
||||
listOf(
|
||||
R.id.game_context_uninstall to dirs.gameDir,
|
||||
R.id.game_context_uninstall_dlc to dirs.dlcDir,
|
||||
R.id.game_context_uninstall_updates to dirs.updatesDir
|
||||
).forEach { (id, dir) ->
|
||||
menu.findItem(id)?.isEnabled =
|
||||
CitraApplication.documentsTree.folderUriHelper(dir)?.let {
|
||||
DocumentFile.fromTreeUri(view.context, it)?.exists()
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener { menuItem ->
|
||||
val uninstallAction: () -> Unit = {
|
||||
when (menuItem.itemId) {
|
||||
R.id.game_context_uninstall -> CitraApplication.documentsTree.deleteDocument(dirs.gameDir)
|
||||
R.id.game_context_uninstall_dlc -> FileUtil.deleteDocument(CitraApplication.documentsTree.folderUriHelper(dirs.dlcDir)
|
||||
.toString())
|
||||
R.id.game_context_uninstall_updates -> FileUtil.deleteDocument(CitraApplication.documentsTree.folderUriHelper(dirs.updatesDir)
|
||||
.toString())
|
||||
}
|
||||
ViewModelProvider(activity)[GamesViewModel::class.java].reloadGames(true)
|
||||
bottomSheetDialog.dismiss()
|
||||
}
|
||||
|
||||
if (menuItem.itemId in listOf(R.id.game_context_uninstall, R.id.game_context_uninstall_dlc, R.id.game_context_uninstall_updates)) {
|
||||
IndeterminateProgressDialogFragment.newInstance(activity, R.string.uninstalling, false, uninstallAction)
|
||||
.show(activity.supportFragmentManager, IndeterminateProgressDialogFragment.TAG)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
popup.show()
|
||||
}
|
||||
|
||||
private fun showAboutGameDialog(context: Context, game: Game, holder: GameViewHolder, view: View) {
|
||||
val bottomSheetView = inflater.inflate(R.layout.dialog_about_game, null)
|
||||
|
||||
|
@ -360,14 +245,6 @@ class GameAdapter(private val activity: AppCompatActivity, private val inflater:
|
|||
bottomSheetDialog.dismiss()
|
||||
}
|
||||
|
||||
bottomSheetView.findViewById<MaterialButton>(R.id.menu_button_open).setOnClickListener {
|
||||
showOpenContextMenu(it, game)
|
||||
}
|
||||
|
||||
bottomSheetView.findViewById<MaterialButton>(R.id.menu_button_uninstall).setOnClickListener {
|
||||
showUninstallContextMenu(it, game, bottomSheetDialog)
|
||||
}
|
||||
|
||||
val bottomSheetBehavior = bottomSheetDialog.getBehavior()
|
||||
bottomSheetBehavior.skipCollapsed = true
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -41,8 +41,7 @@ enum class SmallScreenPosition(val int: Int) {
|
|||
enum class PortraitScreenLayout(val int: Int) {
|
||||
// These must match what is defined in src/common/settings.h
|
||||
TOP_FULL_WIDTH(0),
|
||||
CUSTOM_PORTRAIT_LAYOUT(1),
|
||||
ORIGINAL(2);
|
||||
CUSTOM_PORTRAIT_LAYOUT(1);
|
||||
|
||||
companion object {
|
||||
fun from(int: Int): PortraitScreenLayout {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -10,6 +10,5 @@ enum class Hotkey(val button: Int) {
|
|||
CLOSE_GAME(10003),
|
||||
PAUSE_OR_RESUME(10004),
|
||||
QUICKSAVE(10005),
|
||||
QUICKLOAD(10006),
|
||||
TURBO_LIMIT(10007);
|
||||
QUICKLOAD(10006);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -9,14 +9,11 @@ import android.widget.Toast
|
|||
import org.citra.citra_emu.NativeLibrary
|
||||
import org.citra.citra_emu.R
|
||||
import org.citra.citra_emu.utils.EmulationLifecycleUtil
|
||||
import org.citra.citra_emu.utils.TurboHelper
|
||||
import org.citra.citra_emu.display.ScreenAdjustmentUtil
|
||||
|
||||
class HotkeyUtility(
|
||||
private val screenAdjustmentUtil: ScreenAdjustmentUtil,
|
||||
private val context: Context) {
|
||||
class HotkeyUtility(private val screenAdjustmentUtil: ScreenAdjustmentUtil, private val context: Context) {
|
||||
|
||||
private val hotkeyButtons = Hotkey.entries.map { it.button }
|
||||
val hotkeyButtons = Hotkey.entries.map { it.button }
|
||||
|
||||
fun handleHotkey(bindedButton: Int): Boolean {
|
||||
if(hotkeyButtons.contains(bindedButton)) {
|
||||
|
@ -25,17 +22,16 @@ class HotkeyUtility(
|
|||
Hotkey.CYCLE_LAYOUT.button -> screenAdjustmentUtil.cycleLayouts()
|
||||
Hotkey.CLOSE_GAME.button -> EmulationLifecycleUtil.closeGame()
|
||||
Hotkey.PAUSE_OR_RESUME.button -> EmulationLifecycleUtil.pauseOrResume()
|
||||
Hotkey.TURBO_LIMIT.button -> TurboHelper.setTurboEnabled(!TurboHelper.isTurboSpeedEnabled())
|
||||
Hotkey.QUICKSAVE.button -> {
|
||||
NativeLibrary.saveState(NativeLibrary.QUICKSAVE_SLOT)
|
||||
Toast.makeText(context,
|
||||
context.getString(R.string.saving),
|
||||
context.getString(R.string.quicksave_saving),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
Hotkey.QUICKLOAD.button -> {
|
||||
val wasLoaded = NativeLibrary.loadStateIfAvailable(NativeLibrary.QUICKSAVE_SLOT)
|
||||
val stringRes = if(wasLoaded) {
|
||||
R.string.loading
|
||||
R.string.quickload_loading
|
||||
} else {
|
||||
R.string.quickload_not_found
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ enum class BooleanSetting(
|
|||
override val section: String,
|
||||
override val defaultValue: Boolean
|
||||
) : AbstractBooleanSetting {
|
||||
EXPAND_TO_CUTOUT_AREA("expand_to_cutout_area", Settings.SECTION_LAYOUT, false),
|
||||
SPIRV_SHADER_GEN("spirv_shader_gen", Settings.SECTION_RENDERER, true),
|
||||
ASYNC_SHADERS("async_shader_compilation", Settings.SECTION_RENDERER, false),
|
||||
PLUGIN_LOADER("plugin_loader", Settings.SECTION_SYSTEM, false),
|
||||
|
|
|
@ -33,7 +33,6 @@ enum class IntSetting(
|
|||
LANDSCAPE_BOTTOM_Y("custom_bottom_y",Settings.SECTION_LAYOUT,480),
|
||||
LANDSCAPE_BOTTOM_WIDTH("custom_bottom_width",Settings.SECTION_LAYOUT,640),
|
||||
LANDSCAPE_BOTTOM_HEIGHT("custom_bottom_height",Settings.SECTION_LAYOUT,480),
|
||||
SCREEN_GAP("screen_gap",Settings.SECTION_LAYOUT,0),
|
||||
PORTRAIT_SCREEN_LAYOUT("portrait_layout_option",Settings.SECTION_LAYOUT,0),
|
||||
PORTRAIT_TOP_X("custom_portrait_top_x",Settings.SECTION_LAYOUT,0),
|
||||
PORTRAIT_TOP_Y("custom_portrait_top_y",Settings.SECTION_LAYOUT,0),
|
||||
|
@ -66,9 +65,7 @@ enum class IntSetting(
|
|||
DELAY_RENDER_THREAD_US("delay_game_render_thread_us", Settings.SECTION_RENDERER, 0),
|
||||
USE_ARTIC_BASE_CONTROLLER("use_artic_base_controller", Settings.SECTION_CONTROLS, 0),
|
||||
ORIENTATION_OPTION("screen_orientation", Settings.SECTION_LAYOUT, 2),
|
||||
DISABLE_RIGHT_EYE_RENDER("disable_right_eye_render", Settings.SECTION_RENDERER, 0),
|
||||
TURBO_LIMIT("turbo_limit", Settings.SECTION_CORE, 200);
|
||||
|
||||
DISABLE_RIGHT_EYE_RENDER("disable_right_eye_render", Settings.SECTION_RENDERER, 0);
|
||||
override var int: Int = defaultValue
|
||||
|
||||
override val valueAsString: String
|
||||
|
@ -97,7 +94,7 @@ enum class IntSetting(
|
|||
ASYNC_CUSTOM_LOADING,
|
||||
AUDIO_INPUT_TYPE,
|
||||
USE_ARTIC_BASE_CONTROLLER,
|
||||
SHADERS_ACCURATE_MUL
|
||||
SHADERS_ACCURATE_MUL,
|
||||
)
|
||||
|
||||
fun from(key: String): IntSetting? = IntSetting.values().firstOrNull { it.key == key }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -139,7 +139,6 @@ class Settings {
|
|||
const val HOTKEY_PAUSE_OR_RESUME = "hotkey_pause_or_resume_game"
|
||||
const val HOTKEY_QUICKSAVE = "hotkey_quickload"
|
||||
const val HOTKEY_QUICKlOAD = "hotkey_quickpause"
|
||||
const val HOTKEY_TURBO_LIMIT = "hotkey_turbo_limit"
|
||||
|
||||
val buttonKeys = listOf(
|
||||
KEY_BUTTON_A,
|
||||
|
@ -205,8 +204,7 @@ class Settings {
|
|||
HOTKEY_CLOSE_GAME,
|
||||
HOTKEY_PAUSE_OR_RESUME,
|
||||
HOTKEY_QUICKSAVE,
|
||||
HOTKEY_QUICKlOAD,
|
||||
HOTKEY_TURBO_LIMIT
|
||||
HOTKEY_QUICKlOAD
|
||||
)
|
||||
val hotkeyTitles = listOf(
|
||||
R.string.emulation_swap_screens,
|
||||
|
@ -215,7 +213,6 @@ class Settings {
|
|||
R.string.emulation_toggle_pause,
|
||||
R.string.emulation_quicksave,
|
||||
R.string.emulation_quickload,
|
||||
R.string.turbo_limit_hotkey
|
||||
)
|
||||
|
||||
const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
|
||||
|
|
|
@ -12,8 +12,7 @@ class DateTimeSetting(
|
|||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val key: String? = null,
|
||||
private val defaultValue: String? = null,
|
||||
override var isEnabled: Boolean = true
|
||||
private val defaultValue: String? = null
|
||||
) : SettingsItem(setting, titleId, descriptionId) {
|
||||
override val type = TYPE_DATETIME_SETTING
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -133,7 +133,6 @@ class InputBindingSetting(
|
|||
Settings.HOTKEY_PAUSE_OR_RESUME -> Hotkey.PAUSE_OR_RESUME.button
|
||||
Settings.HOTKEY_QUICKSAVE -> Hotkey.QUICKSAVE.button
|
||||
Settings.HOTKEY_QUICKlOAD -> Hotkey.QUICKLOAD.button
|
||||
Settings.HOTKEY_TURBO_LIMIT -> Hotkey.TURBO_LIMIT.button
|
||||
else -> -1
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright Citra Emulator Project / Lime3DS Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -28,13 +28,6 @@ abstract class SettingsItem(
|
|||
return setting?.isRuntimeEditable ?: false
|
||||
}
|
||||
|
||||
open var isEnabled: Boolean = true
|
||||
|
||||
val isActive: Boolean
|
||||
get() {
|
||||
return this.isEditable && this.isEnabled
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TYPE_HEADER = 0
|
||||
const val TYPE_SWITCH = 1
|
||||
|
|
|
@ -15,8 +15,7 @@ class SingleChoiceSetting(
|
|||
val choicesId: Int,
|
||||
val valuesId: Int,
|
||||
val key: String? = null,
|
||||
val defaultValue: Int? = null,
|
||||
override var isEnabled: Boolean = true
|
||||
val defaultValue: Int? = null
|
||||
) : SettingsItem(setting, titleId, descriptionId) {
|
||||
override val type = TYPE_SINGLE_CHOICE
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ class SliderSetting(
|
|||
val max: Int,
|
||||
val units: String,
|
||||
val key: String? = null,
|
||||
val defaultValue: Float? = null,
|
||||
override var isEnabled: Boolean = true
|
||||
val defaultValue: Float? = null
|
||||
) : SettingsItem(setting, titleId, descriptionId) {
|
||||
override val type = TYPE_SLIDER
|
||||
val selectedFloat: Float
|
||||
|
|
|
@ -12,8 +12,7 @@ class StringInputSetting(
|
|||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val defaultValue: String,
|
||||
val characterLimit: Int = 0,
|
||||
override var isEnabled: Boolean = true
|
||||
val characterLimit: Int = 0
|
||||
) : SettingsItem(setting, titleId, descriptionId) {
|
||||
override val type = TYPE_STRING_INPUT
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@ class StringSingleChoiceSetting(
|
|||
val choices: Array<String>,
|
||||
val values: Array<String>?,
|
||||
val key: String? = null,
|
||||
private val defaultValue: String? = null,
|
||||
override var isEnabled: Boolean = true
|
||||
private val defaultValue: String? = null
|
||||
) : SettingsItem(setting, titleId, descriptionId) {
|
||||
override val type = TYPE_STRING_SINGLE_CHOICE
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@ class SwitchSetting(
|
|||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val key: String? = null,
|
||||
val defaultValue: Any? = null,
|
||||
override var isEnabled: Boolean = true
|
||||
val defaultValue: Any? = null
|
||||
) : SettingsItem(setting, titleId, descriptionId) {
|
||||
override val type = TYPE_SWITCH
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import org.citra.citra_emu.features.settings.model.Settings
|
|||
import org.citra.citra_emu.utils.SystemSaveGame
|
||||
import org.citra.citra_emu.utils.DirectoryInitialization
|
||||
import org.citra.citra_emu.utils.Log
|
||||
import org.citra.citra_emu.utils.TurboHelper
|
||||
|
||||
class SettingsActivityPresenter(private val activityView: SettingsActivityView) {
|
||||
val settings: Settings get() = activityView.settings
|
||||
|
@ -67,7 +66,6 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView)
|
|||
//added to ensure that layout changes take effect as soon as settings window closes
|
||||
NativeLibrary.reloadSettings()
|
||||
NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode)
|
||||
TurboHelper.reloadTurbo() // TODO: Can this go someone else? -OS
|
||||
}
|
||||
NativeLibrary.reloadSettings()
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package org.citra.citra_emu.features.settings.ui
|
|||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Color
|
||||
import android.icu.util.Calendar
|
||||
import android.icu.util.TimeZone
|
||||
import android.text.Editable
|
||||
|
@ -16,11 +17,11 @@ import android.text.TextWatcher
|
|||
import android.text.format.DateFormat
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.datepicker.MaterialDatePicker
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
@ -65,6 +66,7 @@ import org.citra.citra_emu.features.settings.ui.viewholder.SwitchSettingViewHold
|
|||
import org.citra.citra_emu.fragments.MessageDialogFragment
|
||||
import org.citra.citra_emu.fragments.MotionBottomSheetDialogFragment
|
||||
import org.citra.citra_emu.utils.SystemSaveGame
|
||||
import java.lang.IllegalStateException
|
||||
import java.lang.NumberFormatException
|
||||
import java.text.SimpleDateFormat
|
||||
import kotlin.math.roundToInt
|
||||
|
@ -151,71 +153,15 @@ class SettingsAdapter(
|
|||
return getItem(position)?.type ?: -1
|
||||
}
|
||||
|
||||
fun setSettingsList(newSettings: ArrayList<SettingsItem>?) {
|
||||
if (settings == null) {
|
||||
settings = newSettings ?: arrayListOf()
|
||||
notifyDataSetChanged()
|
||||
return
|
||||
}
|
||||
|
||||
val oldSettings = settings
|
||||
val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
|
||||
override fun getOldListSize() = oldSettings?.size ?: 0
|
||||
override fun getNewListSize() = newSettings?.size ?: 0
|
||||
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldItem = oldSettings?.get(oldItemPosition)?.setting
|
||||
val newItem = newSettings?.get(newItemPosition)?.setting
|
||||
return oldItem?.key == newItem?.key
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldItem = oldSettings?.get(oldItemPosition)
|
||||
val newItem = newSettings?.get(newItemPosition)
|
||||
|
||||
if (oldItem == null || newItem == null || oldItem.type != newItem.type) {
|
||||
return false
|
||||
}
|
||||
|
||||
return when (oldItem.type) {
|
||||
SettingsItem.TYPE_SLIDER -> {
|
||||
(oldItem as SliderSetting).isEnabled == (newItem as SliderSetting).isEnabled
|
||||
}
|
||||
SettingsItem.TYPE_SWITCH -> {
|
||||
(oldItem as SwitchSetting).isEnabled == (newItem as SwitchSetting).isEnabled
|
||||
}
|
||||
SettingsItem.TYPE_SINGLE_CHOICE -> {
|
||||
(oldItem as SingleChoiceSetting).isEnabled == (newItem as SingleChoiceSetting).isEnabled
|
||||
}
|
||||
SettingsItem.TYPE_DATETIME_SETTING -> {
|
||||
(oldItem as DateTimeSetting).isEnabled == (newItem as DateTimeSetting).isEnabled
|
||||
}
|
||||
SettingsItem.TYPE_STRING_SINGLE_CHOICE -> {
|
||||
(oldItem as StringSingleChoiceSetting).isEnabled == (newItem as StringSingleChoiceSetting).isEnabled
|
||||
}
|
||||
SettingsItem.TYPE_STRING_INPUT -> {
|
||||
(oldItem as StringInputSetting).isEnabled == (newItem as StringInputSetting).isEnabled
|
||||
}
|
||||
else -> {
|
||||
oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
settings = newSettings ?: arrayListOf()
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
fun setSettingsList(settings: ArrayList<SettingsItem>?) {
|
||||
this.settings = settings ?: arrayListOf()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun onBooleanClick(item: SwitchSetting, position: Int, checked: Boolean) {
|
||||
val setting = item.setChecked(checked)
|
||||
fragmentView.putSetting(setting)
|
||||
fragmentView.onSettingChanged()
|
||||
|
||||
// If statement is required otherwise the app will crash on activity recreate ex. theme settings
|
||||
if (fragmentView.activityView != null)
|
||||
// Reload the settings list to update the UI
|
||||
fragmentView.loadSettingsList()
|
||||
}
|
||||
|
||||
private fun onSingleChoiceClick(item: SingleChoiceSetting) {
|
||||
|
@ -301,7 +247,6 @@ class SettingsAdapter(
|
|||
notifyItemChanged(clickedPosition)
|
||||
val setting = item.setSelectedValue(rtcString)
|
||||
fragmentView.putSetting(setting)
|
||||
fragmentView.loadSettingsList()
|
||||
clickedItem = null
|
||||
}
|
||||
datePicker.show(
|
||||
|
@ -457,7 +402,6 @@ class SettingsAdapter(
|
|||
else -> throw IllegalStateException("Unrecognized type used for SingleChoiceSetting!")
|
||||
}
|
||||
fragmentView?.putSetting(setting)
|
||||
fragmentView.loadSettingsList()
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
|
@ -481,7 +425,6 @@ class SettingsAdapter(
|
|||
}
|
||||
|
||||
fragmentView?.putSetting(setting)
|
||||
fragmentView.loadSettingsList()
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +447,6 @@ class SettingsAdapter(
|
|||
fragmentView?.putSetting(setting)
|
||||
}
|
||||
}
|
||||
fragmentView.loadSettingsList()
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
|
@ -517,7 +459,6 @@ class SettingsAdapter(
|
|||
}
|
||||
val setting = it.setSelectedValue(textInputValue ?: "")
|
||||
fragmentView?.putSetting(setting)
|
||||
fragmentView.loadSettingsList()
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
|
@ -547,7 +488,6 @@ class SettingsAdapter(
|
|||
}
|
||||
notifyItemChanged(position)
|
||||
fragmentView.onSettingChanged()
|
||||
fragmentView.loadSettingsList()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
|
@ -555,19 +495,10 @@ class SettingsAdapter(
|
|||
return true
|
||||
}
|
||||
|
||||
fun onClickDisabledSetting(isRuntimeDisabled: Boolean) {
|
||||
val titleId = if (isRuntimeDisabled)
|
||||
R.string.setting_not_editable
|
||||
else
|
||||
R.string.setting_disabled
|
||||
val messageId = if (isRuntimeDisabled)
|
||||
R.string.setting_not_editable_description
|
||||
else
|
||||
R.string.setting_disabled_description
|
||||
|
||||
fun onClickDisabledSetting() {
|
||||
MessageDialogFragment.newInstance(
|
||||
titleId,
|
||||
messageId
|
||||
R.string.setting_not_editable,
|
||||
R.string.setting_not_editable_description
|
||||
).show((fragmentView as SettingsFragment).childFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
|
||||
|
|
|
@ -237,18 +237,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
IntSetting.FRAME_LIMIT.defaultValue.toFloat()
|
||||
)
|
||||
)
|
||||
add(
|
||||
SliderSetting(
|
||||
IntSetting.TURBO_LIMIT,
|
||||
R.string.turbo_limit,
|
||||
R.string.turbo_limit_description,
|
||||
100,
|
||||
400,
|
||||
"%",
|
||||
IntSetting.TURBO_LIMIT.key,
|
||||
IntSetting.TURBO_LIMIT.defaultValue.toFloat()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,7 +526,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
DateTimeSetting(
|
||||
StringSetting.INIT_TIME,
|
||||
R.string.simulated_clock,
|
||||
R.string.simulated_clock_description,
|
||||
R.string.init_time_description,
|
||||
StringSetting.INIT_TIME.key,
|
||||
StringSetting.INIT_TIME.defaultValue
|
||||
)
|
||||
|
@ -926,7 +914,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
R.string.factor3d,
|
||||
R.string.factor3d_description,
|
||||
0,
|
||||
255,
|
||||
100,
|
||||
"%",
|
||||
IntSetting.STEREOSCOPIC_3D_DEPTH.key,
|
||||
IntSetting.STEREOSCOPIC_3D_DEPTH.defaultValue.toFloat()
|
||||
|
@ -1050,15 +1038,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
IntSetting.ORIENTATION_OPTION.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SwitchSetting(
|
||||
BooleanSetting.EXPAND_TO_CUTOUT_AREA,
|
||||
R.string.expand_to_cutout_area,
|
||||
R.string.expand_to_cutout_area_description,
|
||||
BooleanSetting.EXPAND_TO_CUTOUT_AREA.key,
|
||||
BooleanSetting.EXPAND_TO_CUTOUT_AREA.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.SCREEN_LAYOUT,
|
||||
|
@ -1092,18 +1071,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
IntSetting.SMALL_SCREEN_POSITION.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SliderSetting(
|
||||
IntSetting.SCREEN_GAP,
|
||||
R.string.screen_gap,
|
||||
R.string.screen_gap_description,
|
||||
0,
|
||||
480,
|
||||
"px",
|
||||
IntSetting.SCREEN_GAP.key,
|
||||
IntSetting.SCREEN_GAP.defaultValue.toFloat()
|
||||
)
|
||||
)
|
||||
add(
|
||||
SliderSetting(
|
||||
FloatSetting.LARGE_SCREEN_PROPORTION,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -47,7 +47,7 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
|
|||
val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
|
||||
binding.textSettingValue.text = dateFormatter.format(zonedTime)
|
||||
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
binding.textSettingName.alpha = 1f
|
||||
binding.textSettingDescription.alpha = 1f
|
||||
binding.textSettingValue.alpha = 1f
|
||||
|
@ -59,18 +59,18 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
|
|||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
adapter.onDateTimeClick(setting, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean {
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
return adapter.onLongClick(setting.setting!!, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -45,7 +45,7 @@ class InputBindingSettingViewHolder(val binding: ListItemSettingBinding, adapter
|
|||
if (setting.isEditable) {
|
||||
adapter.onInputBindingClick(setting, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class InputBindingSettingViewHolder(val binding: ListItemSettingBinding, adapter
|
|||
if (setting.isEditable) {
|
||||
adapter.onLongClick(setting.setting!!, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -60,7 +60,7 @@ class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
|
|||
|
||||
override fun onClick(clicked: View) {
|
||||
if (!setting.isRuntimeRunnable && EmulationActivity.isRunning()) {
|
||||
adapter.onClickDisabledSetting(true)
|
||||
adapter.onClickDisabledSetting()
|
||||
} else {
|
||||
setting.runnable.invoke()
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -27,7 +27,7 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti
|
|||
binding.textSettingValue.visibility = View.VISIBLE
|
||||
binding.textSettingValue.text = getTextSetting()
|
||||
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
binding.textSettingName.alpha = 1f
|
||||
binding.textSettingDescription.alpha = 1f
|
||||
binding.textSettingValue.alpha = 1f
|
||||
|
@ -65,8 +65,8 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti
|
|||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (!setting.isEditable || !setting.isEnabled) {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
if (!setting.isEditable) {
|
||||
adapter.onClickDisabledSetting()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -84,10 +84,10 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti
|
|||
}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean {
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
return adapter.onLongClick(setting.setting!!, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -35,7 +35,7 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda
|
|||
else -> "${(setting.setting as AbstractIntSetting).int}${setting.units}"
|
||||
}
|
||||
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
binding.textSettingName.alpha = 1f
|
||||
binding.textSettingDescription.alpha = 1f
|
||||
binding.textSettingValue.alpha = 1f
|
||||
|
@ -47,18 +47,18 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda
|
|||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
adapter.onSliderClick(setting, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean {
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
return adapter.onLongClick(setting.setting!!, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -25,31 +25,21 @@ class StringInputViewHolder(val binding: ListItemSettingBinding, adapter: Settin
|
|||
}
|
||||
binding.textSettingValue.visibility = View.VISIBLE
|
||||
binding.textSettingValue.text = setting.setting?.valueAsString
|
||||
|
||||
if (setting.isActive) {
|
||||
binding.textSettingName.alpha = 1f
|
||||
binding.textSettingDescription.alpha = 1f
|
||||
binding.textSettingValue.alpha = 1f
|
||||
} else {
|
||||
binding.textSettingName.alpha = 0.5f
|
||||
binding.textSettingDescription.alpha = 0.5f
|
||||
binding.textSettingValue.alpha = 0.5f
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (!setting.isEditable || !setting.isEnabled) {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
if (!setting.isEditable) {
|
||||
adapter.onClickDisabledSetting()
|
||||
return
|
||||
}
|
||||
adapter.onStringInputClick((setting as StringInputSetting), bindingAdapterPosition)
|
||||
}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean {
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
return adapter.onLongClick(setting.setting!!, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -33,26 +33,26 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter
|
|||
adapter.onBooleanClick(item, bindingAdapterPosition, binding.switchWidget.isChecked)
|
||||
}
|
||||
|
||||
binding.switchWidget.isEnabled = setting.isActive
|
||||
binding.switchWidget.isEnabled = setting.isEditable
|
||||
|
||||
val textAlpha = if (setting.isActive) 1f else 0.5f
|
||||
val textAlpha = if (setting.isEditable) 1f else 0.5f
|
||||
binding.textSettingName.alpha = textAlpha
|
||||
binding.textSettingDescription.alpha = textAlpha
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
binding.switchWidget.toggle()
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean {
|
||||
if (setting.isActive) {
|
||||
if (setting.isEditable) {
|
||||
return adapter.onLongClick(setting.setting!!, bindingAdapterPosition)
|
||||
} else {
|
||||
adapter.onClickDisabledSetting(!setting.isEditable)
|
||||
adapter.onClickDisabledSetting()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -22,7 +22,6 @@ import android.view.Surface
|
|||
import android.view.SurfaceHolder
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.PopupMenu
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
|
@ -233,15 +232,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
)
|
||||
}
|
||||
|
||||
binding.inGameMenu.getHeaderView(0).apply {
|
||||
val titleView = findViewById<TextView>(R.id.text_game_title)
|
||||
val iconView = findViewById<ImageView>(R.id.game_icon)
|
||||
|
||||
titleView.text = game.title
|
||||
|
||||
GameIconUtils.loadGameIcon(requireActivity(), game, iconView)
|
||||
}
|
||||
|
||||
binding.inGameMenu.getHeaderView(0).findViewById<TextView>(R.id.text_game_title).text =
|
||||
game.title
|
||||
binding.inGameMenu.setNavigationItemSelectedListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_emulation_pause -> {
|
||||
|
@ -455,14 +447,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
Choreographer.getInstance().postFrameCallback(this)
|
||||
if (NativeLibrary.isRunning()) {
|
||||
NativeLibrary.unPauseEmulation()
|
||||
binding.inGameMenu.menu.findItem(R.id.menu_emulation_pause)?.let { menuItem ->
|
||||
menuItem.title = resources.getString(R.string.pause_emulation)
|
||||
menuItem.icon = ResourcesCompat.getDrawable(
|
||||
resources,
|
||||
R.drawable.ic_pause,
|
||||
requireContext().theme
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -549,6 +533,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
val slot = i
|
||||
var enableClick = isSaving
|
||||
val text = if (slot == NativeLibrary.QUICKSAVE_SLOT) {
|
||||
enableClick = false
|
||||
getString(R.string.emulation_quicksave_slot)
|
||||
} else {
|
||||
getString(R.string.emulation_empty_state_slot, slot)
|
||||
|
@ -557,14 +542,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
add(text).setEnabled(enableClick).setOnMenuItemClickListener {
|
||||
if(isSaving) {
|
||||
NativeLibrary.saveState(slot)
|
||||
Toast.makeText(context,
|
||||
getString(R.string.saving),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
NativeLibrary.loadState(slot)
|
||||
binding.drawerLayout.close()
|
||||
Toast.makeText(context,
|
||||
getString(R.string.loading),
|
||||
getString(R.string.quickload_loading),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
true
|
||||
|
@ -575,6 +557,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
savestates?.forEach {
|
||||
var enableClick = true
|
||||
val text = if(it.slot == NativeLibrary.QUICKSAVE_SLOT) {
|
||||
// do not allow saving in quicksave slot
|
||||
enableClick = !isSaving
|
||||
getString(R.string.emulation_occupied_quicksave_slot, it.time)
|
||||
} else{
|
||||
getString(R.string.emulation_occupied_state_slot, it.slot, it.time)
|
||||
|
@ -902,10 +886,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
val layoutOptionMenuItem = when (IntSetting.PORTRAIT_SCREEN_LAYOUT.int) {
|
||||
PortraitScreenLayout.TOP_FULL_WIDTH.int ->
|
||||
R.id.menu_portrait_layout_top_full
|
||||
PortraitScreenLayout.ORIGINAL.int ->
|
||||
R.id.menu_portrait_layout_original
|
||||
|
||||
PortraitScreenLayout.CUSTOM_PORTRAIT_LAYOUT.int ->
|
||||
R.id.menu_portrait_layout_custom
|
||||
|
||||
else ->
|
||||
R.id.menu_portrait_layout_top_full
|
||||
|
||||
|
@ -920,11 +904,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
true
|
||||
}
|
||||
|
||||
R.id.menu_portrait_layout_original -> {
|
||||
screenAdjustmentUtil.changePortraitOrientation(PortraitScreenLayout.ORIGINAL.int)
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_portrait_layout_custom -> {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
|
@ -954,12 +933,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
|
||||
private fun showToggleControlsDialog() {
|
||||
val editor = preferences.edit()
|
||||
val enabledButtons = BooleanArray(16)
|
||||
val enabledButtons = BooleanArray(15)
|
||||
enabledButtons.forEachIndexed { i: Int, _: Boolean ->
|
||||
// Buttons that are disabled by default
|
||||
var defaultValue = true
|
||||
when (i) {
|
||||
6, 7, 12, 13, 14, 15 -> defaultValue = false
|
||||
6, 7, 12, 13, 14 -> defaultValue = false
|
||||
}
|
||||
enabledButtons[i] = preferences.getBoolean("buttonToggle$i", defaultValue)
|
||||
}
|
||||
|
@ -1137,10 +1116,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
.apply()
|
||||
|
||||
val editor = preferences.edit()
|
||||
for (i in 0 until 16) {
|
||||
for (i in 0 until 15) {
|
||||
var defaultValue = true
|
||||
when (i) {
|
||||
6, 7, 12, 13, 14, 15 -> defaultValue = false
|
||||
6, 7, 12, 13, 14 -> defaultValue = false
|
||||
}
|
||||
editor.putBoolean("buttonToggle$i", defaultValue)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -25,7 +25,6 @@ import org.citra.citra_emu.CitraApplication
|
|||
import org.citra.citra_emu.NativeLibrary
|
||||
import org.citra.citra_emu.R
|
||||
import org.citra.citra_emu.utils.EmulationMenuSettings
|
||||
import org.citra.citra_emu.utils.TurboHelper
|
||||
import java.lang.NullPointerException
|
||||
import kotlin.math.min
|
||||
|
||||
|
@ -45,7 +44,6 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||
private var buttonBeingConfigured: InputOverlayDrawableButton? = null
|
||||
private var dpadBeingConfigured: InputOverlayDrawableDpad? = null
|
||||
private var joystickBeingConfigured: InputOverlayDrawableJoystick? = null
|
||||
private val settingsViewModel = NativeLibrary.sEmulationActivity.get()!!.settingsViewModel
|
||||
|
||||
// Stores the ID of the pointer that interacted with the 3DS touchscreen.
|
||||
private var touchscreenPointerId = -1
|
||||
|
@ -106,10 +104,6 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||
swapScreen()
|
||||
}
|
||||
|
||||
if (button.id == NativeLibrary.ButtonType.BUTTON_TURBO && button.status == NativeLibrary.ButtonState.PRESSED) {
|
||||
TurboHelper.setTurboEnabled((!TurboHelper.isTurboSpeedEnabled()))
|
||||
}
|
||||
|
||||
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.id, button.status)
|
||||
shouldUpdateView = true
|
||||
}
|
||||
|
@ -474,18 +468,6 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (preferences.getBoolean("buttonToggle15", false)) {
|
||||
overlayButtons.add(
|
||||
initializeOverlayButton(
|
||||
context,
|
||||
R.drawable.button_turbo,
|
||||
R.drawable.button_turbo_pressed,
|
||||
NativeLibrary.ButtonType.BUTTON_TURBO,
|
||||
orientation
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshControls() {
|
||||
|
@ -691,14 +673,6 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||
NativeLibrary.ButtonType.BUTTON_SWAP.toString() + "-Y",
|
||||
resources.getInteger(R.integer.N3DS_BUTTON_SWAP_Y).toFloat() / 1000 * maxY
|
||||
)
|
||||
.putFloat(
|
||||
NativeLibrary.ButtonType.BUTTON_TURBO.toString() + "-X",
|
||||
resources.getInteger(R.integer.N3DS_BUTTON_TURBO_X).toFloat() / 1000 * maxX
|
||||
)
|
||||
.putFloat(
|
||||
NativeLibrary.ButtonType.BUTTON_TURBO.toString() + "-Y",
|
||||
resources.getInteger(R.integer.N3DS_BUTTON_TURBO_Y).toFloat() / 1000 * maxY
|
||||
)
|
||||
.apply()
|
||||
}
|
||||
|
||||
|
@ -842,14 +816,6 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||
NativeLibrary.ButtonType.BUTTON_SWAP.toString() + portrait + "-Y",
|
||||
resources.getInteger(R.integer.N3DS_BUTTON_SWAP_PORTRAIT_Y).toFloat() / 1000 * maxY
|
||||
)
|
||||
.putFloat(
|
||||
NativeLibrary.ButtonType.BUTTON_TURBO.toString() + portrait + "-X",
|
||||
resources.getInteger(R.integer.N3DS_BUTTON_TURBO_PORTRAIT_X).toFloat() / 1000 * maxX
|
||||
)
|
||||
.putFloat(
|
||||
NativeLibrary.ButtonType.BUTTON_TURBO.toString() + portrait + "-Y",
|
||||
resources.getInteger(R.integer.N3DS_BUTTON_TURBO_PORTRAIT_Y).toFloat() / 1000 * maxY
|
||||
)
|
||||
.apply()
|
||||
}
|
||||
|
||||
|
@ -962,7 +928,6 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||
NativeLibrary.ButtonType.BUTTON_START,
|
||||
NativeLibrary.ButtonType.BUTTON_SELECT,
|
||||
NativeLibrary.ButtonType.BUTTON_SWAP -> 0.08f
|
||||
NativeLibrary.ButtonType.BUTTON_TURBO -> 0.10f
|
||||
|
||||
NativeLibrary.ButtonType.TRIGGER_L,
|
||||
NativeLibrary.ButtonType.TRIGGER_R,
|
||||
|
|
|
@ -106,40 +106,6 @@ class DocumentsTree {
|
|||
return node.uri ?: return Uri.EMPTY
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun folderUriHelper(path: String, createIfNotExists: Boolean = false): Uri? {
|
||||
root ?: return null
|
||||
val components = path.split(DELIMITER).filter { it.isNotEmpty() }
|
||||
var current = root
|
||||
|
||||
for (component in components) {
|
||||
if (!current!!.loaded) {
|
||||
structTree(current)
|
||||
}
|
||||
|
||||
var child = current.findChild(component)
|
||||
|
||||
// Create directory if it doesn't exist and creation is enabled
|
||||
if (child == null && createIfNotExists) {
|
||||
try {
|
||||
val createdDir = FileUtil.createDir(current.uri.toString(), component) ?: return null
|
||||
child = DocumentsNode(createdDir, true).apply {
|
||||
parent = current
|
||||
}
|
||||
current.addChild(child)
|
||||
} catch (e: Exception) {
|
||||
error("[DocumentsTree]: Cannot create directory, error: " + e.message)
|
||||
return null
|
||||
}
|
||||
} else if (child == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
current = child
|
||||
}
|
||||
return current?.uri
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun isDirectory(filepath: String): Boolean {
|
||||
val node = resolvePath(filepath) ?: return false
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
package org.citra.citra_emu.utils
|
||||
|
||||
import android.widget.Toast
|
||||
import org.citra.citra_emu.CitraApplication
|
||||
import org.citra.citra_emu.NativeLibrary
|
||||
import org.citra.citra_emu.R
|
||||
import org.citra.citra_emu.features.settings.model.IntSetting
|
||||
|
||||
object TurboHelper {
|
||||
private var turboSpeedEnabled = false
|
||||
|
||||
fun isTurboSpeedEnabled(): Boolean {
|
||||
return turboSpeedEnabled
|
||||
}
|
||||
|
||||
fun setTurboEnabled(state: Boolean) {
|
||||
turboSpeedEnabled = state
|
||||
reloadTurbo()
|
||||
}
|
||||
|
||||
fun reloadTurbo() {
|
||||
val context = CitraApplication.appContext
|
||||
val toastMessage: String
|
||||
|
||||
if (turboSpeedEnabled) {
|
||||
NativeLibrary.setTemporaryFrameLimit(IntSetting.TURBO_LIMIT.int.toDouble())
|
||||
toastMessage = context.getString(R.string.turbo_enabled_toast)
|
||||
} else {
|
||||
NativeLibrary.disableTemporaryFrameLimit()
|
||||
toastMessage = context.getString(R.string.turbo_disabled_toast)
|
||||
}
|
||||
|
||||
Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
|
@ -149,8 +149,8 @@ void Config::ReadValues() {
|
|||
ReadSetting("Renderer", Settings::values.use_vsync_new);
|
||||
ReadSetting("Renderer", Settings::values.texture_filter);
|
||||
ReadSetting("Renderer", Settings::values.texture_sampling);
|
||||
ReadSetting("Renderer", Settings::values.turbo_limit);
|
||||
// Workaround to map Android setting for enabling the frame limiter to the format Citra expects
|
||||
|
||||
// Work around to map Android setting for enabling the frame limiter to the format Citra expects
|
||||
if (sdl2_config->GetBoolean("Renderer", "use_frame_limit", true)) {
|
||||
ReadSetting("Renderer", Settings::values.frame_limit);
|
||||
} else {
|
||||
|
@ -183,13 +183,11 @@ void Config::ReadValues() {
|
|||
layoutInt = static_cast<int>(Settings::LayoutOption::LargeScreen);
|
||||
}
|
||||
Settings::values.layout_option = static_cast<Settings::LayoutOption>(layoutInt);
|
||||
Settings::values.screen_gap = static_cast<int>(sdl2_config->GetReal("Layout", "screen_gap", 0));
|
||||
Settings::values.large_screen_proportion =
|
||||
static_cast<float>(sdl2_config->GetReal("Layout", "large_screen_proportion", 2.25));
|
||||
Settings::values.small_screen_position = static_cast<Settings::SmallScreenPosition>(
|
||||
sdl2_config->GetInteger("Layout", "small_screen_position",
|
||||
static_cast<int>(Settings::SmallScreenPosition::TopRight)));
|
||||
ReadSetting("Layout", Settings::values.screen_gap);
|
||||
ReadSetting("Layout", Settings::values.custom_top_x);
|
||||
ReadSetting("Layout", Settings::values.custom_top_y);
|
||||
ReadSetting("Layout", Settings::values.custom_top_width);
|
||||
|
|
|
@ -156,10 +156,6 @@ use_frame_limit =
|
|||
# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default)
|
||||
frame_limit =
|
||||
|
||||
# Alternative frame limit which can be triggered by the user
|
||||
# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default)
|
||||
turbo_limit =
|
||||
|
||||
# The clear color for the renderer. What shows up on the sides of the bottom screen.
|
||||
# Must be in range of 0.0-1.0. Defaults to 0.0 for all.
|
||||
bg_red =
|
||||
|
@ -171,7 +167,7 @@ bg_green =
|
|||
render_3d =
|
||||
|
||||
# Change 3D Intensity
|
||||
# 0 - 255: Intensity. 0 (default)
|
||||
# 0 - 100: Intensity. 0 (default)
|
||||
factor_3d =
|
||||
|
||||
# The name of the post processing shader to apply.
|
||||
|
@ -206,12 +202,6 @@ disable_right_eye_render =
|
|||
# 5: Custom Layout
|
||||
layout_option =
|
||||
|
||||
# Screen Gap - adds a gap between screens in all two-screen modes
|
||||
# Measured in pixels relative to the 240px default height of the screens
|
||||
# Scales with the larger screen (so 24 is 10% of the larger screen height)
|
||||
# Default value is 0.0
|
||||
screen_gap =
|
||||
|
||||
# Large Screen Proportion - Relative size of large:small in large screen mode
|
||||
# Default value is 2.25
|
||||
large_screen_proportion =
|
||||
|
@ -266,10 +256,6 @@ custom_portrait_bottom_height =
|
|||
# 0 (default): Top Screen is prominent, 1: Bottom Screen is prominent
|
||||
swap_screen =
|
||||
|
||||
# Expands the display area to include the cutout (or notch) area
|
||||
# 0 (default): Off, 1: On
|
||||
expand_to_cutout_area =
|
||||
|
||||
# Screen placement settings when using Cardboard VR (render3d = 4)
|
||||
# 30 - 100: Screen size as a percentage of the viewport. 85 (default)
|
||||
cardboard_screen_size =
|
||||
|
|
|
@ -215,8 +215,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
||||
|
||||
std::unique_ptr<Frontend::GraphicsContext> cpu_context;
|
||||
system.GPU().Renderer().Rasterizer()->LoadDefaultDiskResources(stop_run,
|
||||
&LoadDiskCacheProgress);
|
||||
system.GPU().Renderer().Rasterizer()->LoadDiskResources(stop_run, &LoadDiskCacheProgress);
|
||||
|
||||
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
|
||||
|
||||
|
@ -782,14 +781,4 @@ void Java_org_citra_citra_1emu_NativeLibrary_unlinkConsole(JNIEnv* env, jobject
|
|||
HW::UniqueData::UnlinkConsole();
|
||||
}
|
||||
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_setTemporaryFrameLimit(JNIEnv* env, jobject obj,
|
||||
jdouble speed) {
|
||||
Settings::temporary_frame_limit = speed;
|
||||
Settings::is_temporary_frame_limit = true;
|
||||
}
|
||||
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_disableTemporaryFrameLimit(JNIEnv* env, jobject obj) {
|
||||
Settings::is_temporary_frame_limit = false;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.2 KiB |
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?attr/colorControlNormal"
|
||||
android:pathData="M20,6h-8l-2,-2H4C2.89,4 2,4.89 2,6v12c0,1.1 0.89,2 2,2h16c1.1,0 2,-0.9 2,-2V8C22,6.89 21.1,6 20,6zM19,18H5V8h14v10zM12,9l-4,4h3v3h2v-3h3L12,9z"/>
|
||||
</vector>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?attr/colorControlNormal"
|
||||
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
|
||||
</vector>
|
|
@ -110,24 +110,6 @@
|
|||
android:text="@string/play"
|
||||
app:icon="@drawable/ic_play" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/menu_button_open"
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
app:icon="@drawable/ic_open"
|
||||
app:iconGravity="textStart" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/menu_button_uninstall"
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
app:icon="@drawable/ic_uninstall"
|
||||
app:iconGravity="textStart" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/game_shortcut"
|
||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
||||
|
@ -138,6 +120,11 @@
|
|||
app:icon="@drawable/ic_shortcut"
|
||||
app:iconGravity="textStart" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -161,7 +148,6 @@
|
|||
android:contentDescription="@string/cheats"
|
||||
android:text="@string/cheats" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -1,26 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/text_game_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/game_icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="16dp"/>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/text_game_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?attr/textAppearanceHeadlineMedium"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="text_game_title" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_marginEnd="24dp"
|
||||
android:textAppearance="?attr/textAppearanceHeadlineMedium"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="Super Mario 3D Land" />
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/game_context_open_app"
|
||||
android:title="@string/game_context_open_app" />
|
||||
<item
|
||||
android:id="@+id/game_context_open_save_dir"
|
||||
android:title="@string/game_context_open_save_dir" />
|
||||
<item
|
||||
android:id="@+id/game_context_open_updates"
|
||||
android:title="@string/game_context_open_updates" />
|
||||
<item
|
||||
android:id="@+id/game_context_open_dlc"
|
||||
android:title="@string/game_context_open_dlc" />
|
||||
<item
|
||||
android:id="@+id/game_context_open_extra"
|
||||
android:title="@string/game_context_open_extra" />
|
||||
<item
|
||||
android:id="@+id/game_context_open_textures"
|
||||
android:title="@string/game_context_open_textures" />
|
||||
<item
|
||||
android:id="@+id/game_context_open_mods"
|
||||
android:title="@string/game_context_open_mods" />
|
||||
</menu>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/game_context_uninstall"
|
||||
android:title="@string/uninstall_cia" />
|
||||
<item
|
||||
android:id="@+id/game_context_uninstall_dlc"
|
||||
android:title="@string/game_context_uninstall_dlc" />
|
||||
<item
|
||||
android:id="@+id/game_context_uninstall_updates"
|
||||
android:title="@string/game_context_uninstall_updates" />
|
||||
</menu>
|
|
@ -7,10 +7,6 @@
|
|||
android:id="@+id/menu_portrait_layout_top_full"
|
||||
android:title="@string/emulation_portrait_layout_top_full" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_portrait_layout_original"
|
||||
android:title="@string/emulation_screen_layout_original" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_portrait_layout_custom"
|
||||
android:title="@string/emulation_screen_layout_custom" />
|
||||
|
|
|
@ -31,13 +31,11 @@
|
|||
|
||||
<string-array name="portraitLayouts">
|
||||
<item>@string/emulation_portrait_layout_top_full</item>
|
||||
<item>@string/emulation_screen_layout_original</item>
|
||||
<item>@string/emulation_screen_layout_custom</item>
|
||||
</string-array>
|
||||
|
||||
<integer-array name="portraitLayoutValues">
|
||||
<item>0</item>
|
||||
<item>2</item>
|
||||
<item>1</item>
|
||||
</integer-array>
|
||||
|
||||
|
@ -131,7 +129,6 @@
|
|||
<item>@string/controller_c</item>
|
||||
<item>@string/button_home</item>
|
||||
<item>@string/button_swap</item>
|
||||
<item>@string/button_turbo</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="cameraImageSourceNames">
|
||||
|
@ -312,7 +309,6 @@
|
|||
</integer-array>
|
||||
|
||||
<string-array name="resolutionFactorNames">
|
||||
<item>@string/internal_resolution_setting_auto</item>
|
||||
<item>@string/internal_resolution_setting_1x</item>
|
||||
<item>@string/internal_resolution_setting_2x</item>
|
||||
<item>@string/internal_resolution_setting_3x</item>
|
||||
|
@ -325,7 +321,6 @@
|
|||
<item>@string/internal_resolution_setting_10x</item>
|
||||
</string-array>
|
||||
<integer-array name="resolutionFactorValues">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
<integer name="N3DS_BUTTON_HOME_Y">850</integer>
|
||||
<integer name="N3DS_BUTTON_SWAP_X">370</integer>
|
||||
<integer name="N3DS_BUTTON_SWAP_Y">850</integer>
|
||||
<integer name="N3DS_BUTTON_TURBO_X">630</integer>
|
||||
<integer name="N3DS_BUTTON_TURBO_Y">850</integer>
|
||||
|
||||
<!-- Default N3DS portrait layout -->
|
||||
<integer name="N3DS_BUTTON_A_PORTRAIT_X">810</integer>
|
||||
|
@ -67,7 +65,5 @@
|
|||
<integer name="N3DS_BUTTON_START_PORTRAIT_Y">794</integer>
|
||||
<integer name="N3DS_BUTTON_SWAP_PORTRAIT_X">460</integer>
|
||||
<integer name="N3DS_BUTTON_SWAP_PORTRAIT_Y">675</integer>
|
||||
<integer name="N3DS_BUTTON_TURBO_PORTRAIT_X">453</integer>
|
||||
<integer name="N3DS_BUTTON_TURBO_PORTRAIT_Y">720</integer>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
<string name="app_notification_channel_description">Azahar 3DS emulator notifications</string>
|
||||
<string name="app_notification_running">Azahar is Running</string>
|
||||
<string name="app_game_install_description">Next, you will need to select an Applications Folder. Azahar will display all of the 3DS ROMs inside of the selected folder in the app.\n\nCIA ROMs, updates and DLC will need to be installed separately by clicking on the folder icon and selecting Install CIA.</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="cancelling">Cancelling…</string>
|
||||
<string name="important">Important</string>
|
||||
<string name="dont_show_again">Don\'t show again</string>
|
||||
|
||||
<!-- Home Strings -->
|
||||
<string name="grid_menu_core_settings">Settings</string>
|
||||
|
@ -137,7 +141,6 @@
|
|||
<string name="button_start" translatable="false">START</string>
|
||||
<string name="button_home">HOME</string>
|
||||
<string name="button_swap">Swap Screens</string>
|
||||
<string name="button_turbo">Turbo</string>
|
||||
<string name="button_x" translatable="false">X</string>
|
||||
<string name="button_y" translatable="false">Y</string>
|
||||
<string name="button_l" translatable="false">L</string>
|
||||
|
@ -146,9 +149,6 @@
|
|||
<string name="button_zr" translatable="false">ZR</string>
|
||||
<string name="input_message_analog_only">This control must be bound to a gamepad analog stick or D-pad axis!</string>
|
||||
<string name="input_message_button_only">This control must be bound to a gamepad button!</string>
|
||||
<string name="turbo_limit_hotkey">Turbo Speed</string>
|
||||
<string name="turbo_enabled_toast">Turbo Speed Enabled</string>
|
||||
<string name="turbo_disabled_toast">Turbo Speed Disabled</string>
|
||||
|
||||
<!-- System files strings -->
|
||||
<string name="setup_system_files">System Files</string>
|
||||
|
@ -174,20 +174,20 @@
|
|||
<string name="generic_buttons">Buttons</string>
|
||||
<string name="button">Button</string>
|
||||
|
||||
<!-- Core settings strings -->
|
||||
<string name="cpu_jit">CPU JIT</string>
|
||||
<string name="cpu_jit_description">Uses the Just-in-Time (JIT) compiler for CPU emulation. When enabled, game performance will be significantly improved.</string>
|
||||
<string name="init_clock">Clock</string>
|
||||
<string name="init_clock_description">Set the emulated 3DS clock to either reflect that of your device or start at a simulated date and time.</string>
|
||||
<string name="cpu_clock_speed">CPU Clock Speed</string>
|
||||
|
||||
<!-- System settings strings -->
|
||||
<string name="emulation_settings">Emulation Settings</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="new_3ds">New 3DS Mode</string>
|
||||
<string name="lle_applets">Use LLE Applets (if installed)</string>
|
||||
<string name="enable_required_online_lle_modules">Enable required LLE modules for online features (if installed)</string>
|
||||
<string name="enable_required_online_lle_modules_desc">Enables the LLE modules required for online multiplayer, eShop access, etc.</string>
|
||||
<string name="clock">Clock</string>
|
||||
<string name="init_clock">Clock</string>
|
||||
<string name="init_clock_description">Set the emulated 3DS clock to either reflect that of your device or start at a simulated date and time.</string>
|
||||
<string name="device_clock">Device Clock</string>
|
||||
<string name="simulated_clock">Simulated Clock</string>
|
||||
<string name="simulated_clock_description">If the clock is set to \"Simulated clock\", this changes the fixed date and time to start at.</string>
|
||||
<string name="profile_settings">Profile Settings</string>
|
||||
<string name="init_time">Offset Time</string>
|
||||
<string name="init_time_description">If the clock is set to \"Simulated clock\", this changes the fixed date and time to start at.</string>
|
||||
<string name="emulated_region">Region</string>
|
||||
<string name="emulated_language">Language</string>
|
||||
<string name="birthday">Birthday</string>
|
||||
|
@ -200,9 +200,6 @@
|
|||
<string name="console_id">Console ID</string>
|
||||
<string name="regenerate_console_id">Regenerate Console ID</string>
|
||||
<string name="regenerate_console_id_description">This will replace your current virtual 3DS console ID with a new one. Your current virtual 3DS console ID will not be recoverable. This might have unexpected effects inside applications. This might fail if you use an outdated config save. Continue?</string>
|
||||
<string name="mac_address">MAC Address</string>
|
||||
<string name="regenerate_mac_address">Regenerate MAC Address</string>
|
||||
<string name="regenerate_mac_address_description">This will replace your current MAC address with a new one. It is not recommended to do this if you got the MAC address from your real console using the setup tool. Continue?</string>
|
||||
<string name="plugin_loader">3GX Plugin Loader</string>
|
||||
<string name="plugin_loader_description">Loads 3GX plugins from the emulated SD card if they are available.</string>
|
||||
<string name="allow_plugin_loader">Allow Applications to Change Plugin Loader State</string>
|
||||
|
@ -231,30 +228,29 @@
|
|||
<string name="spirv_shader_gen_description">Emits the fragment shader used to emulate PICA using SPIR-V instead of GLSL</string>
|
||||
<string name="async_shaders">Enable asynchronous shader compilation</string>
|
||||
<string name="async_shaders_description">Compiles shaders in the background to reduce stuttering during gameplay. When enabled expect temporary graphical glitches</string>
|
||||
<string name="renderer_debug">Debug Renderer</string>
|
||||
<string name="renderer_debug_description">Log additional graphics related debug information. When enabled, game performance will be significantly reduced.</string>
|
||||
<string name="vsync">Enable V-Sync</string>
|
||||
<string name="vsync_description">Synchronizes the game frame rate to the refresh rate of your device.</string>
|
||||
<string name="linear_filtering">Linear Filtering</string>
|
||||
<string name="linear_filtering_description">Enables linear filtering, which causes game visuals to appear smoother.</string>
|
||||
<string name="texture_filter_name">Texture Filter</string>
|
||||
<string name="texture_filter_description">Enhances the visuals of applications by applying a filter to textures. The supported filters are Anime4K Ultrafast, Bicubic, ScaleForce, xBRZ freescale, and MMPX.</string>
|
||||
<string name="delay_render_thread">Delay game render thread</string>
|
||||
<string name="delay_render_thread_description">Delay the game render thread when it submits data to the GPU. Helps with performance issues in the (very few) applications with dynamic framerates.</string>
|
||||
<string name="advanced">Advanced"</string>
|
||||
<string name="texture_sampling_name">Texture Sampling</string>
|
||||
<string name="texture_sampling_description">Overrides the sampling filter used by games. This can be useful in certain cases with poorly behaved games when upscaling. If unsure, set this to Game Controlled.</string>
|
||||
<string name="hw_shaders">Enable Hardware Shader</string>
|
||||
<string name="hw_shaders_description">Uses hardware to emulate 3DS shaders. When enabled, game performance will be significantly improved.</string>
|
||||
<string name="shaders_accurate_mul">Accurate Multiplication</string>
|
||||
<string name="shaders_accurate_mul_description">Uses more accurate multiplication in hardware shaders, which may fix some graphical bugs. When enabled, performance will be reduced.</string>
|
||||
<string name="asynchronous_gpu">Enable asynchronous GPU emulation</string>
|
||||
<string name="asynchronous_gpu_description">Uses a separate thread to emulate the GPU asynchronously. When enabled, performance will be improved.</string>
|
||||
<string name="frame_limit_enable">Limit Speed</string>
|
||||
<string name="frame_limit_enable_description">When enabled, emulation speed will be limited to a specified percentage of normal speed. If disabled, emulation speed will be uncapped and the turbo speed hotkey will not work.</string>
|
||||
<string name="frame_limit_enable_description">When enabled, emulation speed will be limited to a specified percentage of normal speed.</string>
|
||||
<string name="frame_limit_slider">Limit Speed Percent</string>
|
||||
<string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. With the default of 100% emulation will be limited to normal speed. Values higher or lower will increase or decrease the speed limit.</string>
|
||||
<string name="turbo_limit">Turbo Speed Limit</string>
|
||||
<string name="turbo_limit_description">Emulation speed limit used while the turbo hotkey is active.</string>
|
||||
<string name="expand_to_cutout_area">Expand to Cutout Area</string>
|
||||
<string name="expand_to_cutout_area_description">Expands the display area to include the cutout (or notch) area.</string>
|
||||
<string name="internal_resolution">Internal Resolution</string>
|
||||
<string name="internal_resolution_description">Specifies the resolution used to render at. A high resolution will improve visual quality a lot but is also quite heavy on performance and might cause glitches in certain applications.</string>
|
||||
<string name="internal_resolution_setting_auto">Auto (Screen Size)</string>
|
||||
<string name="internal_resolution_setting_1x">Native (400x240)</string>
|
||||
<string name="internal_resolution_setting_2x">2x Native (800x480)</string>
|
||||
<string name="internal_resolution_setting_3x">3x Native (1200x720)</string>
|
||||
|
@ -270,9 +266,7 @@
|
|||
<string name="stereoscopy">Stereoscopy</string>
|
||||
<string name="render3d">Stereoscopic 3D Mode</string>
|
||||
<string name="factor3d">Depth</string>
|
||||
<string name="factor3d_description">Specifies the value of the 3D slider. This should be set to higher than 0% when Stereoscopic 3D is enabled.\nNote: Depth values over 100% are not possible on real hardware and may cause graphical issues</string>
|
||||
<string name="disable_right_eye_render">Disable Right Eye Render</string>
|
||||
<string name="disable_right_eye_render_description">Greatly improves performance in some applications, but can cause flickering in others.</string>
|
||||
<string name="factor3d_description">Specifies the value of the 3D slider. This should be set to higher than 0% when Stereoscopic 3D is enabled.</string>
|
||||
<string name="cardboard_vr">Cardboard VR</string>
|
||||
<string name="cardboard_screen_size">Cardboard Screen Size</string>
|
||||
<string name="cardboard_screen_size_description">Scales the screen to a percentage of its original size.</string>
|
||||
|
@ -302,23 +296,6 @@
|
|||
<string name="audio_input_type">Audio Input Device</string>
|
||||
<string name="sound_output_mode">Sound Output Mode</string>
|
||||
|
||||
<!-- Debug settings strings -->
|
||||
<string name="cpu_jit">CPU JIT</string>
|
||||
<string name="cpu_jit_description">Uses the Just-in-Time (JIT) compiler for CPU emulation. When enabled, game performance will be significantly improved.</string>
|
||||
<string name="hw_shaders">Enable Hardware Shader</string>
|
||||
<string name="hw_shaders_description">Uses hardware to emulate 3DS shaders. When enabled, game performance will be significantly improved.</string>
|
||||
<string name="cpu_clock_speed">CPU Clock Speed</string>
|
||||
<string name="vsync">Enable V-Sync</string>
|
||||
<string name="vsync_description">Synchronizes the game frame rate to the refresh rate of your device.</string>
|
||||
<string name="renderer_debug">Debug Renderer</string>
|
||||
<string name="renderer_debug_description">Log additional graphics related debug information. When enabled, game performance will be significantly reduced.</string>
|
||||
<string name="instant_debug_log">Flush log output on every message</string>
|
||||
<string name="instant_debug_log_description">Immediately commits the debug log to file. Use this if Azahar crashes and the log output is being cut.</string>
|
||||
<string name="delay_start_lle_modules">Delay start with LLE modules</string>
|
||||
<string name="delay_start_lle_modules_description">Delays the start of the app when LLE modules are enabled.</string>
|
||||
<string name="deterministic_async_operations">Deterministic Async Operations</string>
|
||||
<string name="deterministic_async_operations_description">Makes async operations deterministic for debugging. Enabling this may cause freezes.</string>
|
||||
|
||||
<!-- Layout settings strings -->
|
||||
<string name="layout_screen_orientation">Screen Orientation</string>
|
||||
<string name="layout_screen_orientation_auto_sensor">Automatic</string>
|
||||
|
@ -333,7 +310,6 @@
|
|||
<string name="ini_saved">Saved settings</string>
|
||||
<string name="gameid_saved">Saved settings for %1$s</string>
|
||||
<string name="error_saving">Error saving %1$s.ini: %2$s</string>
|
||||
<string name="saving">Saving…</string>
|
||||
<string name="loading">Loading…</string>
|
||||
<string name="next">Next</string>
|
||||
<string name="back">Back</string>
|
||||
|
@ -354,14 +330,8 @@
|
|||
<string name="select_rtc_time">Select RTC time</string>
|
||||
<string name="reset_setting_confirmation">Do you want to reset this setting back to its default value?</string>
|
||||
<string name="setting_not_editable">You can\'t edit this now</string>
|
||||
<string name="setting_disabled">Setting disabled</string>
|
||||
<string name="setting_disabled_description">This setting is currently disabled due to another setting not being the appropriate value.</string>
|
||||
<string name="setting_not_editable_description">This option can\'t be changed while a game is running.</string>
|
||||
<string name="auto_select">Auto-Select</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="cancelling">Cancelling…</string>
|
||||
<string name="important">Important</string>
|
||||
<string name="dont_show_again">Don\'t show again</string>
|
||||
|
||||
<!-- Add Directory Screen-->
|
||||
<string name="select_game_folder">Select Game Folder</string>
|
||||
|
@ -429,8 +399,6 @@
|
|||
<string name="small_screen_position_bottom_left">Bottom Left</string>
|
||||
<string name="small_screen_position_above">Above</string>
|
||||
<string name="small_screen_position_below">Below</string>
|
||||
<string name="screen_gap">Screen Gap</string>
|
||||
<string name="screen_gap_description">Gap between screens in all two-screen modes. Measured in px relative to the 240px height of the larger screen.</string>
|
||||
<string name="large_screen_proportion">Large Screen Proportion</string>
|
||||
<string name="large_screen_proportion_description">How many times larger is the large screen than the small screen in Large Screen layout?</string>
|
||||
<string name="emulation_adjust_custom_layout">Adjust Custom Layout in Settings</string>
|
||||
|
@ -448,9 +416,6 @@
|
|||
<string name="emulation_show_overlay">Show Overlay</string>
|
||||
<string name="emulation_close_game">Close Game</string>
|
||||
<string name="emulation_toggle_pause">Toggle Pause</string>
|
||||
<string name="miscellaneous">Miscellaneous</string>
|
||||
<string name="use_artic_base_controller">Use Artic Controller when connected to Artic Base Server</string>
|
||||
<string name="use_artic_base_controller_description">Use the controls provided by Artic Base Server when connected to it instead of the configured input device.</string>
|
||||
<string name="emulation_close_game_message">Are you sure that you would like to close the current game?</string>
|
||||
<string name="menu_emulation_amiibo">Amiibo</string>
|
||||
<string name="menu_emulation_amiibo_load">Load</string>
|
||||
|
@ -522,17 +487,6 @@
|
|||
<!-- About Game Dialog -->
|
||||
<string name="play">Play</string>
|
||||
<string name="shortcut">Shortcut</string>
|
||||
<string name="uninstall_cia">Uninstall Application</string>
|
||||
<string name="uninstalling">Uninstalling...</string>
|
||||
<string name="game_context_open_save_dir">Open Save Data Folder</string>
|
||||
<string name="game_context_open_app">Open Application Folder</string>
|
||||
<string name="game_context_open_mods">Open Mods Folder</string>
|
||||
<string name="game_context_open_textures">Open Textures Folder</string>
|
||||
<string name="game_context_open_dlc">Open DLC Folder</string>
|
||||
<string name="game_context_open_updates">Open Updates Folder</string>
|
||||
<string name="game_context_open_extra">Open Extra Folder</string>
|
||||
<string name="game_context_uninstall_dlc">Uninstall DLC</string>
|
||||
<string name="game_context_uninstall_updates">Uninstall Updates</string>
|
||||
|
||||
<!-- Cheats -->
|
||||
<string name="cheats">Cheats</string>
|
||||
|
@ -594,6 +548,10 @@
|
|||
<string name="use_black_backgrounds">Black Backgrounds</string>
|
||||
<string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string>
|
||||
|
||||
<!-- Clock types -->
|
||||
<string name="device_clock">Device Clock</string>
|
||||
<string name="simulated_clock">Simulated Clock</string>
|
||||
|
||||
<!-- Region names -->
|
||||
<string name="system_region_jpn">JPN</string>
|
||||
<string name="system_region_usa">USA</string>
|
||||
|
@ -819,12 +777,34 @@
|
|||
<string name="artic_base_connect_description">Connect to a real console that is running an Artic Base server</string>
|
||||
<string name="artic_base_connect">Connect to Artic Base</string>
|
||||
<string name="artic_base_enter_address">Enter Artic Base server address</string>
|
||||
<string name="delay_render_thread">Delay game render thread</string>
|
||||
<string name="delay_render_thread_description">Delay the game render thread when it submits data to the GPU. Helps with performance issues in the (very few) applications with dynamic framerates.</string>
|
||||
|
||||
<!-- Quickload&Save-->
|
||||
<string name="emulation_quicksave_slot">Quicksave</string>
|
||||
<string name="emulation_quicksave">Quicksave</string>
|
||||
<string name="emulation_quickload">Quickload</string>
|
||||
<string name="emulation_occupied_quicksave_slot">Quicksave - %1$tF %1$tR</string>
|
||||
<string name="quicksave_saving">Saving…</string>
|
||||
<string name="quickload_loading">Loading…</string>
|
||||
<string name="quickload_not_found">No Quicksave available.</string>
|
||||
<string name="miscellaneous">Miscellaneous</string>
|
||||
<string name="use_artic_base_controller">Use Artic Controller when connected to Artic Base Server</string>
|
||||
<string name="use_artic_base_controller_description">Use the controls provided by Artic Base Server when connected to it instead of the configured input device.</string>
|
||||
<string name="instant_debug_log">Flush log output on every message</string>
|
||||
<string name="instant_debug_log_description">Immediately commits the debug log to file. Use this if Azahar crashes and the log output is being cut.</string>
|
||||
<string name="disable_right_eye_render">Disable Right Eye Render</string>
|
||||
<string name="disable_right_eye_render_description">Greatly improves performance in some applications, but can cause flickering in others.</string>
|
||||
<string name="delay_start_lle_modules">Delay start with LLE modules</string>
|
||||
<string name="delay_start_lle_modules_description">Delays the start of the app when LLE modules are enabled.</string>
|
||||
<string name="deterministic_async_operations">Deterministic Async Operations</string>
|
||||
<string name="deterministic_async_operations_description">Makes async operations deterministic for debugging. Enabling this may cause freezes.</string>
|
||||
<string name="enable_required_online_lle_modules">Enable required LLE modules for online features (if installed)</string>
|
||||
<string name="enable_required_online_lle_modules_desc">Enables the LLE modules required for online multiplayer, eShop access, etc.</string>
|
||||
<string name="emulation_settings">Emulation Settings</string>
|
||||
<string name="profile_settings">Profile Settings</string>
|
||||
<string name="mac_address">MAC Address</string>
|
||||
<string name="regenerate_mac_address">Regenerate MAC Address</string>
|
||||
<string name="regenerate_mac_address_description">This will replace your current MAC address with a new one. It is not recommended to do this if you got the MAC address from your real console using the setup tool. Continue?</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2018 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -144,11 +144,6 @@ Samples CubebInput::Read() {
|
|||
while (impl->sample_queue.Pop(queue)) {
|
||||
samples.insert(samples.end(), queue.begin(), queue.end());
|
||||
}
|
||||
|
||||
if (samples.empty()) {
|
||||
samples = GenerateSilentSamples(parameters);
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -53,22 +53,6 @@ public:
|
|||
*/
|
||||
virtual Samples Read() = 0;
|
||||
|
||||
/**
|
||||
* Generates a buffer of silence.
|
||||
* Takes into account the sample size and signedness of the input.
|
||||
*/
|
||||
virtual Samples GenerateSilentSamples(const InputParameters& params) {
|
||||
u8 silent_value = 0x00;
|
||||
|
||||
if (params.sample_size == 8) {
|
||||
silent_value = params.sign == Signedness::Unsigned ? 0x80 : 0x00;
|
||||
return std::vector<u8>(32, silent_value);
|
||||
} else {
|
||||
silent_value = params.sign == Signedness::Unsigned ? 0x80 : 0x00;
|
||||
return std::vector<u8>(64, silent_value);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
InputParameters parameters;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2019 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -30,11 +30,10 @@ public:
|
|||
void AdjustSampleRate(u32 sample_rate) override {}
|
||||
|
||||
Samples Read() override {
|
||||
return GenerateSilentSamples(parameters);
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
InputParameters parameters;
|
||||
bool is_sampling = false;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -108,10 +108,6 @@ Samples OpenALInput::Read() {
|
|||
return {};
|
||||
}
|
||||
|
||||
if (samples.empty()) {
|
||||
samples = GenerateSilentSamples(parameters);
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,10 +52,6 @@ if (ENABLE_QT)
|
|||
target_link_libraries(citra_meta PRIVATE Boost::boost Qt6::Widgets)
|
||||
endif()
|
||||
|
||||
if (ENABLE_ROOM)
|
||||
target_link_libraries(citra_meta PRIVATE citra_room)
|
||||
endif()
|
||||
|
||||
if (ENABLE_QT AND UNIX AND NOT APPLE)
|
||||
target_link_libraries(citra_meta PRIVATE Qt6::DBus gamemode)
|
||||
endif()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright Citra Emulator Project / Lime3DS Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -25,10 +25,6 @@ constexpr char help_string[] =
|
|||
// TODO: Move -m outside of this check when it is implemented in Qt frontend
|
||||
"-m, --multiplayer [nick:password@address:port] Nickname, password, address and port for "
|
||||
"multiplayer (currently only usable with SDL frontend)\n"
|
||||
#endif
|
||||
#ifdef ENABLE_ROOM
|
||||
" --room Utilize dedicated multiplayer room functionality (equivalent to "
|
||||
"the old citra-room executable)\n"
|
||||
#endif
|
||||
"-v, --version Output version information and exit\n"
|
||||
"-w, --windowed Start in windowed mode";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright Citra Emulator Project / Lime3DS Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -7,9 +7,6 @@
|
|||
#ifdef ENABLE_QT
|
||||
#include "citra_qt/citra_qt.h"
|
||||
#endif
|
||||
#ifdef ENABLE_ROOM
|
||||
#include "citra_room/citra_room.h"
|
||||
#endif
|
||||
#ifdef ENABLE_SDL2_FRONTEND
|
||||
#include "citra_sdl/citra_sdl.h"
|
||||
#endif
|
||||
|
@ -22,20 +19,6 @@ __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
|
|||
#endif
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#if ENABLE_ROOM
|
||||
bool launch_room = false;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--room") == 0) {
|
||||
launch_room = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (launch_room) {
|
||||
LaunchRoom(argc, argv, true);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_QT
|
||||
bool no_gui = false;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
@ -59,4 +42,4 @@ int main(int argc, char* argv[]) {
|
|||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -72,14 +72,9 @@ void EmuThread::run() {
|
|||
std::size_t total) { emit LoadProgress(stage, value, total); });
|
||||
}
|
||||
|
||||
system.GPU().Renderer().Rasterizer()->SetSwitchDiskResourcesCallback(
|
||||
[this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
|
||||
emit SwitchDiskResources(stage, value, total);
|
||||
});
|
||||
|
||||
emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
||||
|
||||
system.GPU().Renderer().Rasterizer()->LoadDefaultDiskResources(
|
||||
system.GPU().Renderer().Rasterizer()->LoadDiskResources(
|
||||
stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
|
||||
emit LoadProgress(stage, value, total);
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Copyright 2014 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -110,9 +110,6 @@ signals:
|
|||
|
||||
void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total);
|
||||
|
||||
void SwitchDiskResources(VideoCore::LoadCallbackStage stage, std::size_t value,
|
||||
std::size_t total);
|
||||
|
||||
void HideLoadingScreen();
|
||||
};
|
||||
|
||||
|
|
|
@ -500,8 +500,6 @@ void GMainWindow::InitializeWidgets() {
|
|||
progress_bar->hide();
|
||||
statusBar()->addPermanentWidget(progress_bar);
|
||||
|
||||
loading_shaders_label = new QLabel();
|
||||
|
||||
artic_traffic_label = new QLabel();
|
||||
artic_traffic_label->setToolTip(
|
||||
tr("Current Artic traffic speed. Higher values indicate bigger transfer loads."));
|
||||
|
@ -517,8 +515,8 @@ void GMainWindow::InitializeWidgets() {
|
|||
tr("Time taken to emulate a 3DS frame, not counting framelimiting or v-sync. For "
|
||||
"full-speed emulation this should be at most 16.67 ms."));
|
||||
|
||||
for (auto& label : {loading_shaders_label, artic_traffic_label, emu_speed_label, game_fps_label,
|
||||
emu_frametime_label}) {
|
||||
for (auto& label :
|
||||
{artic_traffic_label, emu_speed_label, game_fps_label, emu_frametime_label}) {
|
||||
label->setVisible(false);
|
||||
label->setFrameStyle(QFrame::NoFrame);
|
||||
label->setContentsMargins(4, 0, 4, 0);
|
||||
|
@ -700,36 +698,25 @@ void GMainWindow::InitializeRecentFileMenuActions() {
|
|||
void GMainWindow::InitializeSaveStateMenuActions() {
|
||||
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
|
||||
actions_load_state[i] = new QAction(this);
|
||||
actions_load_state[i]->setData(i);
|
||||
actions_load_state[i]->setData(i + 1);
|
||||
connect(actions_load_state[i], &QAction::triggered, this, &GMainWindow::OnLoadState);
|
||||
if (i > 0)
|
||||
ui->menu_Load_State->addAction(actions_load_state[i]);
|
||||
ui->menu_Load_State->addAction(actions_load_state[i]);
|
||||
|
||||
actions_save_state[i] = new QAction(this);
|
||||
actions_save_state[i]->setData(i);
|
||||
actions_save_state[i]->setData(i + 1);
|
||||
connect(actions_save_state[i], &QAction::triggered, this, &GMainWindow::OnSaveState);
|
||||
if (i > 0)
|
||||
ui->menu_Save_State->addAction(actions_save_state[i]);
|
||||
ui->menu_Save_State->addAction(actions_save_state[i]);
|
||||
}
|
||||
|
||||
connect(ui->action_Load_from_Newest_Slot, &QAction::triggered, this, [this] {
|
||||
UpdateSaveStates();
|
||||
if (newest_slot != 0) {
|
||||
actions_load_state[newest_slot]->trigger();
|
||||
actions_load_state[newest_slot - 1]->trigger();
|
||||
}
|
||||
});
|
||||
connect(ui->action_Save_to_Oldest_Slot, &QAction::triggered, this, [this] {
|
||||
UpdateSaveStates();
|
||||
actions_save_state[oldest_slot]->trigger();
|
||||
});
|
||||
|
||||
// Quick save / load uses slot
|
||||
connect(ui->action_Quick_Save, &QAction::triggered, this, [this] {
|
||||
UpdateSaveStates();
|
||||
actions_save_state[0]->trigger();
|
||||
});
|
||||
connect(ui->action_Quick_Load, &QAction::triggered, this, [this] {
|
||||
UpdateSaveStates();
|
||||
actions_load_state[0]->trigger();
|
||||
actions_save_state[oldest_slot - 1]->trigger();
|
||||
});
|
||||
|
||||
connect(ui->menu_Load_State->menuAction(), &QAction::hovered, this,
|
||||
|
@ -772,12 +759,8 @@ void GMainWindow::InitializeHotkeys() {
|
|||
link_action_shortcut(ui->action_Screen_Layout_Upright_Screens,
|
||||
QStringLiteral("Rotate Screens Upright"));
|
||||
link_action_shortcut(ui->action_Advance_Frame, QStringLiteral("Advance Frame"));
|
||||
link_action_shortcut(ui->action_Load_from_Newest_Slot,
|
||||
QStringLiteral("Load from Newest Non-Quicksave Slot"));
|
||||
link_action_shortcut(ui->action_Save_to_Oldest_Slot,
|
||||
QStringLiteral("Save to Oldest Non-Quicksave Slot"));
|
||||
link_action_shortcut(ui->action_Quick_Save, QStringLiteral("Quick Save"));
|
||||
link_action_shortcut(ui->action_Quick_Load, QStringLiteral("Quick Load"));
|
||||
link_action_shortcut(ui->action_Load_from_Newest_Slot, QStringLiteral("Load from Newest Slot"));
|
||||
link_action_shortcut(ui->action_Save_to_Oldest_Slot, QStringLiteral("Save to Oldest Slot"));
|
||||
link_action_shortcut(ui->action_View_Lobby, QStringLiteral("Multiplayer Browse Public Rooms"));
|
||||
link_action_shortcut(ui->action_Start_Room, QStringLiteral("Multiplayer Create Room"));
|
||||
link_action_shortcut(ui->action_Connect_To_Room,
|
||||
|
@ -802,11 +785,6 @@ void GMainWindow::InitializeHotkeys() {
|
|||
}
|
||||
});
|
||||
connect_shortcut(QStringLiteral("Toggle Per-Application Speed"), [&] {
|
||||
if (!hotkey_registry
|
||||
.GetKeySequence(QStringLiteral("Main Window"), QStringLiteral("Toggle Turbo Mode"))
|
||||
.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Settings::values.frame_limit.SetGlobal(!Settings::values.frame_limit.UsingGlobal());
|
||||
UpdateStatusBar();
|
||||
});
|
||||
|
@ -814,12 +792,31 @@ void GMainWindow::InitializeHotkeys() {
|
|||
[&] { Settings::values.dump_textures = !Settings::values.dump_textures; });
|
||||
connect_shortcut(QStringLiteral("Toggle Custom Textures"),
|
||||
[&] { Settings::values.custom_textures = !Settings::values.custom_textures; });
|
||||
|
||||
connect_shortcut(QStringLiteral("Toggle Turbo Mode"),
|
||||
[&] { GMainWindow::SetTurboEnabled(!GMainWindow::IsTurboEnabled()); });
|
||||
|
||||
connect_shortcut(QStringLiteral("Increase Speed Limit"), [&] { AdjustSpeedLimit(true); });
|
||||
connect_shortcut(QStringLiteral("Decrease Speed Limit"), [&] { AdjustSpeedLimit(false); });
|
||||
// We use "static" here in order to avoid capturing by lambda due to a MSVC bug, which makes
|
||||
// the variable hold a garbage value after this function exits
|
||||
static constexpr u16 SPEED_LIMIT_STEP = 5;
|
||||
connect_shortcut(QStringLiteral("Increase Speed Limit"), [&] {
|
||||
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||
return;
|
||||
}
|
||||
if (Settings::values.frame_limit.GetValue() < 995 - SPEED_LIMIT_STEP) {
|
||||
Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() +
|
||||
SPEED_LIMIT_STEP);
|
||||
} else {
|
||||
Settings::values.frame_limit = 0;
|
||||
}
|
||||
UpdateStatusBar();
|
||||
});
|
||||
connect_shortcut(QStringLiteral("Decrease Speed Limit"), [&] {
|
||||
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||
Settings::values.frame_limit = 995;
|
||||
} else if (Settings::values.frame_limit.GetValue() > SPEED_LIMIT_STEP) {
|
||||
Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() -
|
||||
SPEED_LIMIT_STEP);
|
||||
UpdateStatusBar();
|
||||
}
|
||||
UpdateStatusBar();
|
||||
});
|
||||
|
||||
connect_shortcut(QStringLiteral("Audio Mute/Unmute"), &GMainWindow::OnMute);
|
||||
connect_shortcut(QStringLiteral("Audio Volume Down"), &GMainWindow::OnDecreaseVolume);
|
||||
|
@ -841,7 +838,7 @@ void GMainWindow::InitializeHotkeys() {
|
|||
});
|
||||
connect_shortcut(QStringLiteral("Increase 3D Factor"), [this] {
|
||||
const auto factor_3d = Settings::values.factor_3d.GetValue();
|
||||
if (factor_3d < 255) {
|
||||
if (factor_3d < 100) {
|
||||
if (factor_3d % FACTOR_3D_STEP != 0) {
|
||||
Settings::values.factor_3d =
|
||||
factor_3d + FACTOR_3D_STEP - (factor_3d % FACTOR_3D_STEP);
|
||||
|
@ -1432,8 +1429,6 @@ void GMainWindow::BootGame(const QString& filename) {
|
|||
|
||||
connect(emu_thread.get(), &EmuThread::LoadProgress, loading_screen,
|
||||
&LoadingScreen::OnLoadProgress, Qt::QueuedConnection);
|
||||
connect(emu_thread.get(), &EmuThread::SwitchDiskResources, this,
|
||||
&GMainWindow::OnSwitchDiskResources, Qt::QueuedConnection);
|
||||
connect(emu_thread.get(), &EmuThread::HideLoadingScreen, loading_screen,
|
||||
&LoadingScreen::OnLoadComplete);
|
||||
|
||||
|
@ -1533,7 +1528,6 @@ void GMainWindow::ShutdownGame() {
|
|||
status_bar_update_timer.stop();
|
||||
message_label_used_for_movie = false;
|
||||
show_artic_label = false;
|
||||
loading_shaders_label->setVisible(false);
|
||||
artic_traffic_label->setVisible(false);
|
||||
emu_speed_label->setVisible(false);
|
||||
game_fps_label->setVisible(false);
|
||||
|
@ -1599,7 +1593,7 @@ void GMainWindow::UpdateSaveStates() {
|
|||
ui->menu_Save_State->setEnabled(true);
|
||||
ui->action_Load_from_Newest_Slot->setEnabled(false);
|
||||
|
||||
oldest_slot = newest_slot = 1;
|
||||
oldest_slot = newest_slot = 0;
|
||||
oldest_slot_time = std::numeric_limits<u64>::max();
|
||||
newest_slot_time = 0;
|
||||
|
||||
|
@ -1610,33 +1604,13 @@ void GMainWindow::UpdateSaveStates() {
|
|||
auto savestates = Core::ListSaveStates(title_id, movie.GetCurrentMovieID());
|
||||
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
|
||||
actions_load_state[i]->setEnabled(false);
|
||||
if (i == 0) {
|
||||
actions_load_state[i]->setText(tr("Quick Load"));
|
||||
actions_save_state[i]->setText(tr("Quick Save"));
|
||||
} else {
|
||||
actions_load_state[i]->setText(tr("Slot %1").arg(i));
|
||||
actions_save_state[i]->setText(tr("Slot %1").arg(i));
|
||||
}
|
||||
actions_load_state[i]->setText(tr("Slot %1").arg(i + 1));
|
||||
actions_save_state[i]->setText(tr("Slot %1").arg(i + 1));
|
||||
}
|
||||
for (const auto& savestate : savestates) {
|
||||
if (savestate.slot >= Core::SaveStateSlotCount) {
|
||||
continue;
|
||||
}
|
||||
const bool display_name =
|
||||
savestate.status == Core::SaveStateInfo::ValidationStatus::RevisionDismatch &&
|
||||
!savestate.build_name.empty();
|
||||
actions_load_state[savestate.slot]->setEnabled(true);
|
||||
if (savestate.slot == 0) {
|
||||
const auto text = tr("%2 %3")
|
||||
.arg(QDateTime::fromSecsSinceEpoch(savestate.time)
|
||||
.toString(QStringLiteral("yyyy-MM-dd hh:mm:ss")))
|
||||
.arg(display_name ? QString::fromStdString(savestate.build_name)
|
||||
: QLatin1String())
|
||||
.trimmed();
|
||||
ui->action_Quick_Save->setText(tr("Quick Save - %1").arg(text).trimmed());
|
||||
ui->action_Quick_Load->setText(tr("Quick Load - %1").arg(text).trimmed());
|
||||
continue;
|
||||
}
|
||||
const auto text =
|
||||
tr("Slot %1 - %2 %3")
|
||||
.arg(savestate.slot)
|
||||
|
@ -1645,10 +1619,12 @@ void GMainWindow::UpdateSaveStates() {
|
|||
.arg(display_name ? QString::fromStdString(savestate.build_name) : QLatin1String())
|
||||
.trimmed();
|
||||
|
||||
actions_load_state[savestate.slot]->setText(text);
|
||||
actions_save_state[savestate.slot]->setText(text);
|
||||
actions_load_state[savestate.slot - 1]->setEnabled(true);
|
||||
actions_load_state[savestate.slot - 1]->setText(text);
|
||||
actions_save_state[savestate.slot - 1]->setText(text);
|
||||
|
||||
ui->action_Load_from_Newest_Slot->setEnabled(true);
|
||||
|
||||
if (savestate.time > newest_slot_time) {
|
||||
newest_slot = savestate.slot;
|
||||
newest_slot_time = savestate.time;
|
||||
|
@ -1658,11 +1634,10 @@ void GMainWindow::UpdateSaveStates() {
|
|||
oldest_slot_time = savestate.time;
|
||||
}
|
||||
}
|
||||
// Value as 1 because quicksave slot is not used for this calculation
|
||||
for (u32 i = 1; i < Core::SaveStateSlotCount; ++i) {
|
||||
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
|
||||
if (!actions_load_state[i]->isEnabled()) {
|
||||
// Prefer empty slot
|
||||
oldest_slot = i;
|
||||
oldest_slot = i + 1;
|
||||
oldest_slot_time = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -2447,8 +2422,6 @@ void GMainWindow::OnPauseContinueGame() {
|
|||
}
|
||||
|
||||
void GMainWindow::OnStopGame() {
|
||||
SetTurboEnabled(false);
|
||||
|
||||
play_time_manager->Stop();
|
||||
// Update game list to show new play time
|
||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
|
@ -2600,50 +2573,6 @@ void GMainWindow::ChangeSmallScreenPosition() {
|
|||
UpdateSecondaryWindowVisibility();
|
||||
}
|
||||
|
||||
bool GMainWindow::IsTurboEnabled() {
|
||||
return turbo_mode_active;
|
||||
}
|
||||
|
||||
void GMainWindow::SetTurboEnabled(bool state) {
|
||||
turbo_mode_active = state;
|
||||
GMainWindow::ReloadTurbo();
|
||||
}
|
||||
|
||||
void GMainWindow::ReloadTurbo() {
|
||||
if (IsTurboEnabled()) {
|
||||
Settings::temporary_frame_limit = Settings::values.turbo_limit.GetValue();
|
||||
Settings::is_temporary_frame_limit = true;
|
||||
} else {
|
||||
Settings::is_temporary_frame_limit = false;
|
||||
}
|
||||
|
||||
UpdateStatusBar();
|
||||
}
|
||||
|
||||
// TODO: This should probably take in something more descriptive than a bool. -OS
|
||||
void GMainWindow::AdjustSpeedLimit(bool increase) {
|
||||
const int SPEED_LIMIT_STEP = 5;
|
||||
auto active_limit =
|
||||
IsTurboEnabled() ? &Settings::values.turbo_limit : &Settings::values.frame_limit;
|
||||
const auto active_limit_value = active_limit->GetValue();
|
||||
|
||||
if (increase) {
|
||||
if (active_limit_value < 995) {
|
||||
active_limit->SetValue(active_limit_value + SPEED_LIMIT_STEP);
|
||||
}
|
||||
} else {
|
||||
if (active_limit_value > SPEED_LIMIT_STEP) {
|
||||
active_limit->SetValue(active_limit_value - SPEED_LIMIT_STEP);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsTurboEnabled()) {
|
||||
ReloadTurbo();
|
||||
}
|
||||
|
||||
UpdateStatusBar();
|
||||
}
|
||||
|
||||
void GMainWindow::ToggleScreenLayout() {
|
||||
const Settings::LayoutOption new_layout = []() {
|
||||
switch (Settings::values.layout_option.GetValue()) {
|
||||
|
@ -2761,7 +2690,6 @@ void GMainWindow::OnConfigure() {
|
|||
} else {
|
||||
setMouseTracking(false);
|
||||
}
|
||||
ReloadTurbo();
|
||||
UpdateSecondaryWindowVisibility();
|
||||
UpdateBootHomeMenuState();
|
||||
UpdateStatusButtons();
|
||||
|
@ -3719,18 +3647,6 @@ void GMainWindow::OnEmulatorUpdateAvailable() {
|
|||
}
|
||||
#endif
|
||||
|
||||
void GMainWindow::OnSwitchDiskResources(VideoCore::LoadCallbackStage stage, std::size_t value,
|
||||
std::size_t total) {
|
||||
if (stage == VideoCore::LoadCallbackStage::Prepare) {
|
||||
loading_shaders_label->setText(QString());
|
||||
loading_shaders_label->setVisible(true);
|
||||
} else if (stage == VideoCore::LoadCallbackStage::Complete) {
|
||||
loading_shaders_label->setVisible(false);
|
||||
} else {
|
||||
loading_shaders_label->setText(loading_screen->GetStageTranslation(stage, value, total));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateWindowTitle() {
|
||||
const QString full_name = QString::fromUtf8(Common::g_build_fullname);
|
||||
|
||||
|
@ -3901,9 +3817,7 @@ void LaunchQtFrontend(int argc, char* argv[]) {
|
|||
|
||||
// Init settings params
|
||||
QCoreApplication::setOrganizationName(QStringLiteral("Azahar Developers"));
|
||||
QCoreApplication::setOrganizationDomain(QStringLiteral("azahar_emu.org"));
|
||||
QCoreApplication::setApplicationName(QStringLiteral("Azahar"));
|
||||
QGuiApplication::setDesktopFileName(QStringLiteral("org.azahar_emu.Azahar"));
|
||||
|
||||
auto rounding_policy = GetHighDpiRoundingPolicy();
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(rounding_policy);
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "citra_qt/user_data_migration.h"
|
||||
#include "core/core.h"
|
||||
#include "core/savestate.h"
|
||||
#include "video_core/rasterizer_interface.h"
|
||||
|
||||
// Needs to be included at the end due to https://bugreports.qt.io/browse/QTBUG-73263
|
||||
#include <filesystem>
|
||||
|
@ -261,10 +260,6 @@ private slots:
|
|||
void ToggleSecondaryFullscreen();
|
||||
void ChangeScreenLayout();
|
||||
void ChangeSmallScreenPosition();
|
||||
bool IsTurboEnabled();
|
||||
void SetTurboEnabled(bool);
|
||||
void ReloadTurbo();
|
||||
void AdjustSpeedLimit(bool increase);
|
||||
void UpdateSecondaryWindowVisibility();
|
||||
void ToggleScreenLayout();
|
||||
void OnSwapScreens();
|
||||
|
@ -300,8 +295,6 @@ private slots:
|
|||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
void OnEmulatorUpdateAvailable();
|
||||
#endif
|
||||
void OnSwitchDiskResources(VideoCore::LoadCallbackStage stage, std::size_t value,
|
||||
std::size_t total);
|
||||
|
||||
private:
|
||||
Q_INVOKABLE void OnMoviePlaybackCompleted();
|
||||
|
@ -337,7 +330,6 @@ private:
|
|||
QProgressBar* progress_bar = nullptr;
|
||||
QLabel* message_label = nullptr;
|
||||
bool show_artic_label = false;
|
||||
QLabel* loading_shaders_label = nullptr;
|
||||
QLabel* artic_traffic_label = nullptr;
|
||||
QLabel* emu_speed_label = nullptr;
|
||||
QLabel* game_fps_label = nullptr;
|
||||
|
@ -356,9 +348,6 @@ private:
|
|||
UserDataMigrator user_data_migrator;
|
||||
std::unique_ptr<QtConfig> config;
|
||||
|
||||
// Hotkeys
|
||||
bool turbo_mode_active = false;
|
||||
|
||||
// Whether emulation is currently running in Citra.
|
||||
bool emulation_running = false;
|
||||
std::unique_ptr<EmuThread> emu_thread;
|
||||
|
|
|
@ -54,7 +54,7 @@ const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> QtConfi
|
|||
// This must be in alphabetical order according to action name as it must have the same order as
|
||||
// UISetting::values.shortcuts, which is alphabetically ordered.
|
||||
// clang-format off
|
||||
const std::array<UISettings::Shortcut, 38> QtConfig::default_hotkeys {{
|
||||
const std::array<UISettings::Shortcut, 35> QtConfig::default_hotkeys {{
|
||||
{QStringLiteral("Advance Frame"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}},
|
||||
|
@ -70,29 +70,26 @@ const std::array<UISettings::Shortcut, 38> QtConfig::default_hotkeys {{
|
|||
{QStringLiteral("Increase Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral("Load from Newest Non-Quicksave Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+V"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Multiplayer Browse Public Rooms"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+B"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Load from Newest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+V"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Multiplayer Browse Public Lobby"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+B"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Multiplayer Create Room"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+N"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Multiplayer Direct Connect to Room"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Shift"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Multiplayer Leave Room"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+L"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Multiplayer Show Current Room"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+R"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Quick Save"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Quick Load"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Remove Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F3"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Rotate Screens Upright"), QStringLiteral("Main Window"), {QStringLiteral("F8"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Save to Oldest Non-Quicksave Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+C"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Save to Oldest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+C"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Swap Screens"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle 3D"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+3"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Custom Textures"), QStringLiteral("Main Window"), {QStringLiteral("F7"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle Frame Advancing"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Per-Application Speed"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Per-Application Speed"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Screen Layout"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle Texture Dumping"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Turbo Mode"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
}};
|
||||
// clang-format on
|
||||
|
||||
|
@ -522,7 +519,6 @@ void QtConfig::ReadLayoutValues() {
|
|||
ReadGlobalSetting(Settings::values.swap_screen);
|
||||
ReadGlobalSetting(Settings::values.upright_screen);
|
||||
ReadGlobalSetting(Settings::values.large_screen_proportion);
|
||||
ReadGlobalSetting(Settings::values.screen_gap);
|
||||
ReadGlobalSetting(Settings::values.small_screen_position);
|
||||
|
||||
if (global) {
|
||||
|
@ -685,7 +681,6 @@ void QtConfig::ReadRendererValues() {
|
|||
ReadGlobalSetting(Settings::values.use_vsync_new);
|
||||
ReadGlobalSetting(Settings::values.resolution_factor);
|
||||
ReadGlobalSetting(Settings::values.frame_limit);
|
||||
ReadGlobalSetting(Settings::values.turbo_limit);
|
||||
|
||||
ReadGlobalSetting(Settings::values.bg_red);
|
||||
ReadGlobalSetting(Settings::values.bg_green);
|
||||
|
@ -1083,7 +1078,6 @@ void QtConfig::SaveLayoutValues() {
|
|||
WriteGlobalSetting(Settings::values.swap_screen);
|
||||
WriteGlobalSetting(Settings::values.upright_screen);
|
||||
WriteGlobalSetting(Settings::values.large_screen_proportion);
|
||||
WriteGlobalSetting(Settings::values.screen_gap);
|
||||
WriteGlobalSetting(Settings::values.small_screen_position);
|
||||
if (global) {
|
||||
WriteBasicSetting(Settings::values.mono_render_option);
|
||||
|
@ -1212,7 +1206,6 @@ void QtConfig::SaveRendererValues() {
|
|||
WriteGlobalSetting(Settings::values.use_vsync_new);
|
||||
WriteGlobalSetting(Settings::values.resolution_factor);
|
||||
WriteGlobalSetting(Settings::values.frame_limit);
|
||||
WriteGlobalSetting(Settings::values.turbo_limit);
|
||||
|
||||
WriteGlobalSetting(Settings::values.bg_red);
|
||||
WriteGlobalSetting(Settings::values.bg_green);
|
||||
|
|