57 Commits
Author SHA1 Message Date
PabloMK7andGitHub b5126f979c renderer_vulkan: Use proper image view on LCD fills (#91) 2024-04-23 21:42:19 +02:00
PabloMK7andGitHub a8e601ae7d Fix showing color console if debugger attached on windows. (#88) 2024-04-22 23:37:59 +02:00
PabloMK7andGitHub d063f26efc Remove resource limit checks for now. (#89) 2024-04-22 23:37:45 +02:00
PabloMK7andGitHub b1e5485058 Allow loading IPS files from Luma3DS folders. (#87) 2024-04-22 23:37:30 +02:00
de65b15dde renderer_vulkan: Rewrite descriptor set management and various small fixes (#77)
* renderer_vulkan: Remove vulkan prefix in SetObjectName

* renderer_vulkan: Rename renderpass cache to render manager

* It is no longer just a cache

* renderer_vulkan: Rewrite descriptor management

* Switch to batched vkUpdateDescriptorSets from cached descriptor sets with templates

* vk_master_semaphore: Remove waitable atomic

* These are buggy on some platforms and regular condition_variables are faster most of the time

* vk_texture_runtime.cpp: remove outdated references

* vk_render_manager: Minor cleanups and rename to RenderManager

* It is no longer just a renderpass cache
* Revert variable name change from render_manager back to renderpass_cache

---------

Co-authored-by: GPUCode <geoster3d@gmail.com>
2024-04-22 22:43:36 +02:00
MalachiandGitHub e26ceabfd1 vk_instance.cpp: fix getting driver_id for vulkan device (#67)
* vk_instance.cpp: fix getting driver_id for vulkan device

* apply clang-format (fixed)
2024-04-10 23:05:35 +03:00
GPUCodeandGitHub 9dfe3eb4bc rasterizer_cache: Improve validation skip heuristic (#69) 2024-04-10 23:00:53 +03:00
GPUCodeandGitHub f5cf180cee Merge pull request #59 from GPUCode/y2r
y2r: Delay completion event
2024-04-10 01:38:47 +03:00
GPUCode db3da09d85 y2r: Remove goto 2024-04-10 01:23:31 +03:00
GPUCode 5691cf7e91 y2r: Delay completion event 2024-04-07 00:15:18 +03:00
PabloMK7andGitHub 0c2f076dc4 Add svcs to get and set the emulation speed. (#57) 2024-04-06 13:00:58 +02:00
PabloMK7andGitHub 775ceac27d Reduce log levels for some FS functions and stub cache svcs (#51) 2024-04-05 13:49:36 +02:00
Reg TianghaandGitHub 7fc382479d Delete unused files (#52) 2024-04-05 13:48:37 +02:00
8e35df1a6c Remove the telemetry (#45)
* remove the telemetry except from the renderers as I'm not being capable to remove it from there

* remove the telemetry except from the renderers as I'm not being capable to remove it from there

* Remove remainder of non-functional Telemetry and Citra Web Services

Squashed commit of the following:

commit f6dd4d4579c91db323877f0d08b9c01c82e1bb32
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 14:02:26 2024 -0600

    gl_driver.h: add back missing functions

commit 8f14384e7a7b763c3f2ccb3af6b5a59df641d9ee
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 13:56:16 2024 -0600

    gl_driver.cpp: add back missing functions

commit 5c802524b01a6eb05952d88ccf9dd78d63baee0a
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 13:39:46 2024 -0600

    apply clang-format

commit e8f62a7d3ee8a3da885a28bce21bcfcb84f13a84
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 13:16:22 2024 -0600

    remove web_tab

commit ced7f1e4909ae7b2714a96e3c3fa0500e8c62968
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 13:13:47 2024 -0600

    remove unused call?

commit f10e05da887e4570853fae2bd55a71087b4bcc77
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 13:03:47 2024 -0600

    fix build errors

commit 0489c1770b4b48d51f626145ae9235d3c81029fc
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 12:54:35 2024 -0600

    Remove deleted files

commit b2eb56f5a1f01663cc9874d99fe77ee64b48622b
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 12:43:17 2024 -0600

    Remove ConfigureWeb

commit b96f7c724006b2c5ee2272becaa70584fe90d012
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 11:49:51 2024 -0600

    remove unused DebugHandler

commit 91ddf16f63f9ae07b0cb2768171728dc878d1653
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 11:41:31 2024 -0600

    remove CollectToolingInfo() reference

commit 3909ac0502f23f8fb54944b53d5072b6986f8ffd
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 11:33:39 2024 -0600

    Fix "clean renderer_vulkan.cpp"

    This reverts commit 8a882658da9fabca40d71d73bfaf3bb5702acd72.

commit f4a10c4e4f27471b0a263ac363a6fa2abc9d6dc9
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 11:25:12 2024 -0600

    remove Core() references

commit 5593b8484e7c9f525ea218902dd2c13148d86b37
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 11:09:26 2024 -0600

    clean core/core.cpp

commit 55bbd8ad283297ef79db11e19ca6303fdfba6626
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 11:03:45 2024 -0600

    apply clang-format

commit 3707a0b2705dd415876130c9c90b0916bdea11db
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 11:02:16 2024 -0600

    citra_qt/main.h

commit ddbdea9be4d8179a333e04e7c302e215868715a9
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 11:01:30 2024 -0600

    clean common/detached_tasks.h

commit b513ba3b91ebc81bddd634b5690b6434824e1c7a
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:58:51 2024 -0600

    clean android/app/src/main/jni/default_ini.h

commit b6ba7d7cd730393883fdca294c651a4186727b55
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:58:14 2024 -0600

    clean android/app/src/main/jni/native.cpp

commit 2351305bb24b005920af0f3f7bb6bbb5bb3124bd
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:56:59 2024 -0600

    network/network_settings.h

commit 5b4c1ebb97c7fad5daf7789e1d3640041c2412fb
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:55:53 2024 -0600

    clean citra_qt/configuration/configure_web.ui

commit 9526d5122995c2e9c52b4d93b6e836a2ea4c80ef
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:54:53 2024 -0600

    citra_qt/configuration/config.cpp

commit ec6fe57412ce97e06096fc07f8b86dd080b7b944
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:53:50 2024 -0600

    clean citra/default_ini.h

commit acba1cf7e94de2fa87174e9f6d7c7c4554146352
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:52:47 2024 -0600

    clean citra/config.cpp

commit 02888777590d4e4bf1423e168a672ca0c5e140e5
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:50:42 2024 -0600

    clean vk_instance.cpp

commit eae451d5825b3601382c3a6dd08a3bde5c7a9460
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:48:53 2024 -0600

    clean vk_instanch.h

commit 8a882658da9fabca40d71d73bfaf3bb5702acd72
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:47:11 2024 -0600

    clean renderer_vulkan.cpp

commit ea6df111bc447913d2999acd86de984acced7eeb
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:45:51 2024 -0600

    clean renderer_opengl.cpp

commit 6b1bea0ef8cf8831c520d1c4e90b9d73d421c764
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:44:17 2024 -0600

    clean pica_to_gl.h

commit c12e984045a430cb10500241ada68701f73c85ac
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:42:48 2024 -0600

    clean gl_driver.h

commit ca3fe7801fff125a1ab8706bfc3998ca2928bded
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:40:14 2024 -0600

    clean gl_driver.cpp

commit d57381c38b217a423a7039bc7b413d79f59c2ff1
Author: Reg Tiangha <rtiangha@users.noreply.github.com>
Date:   Fri Mar 29 10:38:44 2024 -0600

    delete telemetry files

commit 1af826d1a045c5568a0d9ef4ca423514f298aee2
Author: Miguel <81558772+Miguel-hrvs@users.noreply.github.com>
Date:   Wed Mar 27 16:17:58 2024 +0100

    remove the telemetry except from the renderers as I'm not being capable to remove it from there

* rebase renderer_vulkan

* clean up renderer_vulkan

* bring back vulkan gpu logging

* clang-format vk_instance.h

* fix-formatting

---------

Co-authored-by: Reg Tiangha <rtiangha@users.noreply.github.com>
2024-04-02 20:25:36 +02:00
GPUCodeandGitHub a442389a60 Merge pull request #41 from rtiangha/build-fixes
Some build fixes for GCC 13.2.0 and Clang 18.1.1
2024-03-24 13:43:48 +02:00
Reg Tiangha 12b30be45e apply clang-format 2024-03-23 09:53:04 -06:00
Reg Tiangha b90569700c fix build error with modern openal-soft 2024-03-22 16:52:23 -06:00
Reg Tiangha 0500b993e0 Copilot AI suggestions to comply with LLVM 19 2024-03-22 16:51:41 -06:00
Reg Tiangha 69eba0d295 fix build issue with gcc 13.2.0 2024-03-22 16:51:16 -06:00
GPUCodeandGitHub 8433057909 renderer_vulkan: Disable dynamic index conditionally (#20) 2024-03-07 12:12:21 +01:00
PabloMK7andGitHub c4c90f0190 Remove dependencies to old docker containers (#21)
* Fix CI

* Change missing yml
2024-03-06 18:38:51 +01:00
813d0c2a30 Add console unique data (SecureInfo, LocalFriendCodeSeed, CTCert) (#6)
* Add console unique secure data

* Add CTCert and DeviceID support

* Fix AM_U::GetDeviceID

Co-authored-by: Daniel López Guimaraes <112760654+DaniElectra@users.noreply.github.com>

* Update to latest master changes.

---------

Co-authored-by: Daniel López Guimaraes <112760654+DaniElectra@users.noreply.github.com>
2024-03-05 14:52:17 +01:00
PabloMK7andGitHub f112d975b9 Add log regex filter (#9) 2024-03-05 14:51:58 +01:00
PabloMK7andGitHub bf0127d0ae Add HOST_TICK and BUILD_PLATFORM to svcGetSystemInfo CITRA_INFORMATION type (#8)
* Add HOST_TICK to svcGetSystemInfo CITRA_INFORMATION type

* Add BUILD_PLATFORM
2024-03-05 14:07:04 +01:00
PabloMK7andGitHub c710c0009f Implement plugin loader Mode3 mem strategy (#7) 2024-03-05 14:06:50 +01:00
PabloMK7andGitHub f5316532e6 Revert "Implement some missing/wrong AC functionality." (#5)
* Revert "Implement some missing/wrong AC functionality."

* Remove setting wifi level from nwm
2024-03-05 13:26:48 +01:00
PabloMK7 cb75e1d637 Update README.md 2024-03-05 12:39:15 +01:00
PabloMK7 06b3bed49a Update .gitmodules 2024-03-05 09:43:31 +01:00
0ff3440232 tools: Add reset submodules script (#7465)
Co-authored-by: merry <8682882+merryhime@users.noreply.github.com>
2024-03-03 13:39:55 +02:00
liushuyuandGitHub 69e758d738 dedicated_room: properly initialize logging (#7468) 2024-02-27 20:36:28 +05:30
Steveice10andGitHub f4768cd26c video_core: Remove pre-compilation of Vulkan host-shaders. (#7461) 2024-02-26 10:26:44 -08:00
Théo BandGitHub e0d2c1308e log: fix SOC_U::Accept LOG_DEBUG call, and ensure such mistakes get picked up at compile time (#7463)
* fix SOC_U::Accept invalid log function

* make logging get checked at compile time
- ensures log strings match the amount and type (if the format specifies an integer, for example) of the arguments
- if at any later point a runtime-generated string is used as the log format, FmtLogMessage might require an overload taking a fmt::runtime_format_string<> as the format argument type, everything else being equal. wrap the generated string with fmt::runtime() before passing to the LOG_X function

* formatting fix: aligning the arguments
2024-02-25 21:43:29 -08:00
Steveice10andGitHub 4f9fc88bb3 apt: Improve accuracy of applet slot states on system applet launch. (#7456) 2024-02-23 16:18:16 -08:00
GPUCodeandGitHub d857743075 Downgrade blend factor crash to warning (#7459)
* pica_to_vk: Downgrade assert to warning

* pica_to_gl: Downgrade unreachable to warning
2024-02-22 15:43:44 -08:00
kylonandGitHub b5042a5257 Core: update kernel config memory to latest 11.17 (#7460) 2024-02-22 15:43:33 -08:00
WunkandGitHub e524542a40 vk_texture_runtime: Use boost-static_vector (#7455)
* vk_texture_runtime: Use boost-`static_vector` for image init-barriers

Uses `static_vector` rather than `std::array`+`u32` when passing input
parameters into the initialization barriers.

* vk_texture_runtime: Use boost-`static_vector` for framebuffer attachments

* vk_texture_runtime: Use boost-`static_vector` for surface uploads
2024-02-22 02:35:57 +02:00
Steveice10andGitHub 3a4ebb1413 file_util: Make sure portable user path is absolute. (#7448) 2024-02-18 15:21:53 -08:00
Steveice10andGitHub cbe8987036 ci: Update action versions. (#7449) 2024-02-18 08:23:15 -08:00
Charles LombardoandGitHub da5aa70fc9 android: Port yuzu system info logging (#7431) 2024-02-17 20:10:10 -08:00
749a721aa2 externals: disable system cpp-httplib if it is a shared object (#7446)
Co-authored-by: Castor216 <davidjamescastor215@proton.me>
2024-02-17 06:39:38 -08:00
SachinVinandGitHub bb003c2bd4 audio_core\hle\source.cpp: Improve accuracy of SourceStatus (#7432) 2024-02-17 02:12:54 +01:00
7638f87f74 Port several small multiplayer PRs from yuzu (#7419)
* yuzu: Use displayed port on direct connect

* Color player counts in the multiplayer public lobby list

- Full lobbies have their player count displayed in red.
- Lobbies with one slot left have their player count displayed in orange.
- Empty lobbies have their player count grayed out.

* Add hotkeys for multiplayer actions

Default shortcuts were chosen as to be intuitive (use the first letter
of the action, or the second word's first letter) and work on all
types of keyboards. The hotkeys can be used while playing a game too,
as they are application-wide.

* Persist filters in multiplayer public lobby list

After connecting to a room, the chosen filter text, "Games I Own",
"Hide Empty Rooms" and "Hide Full Rooms" values are persisted
to configuration so they are preserved across restarts.

This makes it easier to rejoin a room if you regularly play the same
game, or after a crash.

* citra_qt/lobby: Fix multiplayer player count color in dark theme

Co-Authored-By: Kevnkkm <56404895+kevnkkm@users.noreply.github.com>

* Address review comments

---------

Co-authored-by: Narr the Reg <juangerman-13@hotmail.com>
Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
Co-authored-by: Kevnkkm <56404895+kevnkkm@users.noreply.github.com>
2024-02-16 04:34:10 -08:00
Steveice10andGitHub aa6809e2a8 renderer_vulkan: Use no more than target supported version. (#7439) 2024-02-15 19:38:32 -08:00
Steveice10andGitHub 5e02be75a3 renderer_vulkan: Use getToolPropertiesEXT instead of getToolProperties (#7434)
getToolProperties is not available until Vulkan 1.3; we need to use the EXT version.
2024-02-13 21:43:09 -08:00
b9c9beeee5 android: add basic support for google game dashboard (#7430)
This adds support for the Performance and Battery Saver modes in the Game Dashboard mostly found on Google Pixel devices.
This does not yet define the specifics for the performance modes but does provide the initial basic support.

Co-authored-by: Emma <153868115+gaypotatoemma@users.noreply.github.com>
2024-02-10 17:24:10 -08:00
GPUCodeandGitHub de993dcfbd service: Stub mcu::HWC (#7428) 2024-02-09 14:09:05 -08:00
oltolmandGitHub 3c9157b1ec fix ASAN error in sdl_impl.cpp (#7427) 2024-02-09 14:08:15 -08:00
Ishan09811andGitHub 0c40c10022 Update Android Deps (#7383) 2024-02-09 07:24:55 -05:00
Daniel López GuimaraesandGitHub 2766118e33 http: Implement various missing commands (#7415) 2024-02-08 11:01:46 -08:00
Steveice10andGitHub 06b26691ba soc: Pass accurate sockaddr length to socket functions. (#7426) 2024-02-08 11:01:38 -08:00
PabloMK7andGitHub d41ce64f7b Add ipv6 socket support (#7418)
* Add IPV6 socket support

* Suggestions
2024-02-07 19:22:44 -08:00
TobiasandGitHub 1165a708d5 .tx/config: Use language mappings for android "tx pull" (#7422)
The language names we are using in the android resources differ from those on Transifex.

We need to manually specify mappings for them, so Transifex is able to place the files in the correct folders.
2024-02-07 05:41:29 -08:00
Steveice10andGitHub 19784355f9 build: Improve support for Windows cross-compilation. (#7389)
* build: Improve support for Windows cross-compilation.

* build: Move linuxdeploy download to bundle target execution time.
2024-02-05 10:09:50 -08:00
SachinVinandGitHub aa6a29d7e1 AudioCore/HLE/source: Partially implement last_buffer_id (#7397)
* AudioCore/HLE/source: Partially implement last_buffer_id

shared_memory.h: fix typo

* tests\audio_core\hle\source.cpp: Add test cases to verify last_buffer_id
2024-02-05 09:54:13 -08:00
GPUCodeandGitHub 106364e01e video_core: Use source3 when GPU_PREVIOUS is used in first stage (#7411) 2024-02-05 09:53:54 -08:00
GPUCodeandGitHub d5a1bd07f3 glsl_shader_gen: Increase z=0 epsillon (#7408) 2024-02-05 09:53:41 -08:00
Steveice10andGitHub 8afa27718c dumpkeys: Add seeddb.bin to output files. (#7417) 2024-02-05 09:14:14 -08:00
206 changed files with 3927 additions and 6569 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ COMPAT_LIST='dist/compatibility_list/compatibility_list.json'
mkdir artifacts mkdir artifacts
pip3 install git-archive-all pip3 install git-archive-all
wget -q https://api.citra-emu.org/gamedb -O "${COMPAT_LIST}" touch "${COMPAT_LIST}"
git describe --abbrev=0 --always HEAD > GIT-COMMIT git describe --abbrev=0 --always HEAD > GIT-COMMIT
git describe --tags HEAD > GIT-TAG || echo 'unknown' > GIT-TAG git describe --tags HEAD > GIT-TAG || echo 'unknown' > GIT-TAG
git archive-all --include "${COMPAT_LIST}" --include GIT-COMMIT --include GIT-TAG --force-submodules artifacts/"${REV_NAME}.tar" git archive-all --include "${COMPAT_LIST}" --include GIT-COMMIT --include GIT-TAG --force-submodules artifacts/"${REV_NAME}.tar"
+26 -35
View File
@@ -12,13 +12,13 @@ jobs:
if: ${{ !github.head_ref }} if: ${{ !github.head_ref }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Pack - name: Pack
run: ./.ci/source.sh run: ./.ci/source.sh
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: source name: source
path: artifacts/ path: artifacts/
@@ -28,7 +28,7 @@ jobs:
matrix: matrix:
target: ["appimage", "fresh"] target: ["appimage", "fresh"]
container: container:
image: citraemu/build-environments:linux-${{ matrix.target }} image: pablomk7/build-environments:linux-${{ matrix.target }}
options: -u 1001 options: -u 1001
env: env:
CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_DIR: ${{ github.workspace }}/.ccache
@@ -37,11 +37,11 @@ jobs:
OS: linux OS: linux
TARGET: ${{ matrix.target }} TARGET: ${{ matrix.target }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ${{ env.CCACHE_DIR }} path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
@@ -53,7 +53,7 @@ jobs:
run: ./.ci/pack.sh run: ./.ci/pack.sh
if: ${{ matrix.target == 'appimage' }} if: ${{ matrix.target == 'appimage' }}
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: ${{ matrix.target == 'appimage' }} if: ${{ matrix.target == 'appimage' }}
with: with:
name: ${{ env.OS }}-${{ env.TARGET }} name: ${{ env.OS }}-${{ env.TARGET }}
@@ -70,24 +70,24 @@ jobs:
OS: macos OS: macos
TARGET: ${{ matrix.target }} TARGET: ${{ matrix.target }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ${{ env.CCACHE_DIR }} path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
restore-keys: | restore-keys: |
${{ runner.os }}-${{ matrix.target }}- ${{ runner.os }}-${{ matrix.target }}-
- name: Install tools - name: Install tools
run: brew install ccache glslang ninja run: brew install ccache ninja
- name: Build - name: Build
run: ./.ci/macos.sh run: ./.ci/macos.sh
- name: Prepare outputs for caching - name: Prepare outputs for caching
run: mv build/bundle $OS-$TARGET run: mv build/bundle $OS-$TARGET
- name: Cache outputs for universal build - name: Cache outputs for universal build
uses: actions/cache/save@v3 uses: actions/cache/save@v4
with: with:
path: ${{ env.OS }}-${{ env.TARGET }} path: ${{ env.OS }}-${{ env.TARGET }}
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
@@ -98,15 +98,15 @@ jobs:
OS: macos OS: macos
TARGET: universal TARGET: universal
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Download x86_64 build from cache - name: Download x86_64 build from cache
uses: actions/cache/restore@v3 uses: actions/cache/restore@v4
with: with:
path: ${{ env.OS }}-x86_64 path: ${{ env.OS }}-x86_64
key: ${{ runner.os }}-x86_64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} key: ${{ runner.os }}-x86_64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
fail-on-cache-miss: true fail-on-cache-miss: true
- name: Download ARM64 build from cache - name: Download ARM64 build from cache
uses: actions/cache/restore@v3 uses: actions/cache/restore@v4
with: with:
path: ${{ env.OS }}-arm64 path: ${{ env.OS }}-arm64
key: ${{ runner.os }}-arm64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} key: ${{ runner.os }}-arm64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
@@ -118,7 +118,7 @@ jobs:
- name: Pack - name: Pack
run: ./.ci/pack.sh run: ./.ci/pack.sh
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.OS }}-${{ env.TARGET }} name: ${{ env.OS }}-${{ env.TARGET }}
path: artifacts/ path: artifacts/
@@ -137,11 +137,11 @@ jobs:
OS: windows OS: windows
TARGET: ${{ matrix.target }} TARGET: ${{ matrix.target }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ${{ env.CCACHE_DIR }} path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
@@ -153,13 +153,6 @@ jobs:
- name: Install extra tools (MSVC) - name: Install extra tools (MSVC)
run: choco install ccache ninja wget run: choco install ccache ninja wget
if: ${{ matrix.target == 'msvc' }} if: ${{ matrix.target == 'msvc' }}
- name: Set up Vulkan SDK (MSVC)
uses: humbletim/setup-vulkan-sdk@v1.2.0
if: ${{ matrix.target == 'msvc' }}
with:
vulkan-query-version: latest
vulkan-components: SPIRV-Tools, Glslang
vulkan-use-cache: true
- name: Set up MSYS2 - name: Set up MSYS2
uses: msys2/setup-msys2@v2 uses: msys2/setup-msys2@v2
if: ${{ matrix.target == 'msys2' }} if: ${{ matrix.target == 'msys2' }}
@@ -168,10 +161,8 @@ jobs:
update: true update: true
install: git make p7zip install: git make p7zip
pacboy: >- pacboy: >-
toolchain:p ccache:p cmake:p ninja:p glslang:p toolchain:p ccache:p cmake:p ninja:p
qt6-base:p qt6-multimedia:p qt6-multimedia-wmf:p qt6-tools:p qt6-translations:p qt6-base:p qt6-multimedia:p qt6-multimedia-wmf:p qt6-tools:p qt6-translations:p
- name: Test glslang
run: glslang --version || glslangValidator --version
- name: Disable line ending translation - name: Disable line ending translation
run: git config --global core.autocrlf input run: git config --global core.autocrlf input
- name: Build - name: Build
@@ -179,7 +170,7 @@ jobs:
- name: Pack - name: Pack
run: ./.ci/pack.sh run: ./.ci/pack.sh
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.OS }}-${{ env.TARGET }} name: ${{ env.OS }}-${{ env.TARGET }}
path: artifacts/ path: artifacts/
@@ -192,11 +183,11 @@ jobs:
OS: android OS: android
TARGET: universal TARGET: universal
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: | path: |
~/.gradle/caches ~/.gradle/caches
@@ -215,7 +206,7 @@ jobs:
run: | run: |
sudo add-apt-repository -y ppa:theofficialgman/gpu-tools sudo add-apt-repository -y ppa:theofficialgman/gpu-tools
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install ccache glslang-dev glslang-tools apksigner -y sudo apt-get install ccache apksigner -y
- name: Build - name: Build
run: JAVA_HOME=$JAVA_HOME_17_X64 ./.ci/android.sh run: JAVA_HOME=$JAVA_HOME_17_X64 ./.ci/android.sh
env: env:
@@ -228,7 +219,7 @@ jobs:
env: env:
UNPACKED: 1 UNPACKED: 1
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.OS }}-${{ env.TARGET }} name: ${{ env.OS }}-${{ env.TARGET }}
path: src/android/app/artifacts/ path: src/android/app/artifacts/
@@ -242,18 +233,18 @@ jobs:
OS: ios OS: ios
TARGET: arm64 TARGET: arm64
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ${{ env.CCACHE_DIR }} path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-ios-${{ github.sha }} key: ${{ runner.os }}-ios-${{ github.sha }}
restore-keys: | restore-keys: |
${{ runner.os }}-ios- ${{ runner.os }}-ios-
- name: Install tools - name: Install tools
run: brew install ccache glslang ninja run: brew install ccache ninja
- name: Build - name: Build
run: ./.ci/ios.sh run: ./.ci/ios.sh
release: release:
@@ -261,7 +252,7 @@ jobs:
needs: [windows, linux, macos-universal, android, source] needs: [windows, linux, macos-universal, android, source]
if: ${{ startsWith(github.ref, 'refs/tags/') }} if: ${{ startsWith(github.ref, 'refs/tags/') }}
steps: steps:
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
- name: Create release - name: Create release
uses: actions/create-release@v1 uses: actions/create-release@v1
env: env:
+1 -1
View File
@@ -200,7 +200,7 @@ async function mergebot(github, context, execa) {
} }
console.info("The following pull requests will be merged:"); console.info("The following pull requests will be merged:");
console.table(displayList); console.table(displayList);
await fetchPullRequests(pulls, "https://github.com/citra-emu/citra", execa); await fetchPullRequests(pulls, "https://github.com/PabloMK7/citra", execa);
const mergeResults = await mergePullRequests(pulls, execa); const mergeResults = await mergePullRequests(pulls, execa);
await generateReadme(pulls, context, mergeResults, execa); await generateReadme(pulls, context, mergeResults, execa);
await tagAndPush(github, context.repo.owner, `${context.repo.repo}-canary`, execa, true); await tagAndPush(github, context.repo.owner, `${context.repo.repo}-canary`, execa, true);
+2 -2
View File
@@ -10,10 +10,10 @@ jobs:
clang-format: clang-format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: citraemu/build-environments:linux-fresh image: pablomk7/build-environments:linux-fresh
options: -u 1001 options: -u 1001
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Build - name: Build
-100
View File
@@ -1,100 +0,0 @@
name: citra-publish
on:
schedule:
- cron: '7 0 * * *'
workflow_dispatch:
inputs:
nightly:
description: 'Whether to trigger a nightly build (true/false/auto)'
required: false
default: 'true'
canary:
description: 'Whether to trigger a canary build (true/false/auto)'
required: false
default: 'true'
jobs:
nightly:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }}
steps:
# this checkout is required to make sure the GitHub Actions scripts are available
- uses: actions/checkout@v3
name: Pre-checkout
with:
submodules: false
- uses: actions/github-script@v6
id: check-changes
name: 'Check for new changes'
env:
# 24 hours
DETECTION_TIME_FRAME: 86400000
with:
result-encoding: string
script: |
if (context.payload.inputs && context.payload.inputs.nightly === 'true') return true;
const checkBaseChanges = require('./.github/workflows/ci-merge.js').checkBaseChanges;
return checkBaseChanges(github, context);
- run: npm install execa@5
if: ${{ steps.check-changes.outputs.result == 'true' }}
- uses: actions/checkout@v3
name: Checkout
if: ${{ steps.check-changes.outputs.result == 'true' }}
with:
path: 'citra-merge'
fetch-depth: 0
submodules: true
token: ${{ secrets.ALT_GITHUB_TOKEN }}
- uses: actions/github-script@v6
name: 'Update and tag new commits'
if: ${{ steps.check-changes.outputs.result == 'true' }}
env:
ALT_GITHUB_TOKEN: ${{ secrets.ALT_GITHUB_TOKEN }}
with:
script: |
const execa = require("execa");
const tagAndPush = require('./.github/workflows/ci-merge.js').tagAndPush;
process.chdir('${{ github.workspace }}/citra-merge');
tagAndPush(github, context.repo.owner, `${context.repo.repo}-nightly`, execa);
canary:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }}
steps:
# this checkout is required to make sure the GitHub Actions scripts are available
- uses: actions/checkout@v3
name: Pre-checkout
with:
submodules: false
- uses: actions/github-script@v6
id: check-changes
name: 'Check for new changes'
env:
# 24 hours
DETECTION_TIME_FRAME: 86400000
with:
script: |
if (context.payload.inputs && context.payload.inputs.canary === 'true') return true;
const checkCanaryChanges = require('./.github/workflows/ci-merge.js').checkCanaryChanges;
return checkCanaryChanges(github, context);
- run: npm install execa@5
if: ${{ steps.check-changes.outputs.result == 'true' }}
- uses: actions/checkout@v3
name: Checkout
if: ${{ steps.check-changes.outputs.result == 'true' }}
with:
path: 'citra-merge'
fetch-depth: 0
submodules: true
token: ${{ secrets.ALT_GITHUB_TOKEN }}
- uses: actions/github-script@v6
name: 'Check and merge canary changes'
if: ${{ steps.check-changes.outputs.result == 'true' }}
env:
ALT_GITHUB_TOKEN: ${{ secrets.ALT_GITHUB_TOKEN }}
with:
script: |
const execa = require("execa");
const mergebot = require('./.github/workflows/ci-merge.js').mergebot;
process.chdir('${{ github.workspace }}/citra-merge');
mergebot(github, context, execa);
+2 -2
View File
@@ -7,10 +7,10 @@ on:
jobs: jobs:
transifex: transifex:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: citraemu/build-environments:linux-fresh container: pablomk7/build-environments:linux-fresh
if: ${{ github.repository == 'citra-emu/citra' }} if: ${{ github.repository == 'citra-emu/citra' }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
fetch-depth: 0 fetch-depth: 0
+6 -6
View File
@@ -1,6 +1,6 @@
[submodule "boost"] [submodule "boost"]
path = externals/boost path = externals/boost
url = https://github.com/citra-emu/ext-boost.git url = https://github.com/PabloMK7/ext-boost.git
[submodule "nihstro"] [submodule "nihstro"]
path = externals/nihstro path = externals/nihstro
url = https://github.com/neobrain/nihstro.git url = https://github.com/neobrain/nihstro.git
@@ -12,7 +12,7 @@
url = https://github.com/catchorg/Catch2 url = https://github.com/catchorg/Catch2
[submodule "dynarmic"] [submodule "dynarmic"]
path = externals/dynarmic path = externals/dynarmic
url = https://github.com/merryhime/dynarmic.git url = https://github.com/PabloMK7/dynarmic.git
[submodule "xbyak"] [submodule "xbyak"]
path = externals/xbyak path = externals/xbyak
url = https://github.com/herumi/xbyak.git url = https://github.com/herumi/xbyak.git
@@ -27,7 +27,7 @@
url = https://github.com/benhoyt/inih.git url = https://github.com/benhoyt/inih.git
[submodule "libressl"] [submodule "libressl"]
path = externals/libressl path = externals/libressl
url = https://github.com/citra-emu/ext-libressl-portable.git url = https://github.com/PabloMK7/ext-libressl-portable.git
[submodule "libusb"] [submodule "libusb"]
path = externals/libusb/libusb path = externals/libusb/libusb
url = https://github.com/libusb/libusb.git url = https://github.com/libusb/libusb.git
@@ -36,7 +36,7 @@
url = https://github.com/mozilla/cubeb url = https://github.com/mozilla/cubeb
[submodule "discord-rpc"] [submodule "discord-rpc"]
path = externals/discord-rpc path = externals/discord-rpc
url = https://github.com/yuzu-emu/discord-rpc.git url = https://github.com/PabloMK7/discord-rpc.git
[submodule "cpp-jwt"] [submodule "cpp-jwt"]
path = externals/cpp-jwt path = externals/cpp-jwt
url = https://github.com/arun11299/cpp-jwt.git url = https://github.com/arun11299/cpp-jwt.git
@@ -78,13 +78,13 @@
url = https://github.com/KhronosGroup/Vulkan-Headers url = https://github.com/KhronosGroup/Vulkan-Headers
[submodule "sirit"] [submodule "sirit"]
path = externals/sirit path = externals/sirit
url = https://github.com/yuzu-emu/sirit url = https://github.com/PabloMK7/sirit
[submodule "faad2"] [submodule "faad2"]
path = externals/faad2/faad2 path = externals/faad2/faad2
url = https://github.com/knik0/faad2 url = https://github.com/knik0/faad2
[submodule "library-headers"] [submodule "library-headers"]
path = externals/library-headers path = externals/library-headers
url = https://github.com/citra-emu/ext-library-headers.git url = https://github.com/PabloMK7/ext-library-headers.git
[submodule "libadrenotools"] [submodule "libadrenotools"]
path = externals/libadrenotools path = externals/libadrenotools
url = https://github.com/bylaws/libadrenotools url = https://github.com/bylaws/libadrenotools
+22 -3
View File
@@ -85,8 +85,6 @@ option(ENABLE_VULKAN "Enables the Vulkan renderer" ON)
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF) option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
CMAKE_DEPENDENT_OPTION(CITRA_ENABLE_BUNDLE_TARGET "Enable the distribution bundling target." ON "NOT ANDROID AND NOT IOS" OFF)
# Compile options # Compile options
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ${IS_DEBUG_BUILD} "MINGW" OFF) CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ${IS_DEBUG_BUILD} "MINGW" OFF)
option(ENABLE_LTO "Enable link time optimization" ${DEFAULT_ENABLE_LTO}) option(ENABLE_LTO "Enable link time optimization" ${DEFAULT_ENABLE_LTO})
@@ -249,6 +247,26 @@ if (ENABLE_QT)
if (ENABLE_QT_TRANSLATION) if (ENABLE_QT_TRANSLATION)
find_package(Qt6 REQUIRED COMPONENTS LinguistTools) find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
endif() endif()
if (NOT DEFINED QT_TARGET_PATH)
# Determine the location of the compile target's Qt.
get_target_property(qtcore_path Qt6::Core LOCATION_Release)
string(FIND "${qtcore_path}" "/bin/" qtcore_path_bin_pos REVERSE)
string(FIND "${qtcore_path}" "/lib/" qtcore_path_lib_pos REVERSE)
if (qtcore_path_bin_pos GREATER qtcore_path_lib_pos)
string(SUBSTRING "${qtcore_path}" 0 ${qtcore_path_bin_pos} QT_TARGET_PATH)
else()
string(SUBSTRING "${qtcore_path}" 0 ${qtcore_path_lib_pos} QT_TARGET_PATH)
endif()
endif()
if (NOT DEFINED QT_HOST_PATH)
# Use the same for host Qt if none is defined.
set(QT_HOST_PATH "${QT_TARGET_PATH}")
endif()
message(STATUS "Using target Qt at ${QT_TARGET_PATH}")
message(STATUS "Using host Qt at ${QT_HOST_PATH}")
endif() endif()
# Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic) # Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic)
@@ -424,7 +442,8 @@ else()
endif() endif()
# Create target for outputting distributable bundles. # Create target for outputting distributable bundles.
if (CITRA_ENABLE_BUNDLE_TARGET) # Not supported for mobile platforms as distributables are built differently.
if (NOT ANDROID AND NOT IOS)
include(BundleTarget) include(BundleTarget)
if (ENABLE_SDL2_FRONTEND) if (ENABLE_SDL2_FRONTEND)
bundle_target(citra) bundle_target(citra)
+170 -73
View File
@@ -2,37 +2,104 @@
if (BUNDLE_TARGET_EXECUTE) if (BUNDLE_TARGET_EXECUTE)
# --- Bundling method logic --- # --- Bundling method logic ---
function(symlink_safe_copy from to)
if (WIN32)
# Use cmake copy for maximum compatibility.
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${from}" "${to}"
RESULT_VARIABLE cp_result)
else()
# Use native copy to turn symlinks into normal files.
execute_process(COMMAND cp -L "${from}" "${to}"
RESULT_VARIABLE cp_result)
endif()
if (NOT cp_result EQUAL "0")
message(FATAL_ERROR "cp \"${from}\" \"${to}\" failed: ${cp_result}")
endif()
endfunction()
function(bundle_qt executable_path) function(bundle_qt executable_path)
if (WIN32) if (WIN32)
# Perform standalone bundling first to copy over all used libraries, as windeployqt does not do this.
bundle_standalone("${executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY) get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY)
find_program(windeployqt_executable windeployqt6)
# Create a qt.conf file pointing to the app directory. # Create a qt.conf file pointing to the app directory.
# This ensures Qt can find its plugins. # This ensures Qt can find its plugins.
file(WRITE "${executable_parent_dir}/qt.conf" "[Paths]\nprefix = .") file(WRITE "${executable_parent_dir}/qt.conf" "[Paths]\nPrefix = .")
find_program(windeployqt_executable windeployqt6 PATHS "${QT_HOST_PATH}/bin")
find_program(qtpaths_executable qtpaths6 PATHS "${QT_HOST_PATH}/bin")
# TODO: Hack around windeployqt's poor cross-compilation support by
# TODO: making a local copy with a prefix pointing to the target Qt.
if (NOT "${QT_HOST_PATH}" STREQUAL "${QT_TARGET_PATH}")
set(windeployqt_dir "${BINARY_PATH}/windeployqt_copy")
file(MAKE_DIRECTORY "${windeployqt_dir}")
symlink_safe_copy("${windeployqt_executable}" "${windeployqt_dir}/windeployqt.exe")
symlink_safe_copy("${qtpaths_executable}" "${windeployqt_dir}/qtpaths.exe")
symlink_safe_copy("${QT_HOST_PATH}/bin/Qt6Core.dll" "${windeployqt_dir}")
if (EXISTS "${QT_TARGET_PATH}/share")
# Unix-style Qt; we need to wire up the paths manually.
file(WRITE "${windeployqt_dir}/qt.conf" "\
[Paths]\n
Prefix = ${QT_TARGET_PATH}\n \
ArchData = ${QT_TARGET_PATH}/share/qt6\n \
Binaries = ${QT_TARGET_PATH}/bin\n \
Data = ${QT_TARGET_PATH}/share/qt6\n \
Documentation = ${QT_TARGET_PATH}/share/qt6/doc\n \
Headers = ${QT_TARGET_PATH}/include/qt6\n \
Libraries = ${QT_TARGET_PATH}/lib\n \
LibraryExecutables = ${QT_TARGET_PATH}/share/qt6/bin\n \
Plugins = ${QT_TARGET_PATH}/share/qt6/plugins\n \
QmlImports = ${QT_TARGET_PATH}/share/qt6/qml\n \
Translations = ${QT_TARGET_PATH}/share/qt6/translations\n \
")
else()
# Windows-style Qt; the defaults should suffice.
file(WRITE "${windeployqt_dir}/qt.conf" "[Paths]\nPrefix = ${QT_TARGET_PATH}")
endif()
set(windeployqt_executable "${windeployqt_dir}/windeployqt.exe")
set(qtpaths_executable "${windeployqt_dir}/qtpaths.exe")
endif()
message(STATUS "Executing windeployqt for executable ${executable_path}") message(STATUS "Executing windeployqt for executable ${executable_path}")
execute_process(COMMAND "${windeployqt_executable}" "${executable_path}" execute_process(COMMAND "${windeployqt_executable}" "${executable_path}"
--qtpaths "${qtpaths_executable}"
--no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --no-translations --no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --no-translations
--plugindir "${executable_parent_dir}/plugins") --plugindir "${executable_parent_dir}/plugins"
RESULT_VARIABLE windeployqt_result)
if (NOT windeployqt_result EQUAL "0")
message(FATAL_ERROR "windeployqt failed: ${windeployqt_result}")
endif()
# Remove the FFmpeg multimedia plugin as we don't include FFmpeg. # Remove the FFmpeg multimedia plugin as we don't include FFmpeg.
# We want to use the Windows media plugin instead, which is also included. # We want to use the Windows media plugin instead, which is also included.
file(REMOVE "${executable_parent_dir}/plugins/multimedia/ffmpegmediaplugin.dll") file(REMOVE "${executable_parent_dir}/plugins/multimedia/ffmpegmediaplugin.dll")
elseif (APPLE) elseif (APPLE)
get_filename_component(executable_name "${executable_path}" NAME_WE) get_filename_component(executable_name "${executable_path}" NAME_WE)
find_program(MACDEPLOYQT_EXECUTABLE macdeployqt6) find_program(macdeployqt_executable macdeployqt6 PATHS "${QT_HOST_PATH}/bin")
message(STATUS "Executing macdeployqt for executable ${executable_path}") message(STATUS "Executing macdeployqt at \"${macdeployqt_executable}\" for executable \"${executable_path}\"")
execute_process( execute_process(
COMMAND "${MACDEPLOYQT_EXECUTABLE}" COMMAND "${macdeployqt_executable}"
"${executable_path}" "${executable_path}"
"-executable=${executable_path}/Contents/MacOS/${executable_name}" "-executable=${executable_path}/Contents/MacOS/${executable_name}"
-always-overwrite) -always-overwrite
RESULT_VARIABLE macdeployqt_result)
if (NOT macdeployqt_result EQUAL "0")
message(FATAL_ERROR "macdeployqt failed: ${macdeployqt_result}")
endif()
# Bundling libraries can rewrite path information and break code signatures of system libraries. # Bundling libraries can rewrite path information and break code signatures of system libraries.
# Perform an ad-hoc re-signing on the whole app bundle to fix this. # Perform an ad-hoc re-signing on the whole app bundle to fix this.
execute_process(COMMAND codesign --deep -fs - "${executable_path}") execute_process(COMMAND codesign --deep -fs - "${executable_path}"
RESULT_VARIABLE codesign_result)
if (NOT codesign_result EQUAL "0")
message(FATAL_ERROR "codesign failed: ${codesign_result}")
endif()
else() else()
message(FATAL_ERROR "Unsupported OS for Qt bundling.") message(FATAL_ERROR "Unsupported OS for Qt bundling.")
endif() endif()
@@ -44,9 +111,9 @@ if (BUNDLE_TARGET_EXECUTE)
if (enable_qt) if (enable_qt)
# Find qmake to make sure the plugin uses the right version of Qt. # Find qmake to make sure the plugin uses the right version of Qt.
find_program(QMAKE_EXECUTABLE qmake6) find_program(qmake_executable qmake6 PATHS "${QT_HOST_PATH}/bin")
set(extra_linuxdeploy_env "QMAKE=${QMAKE_EXECUTABLE}") set(extra_linuxdeploy_env "QMAKE=${qmake_executable}")
set(extra_linuxdeploy_args --plugin qt) set(extra_linuxdeploy_args --plugin qt)
endif() endif()
@@ -59,7 +126,11 @@ if (BUNDLE_TARGET_EXECUTE)
--executable "${executable_path}" --executable "${executable_path}"
--icon-file "${source_path}/dist/citra.svg" --icon-file "${source_path}/dist/citra.svg"
--desktop-file "${source_path}/dist/${executable_name}.desktop" --desktop-file "${source_path}/dist/${executable_name}.desktop"
--appdir "${appdir_path}") --appdir "${appdir_path}"
RESULT_VARIABLE linuxdeploy_appdir_result)
if (NOT linuxdeploy_appdir_result EQUAL "0")
message(FATAL_ERROR "linuxdeploy failed to create AppDir: ${linuxdeploy_appdir_result}")
endif()
if (enable_qt) if (enable_qt)
set(qt_hook_file "${appdir_path}/apprun-hooks/linuxdeploy-plugin-qt-hook.sh") set(qt_hook_file "${appdir_path}/apprun-hooks/linuxdeploy-plugin-qt-hook.sh")
@@ -82,7 +153,11 @@ if (BUNDLE_TARGET_EXECUTE)
"OUTPUT=${bundle_dir}/${executable_name}.AppImage" "OUTPUT=${bundle_dir}/${executable_name}.AppImage"
"${linuxdeploy_executable}" "${linuxdeploy_executable}"
--output appimage --output appimage
--appdir "${appdir_path}") --appdir "${appdir_path}"
RESULT_VARIABLE linuxdeploy_appimage_result)
if (NOT linuxdeploy_appimage_result EQUAL "0")
message(FATAL_ERROR "linuxdeploy failed to create AppImage: ${linuxdeploy_appimage_result}")
endif()
endfunction() endfunction()
function(bundle_standalone executable_path original_executable_path bundle_library_paths) function(bundle_standalone executable_path original_executable_path bundle_library_paths)
@@ -109,16 +184,23 @@ if (BUNDLE_TARGET_EXECUTE)
file(MAKE_DIRECTORY ${lib_dir}) file(MAKE_DIRECTORY ${lib_dir})
foreach (lib_file IN LISTS resolved_deps) foreach (lib_file IN LISTS resolved_deps)
message(STATUS "Bundling library ${lib_file}") message(STATUS "Bundling library ${lib_file}")
# Use native copy to turn symlinks into normal files. symlink_safe_copy("${lib_file}" "${lib_dir}")
execute_process(COMMAND cp -L "${lib_file}" "${lib_dir}")
endforeach() endforeach()
endif() endif()
# Add libs directory to executable rpath where applicable. # Add libs directory to executable rpath where applicable.
if (APPLE) if (APPLE)
execute_process(COMMAND install_name_tool -add_rpath "@loader_path/libs" "${executable_path}") execute_process(COMMAND install_name_tool -add_rpath "@loader_path/libs" "${executable_path}"
RESULT_VARIABLE install_name_tool_result)
if (NOT install_name_tool_result EQUAL "0")
message(FATAL_ERROR "install_name_tool failed: ${install_name_tool_result}")
endif()
elseif (UNIX) elseif (UNIX)
execute_process(COMMAND patchelf --set-rpath '$ORIGIN/../libs' "${executable_path}") execute_process(COMMAND patchelf --set-rpath '$ORIGIN/../libs' "${executable_path}"
RESULT_VARIABLE patchelf_result)
if (NOT patchelf_result EQUAL "0")
message(FATAL_ERROR "patchelf failed: ${patchelf_result}")
endif()
endif() endif()
endfunction() endfunction()
@@ -127,7 +209,7 @@ if (BUNDLE_TARGET_EXECUTE)
set(bundle_dir ${BINARY_PATH}/bundle) set(bundle_dir ${BINARY_PATH}/bundle)
# On Linux, always bundle an AppImage. # On Linux, always bundle an AppImage.
if (DEFINED LINUXDEPLOY) if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
if (IN_PLACE) if (IN_PLACE)
message(FATAL_ERROR "Cannot bundle for Linux in-place.") message(FATAL_ERROR "Cannot bundle for Linux in-place.")
endif() endif()
@@ -146,14 +228,12 @@ if (BUNDLE_TARGET_EXECUTE)
if (BUNDLE_QT) if (BUNDLE_QT)
bundle_qt("${bundled_executable_path}") bundle_qt("${bundled_executable_path}")
endif() else()
if (WIN32 OR NOT BUNDLE_QT)
bundle_standalone("${bundled_executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}") bundle_standalone("${bundled_executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
endif() endif()
endif() endif()
else() elseif (BUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY)
# --- Bundling target creation logic --- # --- linuxdeploy download logic ---
# Downloads and extracts a linuxdeploy component. # Downloads and extracts a linuxdeploy component.
function(download_linuxdeploy_component base_dir name executable_name) function(download_linuxdeploy_component base_dir name executable_name)
@@ -161,7 +241,7 @@ else()
if (NOT EXISTS "${executable_file}") if (NOT EXISTS "${executable_file}")
message(STATUS "Downloading ${executable_name}") message(STATUS "Downloading ${executable_name}")
file(DOWNLOAD file(DOWNLOAD
"https://github.com/linuxdeploy/${name}/releases/download/continuous/${executable_name}" "https://github.com/${name}/releases/download/continuous/${executable_name}"
"${executable_file}" SHOW_PROGRESS) "${executable_file}" SHOW_PROGRESS)
file(CHMOD "${executable_file}" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) file(CHMOD "${executable_file}" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
@@ -170,7 +250,11 @@ else()
message(STATUS "Extracting ${executable_name}") message(STATUS "Extracting ${executable_name}")
execute_process( execute_process(
COMMAND "${executable_file}" --appimage-extract COMMAND "${executable_file}" --appimage-extract
WORKING_DIRECTORY "${base_dir}") WORKING_DIRECTORY "${base_dir}"
RESULT_VARIABLE extract_result)
if (NOT extract_result EQUAL "0")
message(FATAL_ERROR "AppImage extract failed: ${extract_result}")
endif()
else() else()
message(STATUS "Copying ${executable_name}") message(STATUS "Copying ${executable_name}")
file(COPY "${executable_file}" DESTINATION "${base_dir}/squashfs-root/usr/bin/") file(COPY "${executable_file}" DESTINATION "${base_dir}/squashfs-root/usr/bin/")
@@ -178,89 +262,102 @@ else()
endif() endif()
endfunction() endfunction()
# Download plugins first so they don't overwrite linuxdeploy's AppRun file.
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "linuxdeploy/linuxdeploy-plugin-qt" "linuxdeploy-plugin-qt-${LINUXDEPLOY_ARCH}.AppImage")
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "darealshinji/linuxdeploy-plugin-checkrt" "linuxdeploy-plugin-checkrt.sh")
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "linuxdeploy/linuxdeploy" "linuxdeploy-${LINUXDEPLOY_ARCH}.AppImage")
else()
# --- Bundling target creation logic ---
# Creates the base bundle target with common files and pre-bundle steps.
function(create_base_bundle_target)
message(STATUS "Creating base bundle target")
add_custom_target(bundle)
add_custom_command(
TARGET bundle
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/")
add_custom_command(
TARGET bundle
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/icon.png" "${CMAKE_BINARY_DIR}/bundle/dist/citra.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")
add_custom_command(
TARGET bundle
COMMAND ${CMAKE_COMMAND}
"-DBUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY=1"
"-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}")
endif()
endfunction()
# Adds a target to the bundle target, packing in required libraries. # Adds a target to the bundle target, packing in required libraries.
# If in_place is true, the bundling will be done in-place as part of the specified target. # If in_place is true, the bundling will be done in-place as part of the specified target.
function(bundle_target_internal target_name in_place) function(bundle_target_internal target_name in_place)
# Create base bundle target if it does not exist. # Create base bundle target if it does not exist.
if (NOT in_place AND NOT TARGET bundle) if (NOT in_place AND NOT TARGET bundle)
message(STATUS "Creating base bundle target") create_base_bundle_target()
add_custom_target(bundle)
add_custom_command(
TARGET bundle
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/")
add_custom_command(
TARGET bundle
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/icon.png" "${CMAKE_BINARY_DIR}/bundle/dist/citra.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")
endif() endif()
set(BUNDLE_EXECUTABLE_PATH "$<TARGET_FILE:${target_name}>") set(bundle_executable_path "$<TARGET_FILE:${target_name}>")
if (target_name MATCHES ".*qt") if (target_name MATCHES ".*qt")
set(BUNDLE_QT ON) set(bundle_qt ON)
if (APPLE) if (APPLE)
# For Qt targets on Apple, expect an app bundle. # For Qt targets on Apple, expect an app bundle.
set(BUNDLE_EXECUTABLE_PATH "$<TARGET_BUNDLE_DIR:${target_name}>") set(bundle_executable_path "$<TARGET_BUNDLE_DIR:${target_name}>")
endif() endif()
else() else()
set(BUNDLE_QT OFF) set(bundle_qt OFF)
endif() endif()
# Build a list of library search paths from prefix paths. # Build a list of library search paths from prefix paths.
foreach(prefix_path IN LISTS CMAKE_PREFIX_PATH CMAKE_SYSTEM_PREFIX_PATH) foreach(prefix_path IN LISTS CMAKE_FIND_ROOT_PATH CMAKE_PREFIX_PATH CMAKE_SYSTEM_PREFIX_PATH)
if (WIN32) if (WIN32)
list(APPEND BUNDLE_LIBRARY_PATHS "${prefix_path}/bin") list(APPEND bundle_library_paths "${prefix_path}/bin")
endif() endif()
list(APPEND BUNDLE_LIBRARY_PATHS "${prefix_path}/lib") list(APPEND bundle_library_paths "${prefix_path}/lib")
endforeach() endforeach()
foreach(library_path IN LISTS CMAKE_SYSTEM_LIBRARY_PATH) foreach(library_path IN LISTS CMAKE_SYSTEM_LIBRARY_PATH)
list(APPEND BUNDLE_LIBRARY_PATHS "${library_path}") list(APPEND bundle_library_paths "${library_path}")
endforeach() endforeach()
# On Linux, prepare linuxdeploy and any required plugins.
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LINUXDEPLOY_BASE "${CMAKE_BINARY_DIR}/externals/linuxdeploy")
# Download plugins first so they don't overwrite linuxdeploy's AppRun file.
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy-plugin-qt" "linuxdeploy-plugin-qt-x86_64.AppImage")
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy-plugin-checkrt" "linuxdeploy-plugin-checkrt-x86_64.sh")
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy" "linuxdeploy-x86_64.AppImage")
set(EXTRA_BUNDLE_ARGS "-DLINUXDEPLOY=${LINUXDEPLOY_BASE}/squashfs-root/AppRun")
endif()
if (in_place) if (in_place)
message(STATUS "Adding in-place bundling to ${target_name}") message(STATUS "Adding in-place bundling to ${target_name}")
set(DEST_TARGET ${target_name}) set(dest_target ${target_name})
else() else()
message(STATUS "Adding ${target_name} to bundle target") message(STATUS "Adding ${target_name} to bundle target")
set(DEST_TARGET bundle) set(dest_target bundle)
add_dependencies(bundle ${target_name}) add_dependencies(bundle ${target_name})
endif() endif()
add_custom_command(TARGET ${DEST_TARGET} POST_BUILD add_custom_command(TARGET ${dest_target} POST_BUILD
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
"-DCMAKE_PREFIX_PATH=\"${CMAKE_PREFIX_PATH}\"" "-DQT_HOST_PATH=\"${QT_HOST_PATH}\""
"-DQT_TARGET_PATH=\"${QT_TARGET_PATH}\""
"-DBUNDLE_TARGET_EXECUTE=1" "-DBUNDLE_TARGET_EXECUTE=1"
"-DTARGET=${target_name}" "-DTARGET=${target_name}"
"-DSOURCE_PATH=${CMAKE_SOURCE_DIR}" "-DSOURCE_PATH=${CMAKE_SOURCE_DIR}"
"-DBINARY_PATH=${CMAKE_BINARY_DIR}" "-DBINARY_PATH=${CMAKE_BINARY_DIR}"
"-DEXECUTABLE_PATH=${BUNDLE_EXECUTABLE_PATH}" "-DEXECUTABLE_PATH=${bundle_executable_path}"
"-DBUNDLE_LIBRARY_PATHS=\"${BUNDLE_LIBRARY_PATHS}\"" "-DBUNDLE_LIBRARY_PATHS=\"${bundle_library_paths}\""
"-DBUNDLE_QT=${BUNDLE_QT}" "-DBUNDLE_QT=${bundle_qt}"
"-DIN_PLACE=${in_place}" "-DIN_PLACE=${in_place}"
${EXTRA_BUNDLE_ARGS} "-DLINUXDEPLOY=${CMAKE_BINARY_DIR}/externals/linuxdeploy/squashfs-root/AppRun"
-P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake" -P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
endfunction() endfunction()
+95 -36
View File
@@ -1,21 +1,20 @@
set(CURRENT_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR}) set(CURRENT_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR})
# This function downloads Qt using aqt. The path of the downloaded content will be added to the CMAKE_PREFIX_PATH. # Determines parameters based on the host and target for downloading the right Qt binaries.
# Params: function(determine_qt_parameters target host_out type_out arch_out arch_path_out host_type_out host_arch_out host_arch_path_out)
# target: Qt dependency to install. Specify a version number to download Qt, or "tools_(name)" for a specific build tool.
function(download_qt target)
if (target MATCHES "tools_.*") if (target MATCHES "tools_.*")
set(DOWNLOAD_QT_TOOL ON) set(tool ON)
else() else()
set(DOWNLOAD_QT_TOOL OFF) set(tool OFF)
endif() endif()
# Determine installation parameters for OS, architecture, and compiler # Determine installation parameters for OS, architecture, and compiler
if (WIN32) if (WIN32)
set(host "windows") set(host "windows")
set(type "desktop") set(type "desktop")
if (NOT DOWNLOAD_QT_TOOL)
if (NOT tool)
if (MINGW) if (MINGW)
set(arch "win64_mingw") set(arch "win64_mingw")
set(arch_path "mingw_64") set(arch_path "mingw_64")
@@ -28,21 +27,35 @@ function(download_qt target)
message(FATAL_ERROR "Unsupported bundled Qt architecture. Enable USE_SYSTEM_QT and provide your own.") message(FATAL_ERROR "Unsupported bundled Qt architecture. Enable USE_SYSTEM_QT and provide your own.")
endif() endif()
set(arch "win64_${arch_path}") set(arch "win64_${arch_path}")
# In case we're cross-compiling, prepare to also fetch the correct host Qt tools.
if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
set(host_arch_path "msvc2019_64")
elseif (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "ARM64")
# TODO: msvc2019_arm64 doesn't include some of the required tools for some reason,
# TODO: so until it does, just use msvc2019_64 under x86_64 emulation.
# set(host_arch_path "msvc2019_arm64")
set(host_arch_path "msvc2019_64")
endif()
set(host_arch "win64_${host_arch_path}")
else() else()
message(FATAL_ERROR "Unsupported bundled Qt toolchain. Enable USE_SYSTEM_QT and provide your own.") message(FATAL_ERROR "Unsupported bundled Qt toolchain. Enable USE_SYSTEM_QT and provide your own.")
endif() endif()
endif() endif()
elseif (APPLE) elseif (APPLE)
set(host "mac") set(host "mac")
if (IOS AND NOT DOWNLOAD_QT_TOOL) set(type "desktop")
set(arch "clang_64")
set(arch_path "macos")
if (IOS AND NOT tool)
set(host_type "${type}")
set(host_arch "${arch}")
set(host_arch_path "${arch_path}")
set(type "ios") set(type "ios")
set(arch "ios") set(arch "ios")
set(arch_path "ios") set(arch_path "ios")
set(host_arch_path "macos")
else()
set(type "desktop")
set(arch "clang_64")
set(arch_path "macos")
endif() endif()
else() else()
set(host "linux") set(host "linux")
@@ -51,38 +64,64 @@ function(download_qt target)
set(arch_path "linux") set(arch_path "linux")
endif() endif()
get_external_prefix(qt base_path) set(${host_out} "${host}" PARENT_SCOPE)
file(MAKE_DIRECTORY "${base_path}") set(${type_out} "${type}" PARENT_SCOPE)
set(${arch_out} "${arch}" PARENT_SCOPE)
set(${arch_path_out} "${arch_path}" PARENT_SCOPE)
if (DEFINED host_type)
set(${host_type_out} "${host_type}" PARENT_SCOPE)
else()
set(${host_type_out} "${type}" PARENT_SCOPE)
endif()
if (DEFINED host_arch)
set(${host_arch_out} "${host_arch}" PARENT_SCOPE)
else()
set(${host_arch_out} "${arch}" PARENT_SCOPE)
endif()
if (DEFINED host_arch_path)
set(${host_arch_path_out} "${host_arch_path}" PARENT_SCOPE)
else()
set(${host_arch_path_out} "${arch_path}" PARENT_SCOPE)
endif()
endfunction()
# Download Qt binaries for a specifc configuration.
function(download_qt_configuration prefix_out target host type arch arch_path base_path)
if (target MATCHES "tools_.*")
set(tool ON)
else()
set(tool OFF)
endif()
set(install_args -c "${CURRENT_MODULE_DIR}/aqt_config.ini") set(install_args -c "${CURRENT_MODULE_DIR}/aqt_config.ini")
if (DOWNLOAD_QT_TOOL) if (tool)
set(prefix "${base_path}/Tools") set(prefix "${base_path}/Tools")
set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target}) set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target})
else() else()
set(prefix "${base_path}/${target}/${arch_path}") set(prefix "${base_path}/${target}/${arch_path}")
if (host_arch_path) set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch}
set(host_flag "--autodesktop") -m qtmultimedia --archives qttranslations qttools qtsvg qtbase)
set(host_prefix "${base_path}/${target}/${host_arch_path}")
endif()
set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} ${host_flag}
-m qtmultimedia --archives qttranslations qttools qtsvg qtbase)
endif() endif()
if (NOT EXISTS "${prefix}") if (NOT EXISTS "${prefix}")
message(STATUS "Downloading binaries for Qt...") message(STATUS "Downloading Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path}")
set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.1.9") set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.1.9")
if (WIN32) if (WIN32)
set(aqt_path "${base_path}/aqt.exe") set(aqt_path "${base_path}/aqt.exe")
file(DOWNLOAD if (NOT EXISTS "${aqt_path}")
${AQT_PREBUILD_BASE_URL}/aqt.exe file(DOWNLOAD
${aqt_path} SHOW_PROGRESS) ${AQT_PREBUILD_BASE_URL}/aqt.exe
${aqt_path} SHOW_PROGRESS)
endif()
execute_process(COMMAND ${aqt_path} ${install_args} execute_process(COMMAND ${aqt_path} ${install_args}
WORKING_DIRECTORY ${base_path}) WORKING_DIRECTORY ${base_path})
elseif (APPLE) elseif (APPLE)
set(aqt_path "${base_path}/aqt-macos") set(aqt_path "${base_path}/aqt-macos")
file(DOWNLOAD if (NOT EXISTS "${aqt_path}")
${AQT_PREBUILD_BASE_URL}/aqt-macos file(DOWNLOAD
${aqt_path} SHOW_PROGRESS) ${AQT_PREBUILD_BASE_URL}/aqt-macos
${aqt_path} SHOW_PROGRESS)
endif()
execute_process(COMMAND chmod +x ${aqt_path}) execute_process(COMMAND chmod +x ${aqt_path})
execute_process(COMMAND ${aqt_path} ${install_args} execute_process(COMMAND ${aqt_path} ${install_args}
WORKING_DIRECTORY ${base_path}) WORKING_DIRECTORY ${base_path})
@@ -96,18 +135,38 @@ function(download_qt target)
execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args} execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args}
WORKING_DIRECTORY ${base_path}) WORKING_DIRECTORY ${base_path})
endif() endif()
message(STATUS "Downloaded Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path} to ${prefix}")
endif() endif()
message(STATUS "Using downloaded Qt binaries at ${prefix}") set(${prefix_out} "${prefix}" PARENT_SCOPE)
endfunction()
# Add the Qt prefix path so CMake can locate it. # This function downloads Qt using aqt.
# The path of the downloaded content will be added to the CMAKE_PREFIX_PATH.
# QT_TARGET_PATH is set to the Qt for the compile target platform.
# QT_HOST_PATH is set to a host-compatible Qt, for running tools.
# Params:
# target: Qt dependency to install. Specify a version number to download Qt, or "tools_(name)" for a specific build tool.
function(download_qt target)
determine_qt_parameters("${target}" host type arch arch_path host_type host_arch host_arch_path)
get_external_prefix(qt base_path)
file(MAKE_DIRECTORY "${base_path}")
download_qt_configuration(prefix "${target}" "${host}" "${type}" "${arch}" "${arch_path}" "${base_path}")
if (DEFINED host_arch_path AND NOT "${host_arch_path}" STREQUAL "${arch_path}")
download_qt_configuration(host_prefix "${target}" "${host}" "${host_type}" "${host_arch}" "${host_arch_path}" "${base_path}")
else()
set(host_prefix "${prefix}")
endif()
set(QT_TARGET_PATH "${prefix}" CACHE STRING "")
set(QT_HOST_PATH "${host_prefix}" CACHE STRING "")
# Add the target Qt prefix path so CMake can locate it.
list(APPEND CMAKE_PREFIX_PATH "${prefix}") list(APPEND CMAKE_PREFIX_PATH "${prefix}")
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
if (DEFINED host_prefix)
message(STATUS "Using downloaded host Qt binaries at ${host_prefix}")
set(QT_HOST_PATH "${host_prefix}" CACHE STRING "")
endif()
endfunction() endfunction()
function(download_moltenvk) function(download_moltenvk)
+1 -98
View File
@@ -1,98 +1 @@
<h1 align="center"> ñ
<br>
<a href="https://citra-emu.org/"><img src="https://raw.githubusercontent.com/citra-emu/citra-assets/master/Main/citra_logo.svg" alt="Citra" width="200"></a>
<br>
<b>Citra</b>
<br>
</h1>
<h4 align="center"><b>Citra</b> is the world's most popular, open-source, Nintendo 3DS emulator.
<br>
It is written in C++ with portability in mind and builds are actively maintained for Windows, Linux, Android and macOS.
</h4>
<p align="center">
<a href="https://github.com/citra-emu/citra/actions/">
<img src="https://github.com/citra-emu/citra/workflows/citra-ci/badge.svg"
alt="GitHub Actions Build Status">
</a>
<a href="https://discord.gg/FAXfZV9">
<img src="https://img.shields.io/discord/220740965957107713?color=%237289DA&label=Citra&logo=discord&logoColor=white"
alt="Discord">
</a>
</p>
<p align="center">
<a href="#compatibility">Compatibility</a> |
<a href="#releases">Releases</a> |
<a href="#development">Development</a> |
<a href="#building">Building</a> |
<a href="#support">Support</a> |
<a href="#license">License</a>
</p>
## Compatibility
The emulator is capable of running most commercial games at full speed, provided you meet the necessary hardware requirements.
For a full list of games Citra supports, please visit our [Compatibility page](https://citra-emu.org/game/)
Check out our [website](https://citra-emu.org/) for the latest news on exciting features, progress reports, and more!
Please read the [FAQ](https://citra-emu.org/wiki/faq/) before getting started with the project.
Need help? Check out our [asking for help](https://citra-emu.org/help/reference/asking/) guide.
## Releases
Citra has two main release channels: Nightly and Canary.
The [Nightly](https://github.com/citra-emu/citra-nightly) build is based on the master branch, and contains already reviewed and tested features.
The [Canary](https://github.com/citra-emu/citra-canary) build is based on the master branch, but with additional features still under review. PRs tagged `canary-merge` are merged only into the Canary builds.
Both builds can be installed with the installer provided on the [website](https://citra-emu.org/download/), but those looking for specific versions or standalone releases can find them in the release tabs of the [Nightly](https://github.com/citra-emu/citra-nightly/releases) and [Canary](https://github.com/citra-emu/citra-canary/releases) repositories.
Android builds can be downloaded from the Google Play Store.
A Flatpak for Citra is available on [Flathub](https://flathub.org/apps/details/org.citra_emu.citra). Details on the build process can be found in [our Flathub repository](https://github.com/flathub/org.citra_emu.citra).
## Development
Most of the development happens on GitHub. It's also where [our central repository](https://github.com/citra-emu/citra) is hosted.
For development discussion, please join us on our [Discord server](https://citra-emu.org/discord/) or at #citra-dev on libera.
If you want to contribute please take a look at the [Contributor's Guide](https://github.com/citra-emu/citra/wiki/Contributing) and [Developer Information](https://github.com/citra-emu/citra/wiki/Developer-Information). You can also contact any of the developers on Discord in order to know about the current state of the emulator.
If you want to contribute to the user interface translation, please check out the [Citra project on transifex](https://www.transifex.com/citra/citra). We centralize the translation work there, and periodically upstream translations.
## Building
* __Windows__: [Windows Build](https://github.com/citra-emu/citra/wiki/Building-For-Windows)
* __Linux__: [Linux Build](https://github.com/citra-emu/citra/wiki/Building-For-Linux)
* __macOS__: [macOS Build](https://github.com/citra-emu/citra/wiki/Building-for-macOS)
* __Android__: [Android Build](https://github.com/citra-emu/citra/wiki/Building-for-Android)
## Support
If you enjoy the project and want to support us financially, check out our Patreon!
<a href="https://www.patreon.com/citraemu">
<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160">
</a>
We also happily accept donated games and hardware.
Please see our [donations page](https://citra-emu.org/donate/) for more information on how you can contribute to Citra.
Any donations received will go towards things like:
* 3DS consoles for developers to explore the hardware
* 3DS games for testing
* Any equipment required for homebrew
* Infrastructure setup
We also more than gladly accept used 3DS consoles! If you would like to give yours away, don't hesitate to join our [Discord server](https://citra-emu.org/discord/) and talk to bunnei.
## License
Citra is licensed under the GPLv2 (or any later version). Refer to the [LICENSE.txt](https://github.com/citra-emu/citra/blob/master/license.txt) file.
+8
View File
@@ -287,5 +287,13 @@ dumptxt -p $[OUT] "nfcSecret1Seed=$[NFC_SEED_1]"
dumptxt -p $[OUT] "nfcSecret1HmacKey=$[NFC_HMAC_KEY_1]" dumptxt -p $[OUT] "nfcSecret1HmacKey=$[NFC_HMAC_KEY_1]"
dumptxt -p $[OUT] "nfcIv=$[NFC_IV]" dumptxt -p $[OUT] "nfcIv=$[NFC_IV]"
# Dump seeddb.bin as well
set SEEDDB_IN "0:/gm9/out/seeddb.bin"
set SEEDDB_OUT "0:/gm9/seeddb.bin"
sdump -w seeddb.bin
cp -w $[SEEDDB_IN] $[SEEDDB_OUT]
@Exit @Exit
+1 -1
View File
@@ -6,5 +6,5 @@ Usage:
1. Copy "DumpKeys.gm9" into the "gm9/scripts/" directory on your SD card. 1. Copy "DumpKeys.gm9" into the "gm9/scripts/" directory on your SD card.
2. Launch GodMode9, press the HOME button, select Scripts, and select "DumpKeys" from the list of scripts that appears. 2. Launch GodMode9, press the HOME button, select Scripts, and select "DumpKeys" from the list of scripts that appears.
3. Wait for the script to complete and return you to the GodMode9 main menu. 3. Wait for the script to complete and return you to the GodMode9 main menu.
4. Power off your system and copy the "gm9/aes_keys.txt" file off of your SD card into "(Citra directory)/sysdata/". 4. Power off your system and copy the "gm9/aes_keys.txt" and "gm9/seeddb.bin" files off of your SD card into "(Citra directory)/sysdata/".
+1
View File
@@ -11,3 +11,4 @@ type = QT
file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml
source_file = ../../src/android/app/src/main/res/values/strings.xml source_file = ../../src/android/app/src/main/res/values/strings.xml
type = ANDROID type = ANDROID
lang_map = es_ES:es, hu_HU:hu, ru_RU:ru, pt_BR:pt, zh_CN:zh
+1 -137
View File
@@ -3583,142 +3583,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Engelsk</translation> <translation>Engelsk</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citras webservice</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Ved at give dit brugernavn og token, accepterer du at Citra indsamler yderligere brugsdata, som måske kan indeholde brugeridentificerende information.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Bekræft</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Opret konto</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Brugernavn:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Hvad er min token?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Konfiguration af webservicen kan kun ændres mens du ikke er vært af et offentligt rum.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Del anonym brugsdata med udviklerne af Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Lær mere</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>Telemetri-id:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Generer nyt</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord-presence</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Vis kørende spil som din Discord-status</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Lær mere&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Opret bruger&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Hvad er min token?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>Telemetri-id: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Godkender...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Bekræftelse mislykkedes</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -6997,4 +6861,4 @@ They may have left the room.</source>
<translation>Afventningstræ</translation> <translation>Afventningstræ</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3585,142 +3585,6 @@ Ziehe Punkte, um ihre Position zu verändern, oder doppelklicke auf Zellen in de
<translation>Englisch</translation> <translation>Englisch</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra Web Service</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Mit dem Bereitstellen Ihres Nutzernamens und Tokens, erlauben Sie Citra, zusätzliche Nutzungsdaten zu sammeln. Die Nutzungsdaten können auch Daten zur Nutzeridentifikation beinhalten.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Verifizieren</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Registrieren</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token: </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Nutzername:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Was ist mein Token?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Die Web-Service-Konfiguration kann nur geändert werden, wenn kein öffentlicher Raum gehostet wird.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetrie</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Anonyme Nutzungsdaten an das Citra-Team senden</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Mehr erfahren</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>Telemetrie-ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Regenerieren</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord Presence</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Aktuelles Spiel in Ihrem Discordstatus anzeigen</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Mehr erfahren&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Anmelden&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Was ist mein Token?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Nicht spezifiziert</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>Telemetrie-ID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token nicht verifiziert</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Der Token wurde nicht verifiziert. Die Änderung zu dem Token wurde nicht gespeichert.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Verifizieren...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Verifizierung fehlgeschlagen</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verifizierung fehlgeschlagen. Stellen Sie sicher, dass Sie sowohl Ihren Token korrekt eingegeben haben und dass Sie mit dem Internet verbunden sind.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7004,4 +6868,4 @@ They may have left the room.</source>
<translation>Wait Tree</translation> <translation>Wait Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3584,142 +3584,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Αγγλικά</translation> <translation>Αγγλικά</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Φόρμα</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra Web Service</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Παρέχοντας το όνομα χρήστη και το αναγνωριστικό σας, επιτρέπετε στο Citra να συλλέξει περισσότερα δεδομένα χρήσης, που ενδέχεται να περιέχουν αναγνωριστικές πληροφορίες χρήστη.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Επαλήθευση</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Εγγραφή</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Αναγνωριστικό: </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Όνομα χρήστη:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Ποιο είναι το αναγνωριστικό μου;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Η ρύθμιση της διαδικτυακής υπηρεσίας μπορεί να αλλάξει μόνο όταν δεν είναι σε λειτουργία κάποιο δημόσιο δωμάτιο.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Τηλεμετρία</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Κοινοποίηση ανώνυμων δεδομένων χρήσης στην ομάδα του Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Μάθετε περισσότερα</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID τηλεμετρίας:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Επαναδημιουργία</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Παρουσία Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Εμφάνιση τρέχοντος παιχνιδιού στην κατάσταση Discord σας</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Μάθετε περισσότερα&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Εγγραφή&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Ποιο είναι το αναγνωριστικό μου;&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Δεν έχει καθοριστεί</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID τηλεμετρίας: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Μη επαληθευμένο αναγνωριστικό</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Το αναγνωριστικό δεν επαληθεύτηκε. Η αλλαγή στο αναγνωριστικό σας δεν έχει αποθηκευτεί.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Επαλήθευση...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Αποτυχία επαλήθευσης</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Αποτυχία επαλήθευσης. Βεβαιωθείτε ότι έχετε εισαγάγει σωστά το αναγνωστικό σας και ότι λειτουργεί η σύνδεσή σας στο διαδίκτυο.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7001,4 +6865,4 @@ They may have left the room.</source>
<translation>Δένδρο αναμονής</translation> <translation>Δένδρο αναμονής</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3585,142 +3585,6 @@ Mueve los puntos para cambiar la posición, o haz doble click en las celdas de l
<translation>Inglés (English)</translation> <translation>Inglés (English)</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Formulario</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Servicio Web de Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Al dar tu nombre de usuario y tu token, das tu consentimiento a que Citra recopile datos de uso adicionales, que pueden incluir información que identifique al usuario.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Verificar</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Registrarse</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Nombre de usuario:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>¿Cuál es mi token?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>La configuración del Servicio Web sólo puede ser cambiada cuando una sala pública no está siendo alojada.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetría</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Compartir datos de uso anónimos con el equipo de Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Más Información</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID de Telemetría:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Regenerar</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Presencia en Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Mostrar Juego Actual en el Estado de Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Más información&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Regístrate&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;¿Cuál es mi token?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Sin especificar</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID de Telemetría: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token no verificado</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>El token no ha sido verificado. El cambio a tu token no se ha guardado.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Verificando...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>La verificación falló</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>La verificación ha fallado. Comprueba que has introducido tu token correctamente y que tu conexión a Internet funcione correctamente.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7014,4 +6878,4 @@ Puede que haya dejado la sala.</translation>
<translation>Árbol de Espera</translation> <translation>Árbol de Espera</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3583,142 +3583,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Englanti</translation> <translation>Englanti</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Muot</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citran Nettipalvelu</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Todenna</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Rekisteröidy</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Avain:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Käyttäjänimi</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Mikä on avaimeni?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Jaa anonyymejä käyttötietoja Citran tekiöiden kanssa</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Opi lisää</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>Telemetria tunnus:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Uudista</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord läsnäolo</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Näytä nykyinen peli Discord tilassa</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Lue lisää&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Kirjaudu&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Mikä on avaimeni?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>Telemetria tunnus: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Varmennetaan...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Varmennus epäonnistui</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -6981,4 +6845,4 @@ They may have left the room.</source>
<translation type="unfinished"/> <translation type="unfinished"/>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3585,142 +3585,6 @@ Glissez les points pour modifier la position, ou double-cliquez les cellules pou
<translation>Anglais</translation> <translation>Anglais</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Forme</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Service web de Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>En fournissant votre nom d&apos;utilisateur et votre jeton, vous acceptez d&apos;autoriser Citra à collecter des données d&apos;utilisation supplémentaires, qui peuvent inclure des informations d&apos;identification de l&apos;utilisateur.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Vérifier</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>S&apos;inscrire</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Jeton :</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Nom d&apos;utilisateur</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Quel est mon jeton ?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>La configuration du service Web ne peut être modifiée que si un salon publique n&apos;est pas en cours d&apos;hébergement.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Télémétrie</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Partage des données d&apos;utilisation anonymes avec l&apos;équipe Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>En savoir plus</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID de télémétrie :</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Régénérer</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Présence sur Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Afficher votre jeu en cours dans votre statut Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;En savoir plus&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;S&apos;inscrire&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Quel est mon jeton ?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Non spécifié</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID de télémétrie: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Jeton non vérifié</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Jeton non vérifié. La modification de votre jeton n&apos;a pas é sauvegardée.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Vérification en cours...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Échec de la vérification</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Échec de la vérification. Vérifiez que le jeton a é écris correctement et que votre connexion internet fonctionne.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7009,4 +6873,4 @@ Il a peut-être quitté la salon.</translation>
<translation>Arbre d&apos;instructions</translation> <translation>Arbre d&apos;instructions</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -185
View File
@@ -3582,190 +3582,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Angol</translation> <translation>Angol</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Forma</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra Web-szolgáltatás</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>A felhasználóneved és tokened megadásával, belegyezel abba, hogy a Citra használati adatokat gyűjtsön, ami felhasználó azonosító információt tartalmazhat.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Ellenőrzés</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Regisztráció</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Felhasználónév:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Mi a tokenem?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Névtelen használati adat megosztása a Citra csapatával</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Tudj meg többet</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>Telemetria ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Regeneráció</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord jelenlét</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Jelenlegi játék megjelenítése a Discord állapotodban</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Tudj meg többet&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Regisztráció&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Mi a tokenem?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Nem meghatározott</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>Telemetria ID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token nincs megerősítve</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Token nincs megerősítve. A változtatások nem lettek elmentve.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Megerősítés...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Ellenőrzés sikertelen</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Sikertelen megerősítés. Győződj meg róla, hogy helyesen írtad be a tokened, és van internetkapcsolatod.</translation>
</message>
</context>
<context>
<name>DirectConnect</name>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="14"/>
<source>Direct Connect</source>
<translation>Közvetlen Kapcsolódás</translation>
</message>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="47"/>
<source>Server Address</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="54"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Server address of the host&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="64"/>
<source>Port</source>
<translation>Port</translation>
</message>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="71"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Port number the host is listening on&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Annak a portnak a száma, amire a gazda figyel&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="77"/>
<source>24872</source>
<translation>24872</translation>
</message>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="97"/>
<source>Nickname</source>
<translation>Becenév</translation>
</message>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="111"/>
<source>Password</source>
<translation>Jelszó</translation>
</message>
<message>
<location filename="../../src/citra_qt/multiplayer/direct_connect.ui" line="153"/>
<source>Connect</source>
<translation>Kapcsolás</translation>
</message>
</context>
<context> <context>
<name>DirectConnectWindow</name> <name>DirectConnectWindow</name>
<message> <message>
@@ -6991,4 +6807,4 @@ They may have left the room.</source>
<translation>Várakozási Fa</translation> <translation>Várakozási Fa</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -138
View File
@@ -3584,143 +3584,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Inggris</translation> <translation>Inggris</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Formulir</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Layanan Web Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Dengan memberikan nama user dan token, Anda menyetujui Citra untuk mengumpulkan data penggunaan tambahan, mungkin termaksud informasi identifikasi pengguna.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Verifikasi</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Daftar</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token: </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Nama User:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Apa token Saya?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Konfigurasi Servis Web hanya bisa di ubah ketika ruangan publik sedang tidak digunakan</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Bagikan data penggunaan anonim dengan tim Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Pelajari lebih Banyak</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID Telemetri:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Memperbarui</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Status Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Tampilkan Game Saat Ini ke Status Discord Anda</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Pelajari lebih banyak&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Daftar&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Apa token saya ?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Tidak di spesifikasi</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID Telemetri: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token tidak ter-verifikasi</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Token tidak di verifikasi.
Perubahan pada token anda belum tersimpan.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Mem-verifikasi...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Verifikasi gagal</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verifikasi gagal. Pastikan nama user dan token yang Anda masukkan benar dan koneksi internet Anda menyala.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -6998,4 +6861,4 @@ They may have left the room.</source>
<translation>Tunggu Tree</translation> <translation>Tunggu Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3585,142 +3585,6 @@ Trascina i punti per cambiarne la posizione, o fai doppio clic sulla tabella per
<translation>Inglese</translation> <translation>Inglese</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Modulo</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Servizio web di Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Fornendo i tuoi nome utente e token, permetti a Citra di raccogliere dati di utilizzo aggiuntivi, che potrebbero contenere informazioni identificative dell&apos;utente.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Verifica</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Registrati</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Nome utente</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Qual è il mio token?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>La configurazione del servizio web può essere cambiata solo quando non si sta ospitando una stanza pubblica.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Condividi dati anonimi sull&apos;utilizzo con il team di Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Per saperne di più</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID telemetria:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Rigenera</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord Presence</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Mostra il gioco attuale nel tuo stato di Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Per saperne di più&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Registrati&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Qual è il mio token?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Non specificato</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID telemetria: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token non verificato</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Il token non è stato verificato. La modifica al token non è stata salvata.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Verifica...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Verifica fallita</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verifica fallita. Controlla di aver inserito il token correttamente, e che la tua connessione a internet sia funzionante.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7010,4 +6874,4 @@ Potrebbe aver lasciato la stanza.</translation>
<translation>Wait Tree</translation> <translation>Wait Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3587,142 +3587,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra Webサービス</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Citraへの追加の情報データの収集</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Web設定はPublicなルームをホスティング中は変更できません</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Citraチームに匿名で使用データを共有する</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord Presence</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Discordに表示</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;もっと詳しく&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;サインアップ&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;トークンの取得&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>テレメトリーID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7002,4 +6866,4 @@ They may have left the room.</source>
<translation>Wait Tree</translation> <translation>Wait Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3585,142 +3585,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>English</translation> <translation>English</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation> Citra가 .</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation> :</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation> ?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation> .</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Citra팀과 </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation> </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation> ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation> </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation> </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;자세히 알아보기&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;가입&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;나의 토큰이 무엇인가요?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation> ID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation> </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation> . .</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation> </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation> . .</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7004,4 +6868,4 @@ They may have left the room.</source>
<translation>Wait Tree</translation> <translation>Wait Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3581,142 +3581,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Anglų k.</translation> <translation>Anglų k.</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Forma</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra interneto tarnyba</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Įrašydami jūsų vartotojo vardą ir simbolinį ID, jūs sutinkate, kad Citra rinktų papildomus naudojimo duomenis, tarp kurių gali būti informacija, skirta atpažinti vartotoją.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Patikrinti</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Užsiregistruoti</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Simbolinis ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Vartotojo vardas:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Koks yra mano simbolinis ID?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetrija</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Pasidalinti anonimiškais naudojimo duomenimis su Citra komanda</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Sužinoti daugiau</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>Telemetrijos ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Regeneruoti</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord nustatymai</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Rodyti jūsų žaidžiamą žaidimą Discord&apos;e</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sužinoti daugiau&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Užsiregistruoti&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Koks yra mano simbolinis ID?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>Telemetrijos ID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Tikrinama...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Tikrinimas nepavyko</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -6989,4 +6853,4 @@ They may have left the room.</source>
<translation>Laukimo gijų medis</translation> <translation>Laukimo gijų medis</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3584,142 +3584,6 @@ Dra punkter for å endre posisjon, eller dobbeltklikk på tabellceller for å re
<translation>Engelsk</translation> <translation>Engelsk</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra Web Tjenester</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Ved å gi brukernavn og nøkkel, samtykker du i å tillate Citra å samle inn brukerdata, som kan inneholde bruker indentifiserende informasjon.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Verifisere</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Registrer deg</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Nøkkel: </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Brukernavn:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Hva er min nøkkel?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Web Service-konfigurasjon kan bare endres når et offentlig rom ikke blir hostet.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Del anonyme brukerdata med Citra-teamet</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Lær mer</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>Telemetri ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Regenerere</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord tilstedeværelse</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Vis Gjeldende Spill i Discord Statusen din.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Lær mer&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Registrer deg&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Hva er min nøkkel?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Uspesifisert</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>Telemetri ID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Nøkkel ikke bekreftet</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Nøkkel ble ikke bekreftet. Endringen til nøkelen ditt er ikke lagret.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Verifiserer...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Verifikasjon misslyktes</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Bekreftelsen mislyktes. Sjekk at du har lagt inn nøkkelen riktig, og at internettforbindelsen din fungerer.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7001,4 +6865,4 @@ They may have left the room.</source>
<translation>Wait Tree</translation> <translation>Wait Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3585,142 +3585,6 @@ Sleep punten om de positie te wijzigen of dubbelklik op tabelcellen om waarden t
<translation>Engels</translation> <translation>Engels</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Formulier</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra-webdienst</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Door het voorzien van je gebruikersnaam en token, ga je akkoord dat Citra aanvullende gebruiksdata verzameld, waaronder informatie waarmee de gebruiker zou kunnen worden geïdentificeerd.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Verifiëren </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Registreren</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Gebruikersnaam:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Wat is mijn token?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>De webserviceconfiguratie kan alleen worden gewijzigd als er geen publieke ruimte wordt gehost.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetrie</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Deel anonieme gebruiksdata met het Citra team</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Meer leren</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>Telemetrie ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Regenereren</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord Presence</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Toon Huidige Spel in je Discord Status</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Meer leren&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Registreren&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Wat is mijn token?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Ongespecificeerd</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>Telemetrie ID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token niet geverifieerd</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Token is niet geverifieerd. De wijziging van uw token is niet opgeslagen.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Verifiëren...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Verificatie mislukt</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verificatie mislukt. Controleer of je je token correct hebt ingevoerd en of uw internetverbinding werkt.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7012,4 +6876,4 @@ Misschien hebben ze de kamer verlaten.</translation>
<translation>Wait Tree</translation> <translation>Wait Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3583,142 +3583,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Angielski (English)</translation> <translation>Angielski (English)</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Formularz</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Usługa Sieciowa Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Poprzez wprowadzenia nazwy użytkownika i tokenu, wyrażasz zgodę na wysłanie dodatkowych danych do Citra. Dane te mogą zawierać informacje identyfikujące użytkownika.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Zweryfikuj</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Zarejestruj się</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token: </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Nazwa Użytkownika:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Czym jest mój token?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Udostępnij anonimowe dane użytkowania zespołowi Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Dowiedz się więcej</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID Telemetrii:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Regeneruj</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Widoczność na Discordzie</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Pokaż obecnie włączoną grę w statusie na Discrodzie</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Dowiedz się więcej&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Czym jest mój token?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID Telemetrii: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token nie zweryfikowany</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Weryfikowanie...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Weryfikacja nieudana</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -6992,4 +6856,4 @@ They may have left the room.</source>
<translation>Kolejka Oczekiwania</translation> <translation>Kolejka Oczekiwania</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3585,142 +3585,6 @@ Arraste os pontos para alterar a posição ou clique duas vezes nas células da
<translation>Inglês (English)</translation> <translation>Inglês (English)</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Formulário</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra Web Service</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Ao informar o seu usuário e token, você concorda em permitir ao Citra recolher dados de utilização adicionais, que podem incluir informações de identificação de usuário.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Verificar</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Registrar-se</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Nome de usuário</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Qual é o meu token?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>As configurações do Web Service não podem ser alteradas quando uma sala pública criada por você estiver em operação.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Compartilhar anonimamente dados de utilização com a equipe do Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Saiba mais</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID de telemetria:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Gerar um novo</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Presença no Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Mostrar o jogo atual no seu perfil do Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Saber mais&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Registrar-se&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Qual é o meu token?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Não especificado</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID de telemetria: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token não verificado</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>O token não foi verificado. A alteração no seu token não foi salva.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Verificando...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Falha na verificação</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Falha na verificação. Verifique se o token foi inserido corretamente e se a conexão à internet está funcionando.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7005,4 +6869,4 @@ They may have left the room.</source>
<translation>Árvore de espera</translation> <translation>Árvore de espera</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3584,142 +3584,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Engleză</translation> <translation>Engleză</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Model</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra Serviciu Web</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Furnizând numele de utilizator și token-ul, sunteți de acord permiți companiei Citra colecteze date suplimentare de utilizare, care pot include informații de identificare a utilizatorului.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Verificați</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Înregistrare</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token: </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Nume de utilizator:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Care este token-ul meu?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Configurarea de săli publice poate fi modificată doar când o sală publică nu este găzduită.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetrie</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Distribuiți date de utilizare anonime cu echipa Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Mai multe informații</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID telemetrie:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Regenerează</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Prezență pe Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Afișează Jocul Prezent pe Statusul Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Mai multe informații&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Înregistrare&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Care este token-ul meu?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Nespecificat</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID de Telemetrie: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Verificănd...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Verificare eșuată</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -6999,4 +6863,4 @@ They may have left the room.</source>
<translation>Copac de Așteptare</translation> <translation>Copac de Așteptare</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -138
View File
@@ -3587,143 +3587,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Английский</translation> <translation>Английский</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Веб-сервис Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Отправка имени пользователя и токена означает согласие на сбор приложением Citra дополнительных данных об использовании,
которые могут включать сведения, идентифицирующие пользователя.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Подтвердить</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Регистрация</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Токен:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Имя пользователя:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Что такое токен?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Настройки веб-сервиса можно изменять только в том случае, если на компьютере не размещается публичная комната чата.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Телеметрия</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Поделиться анонимными данными использования с командой Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Дополнительная информация</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>ID телеметрии:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Пересоздать</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Интеграция с Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Показывать текущую игру в статусе Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Дополнительная информация&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Зарегистрироваться&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Что такое токен?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Не указано</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>ID телеметрии: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Токен не проверен</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Токен не был проверен. Изменения к токену сохранены не были.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Проверка...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Сбой проверки</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Сбой проверки. Убедитесь в том, что токен введён верно и подключение к Интернету работает.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7005,4 +6868,4 @@ They may have left the room.</source>
<translation>Дерево цепочки ожидания</translation> <translation>Дерево цепочки ожидания</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3583,142 +3583,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>İngilizce</translation> <translation>İngilizce</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra Servisi</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Kullanıcı adınızı ve tokeninizi sağlayarak Citra&apos;nın ek kullanım verilerini toplamasına izin vermeyi kabul ediyorsunuz, bu kullanıcı tanımlayıcı bilgileri de içerebilir.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Doğrula</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Kaydol</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Kullanıcı Adı:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Tokenim nedir?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Web servisi yapılandırması yalnızca Herkese Açık Oda sunulmadığı sürece değiştirilebilir.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Citra ekibiyle anonim kullanım verilerini paylaş</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Daha fazla bilgi edinin</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation>Telemetri ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Yeniden Oluştur</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord Görünümü</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Şu Anki Oyunu Discord Durumunda Göster</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Daha fazla bilgi edinin&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Kaydol&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Tokenim nedir?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Belirtilmemiş</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation>Telemetri ID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token doğrulanmadı</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Token doğrulanmadı. Token&apos;inizdeki değişiklikler kaydedilmeyecektir.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Doğrulanıyor...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Doğrulama başarısız oldu</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Doğrulama başarısız oldu. Token&apos;inizi doğru girdiğinizden ve internet bağlantınızın çalıştığından emin olun.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7001,4 +6865,4 @@ They may have left the room.</source>
<translation>Wait Tree</translation> <translation>Wait Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3583,142 +3583,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Tiếng Anh</translation> <translation>Tiếng Anh</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Đnh dạng</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Dịch vụ Web Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>Bằng việc cung cấp tên tài khoản token, bạn đã cho phép Citra thu thập các thông tin liên quan đến giả lập, cũng như bao gồm các thông tin đnh danh người dùng.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation>Xác thực</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation>Đăng </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation>Token: </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>Tên người dùng:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation>Token của tôi ?</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation>Thiết lập cho Dịch vụ web chỉ thay đi đưc khi đang không tổ chức phòng công khai nào.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>Theo dõi từ xa</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>Gửi các dữ liệu sử dụng nặc danh cho đi ngũ Citra</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation>Tìm hiểu thêm</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation> theo dõi:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation>Tạo mới</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation>Hiển thị game đang chơi trên trạng thái Discord</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Tìm hiểu thêm&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Đăng ký&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Token là gì?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation>Chưa đnh nghĩa</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation> theo dõi: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation>Token không đưc xác thực</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation>Token này chưa đưc xác thực. Thay đi về token chưa đưc lưu.</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>Đang xác thực...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation>Xác thực thất bại</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Xác thực thất bại. Vui lòng kiểm tra token đã nhập vào đúng, hiện thiết bị đang kết nối đến mạng.</translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -6997,4 +6861,4 @@ They may have left the room.</source>
<translation>Wait Tree</translation> <translation>Wait Tree</translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3585,142 +3585,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation> Citra 使</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation>使</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation> Citra 使</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation> ID:</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation> Discord </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;了解更多&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;注册&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;我的令牌是?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation> ID: 0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation>...</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7009,4 +6873,4 @@ They may have left the room.</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
</TS> </TS>
+1 -137
View File
@@ -3584,142 +3584,6 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>English</translation> <translation>English</translation>
</message> </message>
</context> </context>
<context>
<name>ConfigureWeb</name>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="14"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="22"/>
<source>Citra Web Service</source>
<translation>Citra </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="28"/>
<source>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</source>
<translation>使 Citra 使使</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="46"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="140"/>
<source>Verify</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="53"/>
<source>Sign up</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="63"/>
<source>Token: </source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="73"/>
<source>Username: </source>
<translation>使</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="90"/>
<source>What is my token?</source>
<translation> Citra </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="115"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="125"/>
<source>Telemetry</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="131"/>
<source>Share anonymous usage data with the Citra team</source>
<translation>使 Citra </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="138"/>
<source>Learn more</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="147"/>
<source>Telemetry ID:</source>
<translation> ID</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="163"/>
<source>Regenerate</source>
<translation> ID</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="177"/>
<source>Discord Presence</source>
<translation>Discord </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.ui" line="183"/>
<source>Show Current Game in your Discord Status</source>
<translation> Discord </translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="58"/>
<source>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;了解更多&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="66"/>
<source>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://profile.citra-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;註冊&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="70"/>
<source>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
<translation>&lt;a href=&apos;https://citra-emu.org/wiki/citra-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;什麼是 Citra 權杖?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="76"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="151"/>
<source>Unspecified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="87"/>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="111"/>
<source>Telemetry ID: 0x%1</source>
<translation> ID0x%1</translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="103"/>
<source>Token not verified</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="104"/>
<source>Token was not verified. The change to your token has not been saved.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="130"/>
<source>Verifying...</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="152"/>
<source>Verification failed</source>
<translation></translation>
</message>
<message>
<location filename="../../src/citra_qt/configuration/configure_web.cpp" line="153"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
</context>
<context> <context>
<name>DirectConnect</name> <name>DirectConnect</name>
<message> <message>
@@ -7001,4 +6865,4 @@ They may have left the room.</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
</TS> </TS>
+31 -4
View File
@@ -57,6 +57,12 @@ if(USE_SYSTEM_CRYPTOPP)
add_library(cryptopp INTERFACE) add_library(cryptopp INTERFACE)
target_link_libraries(cryptopp INTERFACE cryptopp::cryptopp) target_link_libraries(cryptopp INTERFACE cryptopp::cryptopp)
else() else()
if (WIN32 AND NOT MSVC AND "arm64" IN_LIST ARCHITECTURE)
# TODO: CryptoPP ARM64 ASM does not seem to support Windows unless compiled with MSVC.
# TODO: See https://github.com/weidai11/cryptopp/issues/1260
set(CRYPTOPP_DISABLE_ASM ON CACHE BOOL "")
endif()
set(CRYPTOPP_BUILD_DOCUMENTATION OFF CACHE BOOL "") set(CRYPTOPP_BUILD_DOCUMENTATION OFF CACHE BOOL "")
set(CRYPTOPP_BUILD_TESTING OFF CACHE BOOL "") set(CRYPTOPP_BUILD_TESTING OFF CACHE BOOL "")
set(CRYPTOPP_INSTALL OFF CACHE BOOL "") set(CRYPTOPP_INSTALL OFF CACHE BOOL "")
@@ -235,6 +241,18 @@ endif()
# DiscordRPC # DiscordRPC
if (USE_DISCORD_PRESENCE) if (USE_DISCORD_PRESENCE)
# rapidjson used by discord-rpc is old and doesn't correctly detect endianness for some platforms.
include(TestBigEndian)
test_big_endian(RAPIDJSON_BIG_ENDIAN)
if(RAPIDJSON_BIG_ENDIAN)
add_compile_definitions(RAPIDJSON_ENDIAN=1)
else()
add_compile_definitions(RAPIDJSON_ENDIAN=0)
endif()
# Apply a dummy CLANG_FORMAT_SUFFIX to disable discord-rpc's unnecessary automatic clang-format.
set(CLANG_FORMAT_SUFFIX "dummy")
add_subdirectory(discord-rpc EXCLUDE_FROM_ALL) add_subdirectory(discord-rpc EXCLUDE_FROM_ALL)
target_include_directories(discord-rpc INTERFACE ./discord-rpc/include) target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
endif() endif()
@@ -276,11 +294,20 @@ endif()
add_library(httplib INTERFACE) add_library(httplib INTERFACE)
if(USE_SYSTEM_CPP_HTTPLIB) if(USE_SYSTEM_CPP_HTTPLIB)
find_package(CppHttp 0.14.1) find_package(CppHttp 0.14.1)
if(CppHttp_FOUND) # Detect if system cpphttplib is a shared library
target_link_libraries(httplib INTERFACE httplib::httplib) # this breaks building as Citra relies on functions that are moved
else() # into the shared object.
message(STATUS "Cpp-httplib not found or not suitable version! Falling back to bundled...") get_target_property(HTTP_LIBS httplib::httplib INTERFACE_LINK_LIBRARIES)
if(HTTP_LIBS)
message(WARNING "Shared cpp-http (${HTTP_LIBS}) not supported. Falling back to bundled...")
target_include_directories(httplib SYSTEM INTERFACE ./httplib) target_include_directories(httplib SYSTEM INTERFACE ./httplib)
else()
if(CppHttp_FOUND)
target_link_libraries(httplib INTERFACE httplib::httplib)
else()
message(STATUS "Cpp-httplib not found or not suitable version! Falling back to bundled...")
target_include_directories(httplib SYSTEM INTERFACE ./httplib)
endif()
endif() endif()
else() else()
target_include_directories(httplib SYSTEM INTERFACE ./httplib) target_include_directories(httplib SYSTEM INTERFACE ./httplib)
+8 -8
View File
@@ -10,7 +10,7 @@ plugins {
id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.android")
id("de.undercouch.download") version "5.5.0" id("de.undercouch.download") version "5.5.0"
id("kotlin-parcelize") id("kotlin-parcelize")
kotlin("plugin.serialization") version "1.8.21" kotlin("plugin.serialization") version "1.9.22"
id("androidx.navigation.safeargs.kotlin") id("androidx.navigation.safeargs.kotlin")
} }
@@ -173,23 +173,23 @@ android {
dependencies { dependencies {
implementation("androidx.recyclerview:recyclerview:1.3.2") implementation("androidx.recyclerview:recyclerview:1.3.2")
implementation("androidx.activity:activity-ktx:1.8.0") implementation("androidx.activity:activity-ktx:1.8.2")
implementation("androidx.fragment:fragment-ktx:1.6.2") implementation("androidx.fragment:fragment-ktx:1.6.2")
implementation("androidx.appcompat:appcompat:1.6.1") implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.documentfile:documentfile:1.0.1") implementation("androidx.documentfile:documentfile:1.0.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
implementation("androidx.slidingpanelayout:slidingpanelayout:1.2.0") implementation("androidx.slidingpanelayout:slidingpanelayout:1.2.0")
implementation("com.google.android.material:material:1.9.0") implementation("com.google.android.material:material:1.9.0")
implementation("androidx.core:core-splashscreen:1.0.1") implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.work:work-runtime:2.8.1") implementation("androidx.work:work-runtime:2.9.0")
implementation("org.ini4j:ini4j:0.5.4") implementation("org.ini4j:ini4j:0.5.4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.5") implementation("androidx.navigation:navigation-fragment-ktx:2.7.6")
implementation("androidx.navigation:navigation-ui-ktx:2.7.5") implementation("androidx.navigation:navigation-ui-ktx:2.7.6")
implementation("info.debatty:java-string-similarity:2.0.0") implementation("info.debatty:java-string-similarity:2.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
implementation("androidx.preference:preference-ktx:1.2.1") implementation("androidx.preference:preference-ktx:1.2.1")
implementation("io.coil-kt:coil:2.2.2") implementation("io.coil-kt:coil:2.5.0")
} }
// Download Vulkan Validation Layers from the KhronosGroup GitHub. // Download Vulkan Validation Layers from the KhronosGroup GitHub.
@@ -42,6 +42,9 @@
android:banner="@mipmap/ic_launcher" android:banner="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"> android:requestLegacyExternalStorage="true">
<meta-data android:name="android.game_mode_config"
android:resource="@xml/game_mode_config" />
<activity <activity
android:name="org.citra.citra_emu.ui.main.MainActivity" android:name="org.citra.citra_emu.ui.main.MainActivity"
android:theme="@style/Theme.Citra.Splash.Main" android:theme="@style/Theme.Citra.Splash.Main"
@@ -9,10 +9,13 @@ import android.app.Application
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.content.Context import android.content.Context
import android.os.Build
import org.citra.citra_emu.utils.DirectoryInitialization import org.citra.citra_emu.utils.DirectoryInitialization
import org.citra.citra_emu.utils.DocumentsTree import org.citra.citra_emu.utils.DocumentsTree
import org.citra.citra_emu.utils.GpuDriverHelper import org.citra.citra_emu.utils.GpuDriverHelper
import org.citra.citra_emu.utils.PermissionsHandler import org.citra.citra_emu.utils.PermissionsHandler
import org.citra.citra_emu.utils.Log
import org.citra.citra_emu.utils.MemoryUtil
class CitraApplication : Application() { class CitraApplication : Application() {
private fun createNotificationChannel() { private fun createNotificationChannel() {
@@ -53,9 +56,20 @@ class CitraApplication : Application() {
} }
NativeLibrary.logDeviceInfo() NativeLibrary.logDeviceInfo()
logDeviceInfo()
createNotificationChannel() createNotificationChannel()
} }
fun logDeviceInfo() {
Log.info("Device Manufacturer - ${Build.MANUFACTURER}")
Log.info("Device Model - ${Build.MODEL}")
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
Log.info("SoC Manufacturer - ${Build.SOC_MANUFACTURER}")
Log.info("SoC Model - ${Build.SOC_MODEL}")
}
Log.info("Total System Memory - ${MemoryUtil.getDeviceRAM()}")
}
companion object { companion object {
private var application: CitraApplication? = null private var application: CitraApplication? = null
@@ -413,12 +413,12 @@ object NativeLibrary {
} }
fun setEmulationActivity(emulationActivity: EmulationActivity?) { fun setEmulationActivity(emulationActivity: EmulationActivity?) {
Log.verbose("[NativeLibrary] Registering EmulationActivity.") Log.debug("[NativeLibrary] Registering EmulationActivity.")
sEmulationActivity = WeakReference(emulationActivity) sEmulationActivity = WeakReference(emulationActivity)
} }
fun clearEmulationActivity() { fun clearEmulationActivity() {
Log.verbose("[NativeLibrary] Unregistering EmulationActivity.") Log.debug("[NativeLibrary] Unregistering EmulationActivity.")
sEmulationActivity.clear() sEmulationActivity.clear()
} }
@@ -94,14 +94,14 @@ object DirectoryInitialization {
val dataPath = PermissionsHandler.citraDirectory val dataPath = PermissionsHandler.citraDirectory
if (dataPath.toString().isNotEmpty()) { if (dataPath.toString().isNotEmpty()) {
userPath = dataPath.toString() userPath = dataPath.toString()
Log.debug("[DirectoryInitialization] User Dir: $userPath") android.util.Log.d("[Citra Frontend]", "[DirectoryInitialization] User Dir: $userPath")
return true return true
} }
return false return false
} }
private fun copyAsset(asset: String, output: File, overwrite: Boolean, context: Context) { private fun copyAsset(asset: String, output: File, overwrite: Boolean, context: Context) {
Log.verbose("[DirectoryInitialization] Copying File $asset to $output") Log.debug("[DirectoryInitialization] Copying File $asset to $output")
try { try {
if (!output.exists() || overwrite) { if (!output.exists() || overwrite) {
val inputStream = context.assets.open(asset) val inputStream = context.assets.open(asset)
@@ -121,7 +121,7 @@ object DirectoryInitialization {
overwrite: Boolean, overwrite: Boolean,
context: Context context: Context
) { ) {
Log.verbose("[DirectoryInitialization] Copying Folder $assetFolder to $outputFolder") Log.debug("[DirectoryInitialization] Copying Folder $assetFolder to $outputFolder")
try { try {
var createdFolder = false var createdFolder = false
for (file in context.assets.list(assetFolder)!!) { for (file in context.assets.list(assetFolder)!!) {
@@ -4,34 +4,17 @@
package org.citra.citra_emu.utils package org.citra.citra_emu.utils
import android.util.Log
import org.citra.citra_emu.BuildConfig
/**
* Contains methods that call through to [android.util.Log], but
* with the same TAG automatically provided. Also no-ops VERBOSE and DEBUG log
* levels in release builds.
*/
object Log { object Log {
// Tracks whether we should share the old log or the current log // Tracks whether we should share the old log or the current log
var gameLaunched = false var gameLaunched = false
private const val TAG = "Citra Frontend"
fun verbose(message: String?) { external fun debug(message: String)
if (BuildConfig.DEBUG) {
Log.v(TAG, message!!)
}
}
fun debug(message: String?) { external fun warning(message: String)
if (BuildConfig.DEBUG) {
Log.d(TAG, message!!)
}
}
fun info(message: String?) = Log.i(TAG, message!!) external fun info(message: String)
fun warning(message: String?) = Log.w(TAG, message!!) external fun error(message: String)
fun error(message: String?) = Log.e(TAG, message!!) external fun critical(message: String)
} }
@@ -0,0 +1,108 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.citra.citra_emu.utils
import android.app.ActivityManager
import android.content.Context
import android.os.Build
import org.citra.citra_emu.CitraApplication
import org.citra.citra_emu.R
import java.util.Locale
import kotlin.math.ceil
object MemoryUtil {
private val context get() = CitraApplication.appContext
private val Float.hundredths: String
get() = String.format(Locale.ROOT, "%.2f", this)
const val Kb: Float = 1024F
const val Mb = Kb * 1024
const val Gb = Mb * 1024
const val Tb = Gb * 1024
const val Pb = Tb * 1024
const val Eb = Pb * 1024
fun bytesToSizeUnit(size: Float, roundUp: Boolean = false): String =
when {
size < Kb -> {
context.getString(
R.string.memory_formatted,
size.hundredths,
context.getString(R.string.memory_byte_shorthand)
)
}
size < Mb -> {
context.getString(
R.string.memory_formatted,
if (roundUp) ceil(size / Kb) else (size / Kb).hundredths,
context.getString(R.string.memory_kilobyte)
)
}
size < Gb -> {
context.getString(
R.string.memory_formatted,
if (roundUp) ceil(size / Mb) else (size / Mb).hundredths,
context.getString(R.string.memory_megabyte)
)
}
size < Tb -> {
context.getString(
R.string.memory_formatted,
if (roundUp) ceil(size / Gb) else (size / Gb).hundredths,
context.getString(R.string.memory_gigabyte)
)
}
size < Pb -> {
context.getString(
R.string.memory_formatted,
if (roundUp) ceil(size / Tb) else (size / Tb).hundredths,
context.getString(R.string.memory_terabyte)
)
}
size < Eb -> {
context.getString(
R.string.memory_formatted,
if (roundUp) ceil(size / Pb) else (size / Pb).hundredths,
context.getString(R.string.memory_petabyte)
)
}
else -> {
context.getString(
R.string.memory_formatted,
if (roundUp) ceil(size / Eb) else (size / Eb).hundredths,
context.getString(R.string.memory_exabyte)
)
}
}
val totalMemory: Float
get() {
val memInfo = ActivityManager.MemoryInfo()
with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) {
getMemoryInfo(memInfo)
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
memInfo.advertisedMem.toFloat()
} else {
memInfo.totalMem.toFloat()
}
}
fun isLessThan(minimum: Int, size: Float): Boolean =
when (size) {
Kb -> totalMemory < Mb && totalMemory < minimum
Mb -> totalMemory < Gb && (totalMemory / Mb) < minimum
Gb -> totalMemory < Tb && (totalMemory / Gb) < minimum
Tb -> totalMemory < Pb && (totalMemory / Tb) < minimum
Pb -> totalMemory < Eb && (totalMemory / Pb) < minimum
Eb -> totalMemory / Eb < minimum
else -> totalMemory < Kb && totalMemory < minimum
}
// Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for
// the potential error created by memInfo.totalMem
fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory, true)
}
@@ -28,6 +28,7 @@ add_library(citra-android SHARED
ndk_motion.cpp ndk_motion.cpp
ndk_motion.h ndk_motion.h
system_save_game.cpp system_save_game.cpp
native_log.cpp
) )
target_link_libraries(citra-android PRIVATE audio_core citra_common citra_core input_common network) target_link_libraries(citra-android PRIVATE audio_core citra_common citra_core input_common network)
+2 -2
View File
@@ -244,12 +244,14 @@ void Config::ReadValues() {
// Miscellaneous // Miscellaneous
ReadSetting("Miscellaneous", Settings::values.log_filter); ReadSetting("Miscellaneous", Settings::values.log_filter);
ReadSetting("Miscellaneous", Settings::values.log_regex_filter);
// Apply the log_filter setting as the logger has already been initialized // Apply the log_filter setting as the logger has already been initialized
// and doesn't pick up the filter on its own. // and doesn't pick up the filter on its own.
Common::Log::Filter filter; Common::Log::Filter filter;
filter.ParseFilterString(Settings::values.log_filter.GetValue()); filter.ParseFilterString(Settings::values.log_filter.GetValue());
Common::Log::SetGlobalFilter(filter); Common::Log::SetGlobalFilter(filter);
Common::Log::SetRegexFilter(Settings::values.log_regex_filter.GetValue());
// Debugging // Debugging
Settings::values.record_frame_times = Settings::values.record_frame_times =
@@ -264,8 +266,6 @@ void Config::ReadValues() {
} }
// Web Service // Web Service
NetSettings::values.enable_telemetry =
sdl2_config->GetBoolean("WebService", "enable_telemetry", false);
NetSettings::values.web_api_url = NetSettings::values.web_api_url =
sdl2_config->GetString("WebService", "web_api_url", "https://api.citra-emu.org"); sdl2_config->GetString("WebService", "web_api_url", "https://api.citra-emu.org");
NetSettings::values.citra_username = sdl2_config->GetString("WebService", "citra_username", ""); NetSettings::values.citra_username = sdl2_config->GetString("WebService", "citra_username", "");
@@ -353,9 +353,6 @@ gdbstub_port=24689
# To LLE a service module add "LLE\<module name>=true" # To LLE a service module add "LLE\<module name>=true"
[WebService] [WebService]
# Whether or not to enable telemetry
# 0 (default): No, 1: Yes
enable_telemetry =
# URL for Web API # URL for Web API
web_api_url = https://api.citra-emu.org web_api_url = https://api.citra-emu.org
# Username and token for Citra Web Service # Username and token for Citra Web Service
-4
View File
@@ -38,7 +38,6 @@
#include "core/hle/service/nfc/nfc.h" #include "core/hle/service/nfc/nfc.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
#include "core/savestate.h" #include "core/savestate.h"
#include "core/telemetry_session.h"
#include "jni/android_common/android_common.h" #include "jni/android_common/android_common.h"
#include "jni/applets/mii_selector.h" #include "jni/applets/mii_selector.h"
#include "jni/applets/swkbd.h" #include "jni/applets/swkbd.h"
@@ -207,9 +206,6 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
return load_result; return load_result;
} }
auto& telemetry_session = system.TelemetrySession();
telemetry_session.AddField(Common::Telemetry::FieldType::App, "Frontend", "Android");
stop_run = false; stop_run = false;
pause_emulation = false; pause_emulation = false;
@@ -0,0 +1,30 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <common/logging/log.h>
#include <jni.h>
#include "android_common/android_common.h"
extern "C" {
void Java_org_citra_citra_1emu_utils_Log_debug(JNIEnv* env, jobject obj, jstring jmessage) {
LOG_DEBUG(Frontend, "{}", GetJString(env, jmessage));
}
void Java_org_citra_citra_1emu_utils_Log_warning(JNIEnv* env, jobject obj, jstring jmessage) {
LOG_WARNING(Frontend, "{}", GetJString(env, jmessage));
}
void Java_org_citra_citra_1emu_utils_Log_info(JNIEnv* env, jobject obj, jstring jmessage) {
LOG_INFO(Frontend, "{}", GetJString(env, jmessage));
}
void Java_org_citra_citra_1emu_utils_Log_error(JNIEnv* env, jobject obj, jstring jmessage) {
LOG_ERROR(Frontend, "{}", GetJString(env, jmessage));
}
void Java_org_citra_citra_1emu_utils_Log_critical(JNIEnv* env, jobject obj, jstring jmessage) {
LOG_CRITICAL(Frontend, "{}", GetJString(env, jmessage));
}
} // extern "C"
@@ -442,6 +442,17 @@
<string name="cia_install_error_encrypted">\"%s\" must be decrypted before being used with Citra.\n A real 3DS is required</string> <string name="cia_install_error_encrypted">\"%s\" must be decrypted before being used with Citra.\n A real 3DS is required</string>
<string name="cia_install_error_unknown">An unknown error occurred while installing \"%s\".\n Please see the log for more details</string> <string name="cia_install_error_unknown">An unknown error occurred while installing \"%s\".\n Please see the log for more details</string>
<!-- Memory Sizes -->
<string name="memory_formatted">%1$s %2$s</string>
<string name="memory_byte">Byte</string>
<string name="memory_byte_shorthand">B</string>
<string name="memory_kilobyte">KB</string>
<string name="memory_megabyte">MB</string>
<string name="memory_gigabyte">GB</string>
<string name="memory_terabyte">TB</string>
<string name="memory_petabyte">PB</string>
<string name="memory_exabyte">EB</string>
<!-- Theme Modes --> <!-- Theme Modes -->
<string name="change_theme_mode">Change Theme Mode</string> <string name="change_theme_mode">Change Theme Mode</string>
<string name="theme_mode_follow_system">Follow System</string> <string name="theme_mode_follow_system">Follow System</string>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<game-mode-config
xmlns:android="http://schemas.android.com/apk/res/android"
android:supportsBatteryGameMode="true"
android:supportsPerformanceGameMode="true"
android:allowGameDownscaling="false"
android:allowGameFpsOverride="false"/>
+5 -5
View File
@@ -4,10 +4,10 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id("com.android.application") version "8.1.2" apply false id("com.android.application") version "8.2.1" apply false
id("com.android.library") version "8.1.2" apply false id("com.android.library") version "8.2.1" apply false
id("org.jetbrains.kotlin.android") version "1.8.21" apply false id("org.jetbrains.kotlin.android") version "1.9.22" apply false
id("org.jetbrains.kotlin.plugin.serialization") version "1.8.21" id("org.jetbrains.kotlin.plugin.serialization") version "1.9.22"
} }
tasks.register("clean").configure { tasks.register("clean").configure {
@@ -19,6 +19,6 @@ buildscript {
google() google()
} }
dependencies { dependencies {
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.5") classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.6")
} }
} }
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
+1 -1
View File
@@ -316,7 +316,7 @@ struct SourceStatus {
u16_le sync_count; ///< Is set by the DSP to the value of SourceConfiguration::sync_count u16_le sync_count; ///< Is set by the DSP to the value of SourceConfiguration::sync_count
u32_dsp buffer_position; ///< Number of samples into the current buffer u32_dsp buffer_position; ///< Number of samples into the current buffer
u16_le current_buffer_id; ///< Updated when a buffer finishes playing u16_le current_buffer_id; ///< Updated when a buffer finishes playing
INSERT_PADDING_DSPWORDS(1); u16_le last_buffer_id; ///< Updated when all buffers in the queue finish playing
}; };
Status status[num_sources]; Status status[num_sources];
+25 -12
View File
@@ -298,9 +298,9 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config,
b.buffer_id, b.buffer_id,
state.mono_or_stereo, state.mono_or_stereo,
state.format, state.format,
true, true, // from_queue
{}, // 0 in u32_dsp 0, // play_position
false, false, // has_played
}); });
} }
LOG_TRACE(Audio_DSP, "enqueuing queued {} addr={:#010x} len={} id={}", i, LOG_TRACE(Audio_DSP, "enqueuing queued {} addr={:#010x} len={} id={}", i,
@@ -321,16 +321,19 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config,
void Source::GenerateFrame() { void Source::GenerateFrame() {
current_frame.fill({}); current_frame.fill({});
if (state.current_buffer.empty() && !DequeueBuffer()) { if (state.current_buffer.empty()) {
// TODO(SachinV): Should dequeue happen at the end of the frame generation?
if (DequeueBuffer()) {
return;
}
state.enabled = false; state.enabled = false;
state.buffer_update = true; state.buffer_update = true;
state.last_buffer_id = state.current_buffer_id;
state.current_buffer_id = 0; state.current_buffer_id = 0;
return; return;
} }
std::size_t frame_position = 0; std::size_t frame_position = 0;
state.current_sample_number = state.next_sample_number;
while (frame_position < current_frame.size()) { while (frame_position < current_frame.size()) {
if (state.current_buffer.empty() && !DequeueBuffer()) { if (state.current_buffer.empty() && !DequeueBuffer()) {
break; break;
@@ -357,7 +360,7 @@ void Source::GenerateFrame() {
} }
// TODO(jroweboy): Keep track of frame_position independently so that it doesn't lose precision // TODO(jroweboy): Keep track of frame_position independently so that it doesn't lose precision
// over time // over time
state.next_sample_number += static_cast<u32>(frame_position * state.rate_multiplier); state.current_sample_number += static_cast<u32>(frame_position * state.rate_multiplier);
state.filters.ProcessFrame(current_frame); state.filters.ProcessFrame(current_frame);
} }
@@ -408,9 +411,9 @@ bool Source::DequeueBuffer() {
// the first playthrough starts at play_position, loops start at the beginning of the buffer // the first playthrough starts at play_position, loops start at the beginning of the buffer
state.current_sample_number = (!buf.has_played) ? buf.play_position : 0; state.current_sample_number = (!buf.has_played) ? buf.play_position : 0;
state.next_sample_number = state.current_sample_number;
state.current_buffer_physical_address = buf.physical_address; state.current_buffer_physical_address = buf.physical_address;
state.current_buffer_id = buf.buffer_id; state.current_buffer_id = buf.buffer_id;
state.last_buffer_id = 0;
state.buffer_update = buf.from_queue && !buf.has_played; state.buffer_update = buf.from_queue && !buf.has_played;
if (buf.is_looping) { if (buf.is_looping) {
@@ -418,8 +421,17 @@ bool Source::DequeueBuffer() {
state.input_queue.push(buf); state.input_queue.push(buf);
} }
LOG_TRACE(Audio_DSP, "source_id={} buffer_id={} from_queue={} current_buffer.size()={}", // Because our interpolation consumes samples instead of using an index,
source_id, buf.buffer_id, buf.from_queue, state.current_buffer.size()); // let's just consume the samples up to the current sample number.
state.current_buffer.erase(
state.current_buffer.begin(),
std::next(state.current_buffer.begin(), state.current_sample_number));
LOG_TRACE(Audio_DSP,
"source_id={} buffer_id={} from_queue={} current_buffer.size()={}, "
"buf.has_played={}, buf.play_position={}",
source_id, buf.buffer_id, buf.from_queue, state.current_buffer.size(), buf.has_played,
buf.play_position);
return true; return true;
} }
@@ -432,9 +444,10 @@ SourceStatus::Status Source::GetCurrentStatus() {
ret.is_enabled = state.enabled; ret.is_enabled = state.enabled;
ret.current_buffer_id_dirty = state.buffer_update ? 1 : 0; ret.current_buffer_id_dirty = state.buffer_update ? 1 : 0;
state.buffer_update = false; state.buffer_update = false;
ret.current_buffer_id = state.current_buffer_id;
ret.buffer_position = state.current_sample_number;
ret.sync_count = state.sync_count; ret.sync_count = state.sync_count;
ret.buffer_position = state.current_sample_number;
ret.current_buffer_id = state.current_buffer_id;
ret.last_buffer_id = state.last_buffer_id;
return ret; return ret;
} }
+4 -5
View File
@@ -87,8 +87,8 @@ private:
Format format; Format format;
bool from_queue; bool from_queue;
u32_dsp play_position; // = 0; u32 play_position; // = 0;
bool has_played; // = false; bool has_played; // = false;
private: private:
template <class Archive> template <class Archive>
@@ -136,14 +136,14 @@ private:
// Current buffer // Current buffer
u32 current_sample_number = 0; u32 current_sample_number = 0;
u32 next_sample_number = 0;
PAddr current_buffer_physical_address = 0; PAddr current_buffer_physical_address = 0;
AudioInterp::StereoBuffer16 current_buffer = {}; AudioInterp::StereoBuffer16 current_buffer = {};
// buffer_id state // buffer_id state
bool buffer_update = false; bool buffer_update = false;
u32 current_buffer_id = 0; u16 last_buffer_id = 0;
u16 current_buffer_id = 0;
// Decoding state // Decoding state
@@ -170,7 +170,6 @@ private:
ar& mono_or_stereo; ar& mono_or_stereo;
ar& format; ar& format;
ar& current_sample_number; ar& current_sample_number;
ar& next_sample_number;
ar& current_buffer_physical_address; ar& current_buffer_physical_address;
ar& current_buffer; ar& current_buffer;
ar& buffer_update; ar& buffer_update;
+3 -2
View File
@@ -73,8 +73,9 @@ OpenALSink::OpenALSink(std::string device_name) : impl(std::make_unique<Impl>())
auto alBufferCallbackSOFT = auto alBufferCallbackSOFT =
reinterpret_cast<LPALBUFFERCALLBACKSOFT>(alGetProcAddress("alBufferCallbackSOFT")); reinterpret_cast<LPALBUFFERCALLBACKSOFT>(alGetProcAddress("alBufferCallbackSOFT"));
alBufferCallbackSOFT(impl->buffer, AL_FORMAT_STEREO16, native_sample_rate, &Impl::Callback, alBufferCallbackSOFT(impl->buffer, AL_FORMAT_STEREO16, native_sample_rate,
impl.get()); reinterpret_cast<ALBUFFERCALLBACKTYPESOFT>(&Impl::Callback), impl.get());
if (alGetError() != AL_NO_ERROR) { if (alGetError() != AL_NO_ERROR) {
LOG_CRITICAL(Audio_Sink, "alBufferCallbackSOFT failed: {}", alGetError()); LOG_CRITICAL(Audio_Sink, "alBufferCallbackSOFT failed: {}", alGetError());
Close(); Close();
-3
View File
@@ -39,7 +39,6 @@
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg.h"
#include "core/movie.h" #include "core/movie.h"
#include "core/telemetry_session.h"
#include "input_common/main.h" #include "input_common/main.h"
#include "network/network.h" #include "network/network.h"
#include "video_core/gpu.h" #include "video_core/gpu.h"
@@ -436,8 +435,6 @@ int main(int argc, char** argv) {
break; break;
} }
system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "SDL");
if (use_multiplayer) { if (use_multiplayer) {
if (auto member = Network::GetRoomMember().lock()) { if (auto member = Network::GetRoomMember().lock()) {
member->BindOnChatMessageRecieved(OnMessageReceived); member->BindOnChatMessageRecieved(OnMessageReceived);
+2 -2
View File
@@ -306,12 +306,14 @@ void Config::ReadValues() {
// Miscellaneous // Miscellaneous
ReadSetting("Miscellaneous", Settings::values.log_filter); ReadSetting("Miscellaneous", Settings::values.log_filter);
ReadSetting("Miscellaneous", Settings::values.log_regex_filter);
// Apply the log_filter setting as the logger has already been initialized // Apply the log_filter setting as the logger has already been initialized
// and doesn't pick up the filter on its own. // and doesn't pick up the filter on its own.
Common::Log::Filter filter; Common::Log::Filter filter;
filter.ParseFilterString(Settings::values.log_filter.GetValue()); filter.ParseFilterString(Settings::values.log_filter.GetValue());
Common::Log::SetGlobalFilter(filter); Common::Log::SetGlobalFilter(filter);
Common::Log::SetRegexFilter(Settings::values.log_regex_filter.GetValue());
// Debugging // Debugging
Settings::values.record_frame_times = Settings::values.record_frame_times =
@@ -326,8 +328,6 @@ void Config::ReadValues() {
} }
// Web Service // Web Service
NetSettings::values.enable_telemetry =
sdl2_config->GetBoolean("WebService", "enable_telemetry", false);
NetSettings::values.web_api_url = NetSettings::values.web_api_url =
sdl2_config->GetString("WebService", "web_api_url", "https://api.citra-emu.org"); sdl2_config->GetString("WebService", "web_api_url", "https://api.citra-emu.org");
NetSettings::values.citra_username = sdl2_config->GetString("WebService", "citra_username", ""); NetSettings::values.citra_username = sdl2_config->GetString("WebService", "citra_username", "");
-3
View File
@@ -361,9 +361,6 @@ renderer_debug =
# To LLE a service module add "LLE\<module name>=true" # To LLE a service module add "LLE\<module name>=true"
[WebService] [WebService]
# Whether or not to enable telemetry
# 0 (default): No, 1: Yes
enable_telemetry =
# URL for Web API # URL for Web API
web_api_url = https://api.citra-emu.org web_api_url = https://api.citra-emu.org
# Username and token for Citra Web Service # Username and token for Citra Web Service
-3
View File
@@ -81,9 +81,6 @@ add_executable(citra-qt
configuration/configure_ui.cpp configuration/configure_ui.cpp
configuration/configure_ui.h configuration/configure_ui.h
configuration/configure_ui.ui configuration/configure_ui.ui
configuration/configure_web.cpp
configuration/configure_web.h
configuration/configure_web.ui
configuration/configure_cheats.cpp configuration/configure_cheats.cpp
configuration/configure_cheats.h configuration/configure_cheats.h
configuration/configure_cheats.ui configuration/configure_cheats.ui
+2 -8
View File
@@ -7,14 +7,12 @@
#include <QPushButton> #include <QPushButton>
#include <QtConcurrent/qtconcurrentrun.h> #include <QtConcurrent/qtconcurrentrun.h>
#include "citra_qt/compatdb.h" #include "citra_qt/compatdb.h"
#include "common/telemetry.h"
#include "core/core.h" #include "core/core.h"
#include "core/telemetry_session.h"
#include "ui_compatdb.h" #include "ui_compatdb.h"
CompatDB::CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent) CompatDB::CompatDB(QWidget* parent)
: QWizard(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), : QWizard(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
ui{std::make_unique<Ui::CompatDB>()}, telemetry_session{telemetry_session_} { ui{std::make_unique<Ui::CompatDB>()} {
ui->setupUi(this); ui->setupUi(this);
connect(ui->radioButton_Perfect, &QRadioButton::clicked, this, &CompatDB::EnableNext); connect(ui->radioButton_Perfect, &QRadioButton::clicked, this, &CompatDB::EnableNext);
connect(ui->radioButton_Great, &QRadioButton::clicked, this, &CompatDB::EnableNext); connect(ui->radioButton_Great, &QRadioButton::clicked, this, &CompatDB::EnableNext);
@@ -52,15 +50,11 @@ void CompatDB::Submit() {
case CompatDBPage::Final: case CompatDBPage::Final:
back(); back();
LOG_DEBUG(Frontend, "Compatibility Rating: {}", compatibility->checkedId()); LOG_DEBUG(Frontend, "Compatibility Rating: {}", compatibility->checkedId());
telemetry_session.AddField(Common::Telemetry::FieldType::UserFeedback, "Compatibility",
compatibility->checkedId());
button(NextButton)->setEnabled(false); button(NextButton)->setEnabled(false);
button(NextButton)->setText(tr("Submitting")); button(NextButton)->setText(tr("Submitting"));
button(CancelButton)->setVisible(false); button(CancelButton)->setVisible(false);
testcase_watcher.setFuture(
QtConcurrent::run([this] { return telemetry_session.SubmitTestcase(); }));
break; break;
default: default:
LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); LOG_ERROR(Frontend, "Unexpected page: {}", currentId());
+1 -7
View File
@@ -8,10 +8,6 @@
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QWizard> #include <QWizard>
namespace Core {
class TelemetrySession;
}
namespace Ui { namespace Ui {
class CompatDB; class CompatDB;
} }
@@ -20,7 +16,7 @@ class CompatDB : public QWizard {
Q_OBJECT Q_OBJECT
public: public:
explicit CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent = nullptr); explicit CompatDB(QWidget* parent = nullptr);
~CompatDB(); ~CompatDB();
private: private:
@@ -31,6 +27,4 @@ private:
void Submit(); void Submit();
void OnTestcaseSubmitted(); void OnTestcaseSubmitted();
void EnableNext(); void EnableNext();
Core::TelemetrySession& telemetry_session;
}; };
+26 -4
View File
@@ -54,7 +54,7 @@ const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config:
// This must be in alphabetical order according to action name as it must have the same order as // 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. // UISetting::values.shortcuts, which is alphabetically ordered.
// clang-format off // clang-format off
const std::array<UISettings::Shortcut, 30> Config::default_hotkeys {{ const std::array<UISettings::Shortcut, 35> Config::default_hotkeys {{
{QStringLiteral("Advance Frame"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}}, {QStringLiteral("Advance Frame"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), Qt::WindowShortcut}}, {QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), Qt::WindowShortcut}},
{QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}}, {QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}},
@@ -71,6 +71,11 @@ const std::array<UISettings::Shortcut, 30> Config::default_hotkeys {{
{QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::WidgetWithChildrenShortcut}}, {QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::WidgetWithChildrenShortcut}}, {QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Load from Newest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+V"), Qt::WindowShortcut}}, {QStringLiteral("Load from Newest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+V"), Qt::WindowShortcut}},
{QStringLiteral("Multiplayer Browse Public Game 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("Remove Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F3"), Qt::ApplicationShortcut}}, {QStringLiteral("Remove Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F3"), Qt::ApplicationShortcut}},
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}}, {QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
{QStringLiteral("Rotate Screens Upright"), QStringLiteral("Main Window"), {QStringLiteral("F8"), Qt::WindowShortcut}}, {QStringLiteral("Rotate Screens Upright"), QStringLiteral("Main Window"), {QStringLiteral("F8"), Qt::WindowShortcut}},
@@ -531,6 +536,7 @@ void Config::ReadMiscellaneousValues() {
qt_config->beginGroup(QStringLiteral("Miscellaneous")); qt_config->beginGroup(QStringLiteral("Miscellaneous"));
ReadBasicSetting(Settings::values.log_filter); ReadBasicSetting(Settings::values.log_filter);
ReadBasicSetting(Settings::values.log_regex_filter);
ReadBasicSetting(Settings::values.enable_gamemode); ReadBasicSetting(Settings::values.enable_gamemode);
qt_config->endGroup(); qt_config->endGroup();
@@ -557,6 +563,15 @@ void Config::ReadMultiplayerValues() {
UISettings::values.game_id = ReadSetting(QStringLiteral("game_id"), 0).toULongLong(); UISettings::values.game_id = ReadSetting(QStringLiteral("game_id"), 0).toULongLong();
UISettings::values.room_description = UISettings::values.room_description =
ReadSetting(QStringLiteral("room_description"), QString{}).toString(); ReadSetting(QStringLiteral("room_description"), QString{}).toString();
UISettings::values.multiplayer_filter_text =
ReadSetting(QStringLiteral("multiplayer_filter_text"), QString{}).toString();
UISettings::values.multiplayer_filter_games_owned =
ReadSetting(QStringLiteral("multiplayer_filter_games_owned"), false).toBool();
UISettings::values.multiplayer_filter_hide_empty =
ReadSetting(QStringLiteral("multiplayer_filter_hide_empty"), false).toBool();
UISettings::values.multiplayer_filter_hide_full =
ReadSetting(QStringLiteral("multiplayer_filter_hide_full"), false).toBool();
// Read ban list back // Read ban list back
int size = qt_config->beginReadArray(QStringLiteral("username_ban_list")); int size = qt_config->beginReadArray(QStringLiteral("username_ban_list"));
UISettings::values.ban_list.first.resize(size); UISettings::values.ban_list.first.resize(size);
@@ -822,8 +837,6 @@ void Config::ReadUpdaterValues() {
void Config::ReadWebServiceValues() { void Config::ReadWebServiceValues() {
qt_config->beginGroup(QStringLiteral("WebService")); qt_config->beginGroup(QStringLiteral("WebService"));
NetSettings::values.enable_telemetry =
ReadSetting(QStringLiteral("enable_telemetry"), false).toBool();
NetSettings::values.web_api_url = NetSettings::values.web_api_url =
ReadSetting(QStringLiteral("web_api_url"), QStringLiteral("https://api.citra-emu.org")) ReadSetting(QStringLiteral("web_api_url"), QStringLiteral("https://api.citra-emu.org"))
.toString() .toString()
@@ -1054,6 +1067,7 @@ void Config::SaveMiscellaneousValues() {
qt_config->beginGroup(QStringLiteral("Miscellaneous")); qt_config->beginGroup(QStringLiteral("Miscellaneous"));
WriteBasicSetting(Settings::values.log_filter); WriteBasicSetting(Settings::values.log_filter);
WriteBasicSetting(Settings::values.log_regex_filter);
WriteBasicSetting(Settings::values.enable_gamemode); WriteBasicSetting(Settings::values.enable_gamemode);
qt_config->endGroup(); qt_config->endGroup();
@@ -1074,6 +1088,15 @@ void Config::SaveMultiplayerValues() {
WriteSetting(QStringLiteral("game_id"), UISettings::values.game_id, 0); WriteSetting(QStringLiteral("game_id"), UISettings::values.game_id, 0);
WriteSetting(QStringLiteral("room_description"), UISettings::values.room_description, WriteSetting(QStringLiteral("room_description"), UISettings::values.room_description,
QString{}); QString{});
WriteSetting(QStringLiteral("multiplayer_filter_text"),
UISettings::values.multiplayer_filter_text, QString{});
WriteSetting(QStringLiteral("multiplayer_filter_games_owned"),
UISettings::values.multiplayer_filter_games_owned, false);
WriteSetting(QStringLiteral("multiplayer_filter_hide_empty"),
UISettings::values.multiplayer_filter_hide_empty, false);
WriteSetting(QStringLiteral("multiplayer_filter_hide_full"),
UISettings::values.multiplayer_filter_hide_full, false);
// Write ban list // Write ban list
qt_config->beginWriteArray(QStringLiteral("username_ban_list")); qt_config->beginWriteArray(QStringLiteral("username_ban_list"));
for (std::size_t i = 0; i < UISettings::values.ban_list.first.size(); ++i) { for (std::size_t i = 0; i < UISettings::values.ban_list.first.size(); ++i) {
@@ -1294,7 +1317,6 @@ void Config::SaveUpdaterValues() {
void Config::SaveWebServiceValues() { void Config::SaveWebServiceValues() {
qt_config->beginGroup(QStringLiteral("WebService")); qt_config->beginGroup(QStringLiteral("WebService"));
WriteSetting(QStringLiteral("enable_telemetry"), NetSettings::values.enable_telemetry, false);
WriteSetting(QStringLiteral("web_api_url"), WriteSetting(QStringLiteral("web_api_url"),
QString::fromStdString(NetSettings::values.web_api_url), QString::fromStdString(NetSettings::values.web_api_url),
QStringLiteral("https://api.citra-emu.org")); QStringLiteral("https://api.citra-emu.org"));
+1 -1
View File
@@ -26,7 +26,7 @@ public:
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons; static const std::array<int, Settings::NativeButton::NumButtons> default_buttons;
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs; static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs;
static const std::array<UISettings::Shortcut, 30> default_hotkeys; static const std::array<UISettings::Shortcut, 35> default_hotkeys;
private: private:
void Initialize(const std::string& config_name); void Initialize(const std::string& config_name);
-6
View File
@@ -97,12 +97,6 @@
<header>configuration/configure_enhancements.h</header> <header>configuration/configure_enhancements.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>ConfigureWeb</class>
<extends>QWidget</extends>
<header>configuration/configure_web.h</header>
<container>1</container>
</customwidget>
<customwidget> <customwidget>
<class>ConfigureUi</class> <class>ConfigureUi</class>
<extends>QWidget</extends> <extends>QWidget</extends>
@@ -97,6 +97,8 @@ void ConfigureDebug::SetConfiguration() {
ui->toggle_console->setEnabled(!is_powered_on); ui->toggle_console->setEnabled(!is_powered_on);
ui->toggle_console->setChecked(UISettings::values.show_console.GetValue()); ui->toggle_console->setChecked(UISettings::values.show_console.GetValue());
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue())); ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
ui->log_regex_filter_edit->setText(
QString::fromStdString(Settings::values.log_regex_filter.GetValue()));
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue()); ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());
ui->delay_start_for_lle_modules->setChecked( ui->delay_start_for_lle_modules->setChecked(
Settings::values.delay_start_for_lle_modules.GetValue()); Settings::values.delay_start_for_lle_modules.GetValue());
@@ -126,10 +128,12 @@ void ConfigureDebug::ApplyConfiguration() {
Settings::values.gdbstub_port = ui->gdbport_spinbox->value(); Settings::values.gdbstub_port = ui->gdbport_spinbox->value();
UISettings::values.show_console = ui->toggle_console->isChecked(); UISettings::values.show_console = ui->toggle_console->isChecked();
Settings::values.log_filter = ui->log_filter_edit->text().toStdString(); Settings::values.log_filter = ui->log_filter_edit->text().toStdString();
Settings::values.log_regex_filter = ui->log_regex_filter_edit->text().toStdString();
Debugger::ToggleConsole(); Debugger::ToggleConsole();
Common::Log::Filter filter; Common::Log::Filter filter;
filter.ParseFilterString(Settings::values.log_filter.GetValue()); filter.ParseFilterString(Settings::values.log_filter.GetValue());
Common::Log::SetGlobalFilter(filter); Common::Log::SetGlobalFilter(filter);
Common::Log::SetRegexFilter(Settings::values.log_regex_filter.GetValue());
Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked(); Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked();
Settings::values.delay_start_for_lle_modules = ui->delay_start_for_lle_modules->isChecked(); Settings::values.delay_start_for_lle_modules = ui->delay_start_for_lle_modules->isChecked();
Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked(); Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked();
@@ -85,6 +85,20 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Regex Log Filter</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="log_regex_filter_edit"/>
</item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
@@ -16,7 +16,6 @@
#include "citra_qt/configuration/configure_storage.h" #include "citra_qt/configuration/configure_storage.h"
#include "citra_qt/configuration/configure_system.h" #include "citra_qt/configuration/configure_system.h"
#include "citra_qt/configuration/configure_ui.h" #include "citra_qt/configuration/configure_ui.h"
#include "citra_qt/configuration/configure_web.h"
#include "citra_qt/hotkeys.h" #include "citra_qt/hotkeys.h"
#include "common/settings.h" #include "common/settings.h"
#include "core/core.h" #include "core/core.h"
@@ -38,7 +37,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Cor
camera_tab{std::make_unique<ConfigureCamera>(this)}, camera_tab{std::make_unique<ConfigureCamera>(this)},
debug_tab{std::make_unique<ConfigureDebug>(is_powered_on, this)}, debug_tab{std::make_unique<ConfigureDebug>(is_powered_on, this)},
storage_tab{std::make_unique<ConfigureStorage>(is_powered_on, this)}, storage_tab{std::make_unique<ConfigureStorage>(is_powered_on, this)},
web_tab{std::make_unique<ConfigureWeb>(this)}, ui_tab{std::make_unique<ConfigureUi>(this)} { ui_tab{std::make_unique<ConfigureUi>(this)} {
Settings::SetConfiguringGlobal(true); Settings::SetConfiguringGlobal(true);
ui->setupUi(this); ui->setupUi(this);
@@ -53,11 +52,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Cor
ui->tabWidget->addTab(camera_tab.get(), tr("Camera")); ui->tabWidget->addTab(camera_tab.get(), tr("Camera"));
ui->tabWidget->addTab(debug_tab.get(), tr("Debug")); ui->tabWidget->addTab(debug_tab.get(), tr("Debug"));
ui->tabWidget->addTab(storage_tab.get(), tr("Storage")); ui->tabWidget->addTab(storage_tab.get(), tr("Storage"));
ui->tabWidget->addTab(web_tab.get(), tr("Web"));
ui->tabWidget->addTab(ui_tab.get(), tr("UI")); ui->tabWidget->addTab(ui_tab.get(), tr("UI"));
hotkeys_tab->Populate(registry); hotkeys_tab->Populate(registry);
web_tab->SetWebServiceConfigEnabled(enable_web_config);
PopulateSelectionList(); PopulateSelectionList();
@@ -90,7 +87,6 @@ void ConfigureDialog::SetConfiguration() {
audio_tab->SetConfiguration(); audio_tab->SetConfiguration();
camera_tab->SetConfiguration(); camera_tab->SetConfiguration();
debug_tab->SetConfiguration(); debug_tab->SetConfiguration();
web_tab->SetConfiguration();
ui_tab->SetConfiguration(); ui_tab->SetConfiguration();
storage_tab->SetConfiguration(); storage_tab->SetConfiguration();
} }
@@ -106,7 +102,6 @@ void ConfigureDialog::ApplyConfiguration() {
audio_tab->ApplyConfiguration(); audio_tab->ApplyConfiguration();
camera_tab->ApplyConfiguration(); camera_tab->ApplyConfiguration();
debug_tab->ApplyConfiguration(); debug_tab->ApplyConfiguration();
web_tab->ApplyConfiguration();
ui_tab->ApplyConfiguration(); ui_tab->ApplyConfiguration();
storage_tab->ApplyConfiguration(); storage_tab->ApplyConfiguration();
system.ApplySettings(); system.ApplySettings();
@@ -119,7 +114,7 @@ void ConfigureDialog::PopulateSelectionList() {
ui->selectorList->clear(); ui->selectorList->clear();
const std::array<std::pair<QString, QList<QWidget*>>, 5> items{ const std::array<std::pair<QString, QList<QWidget*>>, 5> items{
{{tr("General"), {general_tab.get(), web_tab.get(), debug_tab.get(), ui_tab.get()}}, {{tr("General"), {general_tab.get(), debug_tab.get(), ui_tab.get()}},
{tr("System"), {system_tab.get(), camera_tab.get(), storage_tab.get()}}, {tr("System"), {system_tab.get(), camera_tab.get(), storage_tab.get()}},
{tr("Graphics"), {enhancements_tab.get(), graphics_tab.get()}}, {tr("Graphics"), {enhancements_tab.get(), graphics_tab.get()}},
{tr("Audio"), {audio_tab.get()}}, {tr("Audio"), {audio_tab.get()}},
@@ -159,7 +154,6 @@ void ConfigureDialog::RetranslateUI() {
audio_tab->RetranslateUI(); audio_tab->RetranslateUI();
camera_tab->RetranslateUI(); camera_tab->RetranslateUI();
debug_tab->RetranslateUI(); debug_tab->RetranslateUI();
web_tab->RetranslateUI();
ui_tab->RetranslateUI(); ui_tab->RetranslateUI();
storage_tab->RetranslateUI(); storage_tab->RetranslateUI();
} }
@@ -179,7 +173,6 @@ void ConfigureDialog::UpdateVisibleTabs() {
{camera_tab.get(), tr("Camera")}, {camera_tab.get(), tr("Camera")},
{debug_tab.get(), tr("Debug")}, {debug_tab.get(), tr("Debug")},
{storage_tab.get(), tr("Storage")}, {storage_tab.get(), tr("Storage")},
{web_tab.get(), tr("Web")},
{ui_tab.get(), tr("UI")}}; {ui_tab.get(), tr("UI")}};
ui->tabWidget->clear(); ui->tabWidget->clear();
@@ -29,7 +29,6 @@ class ConfigureAudio;
class ConfigureCamera; class ConfigureCamera;
class ConfigureDebug; class ConfigureDebug;
class ConfigureStorage; class ConfigureStorage;
class ConfigureWeb;
class ConfigureUi; class ConfigureUi;
class ConfigureDialog : public QDialog { class ConfigureDialog : public QDialog {
@@ -70,6 +69,5 @@ private:
std::unique_ptr<ConfigureCamera> camera_tab; std::unique_ptr<ConfigureCamera> camera_tab;
std::unique_ptr<ConfigureDebug> debug_tab; std::unique_ptr<ConfigureDebug> debug_tab;
std::unique_ptr<ConfigureStorage> storage_tab; std::unique_ptr<ConfigureStorage> storage_tab;
std::unique_ptr<ConfigureWeb> web_tab;
std::unique_ptr<ConfigureUi> ui_tab; std::unique_ptr<ConfigureUi> ui_tab;
}; };
@@ -1,165 +0,0 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <QIcon>
#include <QMessageBox>
#include <QtConcurrent/QtConcurrentRun>
#include "citra_qt/configuration/configure_web.h"
#include "citra_qt/uisettings.h"
#include "core/telemetry_session.h"
#include "network/network_settings.h"
#include "ui_configure_web.h"
static constexpr char token_delimiter{':'};
static std::string GenerateDisplayToken(const std::string& username, const std::string& token) {
if (username.empty() || token.empty()) {
return {};
}
const std::string unencoded_display_token{username + token_delimiter + token};
QByteArray b{unencoded_display_token.c_str()};
QByteArray b64 = b.toBase64();
return b64.toStdString();
}
static std::string UsernameFromDisplayToken(const std::string& display_token) {
const std::string unencoded_display_token{
QByteArray::fromBase64(display_token.c_str()).toStdString()};
return unencoded_display_token.substr(0, unencoded_display_token.find(token_delimiter));
}
static std::string TokenFromDisplayToken(const std::string& display_token) {
const std::string unencoded_display_token{
QByteArray::fromBase64(display_token.c_str()).toStdString()};
return unencoded_display_token.substr(unencoded_display_token.find(token_delimiter) + 1);
}
ConfigureWeb::ConfigureWeb(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureWeb>()) {
ui->setupUi(this);
connect(ui->button_regenerate_telemetry_id, &QPushButton::clicked, this,
&ConfigureWeb::RefreshTelemetryID);
connect(ui->button_verify_login, &QPushButton::clicked, this, &ConfigureWeb::VerifyLogin);
connect(&verify_watcher, &QFutureWatcher<bool>::finished, this, &ConfigureWeb::OnLoginVerified);
#ifndef USE_DISCORD_PRESENCE
ui->discord_group->setVisible(false);
#endif
SetConfiguration();
}
ConfigureWeb::~ConfigureWeb() = default;
void ConfigureWeb::SetConfiguration() {
ui->web_credentials_disclaimer->setWordWrap(true);
ui->telemetry_learn_more->setOpenExternalLinks(true);
ui->telemetry_learn_more->setText(tr("<a "
"href='https://citra-emu.org/entry/"
"telemetry-and-why-thats-a-good-thing/'><span "
"style=\"text-decoration: underline; "
"color:#039be5;\">Learn more</span></a>"));
ui->web_signup_link->setOpenExternalLinks(true);
ui->web_signup_link->setText(
tr("<a href='https://profile.citra-emu.org/'><span style=\"text-decoration: underline; "
"color:#039be5;\">Sign up</span></a>"));
ui->web_token_info_link->setOpenExternalLinks(true);
ui->web_token_info_link->setText(
tr("<a href='https://citra-emu.org/wiki/citra-web-service/'><span style=\"text-decoration: "
"underline; color:#039be5;\">What is my token?</span></a>"));
ui->toggle_telemetry->setChecked(NetSettings::values.enable_telemetry);
if (NetSettings::values.citra_username.empty()) {
ui->username->setText(tr("Unspecified"));
} else {
ui->username->setText(QString::fromStdString(NetSettings::values.citra_username));
}
ui->edit_token->setText(QString::fromStdString(
GenerateDisplayToken(NetSettings::values.citra_username, NetSettings::values.citra_token)));
// Connect after setting the values, to avoid calling OnLoginChanged now
connect(ui->edit_token, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged);
ui->label_telemetry_id->setText(
tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
user_verified = true;
ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence.GetValue());
}
void ConfigureWeb::ApplyConfiguration() {
NetSettings::values.enable_telemetry = ui->toggle_telemetry->isChecked();
UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked();
if (user_verified) {
NetSettings::values.citra_username =
UsernameFromDisplayToken(ui->edit_token->text().toStdString());
NetSettings::values.citra_token =
TokenFromDisplayToken(ui->edit_token->text().toStdString());
} else {
QMessageBox::warning(
this, tr("Token not verified"),
tr("Token was not verified. The change to your token has not been saved."));
}
}
void ConfigureWeb::RefreshTelemetryID() {
const u64 new_telemetry_id{Core::RegenerateTelemetryId()};
ui->label_telemetry_id->setText(
tr("Telemetry ID: 0x%1").arg(QString::number(new_telemetry_id, 16).toUpper()));
}
void ConfigureWeb::OnLoginChanged() {
if (ui->edit_token->text().isEmpty()) {
user_verified = true;
const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("checked")).pixmap(16);
ui->label_token_verified->setPixmap(pixmap);
} else {
user_verified = false;
const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("failed")).pixmap(16);
ui->label_token_verified->setPixmap(pixmap);
}
}
void ConfigureWeb::VerifyLogin() {
ui->button_verify_login->setDisabled(true);
ui->button_verify_login->setText(tr("Verifying..."));
verify_watcher.setFuture(QtConcurrent::run(
[username = UsernameFromDisplayToken(ui->edit_token->text().toStdString()),
token = TokenFromDisplayToken(ui->edit_token->text().toStdString())] {
return Core::VerifyLogin(username, token);
}));
}
void ConfigureWeb::OnLoginVerified() {
ui->button_verify_login->setEnabled(true);
ui->button_verify_login->setText(tr("Verify"));
if (verify_watcher.result()) {
user_verified = true;
const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("checked")).pixmap(16);
ui->label_token_verified->setPixmap(pixmap);
ui->username->setText(
QString::fromStdString(UsernameFromDisplayToken(ui->edit_token->text().toStdString())));
} else {
const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("failed")).pixmap(16);
ui->label_token_verified->setPixmap(pixmap);
ui->username->setText(tr("Unspecified"));
QMessageBox::critical(this, tr("Verification failed"),
tr("Verification failed. Check that you have entered your token "
"correctly, and that your internet connection is working."));
}
}
void ConfigureWeb::RetranslateUI() {
ui->retranslateUi(this);
}
void ConfigureWeb::SetWebServiceConfigEnabled(bool enabled) {
ui->label_disable_info->setVisible(!enabled);
ui->groupBoxWebConfig->setEnabled(enabled);
}
@@ -1,37 +0,0 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <QFutureWatcher>
#include <QWidget>
namespace Ui {
class ConfigureWeb;
}
class ConfigureWeb : public QWidget {
Q_OBJECT
public:
explicit ConfigureWeb(QWidget* parent = nullptr);
~ConfigureWeb() override;
void ApplyConfiguration();
void RetranslateUI();
void SetConfiguration();
void SetWebServiceConfigEnabled(bool enabled);
private:
void RefreshTelemetryID();
void OnLoginChanged();
void VerifyLogin();
void OnLoginVerified();
bool user_verified = true;
QFutureWatcher<bool> verify_watcher;
std::unique_ptr<Ui::ConfigureWeb> ui;
};
-214
View File
@@ -1,214 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConfigureWeb</class>
<widget class="QWidget" name="ConfigureWeb">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>996</width>
<height>561</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBoxWebConfig">
<property name="title">
<string>Citra Web Service</string>
</property>
<layout class="QVBoxLayout" name="verticalLayoutCitraWebService">
<item>
<widget class="QLabel" name="web_credentials_disclaimer">
<property name="text">
<string>By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information.</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayoutCitraUsername">
<item row="2" column="3">
<widget class="QPushButton" name="button_verify_login">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Verify</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="web_signup_link">
<property name="text">
<string>Sign up</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QLabel" name="username"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_token">
<property name="text">
<string>Token: </string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="label_token_verified"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_username">
<property name="text">
<string>Username: </string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="edit_token">
<property name="maxLength">
<number>80</number>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="web_token_info_link">
<property name="text">
<string>What is my token?</string>
</property>
</widget>
</item>
<item row="2" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_disable_info">
<property name="text">
<string>Web Service configuration can only be changed when a public room isn't being hosted.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Telemetry</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="toggle_telemetry">
<property name="text">
<string>Share anonymous usage data with the Citra team</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="telemetry_learn_more">
<property name="text">
<string>Learn more</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayoutTelemetryId">
<item row="0" column="0">
<widget class="QLabel" name="label_telemetry_id">
<property name="text">
<string>Telemetry ID:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="button_regenerate_telemetry_id">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Regenerate</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="discord_group">
<property name="title">
<string>Discord Presence</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
<item>
<widget class="QCheckBox" name="toggle_discordrpc">
<property name="text">
<string>Show Current Game in your Discord Status</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>edit_token</tabstop>
<tabstop>button_verify_login</tabstop>
<tabstop>toggle_telemetry</tabstop>
<tabstop>button_regenerate_telemetry_id</tabstop>
<tabstop>toggle_discordrpc</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
+8 -1
View File
@@ -25,7 +25,14 @@ void ToggleConsole() {
#ifdef _WIN32 #ifdef _WIN32
FILE* temp; FILE* temp;
if (UISettings::values.show_console) { if (UISettings::values.show_console) {
if (AllocConsole()) { BOOL alloc_console_res = AllocConsole();
DWORD last_error = 0;
if (!alloc_console_res) {
last_error = GetLastError();
}
// If the windows debugger already opened a console, calling AllocConsole again
// will cause ERROR_ACCESS_DENIED. If that's the case assume a console is open.
if (alloc_console_res || last_error == ERROR_ACCESS_DENIED) {
// The first parameter for freopen_s is a out parameter, so we can just ignore it // The first parameter for freopen_s is a out parameter, so we can just ignore it
freopen_s(&temp, "CONIN$", "r", stdin); freopen_s(&temp, "CONIN$", "r", stdin);
freopen_s(&temp, "CONOUT$", "w", stdout); freopen_s(&temp, "CONOUT$", "w", stdout);
+12 -29
View File
@@ -15,7 +15,6 @@
#include <QtGui> #include <QtGui>
#include <QtWidgets> #include <QtWidgets>
#include <fmt/format.h> #include <fmt/format.h>
#include "core/telemetry_session.h"
#ifdef __APPLE__ #ifdef __APPLE__
#include <unistd.h> // for chdir #include <unistd.h> // for chdir
#endif #endif
@@ -128,27 +127,6 @@ constexpr int default_mouse_timeout = 2500;
* is a bitfield "callout_flags" options, used to track if a message has already been shown to the * is a bitfield "callout_flags" options, used to track if a message has already been shown to the
* user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones. * user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones.
*/ */
enum class CalloutFlag : uint32_t {
Telemetry = 0x1,
};
void GMainWindow::ShowTelemetryCallout() {
if (UISettings::values.callout_flags.GetValue() &
static_cast<uint32_t>(CalloutFlag::Telemetry)) {
return;
}
UISettings::values.callout_flags =
UISettings::values.callout_flags.GetValue() | static_cast<uint32_t>(CalloutFlag::Telemetry);
const QString telemetry_message =
tr("<a href='https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/'>Anonymous "
"data is collected</a> to help improve Citra. "
"<br/><br/>Would you like to share your usage data with us?");
if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) == QMessageBox::Yes) {
NetSettings::values.enable_telemetry = true;
system.ApplySettings();
}
}
const int GMainWindow::max_recent_files_item; const int GMainWindow::max_recent_files_item;
@@ -263,9 +241,6 @@ GMainWindow::GMainWindow(Core::System& system_)
game_list->LoadCompatibilityList(); game_list->LoadCompatibilityList();
game_list->PopulateAsync(UISettings::values.game_dirs); game_list->PopulateAsync(UISettings::values.game_dirs);
// Show one-time "callout" messages to the user
ShowTelemetryCallout();
mouse_hide_timer.setInterval(default_mouse_timeout); mouse_hide_timer.setInterval(default_mouse_timeout);
connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor); connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor);
connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::OnMouseActivity); connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::OnMouseActivity);
@@ -647,6 +622,13 @@ void GMainWindow::InitializeHotkeys() {
link_action_shortcut(ui->action_Advance_Frame, QStringLiteral("Advance Frame")); link_action_shortcut(ui->action_Advance_Frame, QStringLiteral("Advance Frame"));
link_action_shortcut(ui->action_Load_from_Newest_Slot, QStringLiteral("Load from Newest Slot")); 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_Save_to_Oldest_Slot, QStringLiteral("Save to Oldest Slot"));
link_action_shortcut(ui->action_View_Lobby,
QStringLiteral("Multiplayer Browse Public Game Lobby"));
link_action_shortcut(ui->action_Start_Room, QStringLiteral("Multiplayer Create Room"));
link_action_shortcut(ui->action_Connect_To_Room,
QStringLiteral("Multiplayer Direct Connect to Room"));
link_action_shortcut(ui->action_Show_Room, QStringLiteral("Multiplayer Show Current Room"));
link_action_shortcut(ui->action_Leave_Room, QStringLiteral("Multiplayer Leave Room"));
const auto add_secondary_window_hotkey = [this](QKeySequence hotkey, const char* slot) { const auto add_secondary_window_hotkey = [this](QKeySequence hotkey, const char* slot) {
// This action will fire specifically when secondary_window is in focus // This action will fire specifically when secondary_window is in focus
@@ -1237,7 +1219,6 @@ bool GMainWindow::LoadROM(const QString& filename) {
game_path = filename; game_path = filename;
system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt");
return true; return true;
} }
@@ -1981,7 +1962,7 @@ void GMainWindow::OnLoadComplete() {
void GMainWindow::OnMenuReportCompatibility() { void GMainWindow::OnMenuReportCompatibility() {
if (!NetSettings::values.citra_token.empty() && !NetSettings::values.citra_username.empty()) { if (!NetSettings::values.citra_token.empty() && !NetSettings::values.citra_username.empty()) {
CompatDB compatdb{system.TelemetrySession(), this}; CompatDB compatdb{this};
compatdb.exec(); compatdb.exec();
} else { } else {
QMessageBox::critical(this, tr("Missing Citra Account"), QMessageBox::critical(this, tr("Missing Citra Account"),
@@ -3190,8 +3171,10 @@ int main(int argc, char* argv[]) {
QApplication::setHighDpiScaleFactorRoundingPolicy(rounding_policy); QApplication::setHighDpiScaleFactorRoundingPolicy(rounding_policy);
#ifdef __APPLE__ #ifdef __APPLE__
std::string bin_path = FileUtil::GetBundleDirectory() + DIR_SEP + ".."; auto bundle_dir = FileUtil::GetBundleDirectory();
chdir(bin_path.c_str()); if (bundle_dir) {
FileUtil::SetCurrentDir(bundle_dir.value() + "..");
}
#endif #endif
#ifdef ENABLE_OPENGL #ifdef ENABLE_OPENGL
-1
View File
@@ -152,7 +152,6 @@ private:
void BootGame(const QString& filename); void BootGame(const QString& filename);
void ShutdownGame(); void ShutdownGame();
void ShowTelemetryCallout();
void SetDiscordEnabled(bool state); void SetDiscordEnabled(bool state);
void LoadAmiibo(const QString& filename); void LoadAmiibo(const QString& filename);
+2 -3
View File
@@ -80,9 +80,8 @@ void DirectConnectWindow::Connect() {
// Store settings // Store settings
UISettings::values.nickname = ui->nickname->text(); UISettings::values.nickname = ui->nickname->text();
UISettings::values.ip = ui->ip->text(); UISettings::values.ip = ui->ip->text();
UISettings::values.port = (ui->port->isModified() && !ui->port->text().isEmpty()) UISettings::values.port =
? ui->port->text() !ui->port->text().isEmpty() ? ui->port->text() : UISettings::values.port;
: UISettings::values.port;
// attempt to connect in a different thread // attempt to connect in a different thread
QFuture<void> f = QtConcurrent::run([&] { QFuture<void> f = QtConcurrent::run([&] {
+11 -1
View File
@@ -63,10 +63,10 @@ Lobby::Lobby(Core::System& system_, QWidget* parent, QStandardItemModel* list,
// UI Buttons // UI Buttons
connect(ui->refresh_list, &QPushButton::clicked, this, &Lobby::RefreshLobby); connect(ui->refresh_list, &QPushButton::clicked, this, &Lobby::RefreshLobby);
connect(ui->search, &QLineEdit::textChanged, proxy, &LobbyFilterProxyModel::SetFilterSearch);
connect(ui->games_owned, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterOwned); connect(ui->games_owned, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterOwned);
connect(ui->hide_empty, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterEmpty); connect(ui->hide_empty, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterEmpty);
connect(ui->hide_full, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterFull); connect(ui->hide_full, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterFull);
connect(ui->search, &QLineEdit::textChanged, proxy, &LobbyFilterProxyModel::SetFilterSearch);
connect(ui->room_list, &QTreeView::doubleClicked, this, &Lobby::OnJoinRoom); connect(ui->room_list, &QTreeView::doubleClicked, this, &Lobby::OnJoinRoom);
connect(ui->room_list, &QTreeView::clicked, this, &Lobby::OnExpandRoom); connect(ui->room_list, &QTreeView::clicked, this, &Lobby::OnExpandRoom);
@@ -74,6 +74,12 @@ Lobby::Lobby(Core::System& system_, QWidget* parent, QStandardItemModel* list,
connect(&room_list_watcher, &QFutureWatcher<AnnounceMultiplayerRoom::RoomList>::finished, this, connect(&room_list_watcher, &QFutureWatcher<AnnounceMultiplayerRoom::RoomList>::finished, this,
&Lobby::OnRefreshLobby); &Lobby::OnRefreshLobby);
// Load persistent filters after events are connected to make sure they apply
ui->search->setText(UISettings::values.multiplayer_filter_text);
ui->games_owned->setChecked(UISettings::values.multiplayer_filter_games_owned);
ui->hide_empty->setChecked(UISettings::values.multiplayer_filter_hide_empty);
ui->hide_full->setChecked(UISettings::values.multiplayer_filter_hide_full);
// manually start a refresh when the window is opening // manually start a refresh when the window is opening
// TODO(jroweboy): if this refresh is slow for people with bad internet, then don't do it as // TODO(jroweboy): if this refresh is slow for people with bad internet, then don't do it as
// part of the constructor, but offload the refresh until after the window shown. perhaps emit a // part of the constructor, but offload the refresh until after the window shown. perhaps emit a
@@ -180,6 +186,10 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
UISettings::values.nickname = ui->nickname->text(); UISettings::values.nickname = ui->nickname->text();
UISettings::values.ip = proxy->data(connection_index, LobbyItemHost::HostIPRole).toString(); UISettings::values.ip = proxy->data(connection_index, LobbyItemHost::HostIPRole).toString();
UISettings::values.port = proxy->data(connection_index, LobbyItemHost::HostPortRole).toString(); UISettings::values.port = proxy->data(connection_index, LobbyItemHost::HostPortRole).toString();
UISettings::values.multiplayer_filter_text = ui->search->text();
UISettings::values.multiplayer_filter_games_owned = ui->games_owned->isChecked();
UISettings::values.multiplayer_filter_hide_empty = ui->hide_empty->isChecked();
UISettings::values.multiplayer_filter_hide_full = ui->hide_full->isChecked();
} }
void Lobby::ResetModel() { void Lobby::ResetModel() {
+29 -4
View File
@@ -188,12 +188,37 @@ public:
} }
QVariant data(int role) const override { QVariant data(int role) const override {
if (role != Qt::DisplayRole) { switch (role) {
case Qt::DisplayRole: {
auto members = data(MemberListRole).toList();
return QStringLiteral("%1 / %2").arg(QString::number(members.size()),
data(MaxPlayerRole).toString());
}
case Qt::ForegroundRole: {
auto members = data(MemberListRole).toList();
auto max_players = data(MaxPlayerRole).toInt();
const QColor room_full_color(255, 48, 32);
const QColor room_almost_full_color(255, 140, 32);
const QColor room_has_players_color(32, 160, 32);
const QColor room_empty_color(128, 128, 128);
if (members.size() >= max_players) {
return QBrush(room_full_color);
} else if (members.size() == (max_players - 1)) {
return QBrush(room_almost_full_color);
} else if (members.size() == 0) {
return QBrush(room_empty_color);
} else if (members.size() > 0 && members.size() < (max_players - 1)) {
return QBrush(room_has_players_color);
}
// FIXME: How to return a value that tells Qt not to modify the
// text color from the default (as if Qt::ForegroundRole wasn't overridden)?
return QBrush(nullptr);
}
default:
return LobbyItem::data(role); return LobbyItem::data(role);
} }
auto members = data(MemberListRole).toList();
return QStringLiteral("%1 / %2").arg(QString::number(members.size()),
data(MaxPlayerRole).toString());
} }
bool operator<(const QStandardItem& other) const override { bool operator<(const QStandardItem& other) const override {
+5
View File
@@ -138,6 +138,11 @@ struct Values {
QString room_description; QString room_description;
std::pair<std::vector<std::string>, std::vector<std::string>> ban_list; std::pair<std::vector<std::string>, std::vector<std::string>> ban_list;
QString multiplayer_filter_text;
bool multiplayer_filter_games_owned;
bool multiplayer_filter_hide_empty;
bool multiplayer_filter_hide_full;
// logging // logging
Settings::Setting<bool> show_console{false, "showConsole"}; Settings::Setting<bool> show_console{false, "showConsole"};
}; };
+2 -1
View File
@@ -22,7 +22,8 @@ QString GetOpenGLRenderer() {
QOpenGLContext context; QOpenGLContext context;
if (context.create()) { if (context.create()) {
context.makeCurrent(&surface); context.makeCurrent(&surface);
return QString::fromUtf8(context.functions()->glGetString(GL_RENDERER)); return QString::fromUtf8(
reinterpret_cast<const char*>(context.functions()->glGetString(GL_RENDERER)));
} else { } else {
return QStringLiteral(""); return QStringLiteral("");
} }
-2
View File
@@ -130,8 +130,6 @@ add_library(citra_common STATIC
string_util.cpp string_util.cpp
string_util.h string_util.h
swap.h swap.h
telemetry.cpp
telemetry.h
texture.cpp texture.cpp
texture.h texture.h
thread.cpp thread.cpp
-1
View File
@@ -13,7 +13,6 @@
#endif #endif
// The user data dir // The user data dir
#define ROOT_DIR "."
#define USERDATA_DIR "user" #define USERDATA_DIR "user"
#ifdef USER_DIR #ifdef USER_DIR
#define EMU_DATA_DIR USER_DIR #define EMU_DATA_DIR USER_DIR
+4 -4
View File
@@ -12,10 +12,10 @@ namespace Common {
/** /**
* A background manager which ensures that all detached task is finished before program exits. * A background manager which ensures that all detached task is finished before program exits.
* *
* Some tasks, telemetry submission for example, prefer executing asynchronously and don't care * Some tasks prefer executing asynchronously and don't care
* about the result. These tasks are suitable for std::thread::detach(). However, this is unsafe if * about the result. These tasks are suitable for std::thread::detach().
* the task is launched just before the program exits (which is a common case for telemetry), so we * However, this is unsafe if the task is launched just before the program exits
* need to block on these tasks on program exit. * so we need to block on these tasks on program exit.
* *
* To make detached task safe, a single DetachedTasks object should be placed in the main(), and * To make detached task safe, a single DetachedTasks object should be placed in the main(), and
* call WaitForAllTasks() after all program execution but before global/static variable destruction. * call WaitForAllTasks() after all program execution but before global/static variable destruction.
+36 -27
View File
@@ -634,6 +634,10 @@ std::optional<std::string> GetCurrentDir() {
std::string strDir = dir; std::string strDir = dir;
#endif #endif
free(dir); free(dir);
if (!strDir.ends_with(DIR_SEP)) {
strDir += DIR_SEP;
}
return strDir; return strDir;
} // namespace FileUtil } // namespace FileUtil
@@ -646,17 +650,36 @@ bool SetCurrentDir(const std::string& directory) {
} }
#if defined(__APPLE__) #if defined(__APPLE__)
std::string GetBundleDirectory() { std::optional<std::string> GetBundleDirectory() {
CFURLRef BundleRef;
char AppBundlePath[MAXPATHLEN];
// Get the main bundle for the app // Get the main bundle for the app
BundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); CFBundleRef bundle_ref = CFBundleGetMainBundle();
CFStringRef BundlePath = CFURLCopyFileSystemPath(BundleRef, kCFURLPOSIXPathStyle); if (!bundle_ref) {
CFStringGetFileSystemRepresentation(BundlePath, AppBundlePath, sizeof(AppBundlePath)); return {};
CFRelease(BundleRef); }
CFRelease(BundlePath);
return AppBundlePath; CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref);
if (!bundle_url_ref) {
return {};
}
SCOPE_EXIT({ CFRelease(bundle_url_ref); });
CFStringRef bundle_path_ref = CFURLCopyFileSystemPath(bundle_url_ref, kCFURLPOSIXPathStyle);
if (!bundle_path_ref) {
return {};
}
SCOPE_EXIT({ CFRelease(bundle_path_ref); });
char app_bundle_path[MAXPATHLEN];
if (!CFStringGetFileSystemRepresentation(bundle_path_ref, app_bundle_path,
sizeof(app_bundle_path))) {
return {};
}
std::string path_str(app_bundle_path);
if (!path_str.ends_with(DIR_SEP)) {
path_str += DIR_SEP;
}
return path_str;
} }
#endif #endif
@@ -732,22 +755,6 @@ static const std::string& GetHomeDirectory() {
} }
#endif #endif
std::string GetSysDirectory() {
std::string sysDir;
#if defined(__APPLE__)
sysDir = GetBundleDirectory();
sysDir += DIR_SEP;
sysDir += SYSDATA_DIR;
#else
sysDir = SYSDATA_DIR;
#endif
sysDir += DIR_SEP;
LOG_DEBUG(Common_Filesystem, "Setting to {}:", sysDir);
return sysDir;
}
namespace { namespace {
std::unordered_map<UserPath, std::string> g_paths; std::unordered_map<UserPath, std::string> g_paths;
std::unordered_map<UserPath, std::string> g_default_paths; std::unordered_map<UserPath, std::string> g_default_paths;
@@ -777,8 +784,10 @@ void SetUserPath(const std::string& path) {
g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP);
g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP);
#else #else
if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { auto current_dir = FileUtil::GetCurrentDir();
user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; if (current_dir.has_value() &&
FileUtil::Exists(current_dir.value() + USERDATA_DIR DIR_SEP)) {
user_path = current_dir.value() + USERDATA_DIR DIR_SEP;
g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP);
g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP);
} else { } else {
+1 -4
View File
@@ -193,11 +193,8 @@ void SetCurrentRomPath(const std::string& path);
// Update the Global Path with the new value // Update the Global Path with the new value
void UpdateUserPath(UserPath path, const std::string& filename); void UpdateUserPath(UserPath path, const std::string& filename);
// Returns the path to where the sys file are
[[nodiscard]] std::string GetSysDirectory();
#ifdef __APPLE__ #ifdef __APPLE__
[[nodiscard]] std::string GetBundleDirectory(); [[nodiscard]] std::optional<std::string> GetBundleDirectory();
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
+27 -3
View File
@@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <chrono> #include <chrono>
#include <boost/regex.hpp>
#include <fmt/format.h> #include <fmt/format.h>
@@ -234,6 +235,19 @@ public:
filter = f; filter = f;
} }
bool SetRegexFilter(const std::string& regex) {
if (regex.empty()) {
regex_filter = boost::regex();
return true;
}
regex_filter = boost::regex(regex, boost::regex_constants::no_except);
if (regex_filter.status() != 0) {
regex_filter = boost::regex();
return false;
}
return true;
}
void SetColorConsoleBackendEnabled(bool enabled) { void SetColorConsoleBackendEnabled(bool enabled) {
color_console_backend.SetEnabled(enabled); color_console_backend.SetEnabled(enabled);
} }
@@ -243,8 +257,13 @@ public:
if (!filter.CheckMessage(log_class, log_level)) { if (!filter.CheckMessage(log_class, log_level)) {
return; return;
} }
message_queue.EmplaceWait( Entry new_entry =
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message))); CreateEntry(log_class, log_level, filename, line_num, function, std::move(message));
if (!regex_filter.empty() &&
!boost::regex_search(FormatLogMessage(new_entry), regex_filter)) {
return;
}
message_queue.EmplaceWait(new_entry);
} }
private: private:
@@ -406,6 +425,7 @@ private:
static inline std::unique_ptr<Impl, decltype(&Deleter)> instance{nullptr, Deleter}; static inline std::unique_ptr<Impl, decltype(&Deleter)> instance{nullptr, Deleter};
Filter filter; Filter filter;
boost::regex regex_filter;
DebuggerBackend debugger_backend{}; DebuggerBackend debugger_backend{};
ColorConsoleBackend color_console_backend{}; ColorConsoleBackend color_console_backend{};
FileBackend file_backend; FileBackend file_backend;
@@ -446,12 +466,16 @@ void SetGlobalFilter(const Filter& filter) {
Impl::Instance().SetGlobalFilter(filter); Impl::Instance().SetGlobalFilter(filter);
} }
bool SetRegexFilter(const std::string& regex) {
return Impl::Instance().SetRegexFilter(regex);
}
void SetColorConsoleBackendEnabled(bool enabled) { void SetColorConsoleBackendEnabled(bool enabled) {
Impl::Instance().SetColorConsoleBackendEnabled(enabled); Impl::Instance().SetColorConsoleBackendEnabled(enabled);
} }
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, const char* format, unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args) { const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) { if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,
+6
View File
@@ -26,5 +26,11 @@ void DisableLoggingInTests();
*/ */
void SetGlobalFilter(const Filter& filter); void SetGlobalFilter(const Filter& filter);
/**
* Only allow messages that match the specified regex. The regex is matched against the final log
* text.
*/
bool SetRegexFilter(const std::string& regex);
void SetColorConsoleBackendEnabled(bool enabled); void SetColorConsoleBackendEnabled(bool enabled);
} // namespace Common::Log } // namespace Common::Log
+2 -2
View File
@@ -24,12 +24,12 @@ constexpr const char* TrimSourcePath(std::string_view source) {
/// Logs a message to the global logger, using fmt /// Logs a message to the global logger, using fmt
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, const char* format, unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args); const fmt::format_args& args);
template <typename... Args> template <typename... Args>
void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num, void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, const char* format, const Args&... args) { const char* function, fmt::format_string<Args...> format, const Args&... args) {
FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format, FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format,
fmt::make_format_args(args...)); fmt::make_format_args(args...));
} }
+1
View File
@@ -542,6 +542,7 @@ struct Values {
// Miscellaneous // Miscellaneous
Setting<std::string> log_filter{"*:Info", "log_filter"}; Setting<std::string> log_filter{"*:Info", "log_filter"};
Setting<std::string> log_regex_filter{"", "log_regex_filter"};
// Video Dumping // Video Dumping
std::string output_format; std::string output_format;
-92
View File
@@ -1,92 +0,0 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <cstring>
#include "common/arch.h"
#include "common/assert.h"
#include "common/scm_rev.h"
#include "common/telemetry.h"
#if CITRA_ARCH(x86_64)
#include "common/x64/cpu_detect.h"
#endif
namespace Common::Telemetry {
void FieldCollection::Accept(VisitorInterface& visitor) const {
for (const auto& field : fields) {
field.second->Accept(visitor);
}
}
void FieldCollection::AddField(std::unique_ptr<FieldInterface> field) {
fields[field->GetName()] = std::move(field);
}
template <class T>
void Field<T>::Accept(VisitorInterface& visitor) const {
visitor.Visit(*this);
}
template class Field<bool>;
template class Field<double>;
template class Field<float>;
template class Field<u8>;
template class Field<u16>;
template class Field<u32>;
template class Field<u64>;
template class Field<s8>;
template class Field<s16>;
template class Field<s32>;
template class Field<s64>;
template class Field<std::string>;
template class Field<const char*>;
template class Field<std::chrono::microseconds>;
void AppendBuildInfo(FieldCollection& fc) {
const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr};
fc.AddField(FieldType::App, "Git_IsDirty", is_git_dirty);
fc.AddField(FieldType::App, "Git_Branch", Common::g_scm_branch);
fc.AddField(FieldType::App, "Git_Revision", Common::g_scm_rev);
fc.AddField(FieldType::App, "BuildDate", Common::g_build_date);
fc.AddField(FieldType::App, "BuildName", Common::g_build_name);
}
void AppendCPUInfo(FieldCollection& fc) {
#if CITRA_ARCH(x86_64)
fc.AddField(FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string);
fc.AddField(FieldType::UserSystem, "CPU_BrandString", Common::GetCPUCaps().brand_string);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX", Common::GetCPUCaps().avx);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX2", Common::GetCPUCaps().avx2);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX512", Common::GetCPUCaps().avx512);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_BMI1", Common::GetCPUCaps().bmi1);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_BMI2", Common::GetCPUCaps().bmi2);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_FMA", Common::GetCPUCaps().fma);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_FMA4", Common::GetCPUCaps().fma4);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE", Common::GetCPUCaps().sse);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE2", Common::GetCPUCaps().sse2);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE3", Common::GetCPUCaps().sse3);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSSE3", Common::GetCPUCaps().ssse3);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE41", Common::GetCPUCaps().sse4_1);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE42", Common::GetCPUCaps().sse4_2);
#else
fc.AddField(FieldType::UserSystem, "CPU_Model", "Other");
#endif
}
void AppendOSInfo(FieldCollection& fc) {
#ifdef __APPLE__
fc.AddField(FieldType::UserSystem, "OsPlatform", "Apple");
#elif defined(_WIN32)
fc.AddField(FieldType::UserSystem, "OsPlatform", "Windows");
#elif defined(__linux__) || defined(linux) || defined(__linux)
fc.AddField(FieldType::UserSystem, "OsPlatform", "Linux");
#else
fc.AddField(FieldType::UserSystem, "OsPlatform", "Unknown");
#endif
}
} // namespace Common::Telemetry
-199
View File
@@ -1,199 +0,0 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <chrono>
#include <map>
#include <memory>
#include <string>
#include "common/common_types.h"
namespace Common::Telemetry {
/// Field type, used for grouping fields together in the final submitted telemetry log
enum class FieldType : u8 {
None = 0, ///< No specified field group
App, ///< Citra application fields (e.g. version, branch, etc.)
Session, ///< Emulated session fields (e.g. title ID, log, etc.)
Performance, ///< Emulated performance (e.g. fps, emulated CPU speed, etc.)
UserFeedback, ///< User submitted feedback (e.g. star rating, user notes, etc.)
UserConfig, ///< User configuration fields (e.g. emulated CPU core, renderer, etc.)
UserSystem, ///< User system information (e.g. host CPU type, RAM, etc.)
};
struct VisitorInterface;
/**
* Interface class for telemetry data fields.
*/
class FieldInterface : NonCopyable {
public:
virtual ~FieldInterface() = default;
/**
* Accept method for the visitor pattern.
* @param visitor Reference to the visitor that will visit this field.
*/
virtual void Accept(VisitorInterface& visitor) const = 0;
/**
* Gets the name of this field.
* @returns Name of this field as a string.
*/
virtual const std::string& GetName() const = 0;
};
/**
* Represents a telemetry data field, i.e. a unit of data that gets logged and submitted to our
* telemetry web service.
*/
template <typename T>
class Field : public FieldInterface {
public:
Field(FieldType type, std::string name, T value)
: name(std::move(name)), type(type), value(std::move(value)) {}
Field(const Field&) = default;
Field& operator=(const Field&) = default;
Field(Field&&) = default;
Field& operator=(Field&& other) = default;
void Accept(VisitorInterface& visitor) const override;
[[nodiscard]] const std::string& GetName() const override {
return name;
}
/**
* Returns the type of the field.
*/
[[nodiscard]] FieldType GetType() const {
return type;
}
/**
* Returns the value of the field.
*/
[[nodiscard]] const T& GetValue() const {
return value;
}
[[nodiscard]] bool operator==(const Field& other) const {
return (type == other.type) && (name == other.name) && (value == other.value);
}
[[nodiscard]] bool operator!=(const Field& other) const {
return !operator==(other);
}
private:
std::string name; ///< Field name, must be unique
FieldType type{}; ///< Field type, used for grouping fields together
T value; ///< Field value
};
/**
* Collection of data fields that have been logged.
*/
class FieldCollection final : NonCopyable {
public:
FieldCollection() = default;
/**
* Accept method for the visitor pattern, visits each field in the collection.
* @param visitor Reference to the visitor that will visit each field.
*/
void Accept(VisitorInterface& visitor) const;
/**
* Creates a new field and adds it to the field collection.
* @param type Type of the field to add.
* @param name Name of the field to add.
* @param value Value for the field to add.
*/
template <typename T>
void AddField(FieldType type, const char* name, T value) {
return AddField(std::make_unique<Field<T>>(type, name, std::move(value)));
}
/**
* Adds a new field to the field collection.
* @param field Field to add to the field collection.
*/
void AddField(std::unique_ptr<FieldInterface> field);
private:
std::map<std::string, std::unique_ptr<FieldInterface>> fields;
};
/**
* Telemetry fields visitor interface class. A backend to log to a web service should implement
* this interface.
*/
struct VisitorInterface : NonCopyable {
virtual ~VisitorInterface() = default;
virtual void Visit(const Field<bool>& field) = 0;
virtual void Visit(const Field<double>& field) = 0;
virtual void Visit(const Field<float>& field) = 0;
virtual void Visit(const Field<u8>& field) = 0;
virtual void Visit(const Field<u16>& field) = 0;
virtual void Visit(const Field<u32>& field) = 0;
virtual void Visit(const Field<u64>& field) = 0;
virtual void Visit(const Field<s8>& field) = 0;
virtual void Visit(const Field<s16>& field) = 0;
virtual void Visit(const Field<s32>& field) = 0;
virtual void Visit(const Field<s64>& field) = 0;
virtual void Visit(const Field<std::string>& field) = 0;
virtual void Visit(const Field<const char*>& field) = 0;
virtual void Visit(const Field<std::chrono::microseconds>& field) = 0;
/// Completion method, called once all fields have been visited
virtual void Complete() = 0;
virtual bool SubmitTestcase() = 0;
};
/**
* Empty implementation of VisitorInterface that drops all fields. Used when a functional
* backend implementation is not available.
*/
struct NullVisitor : public VisitorInterface {
~NullVisitor() = default;
void Visit(const Field<bool>& /*field*/) override {}
void Visit(const Field<double>& /*field*/) override {}
void Visit(const Field<float>& /*field*/) override {}
void Visit(const Field<u8>& /*field*/) override {}
void Visit(const Field<u16>& /*field*/) override {}
void Visit(const Field<u32>& /*field*/) override {}
void Visit(const Field<u64>& /*field*/) override {}
void Visit(const Field<s8>& /*field*/) override {}
void Visit(const Field<s16>& /*field*/) override {}
void Visit(const Field<s32>& /*field*/) override {}
void Visit(const Field<s64>& /*field*/) override {}
void Visit(const Field<std::string>& /*field*/) override {}
void Visit(const Field<const char*>& /*field*/) override {}
void Visit(const Field<std::chrono::microseconds>& /*field*/) override {}
void Complete() override {}
bool SubmitTestcase() override {
return false;
}
};
/// Appends build-specific information to the given FieldCollection,
/// such as branch name, revision hash, etc.
void AppendBuildInfo(FieldCollection& fc);
/// Appends CPU-specific information to the given FieldCollection,
/// such as instruction set extensions, etc.
void AppendCPUInfo(FieldCollection& fc);
/// Appends OS-specific information to the given FieldCollection,
/// such as platform name, etc.
void AppendOSInfo(FieldCollection& fc);
} // namespace Common::Telemetry
+4 -2
View File
@@ -327,6 +327,10 @@ add_library(citra_core STATIC
hle/service/ldr_ro/cro_helper.h hle/service/ldr_ro/cro_helper.h
hle/service/ldr_ro/ldr_ro.cpp hle/service/ldr_ro/ldr_ro.cpp
hle/service/ldr_ro/ldr_ro.h hle/service/ldr_ro/ldr_ro.h
hle/service/mcu/mcu_hwc.cpp
hle/service/mcu/mcu_hwc.h
hle/service/mcu/mcu.cpp
hle/service/mcu/mcu.h
hle/service/mic/mic_u.cpp hle/service/mic/mic_u.cpp
hle/service/mic/mic_u.h hle/service/mic/mic_u.h
hle/service/mvd/mvd.cpp hle/service/mvd/mvd.cpp
@@ -463,8 +467,6 @@ add_library(citra_core STATIC
savestate_data.h savestate_data.h
system_titles.cpp system_titles.cpp
system_titles.h system_titles.h
telemetry_session.cpp
telemetry_session.h
tracer/citrace.h tracer/citrace.h
tracer/recorder.cpp tracer/recorder.cpp
tracer/recorder.h tracer/recorder.h
+12 -15
View File
@@ -47,7 +47,6 @@
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
#include "core/rpc/server.h" #include "core/rpc/server.h"
#endif #endif
#include "core/telemetry_session.h"
#include "network/network.h" #include "network/network.h"
#include "video_core/custom_textures/custom_tex_manager.h" #include "video_core/custom_textures/custom_tex_manager.h"
#include "video_core/gpu.h" #include "video_core/gpu.h"
@@ -263,6 +262,18 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
return ResultStatus::ErrorGetLoader; return ResultStatus::ErrorGetLoader;
} }
if (restore_plugin_context.has_value() && restore_plugin_context->is_enabled &&
restore_plugin_context->use_user_load_parameters) {
u64_le program_id = 0;
app_loader->ReadProgramId(program_id);
if (restore_plugin_context->user_load_parameters.low_title_Id ==
static_cast<u32_le>(program_id) &&
restore_plugin_context->user_load_parameters.plugin_memory_strategy ==
Service::PLGLDR::PLG_LDR::PluginMemoryStrategy::PLG_STRATEGY_MODE3) {
app_loader->SetKernelMemoryModeOverride(Kernel::MemoryMode::Dev2);
}
}
auto memory_mode = app_loader->LoadKernelMemoryMode(); auto memory_mode = app_loader->LoadKernelMemoryMode();
if (memory_mode.second != Loader::ResultStatus::Success) { if (memory_mode.second != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!", LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!",
@@ -310,7 +321,6 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
restore_plugin_context.reset(); restore_plugin_context.reset();
} }
telemetry_session->AddInitialInfo(*app_loader);
std::shared_ptr<Kernel::Process> process; std::shared_ptr<Kernel::Process> process;
const Loader::ResultStatus load_result{app_loader->Load(process)}; const Loader::ResultStatus load_result{app_loader->Load(process)};
if (Loader::ResultStatus::Success != load_result) { if (Loader::ResultStatus::Success != load_result) {
@@ -440,8 +450,6 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
Settings::values.output_device.GetValue()); Settings::values.output_device.GetValue());
dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue()); dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue());
telemetry_session = std::make_unique<Core::TelemetrySession>();
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
rpc_server = std::make_unique<RPC::Server>(*this); rpc_server = std::make_unique<RPC::Server>(*this);
#endif #endif
@@ -566,16 +574,6 @@ void System::RegisterImageInterface(std::shared_ptr<Frontend::ImageInterface> im
} }
void System::Shutdown(bool is_deserializing) { void System::Shutdown(bool is_deserializing) {
// Log last frame performance stats
const auto perf_results = GetAndResetPerfStats();
constexpr auto performance = Common::Telemetry::FieldType::Performance;
telemetry_session->AddField(performance, "Shutdown_EmulationSpeed",
perf_results.emulation_speed * 100.0);
telemetry_session->AddField(performance, "Shutdown_Framerate", perf_results.game_fps);
telemetry_session->AddField(performance, "Shutdown_Frametime", perf_results.frametime * 1000.0);
telemetry_session->AddField(performance, "Mean_Frametime_MS",
perf_stats ? perf_stats->GetMeanFrametime() : 0);
// Shutdown emulation session // Shutdown emulation session
is_powered_on = false; is_powered_on = false;
@@ -587,7 +585,6 @@ void System::Shutdown(bool is_deserializing) {
app_loader.reset(); app_loader.reset();
} }
custom_tex_manager.reset(); custom_tex_manager.reset();
telemetry_session.reset();
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
rpc_server.reset(); rpc_server.reset();
#endif #endif
-12
View File
@@ -72,7 +72,6 @@ class AppLoader;
namespace Core { namespace Core {
class ARM_Interface; class ARM_Interface;
class TelemetrySession;
class ExclusiveMonitor; class ExclusiveMonitor;
class Timing; class Timing;
@@ -165,14 +164,6 @@ public:
return is_powered_on; return is_powered_on;
} }
/**
* Returns a reference to the telemetry session for this emulation session.
* @returns Reference to the telemetry session.
*/
[[nodiscard]] Core::TelemetrySession& TelemetrySession() const {
return *telemetry_session;
}
/// Prepare the core emulation for a reschedule /// Prepare the core emulation for a reschedule
void PrepareReschedule(); void PrepareReschedule();
@@ -385,9 +376,6 @@ private:
/// When true, signals that a reschedule should happen /// When true, signals that a reschedule should happen
bool reschedule_pending{}; bool reschedule_pending{};
/// Telemetry session for this emulation session
std::unique_ptr<Core::TelemetrySession> telemetry_session;
std::unique_ptr<VideoCore::GPU> gpu; std::unique_ptr<VideoCore::GPU> gpu;
/// Service manager /// Service manager
+3 -3
View File
@@ -128,14 +128,14 @@ public:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point);
return ResultFileNotFound; return ResultFileNotFound;
case PathParser::PathNotFound: case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found {}", full_path); LOG_DEBUG(Service_FS, "Path not found {}", full_path);
return ResultPathNotFound; return ResultPathNotFound;
case PathParser::FileInPath: case PathParser::FileInPath:
case PathParser::DirectoryFound: case PathParser::DirectoryFound:
LOG_ERROR(Service_FS, "Unexpected file or directory in {}", full_path); LOG_DEBUG(Service_FS, "Unexpected file or directory in {}", full_path);
return ResultUnexpectedFileOrDirectory; return ResultUnexpectedFileOrDirectory;
case PathParser::NotFound: case PathParser::NotFound:
LOG_ERROR(Service_FS, "{} not found", full_path); LOG_DEBUG(Service_FS, "{} not found", full_path);
return ResultFileNotFound; return ResultFileNotFound;
case PathParser::FileFound: case PathParser::FileFound:
break; // Expected 'success' case break; // Expected 'success' case

Some files were not shown because too many files have changed in this diff Show More