Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 060026dc2d | |||
| 92f54a034a | |||
| 7a6d055094 | |||
| c6fa5c1f77 | |||
| 2c40328a23 | |||
| 41b6807f12 | |||
| 2bec66c092 | |||
| be972d7fdc | |||
| 972860ac8f | |||
| 3d3ed4b7d1 | |||
| be21ccce25 | |||
| db83070bf2 | |||
| e903d70d9e | |||
| 802531c457 | |||
| bd071e3464 | |||
| a845100bf0 |
@@ -0,0 +1,2 @@
|
|||||||
|
liberapay: crueter
|
||||||
|
custom: 'https://www.paypal.biz/edenemulator'
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
- [ ] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
|
- [ ] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
|
||||||
- [ ] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
|
- [ ] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
|
||||||
|
- [ ] I have read and followed the [website policy](https://git.eden-emu.dev/eden-emu/site-policy).
|
||||||
|
- [ ] I affirm that the content of this pull request body was written and submitted entirely by me, in my own words, and not by an AI agent or LLM.
|
||||||
|
- [ ] I affirm that I did not read any of this, and understand that my pull request will be closed if I check this box.
|
||||||
|
- [ ] I affirm that, by submitting this pull request, I am responsible for all of the changes contained within these commits.
|
||||||
|
|
||||||
-------------------
|
-------------------
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake
|
||||||
|
index 3012e05..2ae23ff 100644
|
||||||
|
--- a/cmake/ConfigureOpenSSL.cmake
|
||||||
|
+++ b/cmake/ConfigureOpenSSL.cmake
|
||||||
|
@@ -108,7 +108,8 @@ function(configure_openssl)
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT "${CONFIGURE_OPTIONS_OLD}" STREQUAL "")
|
||||||
|
- if(CONFIGURE_OPTIONS STREQUAL CONFIGURE_OPTIONS_OLD)
|
||||||
|
+ # TODO(lizzie): Emscripten has issues with rebuilding due to the wrapper it uses
|
||||||
|
+ if(CMAKE_SYSTEM_NAME MATCHES "Emscripten" OR CONFIGURE_OPTIONS STREQUAL CONFIGURE_OPTIONS_OLD)
|
||||||
|
message(STATUS "Found previous configure results. Don't perform configuration")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
@@ -134,10 +135,24 @@ function(configure_openssl)
|
||||||
|
set(VERBOSE_OPTION OUTPUT_QUIET)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
+ if (CMAKE_SYSTEM_NAME MATCHES "Emscripten")
|
||||||
|
+ set(EMSCRIPTEN_CMAKE_WRAPPER "emcmake")
|
||||||
|
+ find_program(EMCC emcc REQUIRED)
|
||||||
|
+ set(EMSCRIPTEN_LINKER ${EMCC})
|
||||||
|
+ list(APPEND CONFIGURE_COMMAND wasm64)
|
||||||
|
+ else()
|
||||||
|
+ set(EMSCRIPTEN_CMAKE_WRAPPER "")
|
||||||
|
+ set(EMSCRIPTEN_LINKER ${CMAKE_LINKER})
|
||||||
|
+ endif ()
|
||||||
|
+
|
||||||
|
execute_process(
|
||||||
|
- COMMAND ${CMAKE_COMMAND} -E env
|
||||||
|
+ COMMAND ${EMSCRIPTEN_CMAKE_WRAPPER} ${CMAKE_COMMAND} -E env
|
||||||
|
"CFLAGS=${CMAKE_C_FLAGS}"
|
||||||
|
"CXXFLAGS=${CMAKE_CXX_FLAGS}"
|
||||||
|
+ "LDFLAGS=${CMAKE_CXX_LINK_FLAGS}"
|
||||||
|
+ "CC=${CMAKE_C_COMPILER}"
|
||||||
|
+ "CXX=${CMAKE_CXX_COMPILER}"
|
||||||
|
+ "LD=${EMSCRIPTEN_LINKER}"
|
||||||
|
${CONFIGURE_COMMAND}
|
||||||
|
WORKING_DIRECTORY ${CONFIGURE_BUILD_DIR}
|
||||||
|
${VERBOSE_OPTION}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
# AGENTS
|
# AGENTS
|
||||||
|
|
||||||
Read and follow the AI policy found in `docs/policies/AI.md`, and the coding policies found in `docs/policies/Coding.md`.
|
Read and follow the [contribution guidelines](./CONTRIBUTING.md) and our [site policy](https://git.eden-emu.dev/eden-emu/site-policy/src/branch/master)..
|
||||||
|
|
||||||
Do not, under any circumstances, ever submit PRs or push commits on behalf of the user.
|
Do not, under any circumstances, ever:
|
||||||
|
|
||||||
|
- Submit PRs, push commits, or request any API calls on behalf of the user.
|
||||||
|
- Write commit messages, PR descriptions, or issues on behalf of the user.
|
||||||
|
|
||||||
Keep comments to a reasonable level. Do not overexplain or add/remove comments from unrelated parts of the codebase.
|
Keep comments to a reasonable level. Do not overexplain or add/remove comments from unrelated parts of the codebase.
|
||||||
|
|||||||
@@ -16,8 +16,11 @@ Eden is free, open-source, copyleft software, licensed under the terms of the [G
|
|||||||
|
|
||||||
### Policies
|
### Policies
|
||||||
|
|
||||||
- AI usage is allowed, but we reserve the right to close and rework your PR if you don't fully understand the changes you're making.
|
- AI usage is allowed, but we reserve the right to close and rework your PR if you don't fully understand the changes you're making. Additionally:
|
||||||
- As a common courtesy, please disclose your AI usage under the PR description, as `Assisted-by: <AI model> (<how it helped>)`.
|
- As a common courtesy, please disclose your AI usage under the PR description, as `Assisted-by: <AI model> (<how it helped>)`.
|
||||||
|
- All PR descriptions, issue bodies, and comments **must** be written by you, in your own words.
|
||||||
|
- AI-written comments/descriptions/bodies are not only difficult for us to read, they also indicate to us that you did not put in the effort to actually understand your changes. These will be closed, deleted, or hidden without warning.
|
||||||
|
- Spamming of low-effort AI-generated pull requests or issues is considered a [Human Effort Denial of Service](https://tiangolo.com/open-source/contributing/#human-effort-denial-of-service), and will result in the immediate suspension of your Forgejo account, or you getting blocked from the organization on other platforms.
|
||||||
- Usage of any form of profanity or otherwise unsavory language is discouraged but not strictly disallowed.
|
- Usage of any form of profanity or otherwise unsavory language is discouraged but not strictly disallowed.
|
||||||
- New code must follow the same style as the surrounding codebase. Exceptions may be granted in certain cases.
|
- New code must follow the same style as the surrounding codebase. Exceptions may be granted in certain cases.
|
||||||
- Maintainers reserve the right to change your patches and pull requests at will. We will try to avoid this.
|
- Maintainers reserve the right to change your patches and pull requests at will. We will try to avoid this.
|
||||||
@@ -26,6 +29,25 @@ Eden is free, open-source, copyleft software, licensed under the terms of the [G
|
|||||||
- While we do *not* adhere to the terms of a formal code of conduct, you are expected to treat other developers, contributors, and community members respectfully.
|
- While we do *not* adhere to the terms of a formal code of conduct, you are expected to treat other developers, contributors, and community members respectfully.
|
||||||
- You **must** have basic knowledge of [Git](https://git-scm.com/learn). Knowing how to manage your branches and follow proper fork policies is a necessity.
|
- You **must** have basic knowledge of [Git](https://git-scm.com/learn). Knowing how to manage your branches and follow proper fork policies is a necessity.
|
||||||
|
|
||||||
|
### Pull Requests
|
||||||
|
|
||||||
|
Pull requests are only to be merged by core developers when properly tested and discussions conclude on Discord or other communication channels. Labels are recommended but not required. However, all PRs MUST be namespaced and optionally typed:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
[cmake] refactor: CPM over submodules
|
||||||
|
[desktop] feat: implement firmware install from ZIP
|
||||||
|
[hle] stub fw20 functions
|
||||||
|
[core] test: raise maximum CPU cores to 6
|
||||||
|
[cmake, core] Unbreak FreeBSD Building Process
|
||||||
|
```
|
||||||
|
|
||||||
|
- The level of namespacing is generally left to the committer's choice.
|
||||||
|
- However, we never recommend going more than two levels *except* in `hle`, in which case you may go as many as four levels depending on the specificity of your changes.
|
||||||
|
- Ocassionally, up to two additional namespaces may be provided for more clarity.
|
||||||
|
- Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`.
|
||||||
|
- Maintainers are permitted to change namespaces at will.
|
||||||
|
- Commits within PRs are not required to be namespaced, but it is highly recommended.
|
||||||
|
|
||||||
### Where do I start?
|
### Where do I start?
|
||||||
|
|
||||||
Anywhere you like! If you are facing an issue and want to fix it, go ahead. For new features, you are heavily encouraged to open a feature request on GitHub, Codeberg, or Forgejo first, discussing the motivations, potential implementation, and user flow of your desired feature. Our UI/UX designers will work with you to refine your feature before you actually choose to implement it.
|
Anywhere you like! If you are facing an issue and want to fix it, go ahead. For new features, you are heavily encouraged to open a feature request on GitHub, Codeberg, or Forgejo first, discussing the motivations, potential implementation, and user flow of your desired feature. Our UI/UX designers will work with you to refine your feature before you actually choose to implement it.
|
||||||
@@ -39,6 +61,8 @@ There are five primary ways to contribute.
|
|||||||
- Submit pull requests directly to our source tree
|
- Submit pull requests directly to our source tree
|
||||||
- You must first [create an account](https://git.eden-emu.dev/user/sign_up).
|
- You must first [create an account](https://git.eden-emu.dev/user/sign_up).
|
||||||
- You may use an internal account, or you may use a GitHub/Codeberg account linked to our instance.
|
- You may use an internal account, or you may use a GitHub/Codeberg account linked to our instance.
|
||||||
|
- Please make sure to read our [site policy](https://git.eden-emu.dev/eden-emu/site-policy/src/branch/master).
|
||||||
|
- Both your account and your associated fork must be public, *not* limited/private, otherwise our CI workflow will not work on your pull requests.
|
||||||
- Submit pull requests to our [GitHub mirror](https://github.com/eden-emulator/Issue-Reports)
|
- Submit pull requests to our [GitHub mirror](https://github.com/eden-emulator/Issue-Reports)
|
||||||
- Note that this is subject to being removed by DMCA, so don't rely on this.
|
- Note that this is subject to being removed by DMCA, so don't rely on this.
|
||||||
- Submit pull requests to our [Codeberg mirror](https://codeberg.org/eden-emu/eden)
|
- Submit pull requests to our [Codeberg mirror](https://codeberg.org/eden-emu/eden)
|
||||||
@@ -48,7 +72,7 @@ There are five primary ways to contribute.
|
|||||||
- Alongside the contents of your email, please attach the patch/diff file itself for easy access and use.
|
- Alongside the contents of your email, please attach the patch/diff file itself for easy access and use.
|
||||||
- Email our developers at [`developers@eden-emu.dev`](mailto:developers@eden-emu.dev) with any of your relevant findings or code changes.
|
- Email our developers at [`developers@eden-emu.dev`](mailto:developers@eden-emu.dev) with any of your relevant findings or code changes.
|
||||||
|
|
||||||
To test your changes, ensure to read the [build documentation](./docs/Build.md) for your specific platform(s) to ensure everything compiles and works properly. You should also make sure that your branch is up-to-date with the upstream `master` branch before opening a pull request.
|
To test your changes, ensure to read the [build documentation](./docs/Build.md) for your specific platform(s) to ensure everything compiles and works properly. You should also make sure that your branch is up-to-date with the upstream `master` branch before opening a pull request. **You** are responsible for ensuring that your contribution does what it says and doesn't break everything else horribly.
|
||||||
|
|
||||||
## Non-code Contributions
|
## Non-code Contributions
|
||||||
|
|
||||||
|
|||||||
@@ -202,7 +202,8 @@
|
|||||||
"0001-cpmutil-compat.patch",
|
"0001-cpmutil-compat.patch",
|
||||||
"0002-use-ccache.patch",
|
"0002-use-ccache.patch",
|
||||||
"0003-use-cmake-compiler-flags.patch",
|
"0003-use-cmake-compiler-flags.patch",
|
||||||
"0004-use-shell-wrapper.patch"
|
"0004-use-shell-wrapper.patch",
|
||||||
|
"0005-cross-compile.patch"
|
||||||
],
|
],
|
||||||
"repo": "jimmy-park/openssl-cmake",
|
"repo": "jimmy-park/openssl-cmake",
|
||||||
"version": "3.6.2"
|
"version": "3.6.2"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 5.6 KiB |
@@ -1,144 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512" fill="none" viewBox="0 0 512 512"><defs><linearGradient id="c"><stop offset="0" style="stop-color:#f71baa;stop-opacity:.56623769"/><stop offset="1" style="stop-color:#fa87d4;stop-opacity:.25"/></linearGradient><linearGradient id="b"><stop offset="0" style="stop-color:#fe00b1;stop-opacity:1"/><stop offset="1" style="stop-color:#fe00b1;stop-opacity:0"/></linearGradient><linearGradient id="a"><stop offset="0" style="stop-color:#ff0950;stop-opacity:.5"/><stop offset=".496" style="stop-color:#bf42f6;stop-opacity:.75"/><stop offset="1" style="stop-color:#5da5ed;stop-opacity:1"/></linearGradient><linearGradient xlink:href="#a" id="d" x1="270.4" x2="270.4" y1="40" y2="494.4" gradientTransform="translate(-33.928 -34.199)scale(1.07505)" gradientUnits="userSpaceOnUse" spreadMethod="reflect"/><linearGradient xlink:href="#b" id="f" x1="125.402" x2="431.024" y1="271.834" y2="271.834" gradientTransform="translate(-33.928 -34.199)scale(1.07505)" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#c" id="e" x1="270.4" x2="270.4" y1="33.584" y2="500.816" gradientTransform="translate(-33.928 -34.199)scale(1.07505)" gradientUnits="userSpaceOnUse"/></defs><circle cx="256.764" cy="253.054" r="244.25" style="fill:url(#d);fill-opacity:1;stroke:url(#e);stroke-width:13.7948;stroke-opacity:.566238;paint-order:stroke fill markers"/><path d="M55.701 114.372a244 244 0 0 0-10.836 17.2h423.797a244 244 0 0 0-10.837-17.2z" style="fill:#fff;fill-opacity:.5;stroke:none;stroke-width:17.2007;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"/><path d="m219.665 499.138-10.338-55.949" style="fill:#ff2bd5;fill-opacity:1;stroke-width:14.3776;stroke-opacity:.415999;paint-order:stroke fill markers"/><path d="M58.272 395.39a244 244 0 0 0 13.54 17.2h369.902a244 244 0 0 0 13.541-17.2zM24.605 328.953a244 244 0 0 0 6.347 17.2h451.623a244 244 0 0 0 6.347-17.2zM12.586 259.075a244 244 0 0 0 1.033 17.2h486.289a244 244 0 0 0 1.033-17.2z" style="fill:#fff;fill-opacity:.5;stroke:none;stroke-width:17.2007;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"/><path d="M306.217 12.242s-11.75 42.031-17.703 63.363c-12.713 9.965-21.075 19.29-21.075 19.29s-22.956-32.534-44.85-46.065c-21.892-13.531-51.398-11.788-51.398-11.788s-12.257 0-27.092 5.806c-14.836 5.805-20.857 9.675-20.857 9.675s15.053-.43 37.199 7.095 31.82 12.042 31.82 12.042l30.423-6.881-8.277 11.611s14.514 9.353 22.362 17.739c7.848 8.385 11.502 13.114 11.502 13.114s-13.652-5.697-55.579-1.826-83.209 59.127-83.209 59.127 40.42-16.771 64.287-22.362c23.866-5.59 46.657-8.386 46.657-8.386s-18.06 7.74-37.41 40.207c-19.351 32.467-13.762 84.07-13.762 84.07s30.747-61.923 60.203-82.778 35.476-21.501 35.476-21.501-23.65 50.742-32.896 132.23c-9.245 81.489 29.671 217.804 29.671 217.804l46.872-7.311s-44.721-44.291-48.591-158.676 16.34-182.758 16.34-182.758 16.771 1.29 41.712 34.401 39.56 60.203 39.56 60.203 9.463-53.753-11.178-78.264-52.463-35.26-52.463-35.26 13.438-6.988 41.282-4.945c27.844 2.042 85.6 28.444 85.6 28.444S405.336 132.903 369 114.355s-79.77.307-79.77.307 4.055-16.119 28.533-34.21C342.24 62.358 373.56 44.42 373.56 44.42s-25.845 1.217-54.124 12.62c-7.036 2.837-13.79 6.605-19.966 10.666l17.067-53.528z" style="fill:url(#f);fill-opacity:1;stroke:#fff;stroke-width:17.2007;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"/></svg>
|
||||||
<svg
|
|
||||||
width="512"
|
|
||||||
height="512"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
version="1.1"
|
|
||||||
id="svg7"
|
|
||||||
sodipodi:docname="base.svg"
|
|
||||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs7">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient24"
|
|
||||||
inkscape:collect="always">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#f71baa;stop-opacity:0.56623769;"
|
|
||||||
offset="0"
|
|
||||||
id="stop24" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#fa87d4;stop-opacity:0.25;"
|
|
||||||
offset="1"
|
|
||||||
id="stop25" />
|
|
||||||
</linearGradient>
|
|
||||||
<rect
|
|
||||||
x="22.627417"
|
|
||||||
y="402.76802"
|
|
||||||
width="521.34025"
|
|
||||||
height="248.94868"
|
|
||||||
id="rect24" />
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient1"
|
|
||||||
inkscape:collect="always">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#fe00b1;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop1" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#fe00b1;stop-opacity:0;"
|
|
||||||
offset="1"
|
|
||||||
id="stop2" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient11"
|
|
||||||
inkscape:collect="always">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#ff0950;stop-opacity:0.5;"
|
|
||||||
offset="0"
|
|
||||||
id="stop11" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#bf42f6;stop-opacity:0.75;"
|
|
||||||
offset="0.49556771"
|
|
||||||
id="stop20" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#5da5ed;stop-opacity:1;"
|
|
||||||
offset="1"
|
|
||||||
id="stop12" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient11"
|
|
||||||
id="linearGradient12"
|
|
||||||
x1="270.39996"
|
|
||||||
y1="39.999989"
|
|
||||||
x2="270.39996"
|
|
||||||
y2="494.39996"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
spreadMethod="reflect"
|
|
||||||
gradientTransform="matrix(1.075046,0,0,1.075046,-33.928383,-34.198735)" />
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient1"
|
|
||||||
id="linearGradient2"
|
|
||||||
x1="125.40197"
|
|
||||||
y1="271.834"
|
|
||||||
x2="431.02424"
|
|
||||||
y2="271.834"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(1.075046,0,0,1.075046,-33.928383,-34.198735)" />
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient24"
|
|
||||||
id="linearGradient25"
|
|
||||||
x1="270.39996"
|
|
||||||
y1="33.58408"
|
|
||||||
x2="270.39996"
|
|
||||||
y2="500.81589"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(1.075046,0,0,1.075046,-33.928383,-34.198735)" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview7"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="0.88388348"
|
|
||||||
inkscape:cx="141.98704"
|
|
||||||
inkscape:cy="265.87215"
|
|
||||||
inkscape:window-width="1600"
|
|
||||||
inkscape:window-height="849"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg7" />
|
|
||||||
<circle
|
|
||||||
style="fill:url(#linearGradient12);fill-opacity:1;stroke:url(#linearGradient25);stroke-width:13.7948;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
|
||||||
id="path8"
|
|
||||||
cx="256.76401"
|
|
||||||
cy="253.05354"
|
|
||||||
r="244.25046" />
|
|
||||||
<path
|
|
||||||
id="rect1-3"
|
|
||||||
style="fill:#ffffff;fill-opacity:0.5;stroke:none;stroke-width:17.2007;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
|
||||||
d="M 55.701477,114.37179 A 244.25044,244.25044 0 0 0 44.86493,131.57252 h 423.79699 a 244.25044,244.25044 0 0 0 -10.83655,-17.20073 z" />
|
|
||||||
<path
|
|
||||||
style="fill:#ff2bd5;fill-opacity:1;stroke-width:14.3776;stroke-opacity:0.415999;paint-order:stroke fill markers"
|
|
||||||
d="M 219.6651,499.13816 209.32675,443.18948"
|
|
||||||
id="path9" />
|
|
||||||
<path
|
|
||||||
id="rect1-2"
|
|
||||||
style="fill:#ffffff;fill-opacity:0.5;stroke:none;stroke-width:17.2007;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
|
||||||
d="m 58.271509,395.38922 a 244.25044,244.25044 0 0 0 13.54096,17.20073 H 441.71437 a 244.25044,244.25044 0 0 0 13.54097,-17.20073 z" />
|
|
||||||
<path
|
|
||||||
id="rect1-2-5"
|
|
||||||
style="fill:#ffffff;fill-opacity:0.5;stroke:none;stroke-width:17.2007;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
|
||||||
d="m 24.604933,328.95264 a 244.25044,244.25044 0 0 0 6.347389,17.20074 H 482.57453 a 244.25044,244.25044 0 0 0 6.34738,-17.20074 z" />
|
|
||||||
<path
|
|
||||||
id="rect1"
|
|
||||||
style="fill:#ffffff;fill-opacity:0.5;stroke:none;stroke-width:17.2007;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
|
||||||
d="m 12.586253,259.07464 a 244.25044,244.25044 0 0 0 1.033053,17.20075 H 499.90754 a 244.25044,244.25044 0 0 0 1.03305,-17.20075 z" />
|
|
||||||
<path
|
|
||||||
id="path15"
|
|
||||||
style="fill:url(#linearGradient2);fill-opacity:1;stroke:#ffffff;stroke-width:17.2007;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
|
|
||||||
d="m 306.21658,12.242412 c 0,0 -11.75029,42.031067 -17.70256,63.362621 -12.7133,9.964494 -21.07468,19.289937 -21.07468,19.289937 0,0 -22.95662,-32.534232 -44.84956,-46.065299 C 200.69681,35.298604 171.19123,37.04196 171.19123,37.04196 c 0,0 -12.25678,4.2e-4 -27.09242,5.805668 -14.83563,5.805249 -20.85631,9.675414 -20.85631,9.675414 0,0 15.05232,-0.430438 37.19828,7.094883 22.14594,7.525322 31.82093,12.041775 31.82093,12.041775 l 30.42255,-6.880714 -8.27702,11.611336 c 0,0 14.51396,9.3529 22.36179,17.738259 7.84785,8.385359 11.50216,13.114729 11.50216,13.114729 0,0 -13.65224,-5.69691 -55.57904,-1.82674 -41.92679,3.87016 -83.20898,59.12752 -83.20898,59.12752 0,0 40.42048,-16.77155 64.28649,-22.36179 23.86602,-5.59024 46.65742,-8.3862 46.65742,-8.3862 0,0 -18.05952,7.74075 -37.41035,40.20714 -19.35082,32.46639 -13.76142,84.06986 -13.76142,84.06986 0,0 30.74631,-61.92266 60.20258,-82.77854 29.45625,-20.8559 35.47652,-21.50092 35.47652,-21.50092 0,0 -23.6506,50.74216 -32.896,132.23065 -9.24539,81.48849 29.67085,217.8039 29.67085,217.8039 l 46.87159,-7.31116 c 0,0 -44.72107,-44.29147 -48.59124,-158.67636 -3.87017,-114.3849 16.33986,-182.75782 16.33986,-182.75782 0,0 16.77156,1.29005 41.71263,34.40147 24.94106,33.11142 39.56043,60.20258 39.56043,60.20258 0,0 9.46208,-53.75314 -11.1788,-78.26419 -20.64088,-24.51105 -52.46309,-35.26025 -52.46309,-35.26025 0,0 13.4385,-6.98738 41.28219,-4.94479 27.84369,2.04258 85.60053,28.44463 85.60053,28.44462 0,0 -15.50743,-26.7591 -51.84367,-45.30731 -36.33623,-18.548198 -79.76967,0.30655 -79.76967,0.30655 0,0 4.05525,-16.118294 28.53281,-34.210394 24.47756,-18.092095 55.79742,-36.030833 55.79742,-36.030833 0,0 -25.84554,1.216607 -54.12395,12.619193 -7.03608,2.837127 -13.78978,6.605056 -19.96604,10.666471 l 17.06635,-53.527632 z" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 11 KiB |
@@ -1,80 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512" fill="none" viewBox="0 0 512 512"><defs><linearGradient id="a"><stop offset="0" style="stop-color:#f977d9;stop-opacity:1"/><stop offset=".541" style="stop-color:#a655d5;stop-opacity:1"/><stop offset=".571" style="stop-color:#984fd5;stop-opacity:1"/><stop offset=".597" style="stop-color:#8c4ad4;stop-opacity:1"/><stop offset="1" style="stop-color:#3928d2;stop-opacity:1"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="264.175" x2="264.175" y1="28.386" y2="488.651" gradientTransform="matrix(.97816 0 0 .9788 4.57 5.88)" gradientUnits="userSpaceOnUse"/></defs><path d="M262.975 33.688A218.443 225.23 0 0 0 138.838 73.59l2.3-1.324 20.083-7.07 19.799-3.678 23.334 2.687L228.96 76.65 265.8 115 283 99.4l21.6-13.6 26.4-9.4 29.6-6.8 19.355-.391a218.443 225.23 0 0 0-116.98-35.521M380.076 69.29l-29.877 8.51-21 11.398L307.4 108l-18.6 21.8-1.4 5.2 15-5.4 16.6-1.8 29.8 4 21.4 9.6 22.8 20 6.6 10.2-24.8-10.8-36.4-10-29.2-.8-20.4 4.4 4.4.8 26 13.6 18.8 18.4 12.8 36.8-1.6 36-23.2-37.2-23.2-28.8-25.2-21.6-8.4 15.2-12.4 94L258 364l20.4 88.8 18.795 28.57a218.443 225.23 0 0 0 184.223-222.452A218.443 225.23 0 0 0 380.076 69.291M133.074 77.84a218.443 225.23 0 0 0-88.54 181.078A218.443 225.23 0 0 0 257.04 484.066l-9.695-25.437-9.475-40.445-4.809-37.76-2.687-25.457-.424-33.658 2.404-29.98 5.092-36.347 17.112-63.074 7.07-19.375-6.08 1.557-14.567 6.787-11.382 9.322-19 18-13.2 21.201-11 23.2-13 16.4-2-15.8 2.2-23.8 9.4-27 16.4-24.4 21.641-24.559-12.02 2.264-31.962 7.07-28.99 8.627L119.925 183l.707-2.83 9.191-14.283 21.356-18.385 21.779-12.02 17.111-5.941 18.951-1.555 18.667.707 20.082-.283-1.272-3.252-19.799-19.234-7.072-8.485 1.84-7.353-14.71 3.959-10.888 1.414-16.406-6.787-23.334-7.213z" style="fill:url(#b);fill-opacity:1;stroke:none;stroke-width:13.3314;stroke-opacity:1;paint-order:stroke fill markers"/><path d="M259.367 490.166 298.4 483.2l-20-30.4L258 364l-1.2-82.4 12.4-94 8.4-15.2 25.2 21.6 23.2 28.8 23.2 37.2 1.6-36-12.8-36.8-18.8-18.4-26-13.6-4.4-.8 20.4-4.4 29.2.8 36.4 10 24.8 10.8-6.6-10.2-22.8-20-21.4-9.6-29.8-4-16.6 1.8-15 5.4 1.4-5.2 18.6-21.8 21.8-18.8 21-11.4 30.2-8.6-19.8.4-29.6 6.8-26.4 9.4L283 99.4 265.8 115 228.96 76.65l-24.607-12.445-23.335-2.687-19.799 3.677-20.082 7.071-9.333 5.374 24.324 3.818 23.335 7.213 16.404 6.788 10.89-1.414 14.708-3.96-1.839 7.354 7.071 8.485 19.8 19.234 1.272 3.252-20.082.283-18.667-.707-18.95 1.556-17.113 5.94-21.779 12.02-21.354 18.385-9.193 14.284-.707 2.828 28.143-11.597 28.991-8.626 31.962-7.071 12.02-2.263L199.4 178 183 202.4l-9.4 27-2.2 23.8 2 15.8 13-16.4 11-23.2 13.2-21.2 19-18 11.382-9.322 14.566-6.789 6.081-1.555-7.07 19.375-17.113 63.073-5.09 36.346-2.405 29.981.424 33.658 2.687 25.456 4.809 37.76 9.475 40.446z" style="fill:#1b1b1b;fill-opacity:.12492698;stroke:none;stroke-width:13.374;stroke-opacity:.415999;paint-order:stroke fill markers"/></svg>
|
||||||
<svg
|
|
||||||
width="512"
|
|
||||||
height="512"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
version="1.1"
|
|
||||||
id="svg7"
|
|
||||||
sodipodi:docname="base_small.svg"
|
|
||||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs7">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient10"
|
|
||||||
inkscape:collect="always">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#f977d9;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop10" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#a655d5;stop-opacity:1;"
|
|
||||||
offset="0.54051435"
|
|
||||||
id="stop13" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#984fd5;stop-opacity:1;"
|
|
||||||
offset="0.5714342"
|
|
||||||
id="stop12" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#8c4ad4;stop-opacity:1;"
|
|
||||||
offset="0.59666741"
|
|
||||||
id="stop14" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#3928d2;stop-opacity:1;"
|
|
||||||
offset="1"
|
|
||||||
id="stop11" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient10"
|
|
||||||
id="linearGradient11"
|
|
||||||
x1="264.17508"
|
|
||||||
y1="28.385544"
|
|
||||||
x2="264.17508"
|
|
||||||
y2="488.65109"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(0.97815818,0,0,0.97880258,4.570042,5.8799159)" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview7"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="0.88388348"
|
|
||||||
inkscape:cx="153.30075"
|
|
||||||
inkscape:cy="243.24473"
|
|
||||||
inkscape:window-width="1600"
|
|
||||||
inkscape:window-height="849"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg7"
|
|
||||||
showguides="false" />
|
|
||||||
<path
|
|
||||||
id="path9"
|
|
||||||
style="fill:url(#linearGradient11);fill-opacity:1;stroke:none;stroke-width:13.3314;stroke-opacity:1;paint-order:stroke fill markers"
|
|
||||||
d="M 262.97461 33.6875 A 218.44267 225.23091 0 0 0 138.83789 73.589844 L 141.13867 72.265625 L 161.2207 65.195312 L 181.01953 61.517578 L 204.35352 64.205078 L 228.96094 76.650391 L 265.80078 115 L 283 99.400391 L 304.59961 85.800781 L 331 76.400391 L 360.59961 69.599609 L 379.95508 69.208984 A 218.44267 225.23091 0 0 0 262.97461 33.6875 z M 380.07617 69.291016 L 350.19922 77.800781 L 329.19922 89.199219 L 307.40039 108 L 288.80078 129.80078 L 287.40039 135 L 302.40039 129.59961 L 319 127.80078 L 348.80078 131.80078 L 370.19922 141.40039 L 393 161.40039 L 399.59961 171.59961 L 374.80078 160.80078 L 338.40039 150.80078 L 309.19922 150 L 288.80078 154.40039 L 293.19922 155.19922 L 319.19922 168.80078 L 338 187.19922 L 350.80078 224 L 349.19922 260 L 326 222.80078 L 302.80078 194 L 277.59961 172.40039 L 269.19922 187.59961 L 256.80078 281.59961 L 258 364 L 278.40039 452.80078 L 297.19531 481.36914 A 218.44267 225.23091 0 0 0 481.41797 258.91797 A 218.44267 225.23091 0 0 0 380.07617 69.291016 z M 133.07422 77.839844 A 218.44267 225.23091 0 0 0 44.533203 258.91797 A 218.44267 225.23091 0 0 0 257.04102 484.06641 L 247.3457 458.62891 L 237.87109 418.18359 L 233.0625 380.42383 L 230.375 354.9668 L 229.95117 321.30859 L 232.35547 291.32812 L 237.44727 254.98242 L 254.55859 191.9082 L 261.62891 172.5332 L 255.54883 174.08984 L 240.98242 180.87695 L 229.59961 190.19922 L 210.59961 208.19922 L 197.40039 229.40039 L 186.40039 252.59961 L 173.40039 269 L 171.40039 253.19922 L 173.59961 229.40039 L 183 202.40039 L 199.40039 178 L 221.04102 153.44141 L 209.02148 155.70508 L 177.05859 162.77539 L 148.06836 171.40234 L 119.92578 183 L 120.63281 180.16992 L 129.82422 165.88672 L 151.17969 147.50195 L 172.95898 135.48242 L 190.07031 129.54102 L 209.02148 127.98633 L 227.6875 128.69336 L 247.76953 128.41016 L 246.49805 125.1582 L 226.69922 105.92383 L 219.62695 97.439453 L 221.4668 90.085938 L 206.75781 94.044922 L 195.86914 95.458984 L 179.46289 88.671875 L 156.12891 81.458984 L 133.07422 77.839844 z " />
|
|
||||||
<path
|
|
||||||
style="fill:#1b1b1b;fill-opacity:0.12492698;stroke:none;stroke-width:13.374;stroke-opacity:0.415999;paint-order:stroke fill markers"
|
|
||||||
d="m 259.36665,490.16617 39.03323,-6.96642 -20,-30.4 -20.4,-88.8 -1.2,-82.4 12.4,-94 8.4,-15.2 25.2,21.6 23.2,28.8 23.2,37.2 1.6,-36 -12.8,-36.8 -18.8,-18.4 -26,-13.6 -4.4,-0.8 20.4,-4.4 29.2,0.8 36.4,10 24.8,10.8 -6.6,-10.2 -22.8,-20 -21.4,-9.6 -29.8,-4 -16.6,1.8 -15,5.4 1.4,-5.2 18.6,-21.8 21.8,-18.800003 21,-11.4 30.2,-8.6 -19.8,0.4 -29.6,6.8 -26.4,9.4 -21.6,13.6 -17.2,15.600003 -36.83882,-38.349628 -24.60732,-12.445079 -23.33452,-2.687006 -19.79899,3.676955 -20.08184,7.071068 -9.33381,5.374012 24.32448,3.818376 23.33452,7.212489 16.40488,6.788226 10.88944,-1.414214 14.70782,-3.959798 -1.83847,7.353911 7.07106,8.485288 19.79899,19.2333 1.2728,3.25269 -20.08184,0.28284 -18.66762,-0.7071 -18.95046,1.55563 -17.11198,5.9397 -21.77889,12.02081 -21.35462,18.38478 -9.19239,14.28356 -0.70711,2.82843 28.14285,-11.59656 28.99138,-8.6267 31.96122,-7.07107 12.02082,-2.26274 -21.64158,24.55783 -16.4,24.4 -9.4,27 -2.2,23.8 2,15.8 13,-16.4 11,-23.2 13.2,-21.2 19,-18 11.38199,-9.32209 14.5664,-6.78822 6.08112,-1.55564 -7.07107,19.37473 -17.11198,63.07393 -5.09117,36.34528 -2.40416,29.98133 0.42426,33.65828 2.68701,25.45585 4.80832,37.7595 9.47523,40.44651 z"
|
|
||||||
id="path8-4" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -6,10 +6,31 @@ General guide for cross compiling.
|
|||||||
|
|
||||||
A painless guide for cross compilation (or to test NCE) from a x86_64 system without polluting your main.
|
A painless guide for cross compilation (or to test NCE) from a x86_64 system without polluting your main.
|
||||||
|
|
||||||
- Install QEMU: `sudo pkg install qemu`
|
```sh
|
||||||
- Download Debian 13: `wget https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/debian-13.0.0-arm64-netinst.iso`
|
#!/bin/sh
|
||||||
- Create a system disk: `qemu-img create -f qcow2 debian-13-arm64-ci.qcow2 30G`
|
ISO_FILE="debian-13.0.0-arm64-netinst.iso"
|
||||||
- Run the VM: `qemu-system-aarch64 -M virt -m 2G -cpu max -bios /usr/local/share/qemu/edk2-aarch64-code.fd -drive if=none,file=debian-13.0.0-arm64-netinst.iso,format=raw,id=cdrom -device scsi-cd,drive=cdrom -drive if=none,file=debian-13-arm64-ci.qcow2,id=hd0,format=qcow2 -device virtio-blk-device,drive=hd0 -device virtio-gpu-pci -device usb-ehci -device usb-kbd -device intel-hda -device hda-output -nic user,model=virtio-net-pci`
|
DISK_FILE="debian-13-arm64-ci.qcow2"
|
||||||
|
which -- qemu-system-aarch64 || sudo pkg install qemu
|
||||||
|
[ -f "$ISO_FILE" ] || wget https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/$ISO_FILE
|
||||||
|
[ -f "$DISK_FILE" ] || qemu-img create -f qcow2 "$DISK_FILE" 30G
|
||||||
|
QEMU_FLAGS=(
|
||||||
|
-M virt
|
||||||
|
-m 2G
|
||||||
|
-cpu max
|
||||||
|
-bios /usr/local/share/qemu/edk2-aarch64-code.fd
|
||||||
|
-drive if=none,file=$ISO_FILE,format=raw,id=cdrom
|
||||||
|
-drive if=none,file=$DISK_FILE,id=hd0,format=qcow2
|
||||||
|
-device scsi-cd,drive=cdrom
|
||||||
|
-device virtio-blk-device,drive=hd0
|
||||||
|
-device virtio-gpu-pci
|
||||||
|
-device usb-ehci
|
||||||
|
-device usb-kbd
|
||||||
|
-device intel-hda
|
||||||
|
-device hda-output
|
||||||
|
-nic user,model=virtio-net-pci
|
||||||
|
)
|
||||||
|
qemu-system-aarch64 "${QEMU_FLAGS[@]}"
|
||||||
|
```
|
||||||
|
|
||||||
## Gentoo
|
## Gentoo
|
||||||
|
|
||||||
|
|||||||
@@ -24,25 +24,6 @@ If the work is licensed/vendored from other people or projects, you may omit the
|
|||||||
|
|
||||||
For more information on the license header script, run `.ci/license-header.sh -h`.
|
For more information on the license header script, run `.ci/license-header.sh -h`.
|
||||||
|
|
||||||
## Pull Requests
|
|
||||||
|
|
||||||
Pull requests are only to be merged by core developers when properly tested and discussions conclude on Discord or other communication channels. Labels are recommended but not required. However, all PRs MUST be namespaced and optionally typed:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
[cmake] refactor: CPM over submodules
|
|
||||||
[desktop] feat: implement firmware install from ZIP
|
|
||||||
[hle] stub fw20 functions
|
|
||||||
[core] test: raise maximum CPU cores to 6
|
|
||||||
[cmake, core] Unbreak FreeBSD Building Process
|
|
||||||
```
|
|
||||||
|
|
||||||
- The level of namespacing is generally left to the committer's choice.
|
|
||||||
- However, we never recommend going more than two levels *except* in `hle`, in which case you may go as many as four levels depending on the specificity of your changes.
|
|
||||||
- Ocassionally, up to two additional namespaces may be provided for more clarity.
|
|
||||||
- Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`.
|
|
||||||
- Maintainers are permitted to change namespaces at will.
|
|
||||||
- Commits within PRs are not required to be namespaced, but it is highly recommended.
|
|
||||||
|
|
||||||
## Adding new settings
|
## Adding new settings
|
||||||
|
|
||||||
When adding new settings, use `tr("Setting:")` if the setting is meant to be a field, otherwise use `tr("Setting")` if the setting is meant to be a Yes/No or checkmark type of setting, see [this short style guide](https://learn.microsoft.com/en-us/style-guide/punctuation/colons#in-ui).
|
When adding new settings, use `tr("Setting:")` if the setting is meant to be a field, otherwise use `tr("Setting")` if the setting is meant to be a Yes/No or checkmark type of setting, see [this short style guide](https://learn.microsoft.com/en-us/style-guide/punctuation/colons#in-ui).
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ This contains documentation created by developers, build instructions, guideline
|
|||||||
|
|
||||||
Policies and information on development.
|
Policies and information on development.
|
||||||
|
|
||||||
- **[AI and LLM Usage](./policies/AI.md)**
|
- **[AI and LLM Usage](./CONTRIBUTING.md#policies)**
|
||||||
- **[Coding guidelines](./policies/Coding.md)**
|
- **[Coding guidelines](./policies/Coding.md)**
|
||||||
- **[Contributing](../CONTRIBUTING.md)**
|
- **[Contributing](../CONTRIBUTING.md)**
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,9 @@ Eden by default will be cloned into:
|
|||||||
## Building with Terminal
|
## Building with Terminal
|
||||||
|
|
||||||
1. Download the SDK and NDK from Android Studio.
|
1. Download the SDK and NDK from Android Studio.
|
||||||
2. Navigate to SDK and NDK paths.
|
2. Navigate to SDK path.
|
||||||
3. Then set ANDROID_SDK_ROOT and ANDROID_NDK_ROOT in terminal via
|
3. Then set ANDROID_HOME in terminal via
|
||||||
`export ANDROID_SDK_ROOT=path/to/sdk`
|
`export ANDROID_HOME=path/to/sdk`
|
||||||
`export ANDROID_NDK_ROOT=path/to/ndk`.
|
|
||||||
4. Navigate to `eden/src/android`.
|
4. Navigate to `eden/src/android`.
|
||||||
5. Then Build with `./gradlew assembleRelWithDebInfo`.
|
5. Then Build with `./gradlew assembleRelWithDebInfo`.
|
||||||
6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`.
|
6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
@@ -101,6 +101,11 @@ endfunction()
|
|||||||
# ia64 exists
|
# ia64 exists
|
||||||
# the rest exist, but are probably less popular than ia64
|
# the rest exist, but are probably less popular than ia64
|
||||||
|
|
||||||
|
detect_architecture_symbols(
|
||||||
|
ARCH wasm
|
||||||
|
SYMBOLS
|
||||||
|
"__EMSCRIPTEN__")
|
||||||
|
|
||||||
detect_architecture_symbols(
|
detect_architecture_symbols(
|
||||||
ARCH arm64
|
ARCH arm64
|
||||||
SYMBOLS
|
SYMBOLS
|
||||||
@@ -203,11 +208,6 @@ detect_architecture_symbols(
|
|||||||
"__loongarch__"
|
"__loongarch__"
|
||||||
"__loongarch64")
|
"__loongarch64")
|
||||||
|
|
||||||
detect_architecture_symbols(
|
|
||||||
ARCH wasm
|
|
||||||
SYMBOLS
|
|
||||||
"__EMSCRIPTEN__")
|
|
||||||
|
|
||||||
# "generic" target
|
# "generic" target
|
||||||
# If you have reached this point, you're on some as-of-yet unsupported architecture.
|
# If you have reached this point, you're on some as-of-yet unsupported architecture.
|
||||||
# See the docs up above for known unsupported architectures
|
# See the docs up above for known unsupported architectures
|
||||||
|
|||||||
@@ -79,9 +79,8 @@ class DriverFetcherFragment : Fragment() {
|
|||||||
IntRange(100, 599) to "Unsupported",
|
IntRange(100, 599) to "Unsupported",
|
||||||
IntRange(600, 639) to "Mr. Purple EOL-24.3.4",
|
IntRange(600, 639) to "Mr. Purple EOL-24.3.4",
|
||||||
IntRange(640, 699) to "Mr. Purple T19",
|
IntRange(640, 699) to "Mr. Purple T19",
|
||||||
IntRange(700, 710) to "KIMCHI 25.2.0_r5",
|
IntRange(700, 710) to "Mr. Purple T29",
|
||||||
IntRange(711, 799) to "Mr. Purple T23",
|
IntRange(711, 899) to "Mr. Purple T30",
|
||||||
IntRange(800, 899) to "GameHub Adreno 8xx",
|
|
||||||
IntRange(900, Int.MAX_VALUE) to "Unsupported"
|
IntRange(900, Int.MAX_VALUE) to "Unsupported"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
@@ -351,7 +351,7 @@
|
|||||||
<string name="frame_generation_unsupported">غير مدعوم (لا يتوفر نموذج ذاكرة Vulkan أو float16)</string>
|
<string name="frame_generation_unsupported">غير مدعوم (لا يتوفر نموذج ذاكرة Vulkan أو float16)</string>
|
||||||
<string name="lossless_scaling">Lossless Scaling</string>
|
<string name="lossless_scaling">Lossless Scaling</string>
|
||||||
<string name="lossless_scaling_description">قم بتوفير نسختك الخاصة من ملف Lossless.dll لتفعيل توليد الإطارات</string>
|
<string name="lossless_scaling_description">قم بتوفير نسختك الخاصة من ملف Lossless.dll لتفعيل توليد الإطارات</string>
|
||||||
<string name="lossless_scaling_installed">مثبت</string>
|
<string name="lossless_scaling_installed">تم التثبيت</string>
|
||||||
<string name="lossless_scaling_not_installed">غير مثبت</string>
|
<string name="lossless_scaling_not_installed">غير مثبت</string>
|
||||||
<string name="lossless_scaling_replace">استبدل</string>
|
<string name="lossless_scaling_replace">استبدل</string>
|
||||||
<string name="lossless_scaling_remove">إزالة</string>
|
<string name="lossless_scaling_remove">إزالة</string>
|
||||||
@@ -501,9 +501,9 @@
|
|||||||
<string name="frame_limit_enable_description">يحدد سرعة المحاكاة بنسبة مئوية محددة من السرعة العادية.</string>
|
<string name="frame_limit_enable_description">يحدد سرعة المحاكاة بنسبة مئوية محددة من السرعة العادية.</string>
|
||||||
<string name="frame_limit_slider">نسبة الحد الأقصى للسرعة</string>
|
<string name="frame_limit_slider">نسبة الحد الأقصى للسرعة</string>
|
||||||
<string name="frame_limit_slider_description">يحدد النسبة المئوية للحد من سرعة المحاكاة. %100 هي السرعة الطبيعية. القيم الأعلى أو الأقل ستزيد أو تقلل من الحد الأقصى للسرعة.</string>
|
<string name="frame_limit_slider_description">يحدد النسبة المئوية للحد من سرعة المحاكاة. %100 هي السرعة الطبيعية. القيم الأعلى أو الأقل ستزيد أو تقلل من الحد الأقصى للسرعة.</string>
|
||||||
<string name="turbo_speed_limit">سرعة تيربو</string>
|
<string name="turbo_speed_limit">السرعة الفائقة</string>
|
||||||
<string name="turbo_speed_limit_description">عند تفعيل وضع التيربو، سيتم تشغيل المحاكاة بهذه السرعة.</string>
|
<string name="turbo_speed_limit_description">عند تفعيل وضع التيربو، سيتم تشغيل المحاكاة بهذه السرعة.</string>
|
||||||
<string name="slow_speed_limit">سرعة بطيئة</string>
|
<string name="slow_speed_limit">السرعة البطيئة</string>
|
||||||
<string name="slow_speed_limit_description">عند تفعيل الوضع البطيء، سيتم تشغيل المحاكاة بهذه السرعة.</string>
|
<string name="slow_speed_limit_description">عند تفعيل الوضع البطيء، سيتم تشغيل المحاكاة بهذه السرعة.</string>
|
||||||
<string name="cpu_backend">خلفية وحدة المعالجة المركزية</string>
|
<string name="cpu_backend">خلفية وحدة المعالجة المركزية</string>
|
||||||
<string name="cpu_accuracy">دقة وحدة المعالجة المركزية</string>
|
<string name="cpu_accuracy">دقة وحدة المعالجة المركزية</string>
|
||||||
@@ -514,7 +514,7 @@
|
|||||||
|
|
||||||
<!-- System settings strings -->
|
<!-- System settings strings -->
|
||||||
<string name="device_name">اسم الجهاز</string>
|
<string name="device_name">اسم الجهاز</string>
|
||||||
<string name="use_docked_mode">وضع الإرساء</string>
|
<string name="use_docked_mode">وضع المنصة</string>
|
||||||
<string name="use_docked_mode_description">يزيد الدقة ويقلل الأداء. يتم استخدام الوضع المحمول عند تعطيله، مما يقلل الدقة ويزيد الأداء.</string>
|
<string name="use_docked_mode_description">يزيد الدقة ويقلل الأداء. يتم استخدام الوضع المحمول عند تعطيله، مما يقلل الدقة ويزيد الأداء.</string>
|
||||||
<string name="emulated_region">المنطقة التي تمت محاكاتها</string>
|
<string name="emulated_region">المنطقة التي تمت محاكاتها</string>
|
||||||
<string name="emulated_language">لغة المحاكاة</string>
|
<string name="emulated_language">لغة المحاكاة</string>
|
||||||
@@ -543,7 +543,7 @@
|
|||||||
<string name="network">الشبكة</string>
|
<string name="network">الشبكة</string>
|
||||||
|
|
||||||
<!-- Graphics settings strings -->
|
<!-- Graphics settings strings -->
|
||||||
<string name="renderer_resolution">الدقة (الإرساء/محمول)</string>
|
<string name="renderer_resolution">الدقة (المنصة/محمول)</string>
|
||||||
<string name="renderer_vsync">VSync وضع</string>
|
<string name="renderer_vsync">VSync وضع</string>
|
||||||
<string name="renderer_scaling_filter">مرشح ملائم للنافذة</string>
|
<string name="renderer_scaling_filter">مرشح ملائم للنافذة</string>
|
||||||
<string name="fsr_sharpness">حدة FSR/SGSR</string>
|
<string name="fsr_sharpness">حدة FSR/SGSR</string>
|
||||||
@@ -588,7 +588,7 @@
|
|||||||
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
|
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
|
||||||
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
|
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
|
||||||
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
|
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
|
||||||
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى.</string>
|
<string name="fix_bloom_effects_description">يزيل تأثير التوهج في لعبة Burnout.</string>
|
||||||
<string name="emulate_bgr565">محاكاة BGR565</string>
|
<string name="emulate_bgr565">محاكاة BGR565</string>
|
||||||
<string name="emulate_bgr565_description">يُصلح مشاكل انعكاس الألوان في الألعاب أو ظهور تشوهات غريبة أو ظلال غريبة.</string>
|
<string name="emulate_bgr565_description">يُصلح مشاكل انعكاس الألوان في الألعاب أو ظهور تشوهات غريبة أو ظلال غريبة.</string>
|
||||||
<string name="rescale_hack">تفعيل ميزة إعادة التحجيم القديمة</string>
|
<string name="rescale_hack">تفعيل ميزة إعادة التحجيم القديمة</string>
|
||||||
@@ -694,7 +694,7 @@
|
|||||||
<string name="control_stick">عصا التحكم</string>
|
<string name="control_stick">عصا التحكم</string>
|
||||||
<string name="right_stick">العصا اليمنى</string>
|
<string name="right_stick">العصا اليمنى</string>
|
||||||
<string name="c_stick">عصا-C</string>
|
<string name="c_stick">عصا-C</string>
|
||||||
<string name="pressed">مضغوط</string>
|
<string name="pressed">ضغط العصا</string>
|
||||||
<string name="range">النطاق</string>
|
<string name="range">النطاق</string>
|
||||||
<string name="deadzone">المنطقة الميتة</string>
|
<string name="deadzone">المنطقة الميتة</string>
|
||||||
<string name="modifier">معدل</string>
|
<string name="modifier">معدل</string>
|
||||||
@@ -821,10 +821,16 @@
|
|||||||
<!-- Preferences Screen -->
|
<!-- Preferences Screen -->
|
||||||
<string name="preferences_settings">الإعدادات</string>
|
<string name="preferences_settings">الإعدادات</string>
|
||||||
<string name="preferences_system">النظام</string>
|
<string name="preferences_system">النظام</string>
|
||||||
<string name="preferences_system_description">وضع الإرساء، المنطقة، اللغة</string>
|
<string name="preferences_system_description">وضع المنصة، المنطقة، اللغة</string>
|
||||||
<string name="preferences_graphics">الرسومات</string>
|
<string name="preferences_graphics">الرسومات</string>
|
||||||
<string name="preferences_graphics_description">مستوى دقة المحاكاة، الدقة، ذاكرة التخزين المؤقتة للتظليل</string>
|
<string name="preferences_graphics_description">مستوى دقة المحاكاة، الدقة، ذاكرة التخزين المؤقتة للتظليل</string>
|
||||||
<string name="quick_settings">الإعدادات السريعة</string>
|
<string name="quick_settings">الإعدادات السريعة</string>
|
||||||
|
<string name="cheats">رموز الغش</string>
|
||||||
|
<string name="enable_all_cheats">تفعيل جميع رموز الغش</string>
|
||||||
|
<string name="disable_all_cheats">تعطيل جميع رموز الغش</string>
|
||||||
|
<string name="unnamed_cheat">رمز الغش بدون اسم</string>
|
||||||
|
<string name="enable_cheats_by_default">تفعيل رموز الغش بشكل افتراضي</string>
|
||||||
|
<string name="enable_cheats_by_default_description">تفعيل رموز الغش الاعتيادية عند بدء اللعبة</string>
|
||||||
<string name="enable_quick_settings">تفعيل الإعدادات السريعة</string>
|
<string name="enable_quick_settings">تفعيل الإعدادات السريعة</string>
|
||||||
<string name="enable_quick_settings_description">السماح بالوصول إلى قائمة الإعدادات السريعة عن طريق التمرير و زر القائمة</string>
|
<string name="enable_quick_settings_description">السماح بالوصول إلى قائمة الإعدادات السريعة عن طريق التمرير و زر القائمة</string>
|
||||||
<string name="preferences_audio">الصوت</string>
|
<string name="preferences_audio">الصوت</string>
|
||||||
@@ -869,12 +875,12 @@
|
|||||||
<string name="copy_details">نسخ التفاصيل</string>
|
<string name="copy_details">نسخ التفاصيل</string>
|
||||||
<string name="add_ons">الإضافات</string>
|
<string name="add_ons">الإضافات</string>
|
||||||
<string name="add_ons_description">تفعيل/تعطيل التعديلات، التحديثات، المحتوى القابل للتنزيل</string>
|
<string name="add_ons_description">تفعيل/تعطيل التعديلات، التحديثات، المحتوى القابل للتنزيل</string>
|
||||||
<string name="playtime">زمن اللعب:</string>
|
<string name="playtime">وقت اللعب:</string>
|
||||||
<string name="reset_playtime">مسح زمن اللعب</string>
|
<string name="reset_playtime">مسح وقت اللعب</string>
|
||||||
<string name="reset_playtime_description">إعادة تعيين زمن اللعب للعبة الحالية إلى 0 ثانية</string>
|
<string name="reset_playtime_description">إعادة تعيين وقت لعب اللعبة الحالية إلى 0 ثانية</string>
|
||||||
<string name="reset_playtime_warning_description">سيؤدي هذا إلى مسح بيانات زمن اللعب الحالية للعبة. هل أنت متأكد؟</string>
|
<string name="reset_playtime_warning_description">سيؤدي هذا إلى مسح بيانات وقت اللعب للعبة الحالية. هل أنت متأكد؟</string>
|
||||||
<string name="playtime_reset_successfully">تمت إعادة تعيين زمن اللعب</string>
|
<string name="playtime_reset_successfully">تمت إعادة تعيين وقت اللعب</string>
|
||||||
<string name="edit_playtime">تعديل زمن اللعب</string>
|
<string name="edit_playtime">تعديل وقت اللعب</string>
|
||||||
<string name="hours">ساعات</string>
|
<string name="hours">ساعات</string>
|
||||||
<string name="minutes">دقائق</string>
|
<string name="minutes">دقائق</string>
|
||||||
<string name="hours_abbr">س</string>
|
<string name="hours_abbr">س</string>
|
||||||
@@ -883,7 +889,7 @@
|
|||||||
<string name="hours_must_be_between_0_and_9999">يجب أن تكون الساعات بين 0 و 9999</string>
|
<string name="hours_must_be_between_0_and_9999">يجب أن تكون الساعات بين 0 و 9999</string>
|
||||||
<string name="minutes_must_be_between_0_and_59">يجب أن تكون الدقائق بين 0 و 59</string>
|
<string name="minutes_must_be_between_0_and_59">يجب أن تكون الدقائق بين 0 و 59</string>
|
||||||
<string name="seconds_must_be_between_0_and_59">يجب أن تكون الثواني بين 0 و 59</string>
|
<string name="seconds_must_be_between_0_and_59">يجب أن تكون الثواني بين 0 و 59</string>
|
||||||
<string name="playtime_updated_successfully">تم تحديث زمن اللعب بنجاح</string>
|
<string name="playtime_updated_successfully">تم تحديث وقت اللعب بنجاح</string>
|
||||||
<string name="clear_shader_cache">مسح ذاكرة التخزين المؤقتة للتظليل</string>
|
<string name="clear_shader_cache">مسح ذاكرة التخزين المؤقتة للتظليل</string>
|
||||||
<string name="clear_shader_cache_description">يزيل جميع التظليلات التي تم إنشاؤها أثناء لعب هذه اللعبة</string>
|
<string name="clear_shader_cache_description">يزيل جميع التظليلات التي تم إنشاؤها أثناء لعب هذه اللعبة</string>
|
||||||
<string name="clear_shader_cache_warning_description">ستواجه المزيد من التقطع مع إعادة إنشاء ذاكرة التخزين المؤقتة للتظلل</string>
|
<string name="clear_shader_cache_warning_description">ستواجه المزيد من التقطع مع إعادة إنشاء ذاكرة التخزين المؤقتة للتظلل</string>
|
||||||
|
|||||||
@@ -531,7 +531,6 @@
|
|||||||
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
|
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
|
||||||
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché de la CPU durante las actualizaciones de memoria, lo que reduce el uso de la CPU y mejora su rendimiento. Esto puede causar fallos o bloqueos en algunos juegos.</string>
|
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché de la CPU durante las actualizaciones de memoria, lo que reduce el uso de la CPU y mejora su rendimiento. Esto puede causar fallos o bloqueos en algunos juegos.</string>
|
||||||
<string name="fix_bloom_effects">Arreglar los efectos de resplandor</string>
|
<string name="fix_bloom_effects">Arreglar los efectos de resplandor</string>
|
||||||
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno A6XX - A7XX/ Turnip), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
|
|
||||||
<string name="emulate_bgr565">Emular BGR565</string>
|
<string name="emulate_bgr565">Emular BGR565</string>
|
||||||
<string name="emulate_bgr565_description">Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas.</string>
|
<string name="emulate_bgr565_description">Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas.</string>
|
||||||
<string name="rescale_hack">Activar la pasada de reescalado heredada</string>
|
<string name="rescale_hack">Activar la pasada de reescalado heredada</string>
|
||||||
|
|||||||
@@ -577,7 +577,6 @@
|
|||||||
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
|
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
|
||||||
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
|
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
|
||||||
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
|
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
|
||||||
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
|
|
||||||
<string name="emulate_bgr565">Эмулировать BGR565</string>
|
<string name="emulate_bgr565">Эмулировать BGR565</string>
|
||||||
<string name="emulate_bgr565_description">Исправляет проблемы с инвертированными цветами в играх, а также со странными артефактами или некорректными тенями.</string>
|
<string name="emulate_bgr565_description">Исправляет проблемы с инвертированными цветами в играх, а также со странными артефактами или некорректными тенями.</string>
|
||||||
<string name="rescale_hack">Включить старый метод изменения разрешения</string>
|
<string name="rescale_hack">Включить старый метод изменения разрешения</string>
|
||||||
|
|||||||
@@ -493,7 +493,6 @@
|
|||||||
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
|
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
|
||||||
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
|
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
|
||||||
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
|
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
|
||||||
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno A6XX–A7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
|
|
||||||
<string name="emulate_bgr565">Емулювати BGR565</string>
|
<string name="emulate_bgr565">Емулювати BGR565</string>
|
||||||
<string name="emulate_bgr565_description">Виправляє проблеми з інвертованими кольорами в іграх або дивними артефактами чи тінями.</string>
|
<string name="emulate_bgr565_description">Виправляє проблеми з інвертованими кольорами в іграх або дивними артефактами чи тінями.</string>
|
||||||
<string name="rescale_hack">Увімкнути застаріле масштабування</string>
|
<string name="rescale_hack">Увімкнути застаріле масштабування</string>
|
||||||
|
|||||||
@@ -578,7 +578,7 @@
|
|||||||
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
|
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
|
||||||
<string name="skip_cpu_inner_invalidation_description">在更新内存时跳过某些 CPU 端的缓存失效操作,从而降低 CPU 占用率并提升性能。可能会在某些游戏中引发故障点或崩溃。</string>
|
<string name="skip_cpu_inner_invalidation_description">在更新内存时跳过某些 CPU 端的缓存失效操作,从而降低 CPU 占用率并提升性能。可能会在某些游戏中引发故障点或崩溃。</string>
|
||||||
<string name="fix_bloom_effects">修复 Bloom 效果</string>
|
<string name="fix_bloom_effects">修复 Bloom 效果</string>
|
||||||
<string name="fix_bloom_effects_description">减少《智慧的再现》和《众神的三角力量2》(Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现图形异常。</string>
|
<string name="fix_bloom_effects_description">去除《火爆狂飙》中的泛光特效。</string>
|
||||||
<string name="emulate_bgr565">模拟 BGR565</string>
|
<string name="emulate_bgr565">模拟 BGR565</string>
|
||||||
<string name="emulate_bgr565_description">修复游戏中的颜色反转或是异常的画面瑕疵或阴影问题</string>
|
<string name="emulate_bgr565_description">修复游戏中的颜色反转或是异常的画面瑕疵或阴影问题</string>
|
||||||
<string name="rescale_hack">启用旧版缩放处理</string>
|
<string name="rescale_hack">启用旧版缩放处理</string>
|
||||||
@@ -815,6 +815,12 @@
|
|||||||
<string name="preferences_graphics">图形</string>
|
<string name="preferences_graphics">图形</string>
|
||||||
<string name="preferences_graphics_description">精度等级、分辨率及着色器缓存</string>
|
<string name="preferences_graphics_description">精度等级、分辨率及着色器缓存</string>
|
||||||
<string name="quick_settings">快速设置</string>
|
<string name="quick_settings">快速设置</string>
|
||||||
|
<string name="cheats">作弊</string>
|
||||||
|
<string name="enable_all_cheats">开启所有作弊</string>
|
||||||
|
<string name="disable_all_cheats">关闭所有作弊</string>
|
||||||
|
<string name="unnamed_cheat">未命名的作弊</string>
|
||||||
|
<string name="enable_cheats_by_default">默认开启作弊</string>
|
||||||
|
<string name="enable_cheats_by_default_description">在游戏启动时启用常规作弊</string>
|
||||||
<string name="enable_quick_settings">启用快速设置</string>
|
<string name="enable_quick_settings">启用快速设置</string>
|
||||||
<string name="enable_quick_settings_description">允许通过滑动和菜单按钮访问快速设置菜单</string>
|
<string name="enable_quick_settings_description">允许通过滑动和菜单按钮访问快速设置菜单</string>
|
||||||
<string name="preferences_audio">声音</string>
|
<string name="preferences_audio">声音</string>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
<string name="input_overlay_options">虛擬按鍵設定</string>
|
<string name="input_overlay_options">虛擬按鍵設定</string>
|
||||||
<string name="input_overlay_options_description">調整虛擬按鍵的位置與顯示設定</string>
|
<string name="input_overlay_options_description">調整虛擬按鍵的位置與顯示設定</string>
|
||||||
<string name="edit_overlay_layout">編輯虛擬按鍵</string>
|
<string name="edit_overlay_layout">調整虛擬按鍵</string>
|
||||||
<string name="edit_overlay_layout_description">調整虛擬按鍵的位置和大小</string>
|
<string name="edit_overlay_layout_description">調整虛擬按鍵的位置和大小</string>
|
||||||
|
|
||||||
|
|
||||||
@@ -253,8 +253,8 @@
|
|||||||
<string name="install_firmware_warning">跳過安裝韌體?</string>
|
<string name="install_firmware_warning">跳過安裝韌體?</string>
|
||||||
<string name="emulator_data">設定模擬器資料</string>
|
<string name="emulator_data">設定模擬器資料</string>
|
||||||
<string name="emulator_data_description">模擬器需要金鑰才能正常執行,同時建議安裝韌體以啟動 QLaunch 小程式</string>
|
<string name="emulator_data_description">模擬器需要金鑰才能正常執行,同時建議安裝韌體以啟動 QLaunch 小程式</string>
|
||||||
<string name="permissions">授予權限</string>
|
<string name="permissions">授予通知權限</string>
|
||||||
<string name="permissions_description">授予權限以使用模擬器的特定功能</string>
|
<string name="permissions_description">授予 Eden 傳送通知的權限以使用模擬器的特定功能</string>
|
||||||
<string name="install_firmware_warning_description">許多遊戲需要韌體才能正常運作</string>
|
<string name="install_firmware_warning_description">許多遊戲需要韌體才能正常運作</string>
|
||||||
<string name="install_firmware_warning_help">https://yuzu-mirror.github.io/help/quickstart/#guide-introduction</string>
|
<string name="install_firmware_warning_help">https://yuzu-mirror.github.io/help/quickstart/#guide-introduction</string>
|
||||||
<string name="notifications">通知</string>
|
<string name="notifications">通知</string>
|
||||||
@@ -268,8 +268,8 @@
|
|||||||
<string name="device_manufacturer">製造商</string>
|
<string name="device_manufacturer">製造商</string>
|
||||||
<string name="device_model">型號</string>
|
<string name="device_model">型號</string>
|
||||||
<string name="product">型號代碼</string>
|
<string name="product">型號代碼</string>
|
||||||
<string name="android_version">安卓版本</string>
|
<string name="android_version">Android 版本</string>
|
||||||
<string name="android_security_patch">安卓安全性修補程式等級</string>
|
<string name="android_security_patch">Android 安全性修補程式等級</string>
|
||||||
<string name="build_id">版本號碼</string>
|
<string name="build_id">版本號碼</string>
|
||||||
<string name="general_information">基本資訊</string>
|
<string name="general_information">基本資訊</string>
|
||||||
<string name="hardware">硬體</string>
|
<string name="hardware">硬體</string>
|
||||||
@@ -287,7 +287,7 @@
|
|||||||
<string name="warning_skip">跳過</string>
|
<string name="warning_skip">跳過</string>
|
||||||
<string name="warning_cancel">取消</string>
|
<string name="warning_cancel">取消</string>
|
||||||
<string name="install_amiibo_keys">安裝 Amiibo 金鑰</string>
|
<string name="install_amiibo_keys">安裝 Amiibo 金鑰</string>
|
||||||
<string name="install_amiibo_keys_description">需要先安裝才能在遊戲中使用 Amiibo</string>
|
<string name="install_amiibo_keys_description">安裝 Amiibo 以在日後遊玩時使用</string>
|
||||||
<string name="gpu_driver_fetcher">GPU 驅動程式下載器</string>
|
<string name="gpu_driver_fetcher">GPU 驅動程式下載器</string>
|
||||||
<string name="gpu_driver_manager">GPU 驅動程式管理員</string>
|
<string name="gpu_driver_manager">GPU 驅動程式管理員</string>
|
||||||
<string name="install_gpu_driver_description">安裝替代驅動程式以取得潛在的更佳效能或準確度</string>
|
<string name="install_gpu_driver_description">安裝替代驅動程式以取得潛在的更佳效能或準確度</string>
|
||||||
@@ -417,17 +417,17 @@
|
|||||||
<string name="custom_driver_not_supported">您的裝置不支援自訂驅動程式</string>
|
<string name="custom_driver_not_supported">您的裝置不支援自訂驅動程式</string>
|
||||||
<string name="custom_driver_not_supported_description">此裝置不支援注入自訂驅動程式\n請以後再來查看是否已新增支援!</string>
|
<string name="custom_driver_not_supported_description">此裝置不支援注入自訂驅動程式\n請以後再來查看是否已新增支援!</string>
|
||||||
<string name="manage_yuzu_data">管理 Eden 資料</string>
|
<string name="manage_yuzu_data">管理 Eden 資料</string>
|
||||||
<string name="manage_yuzu_data_description">安裝韌體、金鑰,導入/導出使用者資料及安裝其它項目!</string>
|
<string name="manage_yuzu_data_description">安裝韌體、金鑰,匯入/匯出使用者資料及安裝其它項目!</string>
|
||||||
<string name="game_folders">遊戲資料夾</string>
|
<string name="game_folders">遊戲資料夾</string>
|
||||||
<string name="deep_scan">深度掃描</string>
|
<string name="deep_scan">深度掃描</string>
|
||||||
<string name="add_game_folder">新增遊戲資料夾</string>
|
<string name="add_game_folder">新增遊戲資料夾</string>
|
||||||
<string name="folder_already_added">這個資料夾已經新增過了!</string>
|
<string name="folder_already_added">這個資料夾已經新增過了!</string>
|
||||||
<string name="game_folder_properties">遊戲資料夾設定</string>
|
<string name="game_folder_properties">遊戲資料夾設定</string>
|
||||||
<plurals name="saves_import_failed">
|
<plurals name="saves_import_failed">
|
||||||
<item quantity="other">%d 個存檔導入失敗</item>
|
<item quantity="other">%d 個存檔匯入失敗</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="saves_import_success">
|
<plurals name="saves_import_success">
|
||||||
<item quantity="other">成功導入 %d 個存檔</item>
|
<item quantity="other">成功匯入 %d 個存檔</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="no_save_data_found">找不到儲存資料</string>
|
<string name="no_save_data_found">找不到儲存資料</string>
|
||||||
<string name="verify_installed_content">驗證已安裝內容的完整性</string>
|
<string name="verify_installed_content">驗證已安裝內容的完整性</string>
|
||||||
@@ -451,7 +451,7 @@
|
|||||||
|
|
||||||
<!-- Applet launcher strings -->
|
<!-- Applet launcher strings -->
|
||||||
<string name="qlaunch_applet">Qlaunch</string>
|
<string name="qlaunch_applet">Qlaunch</string>
|
||||||
<string name="qlaunch_description">從 Switch 系統主畫面啟動應用程式(目前僅支援英文)</string>
|
<string name="qlaunch_description">從 Switch 系統主畫面啟動應用程式(目前模擬區域尚不支援臺灣、澳洲、中國、南韓啟動 Qlaunch)</string>
|
||||||
<string name="applets">小程式啟動器</string>
|
<string name="applets">小程式啟動器</string>
|
||||||
<string name="applets_description">使用已安裝的韌體啟動系統小程式</string>
|
<string name="applets_description">使用已安裝的韌體啟動系統小程式</string>
|
||||||
<string name="applets_error_firmware">未安裝韌體</string>
|
<string name="applets_error_firmware">未安裝韌體</string>
|
||||||
@@ -578,7 +578,7 @@
|
|||||||
<string name="skip_cpu_inner_invalidation">跳過 CPU 內部失效處理</string>
|
<string name="skip_cpu_inner_invalidation">跳過 CPU 內部失效處理</string>
|
||||||
<string name="skip_cpu_inner_invalidation_description">在記憶體更新期間跳過某些 CPU 端快取的失效處理,減少 CPU 使用率並提高其性能。可能會導致某些遊戲出現故障或當機</string>
|
<string name="skip_cpu_inner_invalidation_description">在記憶體更新期間跳過某些 CPU 端快取的失效處理,減少 CPU 使用率並提高其性能。可能會導致某些遊戲出現故障或當機</string>
|
||||||
<string name="fix_bloom_effects">修正光暈特效</string>
|
<string name="fix_bloom_effects">修正光暈特效</string>
|
||||||
<string name="fix_bloom_effects_description">在 \"薩爾達傳說:織夢島\" 和 \"薩爾達傳說:智慧的再現\" 中減少光暈模糊的問題並移除 \"橫衝直撞:狂飆樂園重製版\" 中的光暈效果(適用於 Adreno A6XX - A7XX/ Turnip)。警告:可能會在其它遊戲中導致圖形異常</string>
|
<string name="fix_bloom_effects_description">移除《橫衝直撞:狂飆樂園重製版》中的光暈效果</string>
|
||||||
<string name="emulate_bgr565">模擬 BGR565</string>
|
<string name="emulate_bgr565">模擬 BGR565</string>
|
||||||
<string name="emulate_bgr565_description">修正遊戲中出現的色彩反轉、圖形異常或陰影異常</string>
|
<string name="emulate_bgr565_description">修正遊戲中出現的色彩反轉、圖形異常或陰影異常</string>
|
||||||
<string name="rescale_hack">啟用舊版重新縮放處理</string>
|
<string name="rescale_hack">啟用舊版重新縮放處理</string>
|
||||||
@@ -601,7 +601,7 @@
|
|||||||
<string name="extensions">擴充功能</string>
|
<string name="extensions">擴充功能</string>
|
||||||
|
|
||||||
<string name="dyna_state">擴展動態狀態</string>
|
<string name="dyna_state">擴展動態狀態</string>
|
||||||
<string name="dyna_state_description">控制擴展動態狀態中可使用的功能數量,較高的數值可根據驅動程式支援的動態狀態減少管線編譯的次數</string>
|
<string name="dyna_state_description">控制 Vulkan 擴展動態狀態中可使用的功能數量,較高的數值可根據驅動程式支援的動態狀態減少管線編譯的次數</string>
|
||||||
<string name="disabled">停用</string>
|
<string name="disabled">停用</string>
|
||||||
<string name="vertex_input_dynamic_state">頂點輸入動態狀態</string>
|
<string name="vertex_input_dynamic_state">頂點輸入動態狀態</string>
|
||||||
<string name="vertex_input_dynamic_state_description">啟用此功能可提供更彈性的頂點輸入處理方式,並可能減少頂點/緩衝區的管線編譯時間</string>
|
<string name="vertex_input_dynamic_state_description">啟用此功能可提供更彈性的頂點輸入處理方式,並可能減少頂點/緩衝區的管線編譯時間</string>
|
||||||
@@ -806,7 +806,7 @@
|
|||||||
<string name="recommended_driver">推薦驅動程式:</string>
|
<string name="recommended_driver">推薦驅動程式:</string>
|
||||||
<string name="gpu_model">GPU 型號</string>
|
<string name="gpu_model">GPU 型號</string>
|
||||||
<string name="unsupported_gpu">不支援的 GPU</string>
|
<string name="unsupported_gpu">不支援的 GPU</string>
|
||||||
<string name="unsupported_gpu_warning">您的 GPU 不支援驅動程式注入,不建議嘗試設定自訂驅動程式</string>
|
<string name="unsupported_gpu_warning">您的 GPU 不支援驅動程式注入,不建議嘗試安裝自訂驅動程式</string>
|
||||||
|
|
||||||
<!-- Preferences Screen -->
|
<!-- Preferences Screen -->
|
||||||
<string name="preferences_settings">設定</string>
|
<string name="preferences_settings">設定</string>
|
||||||
@@ -815,6 +815,12 @@
|
|||||||
<string name="preferences_graphics">圖形</string>
|
<string name="preferences_graphics">圖形</string>
|
||||||
<string name="preferences_graphics_description">準確度層級、解析度及著色器快取</string>
|
<string name="preferences_graphics_description">準確度層級、解析度及著色器快取</string>
|
||||||
<string name="quick_settings">快捷設定</string>
|
<string name="quick_settings">快捷設定</string>
|
||||||
|
<string name="cheats">金手指</string>
|
||||||
|
<string name="enable_all_cheats">啟用所有金手指</string>
|
||||||
|
<string name="disable_all_cheats">停用所有金手指</string>
|
||||||
|
<string name="unnamed_cheat">未命名的金手指</string>
|
||||||
|
<string name="enable_cheats_by_default">預設啟用金手指</string>
|
||||||
|
<string name="enable_cheats_by_default_description">在遊戲啟動時啟用一般金手指</string>
|
||||||
<string name="enable_quick_settings">啟用快捷設定</string>
|
<string name="enable_quick_settings">啟用快捷設定</string>
|
||||||
<string name="enable_quick_settings_description">允許透過滑動和選單按鈕存取快捷設定選單</string>
|
<string name="enable_quick_settings_description">允許透過滑動和選單按鈕存取快捷設定選單</string>
|
||||||
<string name="preferences_audio">音訊</string>
|
<string name="preferences_audio">音訊</string>
|
||||||
@@ -831,9 +837,9 @@
|
|||||||
<string name="custom_save_directory">遊戲儲存資料路徑</string>
|
<string name="custom_save_directory">遊戲儲存資料路徑</string>
|
||||||
<string name="custom_save_directory_description">設定遊戲儲存資料的自訂路徑</string>
|
<string name="custom_save_directory_description">設定遊戲儲存資料的自訂路徑</string>
|
||||||
<string name="reset_to_nand">重設為預設值</string>
|
<string name="reset_to_nand">重設為預設值</string>
|
||||||
<string name="migrate_save_data">遷移儲存資料</string>
|
<string name="migrate_save_data">移動儲存資料</string>
|
||||||
<string name="migrate_save_data_question">您要將現有的儲存資料移至新位置嗎?</string>
|
<string name="migrate_save_data_question">您要將現有的儲存資料移至新位置嗎?</string>
|
||||||
<string name="save_migration_complete">成功遷移儲存資料</string>
|
<string name="save_migration_complete">儲存資料遷移成功</string>
|
||||||
<string name="save_migration_failed">儲存資料遷移失敗</string>
|
<string name="save_migration_failed">儲存資料遷移失敗</string>
|
||||||
<string name="save_directory_set">存檔目錄設定完成</string>
|
<string name="save_directory_set">存檔目錄設定完成</string>
|
||||||
<string name="destination_has_saves">所選取的位置已有儲存資料,是否要取代該檔案?</string>
|
<string name="destination_has_saves">所選取的位置已有儲存資料,是否要取代該檔案?</string>
|
||||||
@@ -889,10 +895,10 @@
|
|||||||
<string name="save_data_deleted_successfully">儲存資料已成功刪除</string>
|
<string name="save_data_deleted_successfully">儲存資料已成功刪除</string>
|
||||||
<string name="select_content_type">內容類型</string>
|
<string name="select_content_type">內容類型</string>
|
||||||
<string name="updates_and_dlc">更新及 DLC</string>
|
<string name="updates_and_dlc">更新及 DLC</string>
|
||||||
<string name="mods_and_cheats">模組及金手指</string>
|
<string name="mods_and_cheats">Mod 和金手指</string>
|
||||||
<string name="addon_notice">重要的˙附加元件通知</string>
|
<string name="addon_notice">注意!</string>
|
||||||
<!-- \"cheats/" "romfs/" and \"exefs/ should not be translated -->
|
<!-- \"cheats/" "romfs/" and \"exefs/ should not be translated -->
|
||||||
<string name="addon_notice_description">若要安裝模組及金手指,您必須選擇一個包含 cheats/、romfs/ 或 exefs/ 的目錄。我們無法驗證這些內容是否與您的遊戲相容,所以請謹慎安裝!</string>
|
<string name="addon_notice_description">若要安裝 Mod 和金手指,您必須選擇一個包含 cheats/、romfs/ 或 exefs/ 的目錄。我們無法驗證這些內容是否與您的遊戲相容,所以請謹慎安裝!</string>
|
||||||
<string name="invalid_directory">無效的目錄</string>
|
<string name="invalid_directory">無效的目錄</string>
|
||||||
<!-- \"cheats/" "romfs/" and \"exefs/ should not be translated -->
|
<!-- \"cheats/" "romfs/" and \"exefs/ should not be translated -->
|
||||||
<string name="invalid_directory_description">請確保您選取的目錄包含 cheats/、romfs/ 或 exefs/ 資料夾,然後再試一次</string>
|
<string name="invalid_directory_description">請確保您選取的目錄包含 cheats/、romfs/ 或 exefs/ 資料夾,然後再試一次</string>
|
||||||
@@ -979,7 +985,7 @@
|
|||||||
<string name="emulation_pause">暫停模擬</string>
|
<string name="emulation_pause">暫停模擬</string>
|
||||||
<string name="emulation_unpause">繼續模擬</string>
|
<string name="emulation_unpause">繼續模擬</string>
|
||||||
<string name="emulation_input_overlay">疊加層/虛擬按鍵設定</string>
|
<string name="emulation_input_overlay">疊加層/虛擬按鍵設定</string>
|
||||||
<string name="load_amiibo">導入 Amiibo</string>
|
<string name="load_amiibo">匯入 Amiibo</string>
|
||||||
<string name="touchscreen">觸控螢幕</string>
|
<string name="touchscreen">觸控螢幕</string>
|
||||||
<string name="lock_drawer">鎖定側邊選單</string>
|
<string name="lock_drawer">鎖定側邊選單</string>
|
||||||
<string name="unlock_drawer">解鎖側邊選單</string>
|
<string name="unlock_drawer">解鎖側邊選單</string>
|
||||||
@@ -1126,6 +1132,16 @@
|
|||||||
<string name="freedreno_clear_all">全部清除</string>
|
<string name="freedreno_clear_all">全部清除</string>
|
||||||
<string name="freedreno_saved">Freedreno 設定已儲存</string>
|
<string name="freedreno_saved">Freedreno 設定已儲存</string>
|
||||||
<string name="freedreno_cleared_all">已清除所有 Freedreno 變數</string>
|
<string name="freedreno_cleared_all">已清除所有 Freedreno 變數</string>
|
||||||
|
<string name="freedreno_variable_added">變數 %1$s 已新增</string>
|
||||||
|
<string name="freedreno_preset_applied">設定檔 \"%1$s\" 已套用</string>
|
||||||
|
<string name="freedreno_error_empty_name">變數名稱不可空白</string>
|
||||||
|
<string name="freedreno_error_setting_variable">變數設定失敗</string>
|
||||||
|
<string name="freedreno_info_title">關於 Freedreno 設定</string>
|
||||||
|
<string name="freedreno_info_description">透過調整 Freedreno/Turnip GPU 驅動程式的設定來偵錯、分析和最佳化效能,會自動儲存變更。詳情請參閱 https://docs.mesa3d.org/drivers/freedreno.html</string>
|
||||||
|
<string name="freedreno_per_game_title">Freedreno 設定</string>
|
||||||
|
<string name="freedreno_per_game_description">調整此遊戲的 GPU 驅動程式設定</string>
|
||||||
|
<string name="freedreno_per_game_saved">Freedreno 設定已儲存</string>
|
||||||
|
|
||||||
<!-- Gamepad Buttons -->
|
<!-- Gamepad Buttons -->
|
||||||
<string name="gamepad_d_pad">方向鍵</string>
|
<string name="gamepad_d_pad">方向鍵</string>
|
||||||
<string name="gamepad_left_stick">左搖桿</string>
|
<string name="gamepad_left_stick">左搖桿</string>
|
||||||
@@ -1134,14 +1150,17 @@
|
|||||||
<string name="gamepad_screenshot">螢幕截圖</string>
|
<string name="gamepad_screenshot">螢幕截圖</string>
|
||||||
|
|
||||||
<!-- Disk shader cache -->
|
<!-- Disk shader cache -->
|
||||||
<string name="building_shaders">正在建置著色器</string>
|
<string name="building_shaders">正在編譯著色器</string>
|
||||||
|
|
||||||
<!-- App options -->
|
<!-- App options -->
|
||||||
<string name="change_app_theme">變更應用程式主題</string>
|
<string name="change_app_theme">變更應用程式主題</string>
|
||||||
<string name="theme_default">預設</string>
|
<string name="theme_default">預設</string>
|
||||||
<string name="theme_material_you">質感設計3</string>
|
<string name="theme_material_you">Material You</string>
|
||||||
<string name="app_settings">Eden 介面設定</string>
|
<string name="app_settings">Eden 介面設定</string>
|
||||||
<string name="theme_and_color">主題和顏色</string>
|
<string name="theme_and_color">主題和顏色</string>
|
||||||
|
<string name="fullscreen_mode">全螢幕模式</string>
|
||||||
|
<string name="fullscreen_mode_description">在使用 Eden 時隱藏 Android 系統的導覽列,在直向時從螢幕底部往上滑以暫時顯示它們;橫向時則從螢幕側邊往內滑動</string>
|
||||||
|
|
||||||
<!-- Theme Modes -->
|
<!-- Theme Modes -->
|
||||||
<string name="change_theme_mode">變更主題模式</string>
|
<string name="change_theme_mode">變更主題模式</string>
|
||||||
<string name="theme_mode_follow_system">跟隨系統</string>
|
<string name="theme_mode_follow_system">跟隨系統</string>
|
||||||
@@ -1150,7 +1169,13 @@
|
|||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">黑色背景</string>
|
<string name="use_black_backgrounds">黑色背景</string>
|
||||||
<string name="use_black_backgrounds_description">使用深色主題時,套用黑色背景。</string>
|
<string name="use_black_backgrounds_description">使用深色主題時套用黑色背景</string>
|
||||||
|
|
||||||
|
<!-- Buttons -->
|
||||||
|
<string name="enable_folder_button">遊戲資料夾</string>
|
||||||
|
<string name="enable_folder_button_description">在 Eden 首頁顯示新增遊戲資料夾的按鈕</string>
|
||||||
|
<string name="enable_qlaunch_button">QLaunch</string>
|
||||||
|
<string name="enable_qlaunch_button_description">在 Eden 首頁顯示 QLaunch 按鈕</string>
|
||||||
|
|
||||||
<!-- App Language -->
|
<!-- App Language -->
|
||||||
<string name="app_language">語言</string>
|
<string name="app_language">語言</string>
|
||||||
@@ -1158,10 +1183,12 @@
|
|||||||
<string name="app_language_system">跟隨系統</string>
|
<string name="app_language_system">跟隨系統</string>
|
||||||
<!-- Static Themes -->
|
<!-- Static Themes -->
|
||||||
<string name="static_theme_color">主題色彩</string>
|
<string name="static_theme_color">主題色彩</string>
|
||||||
|
<string name="eden_theme">Eden</string>
|
||||||
<string name="violet">紫色</string>
|
<string name="violet">紫色</string>
|
||||||
<string name="blue">藍色</string>
|
<string name="blue">藍色</string>
|
||||||
<string name="cyan">青色</string>
|
<string name="cyan">青色</string>
|
||||||
<string name="red">紅色</string>
|
<string name="red">紅色</string>
|
||||||
|
<string name="green">綠色</string>
|
||||||
<string name="yellow">黃色</string>
|
<string name="yellow">黃色</string>
|
||||||
<string name="orange">橘色</string>
|
<string name="orange">橘色</string>
|
||||||
<string name="pink">粉紅色</string>
|
<string name="pink">粉紅色</string>
|
||||||
@@ -1190,6 +1217,20 @@
|
|||||||
<string name="airplane_mode">飛航模式</string>
|
<string name="airplane_mode">飛航模式</string>
|
||||||
<string name="airplane_mode_description">將飛航模式傳遞給 Switch 作業系統</string>
|
<string name="airplane_mode_description">將飛航模式傳遞給 Switch 作業系統</string>
|
||||||
|
|
||||||
|
<string name="enable_overlay">啟用小程式虛擬按鍵</string>
|
||||||
|
<string name="enable_overlay_description">啟用 Horizon OS 內建的小程式虛擬按鍵,長按 Home 鍵 1 秒以顯示虛擬按鍵</string>
|
||||||
|
|
||||||
|
<!-- Profile Management -->
|
||||||
|
<string name="profile_manager">使用者管理</string>
|
||||||
|
<string name="profile_manager_description">更改使用者名稱、圖片及新增或刪除使用者</string>
|
||||||
|
<string name="profile_add_user">新增使用者</string>
|
||||||
|
<string name="profile_new_user">新增使用者</string>
|
||||||
|
<string name="profile_edit_user">編輯使用者資料</string>
|
||||||
|
<string name="profile_edit">編輯</string>
|
||||||
|
<string name="profile_delete">刪除</string>
|
||||||
|
<string name="profile_username">使用者名稱</string>
|
||||||
|
<string name="profile_uuid">使用者 ID (通用唯一辨識碼)</string>
|
||||||
|
<string name="profile_uuid_description">這是此使用者設定檔的唯一識別碼,建立後就無法進行更改</string>
|
||||||
<!-- Licenses screen strings -->
|
<!-- Licenses screen strings -->
|
||||||
<string name="licenses">授權</string>
|
<string name="licenses">授權</string>
|
||||||
<string name="license_fidelityfx_fsr_description">來自 AMD 的升級圖像品質</string>
|
<string name="license_fidelityfx_fsr_description">來自 AMD 的升級圖像品質</string>
|
||||||
|
|||||||
@@ -498,7 +498,7 @@
|
|||||||
<string name="user_data_import_failed_description">Make sure the user data folders are at the root of the zip folder and contain a config file at config/config.ini and try again.</string>
|
<string name="user_data_import_failed_description">Make sure the user data folders are at the root of the zip folder and contain a config file at config/config.ini and try again.</string>
|
||||||
<string name="discord_link" translatable="false">https://discord.gg/HstXbPch7X</string>
|
<string name="discord_link" translatable="false">https://discord.gg/HstXbPch7X</string>
|
||||||
<string name="stoat_link" translatable="false">https://stt.gg/qKgFEAbH</string>
|
<string name="stoat_link" translatable="false">https://stt.gg/qKgFEAbH</string>
|
||||||
<string name="x_link" translatable="false">https://nitter.poast.org/edenemuofficial</string>
|
<string name="x_link" translatable="false">https://x.com/edenemuofficial</string>
|
||||||
<string name="website_link" translatable="false">https://eden-emu.dev</string>
|
<string name="website_link" translatable="false">https://eden-emu.dev</string>
|
||||||
<string name="github_link" translatable="false">https://git.eden-emu.dev/eden-emu</string>
|
<string name="github_link" translatable="false">https://git.eden-emu.dev/eden-emu</string>
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,25 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/bit_util.h"
|
||||||
#include "common/fs/file.h"
|
#include "common/fs/file.h"
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
|
#include "common/fs/fs_types.h"
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#include "common/fs/fs_android.h"
|
#include "common/fs/fs_android.h"
|
||||||
#endif
|
#endif
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
|
#include "common/literals.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <share.h>
|
#include <share.h>
|
||||||
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@@ -244,42 +251,162 @@ FileType IOFile::GetType() const {
|
|||||||
return file_type;
|
return file_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__unix__)
|
||||||
|
static int PlatformMapReadOnly(IOFile& io, const char* path) {
|
||||||
|
io.mmap_fd = open(path, O_RDONLY);
|
||||||
|
if (io.mmap_fd > 0) {
|
||||||
|
struct stat st;
|
||||||
|
fstat(io.mmap_fd, &st);
|
||||||
|
io.mmap_size = st.st_size;
|
||||||
|
|
||||||
|
int map_flags = MAP_PRIVATE;
|
||||||
|
#ifdef MAP_PREFAULT_READ
|
||||||
|
// Prefaults reads so the final resulting pagetable from this big stupid mmap()
|
||||||
|
// isn't comically lazily loaded, we just coalesce everything in-place for our
|
||||||
|
// lovely mmap flags; if we didn't prefault the reads the page table will be
|
||||||
|
// constructed in-place (i.e on a read-by-read basis) causing lovely soft-faults
|
||||||
|
// which would nuke any performance gains.
|
||||||
|
//
|
||||||
|
// This of course incurs a cost in the initial mmap(2) call, but that is fine.
|
||||||
|
map_flags |= MAP_PREFAULT_READ;
|
||||||
|
#endif
|
||||||
|
#ifdef MAP_NOSYNC
|
||||||
|
// This causes physical media to not be synched to our file/memory
|
||||||
|
// This means that if the read-only file is written to, we won't see changes
|
||||||
|
// or we may see changes which are just funnily scattered, in any case
|
||||||
|
// this presumes the files won't be changed during execution
|
||||||
|
//
|
||||||
|
// Do not ever use this on write files (if we ever support that); this will create
|
||||||
|
// a fun amount of fragmentation on the disk.
|
||||||
|
map_flags |= MAP_NOSYNC;
|
||||||
|
#endif
|
||||||
|
#if defined(NDEBUG) && defined(MAP_NOCORE)
|
||||||
|
map_flags |= MAP_NOCORE;
|
||||||
|
#endif
|
||||||
|
#ifdef MAP_HUGE_2MB
|
||||||
|
map_flags |= MAP_HUGE_2MB; //2mb pages
|
||||||
|
#elif defined(MAP_ALIGNED)
|
||||||
|
// File must be big enough that it's worth to super align. We can't just super-align every
|
||||||
|
// file otherwise we will run out of alignments for actually important files :)
|
||||||
|
// System doesn't guarantee a super alignment, but if it's available it will delete
|
||||||
|
// about 3 layers(?) of the TLB tree for each read/write.
|
||||||
|
// Again the cost of faults may make this negligible gains, but hey, we gotta work
|
||||||
|
// what we gotta work with.
|
||||||
|
map_flags |= MAP_ALIGNED(21); //2^21 = 2mb use 2MB pages
|
||||||
|
#endif
|
||||||
|
io.mmap_base = (u8*)mmap(nullptr, io.mmap_size, PROT_READ, map_flags, io.mmap_fd, 0);
|
||||||
|
if (io.mmap_base == MAP_FAILED) {
|
||||||
|
close(io.mmap_fd);
|
||||||
|
io.mmap_fd = -1;
|
||||||
|
} else {
|
||||||
|
using namespace Common::Literals;
|
||||||
|
// For small files it is acceptable to use a full readahead
|
||||||
|
// See https://github.com/torvalds/linux/blob/e80d033851b3bc94c3d254ac66660ddd0a49d72c/include/linux/pagemap.h#L1392
|
||||||
|
if (u64(st.st_size) >= 256_MiB) {
|
||||||
|
posix_madvise(io.mmap_base, io.mmap_size, POSIX_MADV_RANDOM);
|
||||||
|
} else {
|
||||||
|
posix_madvise(io.mmap_base, io.mmap_size, POSIX_MADV_SEQUENTIAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return io.mmap_fd;
|
||||||
|
}
|
||||||
|
static void PlatformUnmap(IOFile& io) {
|
||||||
|
if (io.mmap_fd != -1) {
|
||||||
|
munmap(io.mmap_base, io.mmap_size);
|
||||||
|
close(io.mmap_fd);
|
||||||
|
io.mmap_fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
// NO IMPLEMENTATION YET
|
||||||
|
#else
|
||||||
|
static int PlatformMapReadOnly(IOFile& io, const wchar_t* path) {
|
||||||
|
io.file_handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
|
||||||
|
if (HANDLE(io.file_handle) != INVALID_HANDLE_VALUE) {
|
||||||
|
io.mapping_handle = CreateFileMappingW(HANDLE(io.file_handle), nullptr, PAGE_READONLY, 0, 0, nullptr);
|
||||||
|
if (io.mapping_handle) {
|
||||||
|
io.mmap_base = (u8*)MapViewOfFile(HANDLE(io.mapping_handle), FILE_MAP_READ, 0, 0, 0);
|
||||||
|
if (io.mmap_base) {
|
||||||
|
_LARGE_INTEGER pvalue;
|
||||||
|
GetFileSizeEx(io.file_handle, &pvalue);
|
||||||
|
io.mmap_size = uint32_t(pvalue.QuadPart);
|
||||||
|
} else {
|
||||||
|
CloseHandle(io.mapping_handle);
|
||||||
|
CloseHandle(io.file_handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CloseHandle(io.file_handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void PlatformUnmap(IOFile& io) {
|
||||||
|
if(io.mapping_handle) {
|
||||||
|
if(io.mmap_base)
|
||||||
|
UnmapViewOfFile(HANDLE(io.mmap_base));
|
||||||
|
CloseHandle(HANDLE(io.mapping_handle));
|
||||||
|
}
|
||||||
|
if(io.file_handle != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(HANDLE(io.file_handle));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, FileShareFlag flag) {
|
void IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, FileShareFlag flag) {
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
file_path = path;
|
file_path = path;
|
||||||
file_access_mode = mode;
|
file_access_mode = mode;
|
||||||
file_type = type;
|
file_type = type;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
// TODO: this probably can use better logic but oh well I'm not a windowser
|
||||||
|
file_handle = nullptr;
|
||||||
|
if (type == FileType::BinaryFile && mode == FileAccessMode::Read) {
|
||||||
|
if (PlatformMapReadOnly(*this, path.c_str()) == -1) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Error mmap'ing file"); //: {}", path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (file_handle == nullptr) {
|
||||||
if (flag != FileShareFlag::ShareNone) {
|
if (flag != FileShareFlag::ShareNone) {
|
||||||
file = _wfsopen(path.c_str(), AccessModeToWStr(mode, type), ToWindowsFileShareFlag(flag));
|
file = _wfsopen(path.c_str(), AccessModeToWStr(mode, type), ToWindowsFileShareFlag(flag));
|
||||||
} else {
|
} else {
|
||||||
_wfopen_s(&file, path.c_str(), AccessModeToWStr(mode, type));
|
_wfopen_s(&file, path.c_str(), AccessModeToWStr(mode, type));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#elif __ANDROID__
|
#elif __ANDROID__
|
||||||
if (Android::IsContentUri(path)) {
|
if (Android::IsContentUri(path)) {
|
||||||
ASSERT_MSG(mode == FileAccessMode::Read, "Content URI file access is for read-only!");
|
ASSERT_MSG(mode == FileAccessMode::Read, "Content URI file access is for read-only!");
|
||||||
const auto fd = Android::OpenContentUri(path, Android::OpenMode::Read);
|
if (PlatformMapReadOnly(*this, path.c_str()) == -1) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Error mmap'ing file: {}", path.c_str());
|
||||||
|
int const fd = Android::OpenContentUri(path, Android::OpenMode::Read);
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
file = fdopen(fd, "r");
|
file = fdopen(fd, "r");
|
||||||
const auto error_num = errno;
|
if (errno != 0 && file == nullptr)
|
||||||
if (error_num != 0 && file == nullptr) {
|
LOG_ERROR(Common_Filesystem, "Error opening file: {}, error: {}", path.c_str(), strerror(errno));
|
||||||
LOG_ERROR(Common_Filesystem, "Error opening file: {}, error: {}", path.c_str(),
|
|
||||||
strerror(error_num));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(Common_Filesystem, "Error opening file: {}", path.c_str());
|
LOG_ERROR(Common_Filesystem, "Error opening file: {}", path.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
file = std::fopen(path.c_str(), AccessModeToStr(mode, type));
|
file = std::fopen(path.c_str(), AccessModeToStr(mode, type));
|
||||||
}
|
}
|
||||||
|
#elif defined(__HAIKU__) || defined(__managarm__) || defined(__OPENORBIS__) || defined(__APPLE__)
|
||||||
|
file = std::fopen(path.c_str(), AccessModeToStr(mode, type));
|
||||||
|
#elif defined(__unix__)
|
||||||
|
if (type == FileType::BinaryFile && mode == FileAccessMode::Read) {
|
||||||
|
if (PlatformMapReadOnly(*this, path.c_str()) == -1) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Error mmap'ing file: {}", path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mmap_fd == -1) {
|
||||||
|
file = std::fopen(path.c_str(), AccessModeToStr(mode, type)); // mmap(2) failed or simply we can't use it
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
// Some other fancy OS (ahem fucking Darwin/Mac OSX)
|
||||||
file = std::fopen(path.c_str(), AccessModeToStr(mode, type));
|
file = std::fopen(path.c_str(), AccessModeToStr(mode, type));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (!IsOpen()) {
|
||||||
const auto ec = std::error_code{errno, std::generic_category()};
|
const auto ec = std::error_code{errno, std::generic_category()};
|
||||||
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, ec_message={}",
|
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, ec_message={}",
|
||||||
@@ -288,25 +415,25 @@ void IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, File
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IOFile::Close() {
|
void IOFile::Close() {
|
||||||
if (!IsOpen()) {
|
#if defined(__APPLE__)
|
||||||
return;
|
// NO IMPLEMENTATION YET
|
||||||
}
|
#else
|
||||||
|
PlatformUnmap(*this);
|
||||||
|
#endif
|
||||||
|
if (file) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
const auto close_result = std::fclose(file) == 0;
|
const auto close_result = std::fclose(file) == 0;
|
||||||
|
|
||||||
if (!close_result) {
|
if (!close_result) {
|
||||||
const auto ec = std::error_code{errno, std::generic_category()};
|
const auto ec = std::error_code{errno, std::generic_category()};
|
||||||
LOG_ERROR(Common_Filesystem, "Failed to close the file at path={}, ec_message={}",
|
LOG_ERROR(Common_Filesystem, "Failed to close the file at path={}, ec_message={}",
|
||||||
PathToUTF8String(file_path), ec.message());
|
PathToUTF8String(file_path), ec.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
file = nullptr;
|
file = nullptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IOFile::IsOpen() const {
|
bool IOFile::IsOpen() const {
|
||||||
return file != nullptr;
|
return file != nullptr || IsMappedFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IOFile::ReadString(size_t length) const {
|
std::string IOFile::ReadString(size_t length) const {
|
||||||
@@ -323,80 +450,65 @@ size_t IOFile::WriteString(std::span<const char> string) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Flush() const {
|
bool IOFile::Flush() const {
|
||||||
if (!IsOpen()) {
|
ASSERT(!IsMappedFile());
|
||||||
return false;
|
if (file) {
|
||||||
}
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
auto const flush_result = std::fflush(file) == 0;
|
||||||
#ifdef _WIN32
|
|
||||||
const auto flush_result = std::fflush(file) == 0;
|
|
||||||
#else
|
|
||||||
const auto flush_result = std::fflush(file) == 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!flush_result) {
|
if (!flush_result) {
|
||||||
const auto ec = std::error_code{errno, std::generic_category()};
|
const auto ec = std::error_code{errno, std::generic_category()};
|
||||||
LOG_ERROR(Common_Filesystem, "Failed to flush the file at path={}, ec_message={}",
|
LOG_ERROR(Common_Filesystem, "Failed to flush the file at path={}, ec_message={}",
|
||||||
PathToUTF8String(file_path), ec.message());
|
PathToUTF8String(file_path), ec.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
return flush_result;
|
return flush_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Commit() const {
|
|
||||||
if (!IsOpen()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IOFile::Commit() const {
|
||||||
|
ASSERT(!IsMappedFile());
|
||||||
|
if (file) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
const auto commit_result = std::fflush(file) == 0 && _commit(fileno(file)) == 0;
|
const auto commit_result = std::fflush(file) == 0 && _commit(fileno(file)) == 0;
|
||||||
#else
|
#else
|
||||||
const auto commit_result = std::fflush(file) == 0 && fsync(fileno(file)) == 0;
|
const auto commit_result = std::fflush(file) == 0 && fsync(fileno(file)) == 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!commit_result) {
|
if (!commit_result) {
|
||||||
const auto ec = std::error_code{errno, std::generic_category()};
|
const auto ec = std::error_code{errno, std::generic_category()};
|
||||||
LOG_ERROR(Common_Filesystem, "Failed to commit the file at path={}, ec_message={}",
|
LOG_ERROR(Common_Filesystem, "Failed to commit the file at path={}, ec_message={}",
|
||||||
PathToUTF8String(file_path), ec.message());
|
PathToUTF8String(file_path), ec.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
return commit_result;
|
return commit_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::SetSize(u64 size) const {
|
|
||||||
if (!IsOpen()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IOFile::SetSize(u64 size) const {
|
||||||
|
ASSERT(!IsMappedFile());
|
||||||
|
if (file) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
const auto set_size_result = _chsize_s(fileno(file), static_cast<s64>(size)) == 0;
|
const auto set_size_result = _chsize_s(fileno(file), s64(size)) == 0;
|
||||||
#else
|
#else
|
||||||
const auto set_size_result = ftruncate(fileno(file), static_cast<s64>(size)) == 0;
|
const auto set_size_result = ftruncate(fileno(file), s64(size)) == 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!set_size_result) {
|
if (!set_size_result) {
|
||||||
const auto ec = std::error_code{errno, std::generic_category()};
|
const auto ec = std::error_code{errno, std::generic_category()};
|
||||||
LOG_ERROR(Common_Filesystem, "Failed to resize the file at path={}, size={}, ec_message={}",
|
LOG_ERROR(Common_Filesystem, "Failed to resize the file at path={}, size={}, ec_message={}",
|
||||||
PathToUTF8String(file_path), size, ec.message());
|
PathToUTF8String(file_path), size, ec.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
return set_size_result;
|
return set_size_result;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
u64 IOFile::GetSize() const {
|
u64 IOFile::GetSize() const {
|
||||||
if (!IsOpen()) {
|
if (IsMappedFile())
|
||||||
return 0;
|
return mmap_size;
|
||||||
}
|
if (file) {
|
||||||
|
// Flush any unwritten buffered data into the file prior to retrieving the file mmap_size.
|
||||||
// Flush any unwritten buffered data into the file prior to retrieving the file size.
|
|
||||||
std::fflush(file);
|
std::fflush(file);
|
||||||
|
#if __ANDROID__
|
||||||
#ifdef __ANDROID__
|
|
||||||
u64 file_size = 0;
|
u64 file_size = 0;
|
||||||
if (Android::IsContentUri(file_path)) {
|
if (Android::IsContentUri(file_path)) {
|
||||||
file_size = Android::GetSize(file_path);
|
file_size = Android::GetSize(file_path);
|
||||||
@@ -406,54 +518,64 @@ u64 IOFile::GetSize() const {
|
|||||||
file_size = fs::file_size(file_path, ec);
|
file_size = fs::file_size(file_path, ec);
|
||||||
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
LOG_ERROR(Common_Filesystem,
|
LOG_ERROR(Common_Filesystem, "Failed to retrieve the file mmap_size of path={}, ec_message={}",
|
||||||
"Failed to retrieve the file size of path={}, ec_message={}",
|
|
||||||
PathToUTF8String(file_path), ec.message());
|
PathToUTF8String(file_path), ec.message());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
auto const file_size = fs::file_size(file_path, ec);
|
||||||
const auto file_size = fs::file_size(file_path, ec);
|
|
||||||
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
LOG_ERROR(Common_Filesystem, "Failed to retrieve the file size of path={}, ec_message={}",
|
LOG_ERROR(Common_Filesystem, "Failed to retrieve the file mmap_size of path={}, ec_message={}",
|
||||||
PathToUTF8String(file_path), ec.message());
|
PathToUTF8String(file_path), ec.message());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return file_size;
|
return file_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Seek(s64 offset, SeekOrigin origin) const {
|
|
||||||
if (!IsOpen()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
const auto seek_result = fseeko(file, offset, ToSeekOrigin(origin)) == 0;
|
|
||||||
|
|
||||||
if (!seek_result) {
|
|
||||||
const auto ec = std::error_code{errno, std::generic_category()};
|
|
||||||
LOG_ERROR(Common_Filesystem,
|
|
||||||
"Failed to seek the file at path={}, offset={}, origin={}, ec_message={}",
|
|
||||||
PathToUTF8String(file_path), offset, origin, ec.message());
|
|
||||||
}
|
|
||||||
|
|
||||||
return seek_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
s64 IOFile::Tell() const {
|
|
||||||
if (!IsOpen()) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IOFile::Seek(s64 offset, SeekOrigin origin) const {
|
||||||
|
if (IsMappedFile()) {
|
||||||
|
// fuck you to whoever made this method const
|
||||||
|
switch (origin) {
|
||||||
|
case SeekOrigin::SetOrigin:
|
||||||
|
mmap_offset = s64(offset);
|
||||||
|
break;
|
||||||
|
case SeekOrigin::CurrentPosition:
|
||||||
|
mmap_offset += s64(offset);
|
||||||
|
break;
|
||||||
|
case SeekOrigin::End:
|
||||||
|
mmap_offset = s64(mmap_size) + s64(offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (file) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
const auto seek_result = fseeko(file, offset, ToSeekOrigin(origin)) == 0;
|
||||||
|
if (!seek_result) {
|
||||||
|
const auto ec = std::error_code{errno, std::generic_category()};
|
||||||
|
LOG_ERROR(Common_Filesystem, "Failed to seek the file at path={}, offset={}, origin={}, ec_message={}",
|
||||||
|
PathToUTF8String(file_path), offset, origin, ec.message());
|
||||||
|
}
|
||||||
|
return seek_result;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 IOFile::Tell() const {
|
||||||
|
if (IsMappedFile()) {
|
||||||
|
errno = 0;
|
||||||
|
return s64(mmap_offset);
|
||||||
|
}
|
||||||
|
if (file) {
|
||||||
|
errno = 0;
|
||||||
return ftello(file);
|
return ftello(file);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -186,19 +187,6 @@ public:
|
|||||||
FileType type = FileType::BinaryFile,
|
FileType type = FileType::BinaryFile,
|
||||||
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
||||||
|
|
||||||
// #ifdef _WIN32
|
|
||||||
// template <typename Path>
|
|
||||||
// void Open(const Path& path, FileAccessMode mode, FileType type = FileType::BinaryFile,
|
|
||||||
// FileShareFlag flag = FileShareFlag::ShareReadOnly) {
|
|
||||||
// using ValueType = typename Path::value_type;
|
|
||||||
// if constexpr (IsChar<ValueType>) {
|
|
||||||
// Open(ToU8String(path), mode, type, flag);
|
|
||||||
// } else {
|
|
||||||
// Open(std::filesystem::path{path}, mode, type, flag);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
/// Closes the file if it is opened.
|
/// Closes the file if it is opened.
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
@@ -228,8 +216,7 @@ public:
|
|||||||
[[nodiscard]] size_t Read(T& data) const {
|
[[nodiscard]] size_t Read(T& data) const {
|
||||||
if constexpr (IsContiguousContainer<T>) {
|
if constexpr (IsContiguousContainer<T>) {
|
||||||
using ContiguousType = typename T::value_type;
|
using ContiguousType = typename T::value_type;
|
||||||
static_assert(std::is_trivially_copyable_v<ContiguousType>,
|
static_assert(std::is_trivially_copyable_v<ContiguousType>, "Data type must be trivially copyable.");
|
||||||
"Data type must be trivially copyable.");
|
|
||||||
return ReadSpan<ContiguousType>(data);
|
return ReadSpan<ContiguousType>(data);
|
||||||
} else {
|
} else {
|
||||||
return ReadObject(data) ? 1 : 0;
|
return ReadObject(data) ? 1 : 0;
|
||||||
@@ -254,8 +241,7 @@ public:
|
|||||||
[[nodiscard]] size_t Write(const T& data) const {
|
[[nodiscard]] size_t Write(const T& data) const {
|
||||||
if constexpr (IsContiguousContainer<T>) {
|
if constexpr (IsContiguousContainer<T>) {
|
||||||
using ContiguousType = typename T::value_type;
|
using ContiguousType = typename T::value_type;
|
||||||
static_assert(std::is_trivially_copyable_v<ContiguousType>,
|
static_assert(std::is_trivially_copyable_v<ContiguousType>, "Data type must be trivially copyable.");
|
||||||
"Data type must be trivially copyable.");
|
|
||||||
return WriteSpan<ContiguousType>(data);
|
return WriteSpan<ContiguousType>(data);
|
||||||
} else {
|
} else {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||||
@@ -282,10 +268,11 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
requires std::is_trivially_copyable_v<T>
|
requires std::is_trivially_copyable_v<T>
|
||||||
[[nodiscard]] size_t ReadSpan(std::span<T> data) const {
|
[[nodiscard]] size_t ReadSpan(std::span<T> data) const {
|
||||||
if (!IsOpen()) {
|
if (IsMappedFile()) {
|
||||||
return 0;
|
std::memcpy(data.data(), mmap_base + mmap_offset, sizeof(T) * data.size());
|
||||||
|
return data.size();
|
||||||
}
|
}
|
||||||
return std::fread(data.data(), sizeof(T), data.size(), file);
|
return IsOpen() ? std::fread(data.data(), sizeof(T), data.size(), file) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -306,12 +293,11 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] size_t WriteSpan(std::span<const T> data) const {
|
[[nodiscard]] size_t WriteSpan(std::span<const T> data) const {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||||
|
if (IsMappedFile()) {
|
||||||
if (!IsOpen()) {
|
std::memcpy(mmap_base + mmap_offset, data.data(), sizeof(T) * data.size());
|
||||||
return 0;
|
return data.size();
|
||||||
}
|
}
|
||||||
|
return IsOpen() ? std::fwrite(data.data(), sizeof(T), data.size(), file) : 0;
|
||||||
return std::fwrite(data.data(), sizeof(T), data.size(), file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -334,12 +320,15 @@ public:
|
|||||||
[[nodiscard]] bool ReadObject(T& object) const {
|
[[nodiscard]] bool ReadObject(T& object) const {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||||
static_assert(!std::is_pointer_v<T>, "T must not be a pointer to an object.");
|
static_assert(!std::is_pointer_v<T>, "T must not be a pointer to an object.");
|
||||||
|
if (IsMappedFile()) {
|
||||||
if (!IsOpen()) {
|
std::memcpy(&object, mmap_base + mmap_offset, sizeof(T));
|
||||||
return false;
|
#ifdef _WIN32
|
||||||
|
return bool(sizeof(T));
|
||||||
|
#else
|
||||||
|
return sizeof(T);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
return IsOpen() ? std::fread(&object, sizeof(T), 1, file) == 1 : false;
|
||||||
return std::fread(&object, sizeof(T), 1, file) == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -361,12 +350,15 @@ public:
|
|||||||
[[nodiscard]] bool WriteObject(const T& object) const {
|
[[nodiscard]] bool WriteObject(const T& object) const {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||||
static_assert(!std::is_pointer_v<T>, "T must not be a pointer to an object.");
|
static_assert(!std::is_pointer_v<T>, "T must not be a pointer to an object.");
|
||||||
|
if (IsMappedFile()) {
|
||||||
if (!IsOpen()) {
|
std::memcpy(mmap_base + mmap_offset, &object, sizeof(T));
|
||||||
return false;
|
#ifdef _WIN32
|
||||||
|
return sizeof(T) != 0;
|
||||||
|
#else
|
||||||
|
return sizeof(T);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
return IsOpen() ? std::fwrite(&object, sizeof(T), 1, file) == 1 : false;
|
||||||
return std::fwrite(&object, sizeof(T), 1, file) == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -449,12 +441,28 @@ public:
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] s64 Tell() const;
|
[[nodiscard]] s64 Tell() const;
|
||||||
|
|
||||||
private:
|
#ifdef _WIN32
|
||||||
|
inline bool IsMappedFile() const noexcept { return mapping_handle != nullptr; }
|
||||||
|
#else // POSIX
|
||||||
|
inline bool IsMappedFile() const noexcept { return mmap_fd != -1; }
|
||||||
|
#endif
|
||||||
|
|
||||||
std::filesystem::path file_path;
|
std::filesystem::path file_path;
|
||||||
FileAccessMode file_access_mode{};
|
FileAccessMode file_access_mode{};
|
||||||
FileType file_type{};
|
FileType file_type{};
|
||||||
|
|
||||||
std::FILE* file = nullptr;
|
std::FILE* file = nullptr;
|
||||||
|
// Any decent system should have mmap() for files
|
||||||
|
// Systems with artifical mmap() limitations should simply change the logic within file.cpp
|
||||||
|
// and reduce the threshold for which the mmap() is set to
|
||||||
|
#ifdef _WIN32
|
||||||
|
void *mapping_handle = nullptr;
|
||||||
|
void *file_handle = nullptr;
|
||||||
|
#else // POSIX
|
||||||
|
int mmap_fd = -1;
|
||||||
|
#endif
|
||||||
|
u8* mmap_base = nullptr;
|
||||||
|
size_t mmap_size = 0;
|
||||||
|
mutable s64 mmap_offset = 0; // fuck you
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
|||||||
@@ -116,19 +116,121 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string UTF16ToUTF8(std::u16string_view input) {
|
std::string UTF16ToUTF8(std::u16string_view input) {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
|
std::string result;
|
||||||
return convert.to_bytes(input.data(), input.data() + input.size());
|
result.reserve(input.size() * 4);
|
||||||
|
for (size_t i = 0; i < input.size(); ++i) {
|
||||||
|
uint32_t code = input[i];
|
||||||
|
// Handle surrogate pairs
|
||||||
|
if (code >= 0xD800 && code <= 0xDBFF) {
|
||||||
|
if (i + 1 < input.size()) {
|
||||||
|
uint32_t low = input[i + 1];
|
||||||
|
if (low >= 0xDC00 && low <= 0xDFFF) {
|
||||||
|
code = ((code - 0xD800) << 10) + (low - 0xDC00) + 0x10000;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (code <= 0x7F) {
|
||||||
|
result.push_back(char(code));
|
||||||
|
} else if (code <= 0x7FF) {
|
||||||
|
result.push_back(char(0xC0 | (code >> 6)));
|
||||||
|
result.push_back(char(0x80 | (code & 0x3F)));
|
||||||
|
} else if (code <= 0xFFFF) {
|
||||||
|
result.push_back(char(0xE0 | (code >> 12)));
|
||||||
|
result.push_back(char(0x80 | ((code >> 6) & 0x3F)));
|
||||||
|
result.push_back(char(0x80 | (code & 0x3F)));
|
||||||
|
} else {
|
||||||
|
result.push_back(char(0xF0 | (code >> 18)));
|
||||||
|
result.push_back(char(0x80 | ((code >> 12) & 0x3F)));
|
||||||
|
result.push_back(char(0x80 | ((code >> 6) & 0x3F)));
|
||||||
|
result.push_back(char(0x80 | (code & 0x3F)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::u16string UTF8ToUTF16(std::string_view input) {
|
std::u16string UTF8ToUTF16(std::string_view input) {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
|
std::u16string result;
|
||||||
return convert.from_bytes(input.data(), input.data() + input.size());
|
result.reserve(input.size() * 2);
|
||||||
|
for (size_t i = 0; i < input.size(); ) {
|
||||||
|
uint32_t code = 0;
|
||||||
|
unsigned char c = input[i];
|
||||||
|
size_t len = 0;
|
||||||
|
if ((c & 0x80) == 0) {
|
||||||
|
code = c;
|
||||||
|
len = 1;
|
||||||
|
} else if ((c & 0xE0) == 0xC0) {
|
||||||
|
code = c & 0x1F;
|
||||||
|
len = 2;
|
||||||
|
} else if ((c & 0xF0) == 0xE0) {
|
||||||
|
code = c & 0x0F;
|
||||||
|
len = 3;
|
||||||
|
} else if ((c & 0xF8) == 0xF0) {
|
||||||
|
code = c & 0x07;
|
||||||
|
len = 4;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i + len - 1 >= input.size())
|
||||||
|
break;
|
||||||
|
for (size_t j = 1; j <= len - 1; ++j) {
|
||||||
|
if ((input[i + j] & 0xC0) != 0x80) {
|
||||||
|
code = 0xFFFD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code = (code << 6) | (input[i + j] & 0x3F);
|
||||||
|
}
|
||||||
|
if (code <= 0xFFFF) {
|
||||||
|
result.push_back(char16_t(code));
|
||||||
|
} else {
|
||||||
|
code -= 0x10000;
|
||||||
|
result.push_back(char16_t(0xD800 + (code >> 10)));
|
||||||
|
result.push_back(char16_t(0xDC00 + (code & 0x3FF)));
|
||||||
|
}
|
||||||
|
i += len;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::u32string UTF8ToUTF32(std::string_view input) {
|
std::u32string UTF8ToUTF32(std::string_view input) {
|
||||||
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
|
std::u32string result;
|
||||||
return convert.from_bytes(input.data(), input.data() + input.size());
|
result.reserve(input.size());
|
||||||
|
for (size_t i = 0; i < input.size(); ) {
|
||||||
|
uint32_t code = 0;
|
||||||
|
unsigned char c = input[i];
|
||||||
|
size_t len = 0;
|
||||||
|
if ((c & 0x80) == 0) {
|
||||||
|
code = c;
|
||||||
|
len = 1;
|
||||||
|
} else if ((c & 0xE0) == 0xC0) {
|
||||||
|
code = c & 0x1F;
|
||||||
|
len = 2;
|
||||||
|
} else if ((c & 0xF0) == 0xE0) {
|
||||||
|
code = c & 0x0F;
|
||||||
|
len = 3;
|
||||||
|
} else if ((c & 0xF8) == 0xF0) {
|
||||||
|
code = c & 0x07;
|
||||||
|
len = 4;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
if (i + len - 1 >= input.size())
|
||||||
|
break;
|
||||||
|
for (size_t j = 1; j <= len - 1; ++j) {
|
||||||
|
if ((input[i + j] & 0xC0) != 0x80) {
|
||||||
|
code = 0xFFFD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code = (code << 6) | (input[i + j] & 0x3F);
|
||||||
|
}
|
||||||
|
result.push_back(code);
|
||||||
|
i += len;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static std::wstring CPToUTF16(u32 code_page, std::string_view input) {
|
static std::wstring CPToUTF16(u32 code_page, std::string_view input) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#elif defined(__linux__) || defined(__ANDROID__)
|
#elif defined(__linux__) || defined(__ANDROID__) || defined(__APPLE__)
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@@ -33,6 +33,13 @@
|
|||||||
#include <netinet/if_ether.h>
|
#include <netinet/if_ether.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
// Darwin doesn't define this for some very odd reason
|
||||||
|
// See https://stackoverflow.com/questions/5390164/getting-routing-table-on-macosx-programmatically
|
||||||
|
#ifndef SA_SIZE
|
||||||
|
#define SA_SIZE(sa) \
|
||||||
|
((!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? sizeof(long) \
|
||||||
|
: 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) )
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
@@ -104,7 +111,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
|
std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
|
||||||
#if defined(__ANDROID__) || defined(__linux__)
|
#if defined(__ANDROID__) || defined(__linux__) || defined(__APPLE__) || defined(__managarm__)
|
||||||
struct ifaddrs* ifaddr = nullptr;
|
struct ifaddrs* ifaddr = nullptr;
|
||||||
if (getifaddrs(&ifaddr) != 0) {
|
if (getifaddrs(&ifaddr) != 0) {
|
||||||
LOG_ERROR(Network, "getifaddrs: {}", std::strerror(errno));
|
LOG_ERROR(Network, "getifaddrs: {}", std::strerror(errno));
|
||||||
@@ -119,8 +126,9 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
|
|||||||
u32 flags;
|
u32 flags;
|
||||||
};
|
};
|
||||||
std::vector<RoutingEntry> routes{};
|
std::vector<RoutingEntry> routes{};
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__APPLE__)
|
||||||
// Even through Linux based, we can't reliably obtain routing information from there :(
|
// Even through Linux based, we can't reliably obtain routing information from there :(
|
||||||
|
// macOS not Linux based and would murder us if we attempt to access /proc
|
||||||
#else
|
#else
|
||||||
if (std::ifstream file("/proc/net/route"); file.is_open()) {
|
if (std::ifstream file("/proc/net/route"); file.is_open()) {
|
||||||
file.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); //ignore header
|
file.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); //ignore header
|
||||||
@@ -138,7 +146,10 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
|
|||||||
std::vector<Network::NetworkInterface> ifaces;
|
std::vector<Network::NetworkInterface> ifaces;
|
||||||
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
|
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
|
||||||
if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr /* Have a netmask and address */
|
if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr /* Have a netmask and address */
|
||||||
|
// Apple hates human beings so lets pretend all families are fine
|
||||||
|
#if !defined(__APPLE__) && !defined(__managarm__)
|
||||||
|| ifa->ifa_addr->sa_family != AF_INET /* Must be of kind AF_INET */
|
|| ifa->ifa_addr->sa_family != AF_INET /* Must be of kind AF_INET */
|
||||||
|
#endif
|
||||||
|| (ifa->ifa_flags & IFF_UP) == 0 || (ifa->ifa_flags & IFF_LOOPBACK) != 0) /* Not loopback */
|
|| (ifa->ifa_flags & IFF_UP) == 0 || (ifa->ifa_flags & IFF_LOOPBACK) != 0) /* Not loopback */
|
||||||
continue;
|
continue;
|
||||||
// Just use 0 as the gateway address if not found OR routes are empty :)
|
// Just use 0 as the gateway address if not found OR routes are empty :)
|
||||||
@@ -158,7 +169,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
|
|||||||
}
|
}
|
||||||
freeifaddrs(ifaddr);
|
freeifaddrs(ifaddr);
|
||||||
return ifaces;
|
return ifaces;
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
std::vector<Network::NetworkInterface> ifaces;
|
std::vector<Network::NetworkInterface> ifaces;
|
||||||
int fd = ::socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
|
int fd = ::socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -198,11 +209,15 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
|
|||||||
if (msglen == 0 || msglen < SA_SIZE(sa))
|
if (msglen == 0 || msglen < SA_SIZE(sa))
|
||||||
break;
|
break;
|
||||||
if (i == RTA_NETMASK && sa->sa_family == AF_LINK) {
|
if (i == RTA_NETMASK && sa->sa_family == AF_LINK) {
|
||||||
size_t namelen = 0;
|
|
||||||
struct sockaddr_dl const* sdl = reinterpret_cast<struct sockaddr_dl const*>(sa);
|
struct sockaddr_dl const* sdl = reinterpret_cast<struct sockaddr_dl const*>(sa);
|
||||||
|
#if defined(__FreeBSD__) && __FreeBSD__ < 15
|
||||||
|
iface.name = std::string{::link_ntoa(sdl)};
|
||||||
|
#else
|
||||||
|
size_t namelen = 0;
|
||||||
::link_ntoa_r(sdl, nullptr, &namelen);
|
::link_ntoa_r(sdl, nullptr, &namelen);
|
||||||
iface.name = std::string(namelen, ' ');
|
iface.name = std::string(namelen, ' ');
|
||||||
::link_ntoa_r(sdl, iface.name.data(), &namelen);
|
::link_ntoa_r(sdl, iface.name.data(), &namelen);
|
||||||
|
#endif
|
||||||
std::memcpy(&iface.ip_address, sa, sizeof(struct sockaddr_in));
|
std::memcpy(&iface.ip_address, sa, sizeof(struct sockaddr_in));
|
||||||
}
|
}
|
||||||
msglen -= SA_SIZE(sa);
|
msglen -= SA_SIZE(sa);
|
||||||
|
|||||||
@@ -11,34 +11,15 @@ set(dynarmic_VERSION ${dynarmic_VERSION_MAJOR}.${dynarmic_VERSION_MINOR}.${dynar
|
|||||||
|
|
||||||
project(dynarmic LANGUAGES C CXX ASM VERSION ${dynarmic_VERSION})
|
project(dynarmic LANGUAGES C CXX ASM VERSION ${dynarmic_VERSION})
|
||||||
|
|
||||||
# Determine if we're built as a subproject (using add_subdirectory)
|
|
||||||
# or if this is the master project.
|
|
||||||
set(MASTER_PROJECT OFF)
|
|
||||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
|
||||||
set(MASTER_PROJECT ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (MASTER_PROJECT)
|
|
||||||
include(CTest)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Dynarmic project options
|
|
||||||
option(DYNARMIC_ENABLE_CPU_FEATURE_DETECTION "Turning this off causes dynarmic to assume the host CPU doesn't support anything later than SSE3" ON)
|
|
||||||
|
|
||||||
if (OPENBSD OR DRAGONFLY OR NETBSD)
|
if (OPENBSD OR DRAGONFLY OR NETBSD)
|
||||||
set(REQUIRE_WX ON)
|
set(REQUIRE_WX ON)
|
||||||
else()
|
else()
|
||||||
set(REQUIRE_WX OFF)
|
set(REQUIRE_WX OFF)
|
||||||
endif()
|
endif()
|
||||||
option(DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT "Enables support for systems that require W^X" ${REQUIRE_WX})
|
option(DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT "Enables support for systems that require W^X" ${REQUIRE_WX})
|
||||||
|
|
||||||
option(DYNARMIC_IGNORE_ASSERTS "Ignore asserts" ON)
|
|
||||||
option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF)
|
option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF)
|
||||||
CMAKE_DEPENDENT_OPTION(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF "NOT YUZU_DISABLE_LLVM" OFF)
|
CMAKE_DEPENDENT_OPTION(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF "NOT YUZU_DISABLE_LLVM" OFF)
|
||||||
|
|
||||||
option(DYNARMIC_INSTALL "Install dynarmic headers and CMake files" OFF)
|
|
||||||
option(DYNARMIC_USE_BUNDLED_EXTERNALS "Use all bundled externals (useful when e.g. cross-compiling)" OFF)
|
|
||||||
|
|
||||||
# Set hard requirements for C++
|
# Set hard requirements for C++
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
@@ -88,7 +69,7 @@ if (MSVC)
|
|||||||
-Wno-missing-braces)
|
-Wno-missing-braces)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(DYNARMIC_CXX_FLAGS
|
list(APPEND DYNARMIC_CXX_FLAGS
|
||||||
-Wall
|
-Wall
|
||||||
-Wextra
|
-Wextra
|
||||||
-Wcast-qual
|
-Wcast-qual
|
||||||
@@ -103,37 +84,35 @@ else()
|
|||||||
# to Address& after first checking isMEM(), and that code is inlined in a situation where
|
# to Address& after first checking isMEM(), and that code is inlined in a situation where
|
||||||
# GCC knows that the variable is actually a Reg64. isMEM() will never return true for a
|
# GCC knows that the variable is actually a Reg64. isMEM() will never return true for a
|
||||||
# Reg64, but GCC doesn't know that.
|
# Reg64, but GCC doesn't know that.
|
||||||
list(APPEND DYNARMIC_CXX_FLAGS -Wno-array-bounds)
|
list(APPEND DYNARMIC_CXX_FLAGS
|
||||||
list(APPEND DYNARMIC_CXX_FLAGS -Wstack-usage=4096)
|
-Wno-array-bounds
|
||||||
|
-Wstack-usage=4096)
|
||||||
endif()
|
endif()
|
||||||
if (CXX_CLANG)
|
if (CXX_CLANG)
|
||||||
|
list(APPEND DYNARMIC_CXX_FLAGS
|
||||||
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
|
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
|
||||||
# And this in turns limits the size of a std::array.
|
# And this in turns limits the size of a std::array.
|
||||||
list(APPEND DYNARMIC_CXX_FLAGS -fbracket-depth=1024)
|
-fbracket-depth=1024
|
||||||
# Clang mistakenly blames CMake for using unused arguments during compilation
|
# Clang mistakenly blames CMake for using unused arguments during compilation
|
||||||
list(APPEND DYNARMIC_CXX_FLAGS -Wno-unused-command-line-argument)
|
-Wno-unused-command-line-argument)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT Boost_FOUND)
|
if (NOT Boost_FOUND)
|
||||||
find_package(Boost 1.57 REQUIRED)
|
find_package(Boost 1.57 REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(fmt 8 CONFIG)
|
find_package(fmt 8 CONFIG)
|
||||||
|
|
||||||
if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
|
if (ARCHITECTURE_arm64)
|
||||||
find_package(oaknut 2.0.1 CONFIG)
|
find_package(oaknut 2.0.1 CONFIG)
|
||||||
endif()
|
endif()
|
||||||
|
if (ARCHITECTURE_riscv64)
|
||||||
if ("riscv64" IN_LIST ARCHITECTURE)
|
|
||||||
find_package(biscuit 0.9.1 REQUIRED)
|
find_package(biscuit 0.9.1 REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
if (ARCHITECTURE_loongarch64)
|
||||||
if ("loongarch64" IN_LIST ARCHITECTURE)
|
|
||||||
find_package(lagoon REQUIRED)
|
find_package(lagoon REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
if (ARCHITECTURE_x86_64)
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
|
||||||
find_package(xbyak 7 CONFIG)
|
find_package(xbyak 7 CONFIG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -142,44 +121,12 @@ if (DYNARMIC_USE_LLVM)
|
|||||||
separate_arguments(LLVM_DEFINITIONS)
|
separate_arguments(LLVM_DEFINITIONS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Dynarmic project files
|
||||||
|
add_subdirectory(src/dynarmic)
|
||||||
if (DYNARMIC_TESTS)
|
if (DYNARMIC_TESTS)
|
||||||
find_package(Catch2 3 CONFIG)
|
find_package(Catch2 3 CONFIG)
|
||||||
if (DYNARMIC_TESTS_USE_UNICORN)
|
if (DYNARMIC_TESTS_USE_UNICORN)
|
||||||
find_package(Unicorn REQUIRED)
|
find_package(Unicorn REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
|
|
||||||
# Dynarmic project files
|
|
||||||
add_subdirectory(src/dynarmic)
|
|
||||||
if (DYNARMIC_TESTS)
|
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#
|
|
||||||
# Install
|
|
||||||
#
|
|
||||||
if (DYNARMIC_INSTALL)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
include(CMakePackageConfigHelpers)
|
|
||||||
|
|
||||||
install(TARGETS dynarmic EXPORT dynarmicTargets)
|
|
||||||
install(EXPORT dynarmicTargets
|
|
||||||
NAMESPACE dynarmic::
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/dynarmic"
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_package_config_file(CMakeModules/dynarmicConfig.cmake.in
|
|
||||||
dynarmicConfig.cmake
|
|
||||||
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/dynarmic"
|
|
||||||
)
|
|
||||||
write_basic_package_version_file(dynarmicConfigVersion.cmake
|
|
||||||
COMPATIBILITY SameMajorVersion
|
|
||||||
)
|
|
||||||
install(FILES
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/dynarmicConfig.cmake"
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/dynarmicConfigVersion.cmake"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/dynarmic"
|
|
||||||
)
|
|
||||||
|
|
||||||
install(DIRECTORY src/dynarmic TYPE INCLUDE FILES_MATCHING PATTERN "*.h")
|
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
function(target_architecture_specific_sources project arch)
|
|
||||||
if (NOT MULTIARCH_BUILD)
|
|
||||||
target_sources("${project}" PRIVATE ${ARGN})
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
foreach(input_file IN LISTS ARGN)
|
|
||||||
if(input_file MATCHES ".cpp$")
|
|
||||||
if(NOT IS_ABSOLUTE ${input_file})
|
|
||||||
set(input_file "${CMAKE_CURRENT_SOURCE_DIR}/${input_file}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(output_file "${CMAKE_CURRENT_BINARY_DIR}/arch_gen/${input_file}")
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT "${output_file}"
|
|
||||||
COMMAND ${CMAKE_COMMAND} "-Darch=${arch}"
|
|
||||||
"-Dinput_file=${input_file}"
|
|
||||||
"-Doutput_file=${output_file}"
|
|
||||||
-P "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/impl/TargetArchitectureSpecificSourcesWrapFile.cmake"
|
|
||||||
DEPENDS "${input_file}"
|
|
||||||
VERBATIM
|
|
||||||
)
|
|
||||||
target_sources(${project} PRIVATE "${output_file}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endfunction()
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
@PACKAGE_INIT@
|
|
||||||
|
|
||||||
include(CMakeFindDependencyMacro)
|
|
||||||
|
|
||||||
set(ARCHITECTURE "@ARCHITECTURE@")
|
|
||||||
|
|
||||||
if (NOT @BUILD_SHARED_LIBS@)
|
|
||||||
find_dependency(Boost 1.57)
|
|
||||||
find_dependency(fmt 9)
|
|
||||||
find_dependency(mcl 0.1.12 EXACT)
|
|
||||||
|
|
||||||
if ("arm64" IN_LIST ARCHITECTURE)
|
|
||||||
find_dependency(oaknut 2.0.1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if ("riscv" IN_LIST ARCHITECTURE)
|
|
||||||
find_dependency(biscuit 0.9.1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
|
||||||
find_dependency(xbyak 7)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (@DYNARMIC_USE_LLVM@)
|
|
||||||
find_dependency(LLVM)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
|
||||||
|
|
||||||
check_required_components(@PROJECT_NAME@)
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
string(TOUPPER "${arch}" arch)
|
|
||||||
file(READ "${input_file}" f_contents)
|
|
||||||
file(WRITE "${output_file}" "#if defined(ARCHITECTURE_${arch})\n${f_contents}\n#endif\n")
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
include(TargetArchitectureSpecificSources)
|
|
||||||
|
|
||||||
add_library(dynarmic STATIC
|
add_library(dynarmic STATIC
|
||||||
mcl/bit.hpp
|
mcl/bit.hpp
|
||||||
mcl/function_info.hpp
|
mcl/function_info.hpp
|
||||||
@@ -135,7 +133,7 @@ add_library(dynarmic STATIC
|
|||||||
interface/A64/config.h
|
interface/A64/config.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
if (ARCHITECTURE_x86_64)
|
||||||
# Newer versions of xbyak (>= 7.25.0) have stricter checks that currently
|
# Newer versions of xbyak (>= 7.25.0) have stricter checks that currently
|
||||||
# fail in dynarmic
|
# fail in dynarmic
|
||||||
target_compile_definitions(dynarmic PRIVATE XBYAK_STRICT_CHECK_MEM_REG_SIZE=0)
|
target_compile_definitions(dynarmic PRIVATE XBYAK_STRICT_CHECK_MEM_REG_SIZE=0)
|
||||||
@@ -143,7 +141,7 @@ if ("x86_64" IN_LIST ARCHITECTURE)
|
|||||||
target_compile_definitions(dynarmic PRIVATE XBYAK_OLD_DISP_CHECK=1)
|
target_compile_definitions(dynarmic PRIVATE XBYAK_OLD_DISP_CHECK=1)
|
||||||
target_link_libraries(dynarmic PRIVATE xbyak::xbyak)
|
target_link_libraries(dynarmic PRIVATE xbyak::xbyak)
|
||||||
|
|
||||||
target_architecture_specific_sources(dynarmic "x86_64"
|
target_sources(dynarmic PRIVATE
|
||||||
backend/x64/abi.cpp
|
backend/x64/abi.cpp
|
||||||
backend/x64/abi.h
|
backend/x64/abi.h
|
||||||
backend/x64/block_of_code.cpp
|
backend/x64/block_of_code.cpp
|
||||||
@@ -201,10 +199,10 @@ if ("x86_64" IN_LIST ARCHITECTURE)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ("arm64" IN_LIST ARCHITECTURE)
|
if (ARCHITECTURE_arm64)
|
||||||
target_link_libraries(dynarmic PRIVATE merry::oaknut)
|
target_link_libraries(dynarmic PRIVATE merry::oaknut)
|
||||||
|
|
||||||
target_architecture_specific_sources(dynarmic "arm64"
|
target_sources(dynarmic PRIVATE
|
||||||
backend/arm64/a32_jitstate.cpp
|
backend/arm64/a32_jitstate.cpp
|
||||||
backend/arm64/a32_jitstate.h
|
backend/arm64/a32_jitstate.h
|
||||||
backend/arm64/a64_jitstate.h
|
backend/arm64/a64_jitstate.h
|
||||||
@@ -255,7 +253,7 @@ if ("arm64" IN_LIST ARCHITECTURE)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ("riscv64" IN_LIST ARCHITECTURE)
|
if (ARCHITECTURE_riscv64)
|
||||||
target_link_libraries(dynarmic PRIVATE biscuit::biscuit)
|
target_link_libraries(dynarmic PRIVATE biscuit::biscuit)
|
||||||
|
|
||||||
target_sources(dynarmic PRIVATE
|
target_sources(dynarmic PRIVATE
|
||||||
@@ -295,7 +293,7 @@ if ("riscv64" IN_LIST ARCHITECTURE)
|
|||||||
message(WARNING "TODO: Incomplete frontend for this host architecture")
|
message(WARNING "TODO: Incomplete frontend for this host architecture")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if ("loongarch64" IN_LIST ARCHITECTURE)
|
if (ARCHITECTURE_loongarch64)
|
||||||
target_link_libraries(dynarmic PRIVATE lagoon::lagoon)
|
target_link_libraries(dynarmic PRIVATE lagoon::lagoon)
|
||||||
|
|
||||||
target_sources(dynarmic PRIVATE
|
target_sources(dynarmic PRIVATE
|
||||||
@@ -400,15 +398,9 @@ if (DYNARMIC_USE_LLVM)
|
|||||||
target_compile_definitions(dynarmic PRIVATE DYNARMIC_USE_LLVM=1 ${LLVM_DEFINITIONS})
|
target_compile_definitions(dynarmic PRIVATE DYNARMIC_USE_LLVM=1 ${LLVM_DEFINITIONS})
|
||||||
llvm_config(dynarmic USE_SHARED armdesc armdisassembler aarch64desc aarch64disassembler x86desc x86disassembler)
|
llvm_config(dynarmic USE_SHARED armdesc armdisassembler aarch64desc aarch64disassembler x86desc x86disassembler)
|
||||||
endif()
|
endif()
|
||||||
if (DYNARMIC_ENABLE_CPU_FEATURE_DETECTION)
|
|
||||||
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_CPU_FEATURE_DETECTION=1)
|
|
||||||
endif()
|
|
||||||
if (DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT)
|
if (DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT)
|
||||||
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
|
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
|
||||||
endif()
|
endif()
|
||||||
if (DYNARMIC_IGNORE_ASSERTS)
|
|
||||||
target_compile_definitions(dynarmic PRIVATE MCL_IGNORE_ASSERTS=1)
|
|
||||||
endif()
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)
|
target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
|
|||||||
|
|
||||||
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
||||||
ir_block.Reset(descriptor);
|
ir_block.Reset(descriptor);
|
||||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf);
|
||||||
Optimization::Optimize(ir_block, conf, {});
|
Optimization::Optimize(ir_block, conf, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -366,8 +366,7 @@ A64AddressSpace::A64AddressSpace(const A64::UserConfig& conf)
|
|||||||
|
|
||||||
void A64AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
void A64AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
||||||
ir_block.Reset(descriptor);
|
ir_block.Reset(descriptor);
|
||||||
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
|
A64::Translate(ir_block, A64::LocationDescriptor{descriptor}, conf);
|
||||||
A64::Translate(ir_block, A64::LocationDescriptor{descriptor}, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
|
||||||
Optimization::Optimize(ir_block, conf, {});
|
Optimization::Optimize(ir_block, conf, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
||||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf);
|
||||||
Optimization::Optimize(ir_block, conf, {.sha256 = true});
|
Optimization::Optimize(ir_block, conf, {.sha256 = true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
void A32AddressSpace::GenerateIR(IR::Block& ir_block, IR::LocationDescriptor descriptor) const {
|
||||||
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
A32::Translate(ir_block, A32::LocationDescriptor{descriptor}, conf);
|
||||||
Optimization::Optimize(ir_block, conf, {});
|
Optimization::Optimize(ir_block, conf, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -197,15 +197,15 @@ void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx, IR::Term::CheckHa
|
|||||||
|
|
||||||
void EmitA32LeafTerminal(biscuit::Assembler& as, EmitContext& ctx, IR::Term::LeafTerminal terminal, IR::LocationDescriptor initial_location, bool is_single_step) {
|
void EmitA32LeafTerminal(biscuit::Assembler& as, EmitContext& ctx, IR::Term::LeafTerminal terminal, IR::LocationDescriptor initial_location, bool is_single_step) {
|
||||||
if (auto const x = std::get_if<IR::Term::ReturnToDispatch>(&terminal))
|
if (auto const x = std::get_if<IR::Term::ReturnToDispatch>(&terminal))
|
||||||
return EmitA32LeafTerminal(as, ctx, *x, initial_location, is_single_step);
|
return EmitA32Terminal(as, ctx, *x, initial_location, is_single_step);
|
||||||
if (auto const x = std::get_if<IR::Term::LinkBlock>(&terminal))
|
if (auto const x = std::get_if<IR::Term::LinkBlock>(&terminal))
|
||||||
return EmitA32LeafTerminal(as, ctx, *x, initial_location, is_single_step);
|
return EmitA32Terminal(as, ctx, *x, initial_location, is_single_step);
|
||||||
if (auto const x = std::get_if<IR::Term::LinkBlockFast>(&terminal))
|
if (auto const x = std::get_if<IR::Term::LinkBlockFast>(&terminal))
|
||||||
return EmitA32LeafTerminal(as, ctx, *x, initial_location, is_single_step);
|
return EmitA32Terminal(as, ctx, *x, initial_location, is_single_step);
|
||||||
if (auto const x = std::get_if<IR::Term::PopRSBHint>(&terminal))
|
if (auto const x = std::get_if<IR::Term::PopRSBHint>(&terminal))
|
||||||
return EmitA32LeafTerminal(as, ctx, *x, initial_location, is_single_step);
|
return EmitA32Terminal(as, ctx, *x, initial_location, is_single_step);
|
||||||
if (auto const x = std::get_if<IR::Term::FastDispatchHint>(&terminal))
|
if (auto const x = std::get_if<IR::Term::FastDispatchHint>(&terminal))
|
||||||
return EmitA32LeafTerminal(as, ctx, *x, initial_location, is_single_step);
|
return EmitA32Terminal(as, ctx, *x, initial_location, is_single_step);
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ private:
|
|||||||
// LocationDescriptor ctor() does important ops (like tflags) do not skip
|
// LocationDescriptor ctor() does important ops (like tflags) do not skip
|
||||||
auto const arch_descriptor = A32::LocationDescriptor{descriptor};
|
auto const arch_descriptor = A32::LocationDescriptor{descriptor};
|
||||||
ir_block.Reset(arch_descriptor);
|
ir_block.Reset(arch_descriptor);
|
||||||
A32::Translate(ir_block, arch_descriptor, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
A32::Translate(ir_block, arch_descriptor, conf);
|
||||||
Optimization::Optimize(ir_block, conf, polyfill_options);
|
Optimization::Optimize(ir_block, conf, polyfill_options);
|
||||||
return emitter.Emit(ir_block);
|
return emitter.Emit(ir_block);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,11 +254,10 @@ private:
|
|||||||
block_of_code.EnsureMemoryCommitted(MINIMUM_REMAINING_CODESIZE);
|
block_of_code.EnsureMemoryCommitted(MINIMUM_REMAINING_CODESIZE);
|
||||||
|
|
||||||
// JIT Compile
|
// JIT Compile
|
||||||
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
|
|
||||||
// LocationDescriptor ctor() does important ops (like tflags) do not skip
|
// LocationDescriptor ctor() does important ops (like tflags) do not skip
|
||||||
auto const arch_descriptor = A64::LocationDescriptor{descriptor};
|
auto const arch_descriptor = A64::LocationDescriptor{descriptor};
|
||||||
ir_block.Reset(arch_descriptor);
|
ir_block.Reset(arch_descriptor);
|
||||||
A64::Translate(ir_block, arch_descriptor, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
A64::Translate(ir_block, arch_descriptor, conf);
|
||||||
Optimization::Optimize(ir_block, conf, polyfill_options);
|
Optimization::Optimize(ir_block, conf, polyfill_options);
|
||||||
return emitter.Emit(ir_block).entrypoint;
|
return emitter.Emit(ir_block).entrypoint;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ void ProtectMemory(const void* base, size_t size, bool is_executable) {
|
|||||||
|
|
||||||
static const HostFeature features = []() {
|
static const HostFeature features = []() {
|
||||||
HostFeature f{};
|
HostFeature f{};
|
||||||
#ifdef DYNARMIC_ENABLE_CPU_FEATURE_DETECTION
|
|
||||||
using Cpu = Xbyak::util::Cpu;
|
using Cpu = Xbyak::util::Cpu;
|
||||||
Xbyak::util::Cpu cpu_info{};
|
Xbyak::util::Cpu cpu_info{};
|
||||||
if (cpu_info.has(Cpu::tSSSE3)) f |= HostFeature::SSSE3;
|
if (cpu_info.has(Cpu::tSSSE3)) f |= HostFeature::SSSE3;
|
||||||
@@ -121,7 +120,6 @@ static const HostFeature features = []() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
#endif
|
|
||||||
}();
|
}();
|
||||||
HostFeature GetHostFeatures() {
|
HostFeature GetHostFeatures() {
|
||||||
return features;
|
return features;
|
||||||
|
|||||||
@@ -7,34 +7,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
#include "common/assert.h"
|
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/constant_pool.h"
|
#include "dynarmic/backend/x64/constant_pool.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
ConstantPool::ConstantPool(BlockOfCode& code, size_t size)
|
ConstantPool::ConstantPool(BlockOfCode& code, size_t size) noexcept {
|
||||||
: insertion_point(0)
|
auto const align_size = 64; //always align to cacheline
|
||||||
{
|
code.EnsureMemoryCommitted(2 * align_size + size);
|
||||||
code.EnsureMemoryCommitted(align_size + size);
|
|
||||||
code.int3();
|
|
||||||
code.align(align_size);
|
code.align(align_size);
|
||||||
pool = std::span<ConstantT>(reinterpret_cast<ConstantT*>(code.AllocateFromCodeSpace(size)), size / align_size);
|
pool = std::span<u128>(static_cast<u128*>(code.AllocateFromCodeSpace(size)), size / sizeof(u128));
|
||||||
}
|
}
|
||||||
|
|
||||||
Xbyak::Address ConstantPool::GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lower, u64 upper) {
|
Xbyak::Address ConstantPool::GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lo, u64 hi) noexcept {
|
||||||
const auto constant = ConstantT(lower, upper);
|
// offset grows iff new constant is added
|
||||||
auto it = constant_info.find(constant);
|
auto const key = std::make_pair(lo, hi);
|
||||||
if (it == constant_info.end()) {
|
auto const val = u32(constant_info.size());
|
||||||
ASSERT(insertion_point < pool.size());
|
auto const [it, _] = constant_info.insert({key, val});
|
||||||
ConstantT& target_constant = pool[insertion_point];
|
// if it != constant_info.end(): assume(pool[it->second] == c);
|
||||||
target_constant = constant;
|
pool[it->second] = u128{lo, hi};
|
||||||
it = constant_info.insert({constant, &target_constant}).first;
|
return frame[code.rip + std::addressof(pool[it->second])];
|
||||||
++insertion_point;
|
|
||||||
}
|
|
||||||
return frame[code.rip + it->second];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::X64
|
} // namespace Dynarmic::Backend::X64
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/container/unordered_map.h"
|
#include "common/container/unordered_map.h"
|
||||||
@@ -21,31 +22,17 @@ namespace Dynarmic::Backend::X64 {
|
|||||||
|
|
||||||
class BlockOfCode;
|
class BlockOfCode;
|
||||||
|
|
||||||
/// ConstantPool allocates a block of memory from BlockOfCode.
|
/// @brief ConstantPool allocates a block of memory from BlockOfCode.
|
||||||
/// It places constants into this block of memory, returning the address
|
/// It places constants into this block of memory, returning the address
|
||||||
/// of the memory location where the constant is placed. If the constant
|
/// of the memory location where the constant is placed. If the constant
|
||||||
/// already exists, its memory location is reused.
|
/// already exists, its memory location is reused.
|
||||||
class ConstantPool final {
|
class ConstantPool final {
|
||||||
public:
|
public:
|
||||||
ConstantPool(BlockOfCode& code, size_t size);
|
ConstantPool(BlockOfCode& code, size_t size) noexcept;
|
||||||
|
Xbyak::Address GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lower, u64 upper = 0) noexcept;
|
||||||
Xbyak::Address GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lower, u64 upper = 0);
|
// key = identity hash, value = offset from pool.data()
|
||||||
|
::Common::unordered_map<std::pair<u64, u64>, u32, boost::hash<std::pair<u64, u64>>> constant_info;
|
||||||
private:
|
std::span<u128> pool;
|
||||||
static constexpr size_t align_size = 16; // bytes
|
|
||||||
|
|
||||||
using ConstantT = std::pair<u64, u64>;
|
|
||||||
static_assert(sizeof(ConstantT) == align_size);
|
|
||||||
|
|
||||||
struct ConstantHash {
|
|
||||||
std::size_t operator()(const ConstantT& constant) const noexcept {
|
|
||||||
return constant.first ^ std::rotl<u64>(constant.second, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
::Common::unordered_map<ConstantT, void*, ConstantHash> constant_info;
|
|
||||||
std::span<ConstantT> pool;
|
|
||||||
std::size_t insertion_point;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::X64
|
} // namespace Dynarmic::Backend::X64
|
||||||
|
|||||||
@@ -275,6 +275,7 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
|
|||||||
code.xadd(qword[addr], Xbyak::Reg64(value_idx));
|
code.xadd(qword[addr], Xbyak::Reg64(value_idx));
|
||||||
break;
|
break;
|
||||||
case 128:
|
case 128:
|
||||||
|
ASSERT(Xbyak::Xmm(value_idx) != xmm0);
|
||||||
code.lock();
|
code.lock();
|
||||||
code.cmpxchg16b(xword[addr]);
|
code.cmpxchg16b(xword[addr]);
|
||||||
if (code.HasHostFeature(HostFeature::SSE41)) {
|
if (code.HasHostFeature(HostFeature::SSE41)) {
|
||||||
|
|||||||
@@ -6226,9 +6226,7 @@ void EmitX64::EmitVectorZeroExtend64(EmitContext& ctx, IR::Inst* inst) {
|
|||||||
void EmitX64::EmitVectorZeroUpper(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorZeroUpper(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
auto const a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
|
|
||||||
code.movq(a, a); // TODO: !IsLastUse
|
code.movq(a, a); // TODO: !IsLastUse
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(code, inst, a);
|
ctx.reg_alloc.DefineValue(code, inst, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,6 @@
|
|||||||
#include "dynarmic/backend/x64/hostloc.h"
|
#include "dynarmic/backend/x64/hostloc.h"
|
||||||
#include "dynarmic/common/spin_lock.h"
|
#include "dynarmic/common/spin_lock.h"
|
||||||
|
|
||||||
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
|
|
||||||
static const auto default_cg_mode = Xbyak::DontSetProtectRWE;
|
|
||||||
#else
|
|
||||||
static const auto default_cg_mode = nullptr; //Allow RWE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Dynarmic {
|
namespace Dynarmic {
|
||||||
|
|
||||||
void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 tmp, bool waitpkg) {
|
void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 tmp, bool waitpkg) {
|
||||||
@@ -78,7 +72,13 @@ namespace {
|
|||||||
struct SpinLockImpl {
|
struct SpinLockImpl {
|
||||||
void Initialize() noexcept;
|
void Initialize() noexcept;
|
||||||
static void GlobalInitialize() noexcept;
|
static void GlobalInitialize() noexcept;
|
||||||
Xbyak::CodeGenerator code = Xbyak::CodeGenerator(4096, default_cg_mode);
|
Xbyak::CodeGenerator code = Xbyak::CodeGenerator(4096
|
||||||
|
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
|
||||||
|
, Xbyak::DontSetProtectRWE
|
||||||
|
#else
|
||||||
|
, nullptr //Allow RWE
|
||||||
|
#endif
|
||||||
|
);
|
||||||
void (*lock)(volatile int*) = nullptr;
|
void (*lock)(volatile int*) = nullptr;
|
||||||
void (*unlock)(volatile int*) = nullptr;
|
void (*unlock)(volatile int*) = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,15 +9,16 @@
|
|||||||
#include "dynarmic/frontend/A32/translate/a32_translate.h"
|
#include "dynarmic/frontend/A32/translate/a32_translate.h"
|
||||||
|
|
||||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||||
|
#include "dynarmic/interface/A32/config.h"
|
||||||
#include "dynarmic/ir/basic_block.h"
|
#include "dynarmic/ir/basic_block.h"
|
||||||
|
|
||||||
namespace Dynarmic::A32 {
|
namespace Dynarmic::A32 {
|
||||||
|
|
||||||
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf);
|
||||||
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf);
|
||||||
|
|
||||||
void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
void Translate(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) {
|
||||||
return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(block, descriptor, tcb, options);
|
return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(block, descriptor, conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction);
|
bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "dynarmic/interface/A32/arch_version.h"
|
#include "dynarmic/interface/A32/arch_version.h"
|
||||||
|
#include "dynarmic/interface/A32/config.h"
|
||||||
|
|
||||||
namespace Dynarmic::IR {
|
namespace Dynarmic::IR {
|
||||||
class Block;
|
class Block;
|
||||||
@@ -20,28 +21,14 @@ namespace Dynarmic::A32 {
|
|||||||
class LocationDescriptor;
|
class LocationDescriptor;
|
||||||
struct TranslateCallbacks;
|
struct TranslateCallbacks;
|
||||||
|
|
||||||
struct TranslationOptions {
|
|
||||||
ArchVersion arch_version;
|
|
||||||
|
|
||||||
/// This changes what IR we emit when we translate an unpredictable instruction.
|
|
||||||
/// If this is false, the ExceptionRaised IR instruction is emitted.
|
|
||||||
/// If this is true, we define some behaviour for some instructions.
|
|
||||||
bool define_unpredictable_behaviour = false;
|
|
||||||
|
|
||||||
/// This changes what IR we emit when we translate a hint instruction.
|
|
||||||
/// If this is false, we treat the instruction as a NOP.
|
|
||||||
/// If this is true, we emit an ExceptionRaised instruction.
|
|
||||||
bool hook_hint_instructions = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function translates instructions in memory into our intermediate representation.
|
* This function translates instructions in memory into our intermediate representation.
|
||||||
* @param descriptor The starting location of the basic block. Includes information like PC, Thumb state, &c.
|
* @param descriptor The starting location of the basic block. Includes information like PC, Thumb state, &c.
|
||||||
* @param tcb The callbacks we should use to read emulated memory.
|
* @param tcb The callbacks we should use to read emulated memory.
|
||||||
* @param options Configures how certain instructions are translated.
|
* @param conf Configures how certain instructions are translated.
|
||||||
* @return A translated basic block in the intermediate representation.
|
* @return A translated basic block in the intermediate representation.
|
||||||
*/
|
*/
|
||||||
void Translate(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options);
|
void Translate(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function translates a single provided instruction into our intermediate representation.
|
* This function translates a single provided instruction into our intermediate representation.
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2016 MerryMage
|
* Copyright (c) 2016 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
@@ -10,7 +13,7 @@ namespace Dynarmic::A32 {
|
|||||||
|
|
||||||
// BKPT #<imm16>
|
// BKPT #<imm16>
|
||||||
bool TranslatorVisitor::arm_BKPT(Cond cond, Imm<12> /*imm12*/, Imm<4> /*imm4*/) {
|
bool TranslatorVisitor::arm_BKPT(Cond cond, Imm<12> /*imm12*/, Imm<4> /*imm4*/) {
|
||||||
if (cond != Cond::AL && !options.define_unpredictable_behaviour) {
|
if (cond != Cond::AL && !conf.define_unpredictable_behaviour) {
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
// UNPREDICTABLE: The instruction executes conditionally.
|
// UNPREDICTABLE: The instruction executes conditionally.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "dynarmic/interface/A32/config.h"
|
||||||
#include "dynarmic/mcl/bit.hpp"
|
#include "dynarmic/mcl/bit.hpp"
|
||||||
|
|
||||||
#include "dynarmic/frontend/A32/a32_ir_emitter.h"
|
#include "dynarmic/frontend/A32/a32_ir_emitter.h"
|
||||||
@@ -25,12 +26,14 @@ enum class Exception;
|
|||||||
struct TranslatorVisitor final {
|
struct TranslatorVisitor final {
|
||||||
using instruction_return_type = bool;
|
using instruction_return_type = bool;
|
||||||
|
|
||||||
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const TranslationOptions& options)
|
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf)
|
||||||
: ir(block, descriptor, options.arch_version), options(options) {}
|
: ir(block, descriptor, conf.arch_version)
|
||||||
|
, conf(conf)
|
||||||
|
{}
|
||||||
|
|
||||||
A32::IREmitter ir;
|
A32::IREmitter ir;
|
||||||
ConditionalState cond_state = ConditionalState::None;
|
ConditionalState cond_state = ConditionalState::None;
|
||||||
TranslationOptions options;
|
A32::UserConfig const& conf;
|
||||||
|
|
||||||
size_t current_instruction_size;
|
size_t current_instruction_size;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2019 MerryMage
|
* Copyright (c) 2019 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
@@ -9,7 +12,7 @@
|
|||||||
namespace Dynarmic::A32 {
|
namespace Dynarmic::A32 {
|
||||||
|
|
||||||
bool TranslatorVisitor::arm_PLD_imm(bool /*add*/, bool R, Reg /*n*/, Imm<12> /*imm12*/) {
|
bool TranslatorVisitor::arm_PLD_imm(bool /*add*/, bool R, Reg /*n*/, Imm<12> /*imm12*/) {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +21,7 @@ bool TranslatorVisitor::arm_PLD_imm(bool /*add*/, bool R, Reg /*n*/, Imm<12> /*i
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::arm_PLD_reg(bool /*add*/, bool R, Reg /*n*/, Imm<5> /*imm5*/, ShiftType /*shift*/, Reg /*m*/) {
|
bool TranslatorVisitor::arm_PLD_reg(bool /*add*/, bool R, Reg /*n*/, Imm<5> /*imm5*/, ShiftType /*shift*/, Reg /*m*/) {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +30,7 @@ bool TranslatorVisitor::arm_PLD_reg(bool /*add*/, bool R, Reg /*n*/, Imm<5> /*im
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::arm_SEV() {
|
bool TranslatorVisitor::arm_SEV() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +38,7 @@ bool TranslatorVisitor::arm_SEV() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::arm_SEVL() {
|
bool TranslatorVisitor::arm_SEVL() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +46,7 @@ bool TranslatorVisitor::arm_SEVL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::arm_WFE() {
|
bool TranslatorVisitor::arm_WFE() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +54,7 @@ bool TranslatorVisitor::arm_WFE() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::arm_WFI() {
|
bool TranslatorVisitor::arm_WFI() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +62,7 @@ bool TranslatorVisitor::arm_WFI() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::arm_YIELD() {
|
bool TranslatorVisitor::arm_YIELD() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -642,7 +642,7 @@ bool TranslatorVisitor::thumb16_SUB_sp(Imm<7> imm7) {
|
|||||||
|
|
||||||
// SEV<c>
|
// SEV<c>
|
||||||
bool TranslatorVisitor::thumb16_SEV() {
|
bool TranslatorVisitor::thumb16_SEV() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::SendEvent);
|
return RaiseException(Exception::SendEvent);
|
||||||
@@ -650,7 +650,7 @@ bool TranslatorVisitor::thumb16_SEV() {
|
|||||||
|
|
||||||
// SEVL<c>
|
// SEVL<c>
|
||||||
bool TranslatorVisitor::thumb16_SEVL() {
|
bool TranslatorVisitor::thumb16_SEVL() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::SendEventLocal);
|
return RaiseException(Exception::SendEventLocal);
|
||||||
@@ -658,7 +658,7 @@ bool TranslatorVisitor::thumb16_SEVL() {
|
|||||||
|
|
||||||
// WFE<c>
|
// WFE<c>
|
||||||
bool TranslatorVisitor::thumb16_WFE() {
|
bool TranslatorVisitor::thumb16_WFE() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::WaitForEvent);
|
return RaiseException(Exception::WaitForEvent);
|
||||||
@@ -666,7 +666,7 @@ bool TranslatorVisitor::thumb16_WFE() {
|
|||||||
|
|
||||||
// WFI<c>
|
// WFI<c>
|
||||||
bool TranslatorVisitor::thumb16_WFI() {
|
bool TranslatorVisitor::thumb16_WFI() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::WaitForInterrupt);
|
return RaiseException(Exception::WaitForInterrupt);
|
||||||
@@ -674,7 +674,7 @@ bool TranslatorVisitor::thumb16_WFI() {
|
|||||||
|
|
||||||
// YIELD<c>
|
// YIELD<c>
|
||||||
bool TranslatorVisitor::thumb16_YIELD() {
|
bool TranslatorVisitor::thumb16_YIELD() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::Yield);
|
return RaiseException(Exception::Yield);
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2021 MerryMage
|
* Copyright (c) 2021 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
@@ -8,7 +11,7 @@
|
|||||||
|
|
||||||
namespace Dynarmic::A32 {
|
namespace Dynarmic::A32 {
|
||||||
static bool PLDHandler(TranslatorVisitor& v, bool W) {
|
static bool PLDHandler(TranslatorVisitor& v, bool W) {
|
||||||
if (!v.options.hook_hint_instructions) {
|
if (!v.conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +21,7 @@ static bool PLDHandler(TranslatorVisitor& v, bool W) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool PLIHandler(TranslatorVisitor& v) {
|
static bool PLIHandler(TranslatorVisitor& v) {
|
||||||
if (!v.options.hook_hint_instructions) {
|
if (!v.conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,10 +22,12 @@
|
|||||||
|
|
||||||
namespace Dynarmic::A32 {
|
namespace Dynarmic::A32 {
|
||||||
|
|
||||||
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
void TranslateArm(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) {
|
||||||
const bool single_step = descriptor.SingleStepping();
|
const bool single_step = descriptor.SingleStepping();
|
||||||
TranslatorVisitor visitor{block, descriptor, options};
|
TranslatorVisitor visitor{block, descriptor, conf};
|
||||||
bool should_continue = true;
|
bool should_continue = true;
|
||||||
|
|
||||||
|
auto tcb = conf.callbacks;
|
||||||
do {
|
do {
|
||||||
const u32 arm_pc = visitor.ir.current_location.PC();
|
const u32 arm_pc = visitor.ir.current_location.PC();
|
||||||
u64 ticks_for_instruction = 1;
|
u64 ticks_for_instruction = 1;
|
||||||
|
|||||||
@@ -103,10 +103,12 @@ inline bool MaybeVFPOrASIMDInstruction(u32 thumb_instruction) noexcept {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCallbacks* tcb, const TranslationOptions& options) {
|
void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, const A32::UserConfig& conf) {
|
||||||
const bool single_step = descriptor.SingleStepping();
|
const bool single_step = descriptor.SingleStepping();
|
||||||
TranslatorVisitor visitor{block, descriptor, options};
|
TranslatorVisitor visitor{block, descriptor, conf};
|
||||||
bool should_continue = true;
|
bool should_continue = true;
|
||||||
|
|
||||||
|
auto tcb = conf.callbacks;
|
||||||
do {
|
do {
|
||||||
const u32 arm_pc = visitor.ir.current_location.PC();
|
const u32 arm_pc = visitor.ir.current_location.PC();
|
||||||
u64 ticks_for_instruction = 1;
|
u64 ticks_for_instruction = 1;
|
||||||
|
|||||||
@@ -11,19 +11,20 @@
|
|||||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||||
#include "dynarmic/frontend/A64/decoder/a64.h"
|
#include "dynarmic/frontend/A64/decoder/a64.h"
|
||||||
#include "dynarmic/frontend/A64/translate/impl/impl.h"
|
#include "dynarmic/frontend/A64/translate/impl/impl.h"
|
||||||
|
#include "dynarmic/interface/A64/config.h"
|
||||||
#include "dynarmic/ir/basic_block.h"
|
#include "dynarmic/ir/basic_block.h"
|
||||||
#include "dynarmic/ir/terminal.h"
|
#include "dynarmic/ir/terminal.h"
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
namespace Dynarmic::A64 {
|
||||||
|
|
||||||
void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options) {
|
void Translate(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf) {
|
||||||
const bool single_step = descriptor.SingleStepping();
|
const bool single_step = descriptor.SingleStepping();
|
||||||
TranslatorVisitor visitor{block, descriptor, std::move(options)};
|
TranslatorVisitor visitor{block, descriptor, conf};
|
||||||
|
|
||||||
bool should_continue = true;
|
bool should_continue = true;
|
||||||
do {
|
do {
|
||||||
const u64 pc = visitor.ir.current_location->PC();
|
const u64 pc = visitor.ir.current_location->PC();
|
||||||
if (const auto instruction = memory_read_code(pc)) {
|
if (const auto instruction = conf.callbacks->MemoryReadCode(pc)) {
|
||||||
if (auto decoder = Decode<TranslatorVisitor, bool>(visitor, *instruction)) {
|
if (auto decoder = Decode<TranslatorVisitor, bool>(visitor, *instruction)) {
|
||||||
should_continue = *decoder;
|
should_continue = *decoder;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "dynarmic/interface/A64/config.h"
|
||||||
|
|
||||||
namespace Dynarmic {
|
namespace Dynarmic {
|
||||||
|
|
||||||
@@ -22,32 +23,14 @@ namespace A64 {
|
|||||||
|
|
||||||
class LocationDescriptor;
|
class LocationDescriptor;
|
||||||
|
|
||||||
using MemoryReadCodeFuncType = std::function<std::optional<u32>(u64 vaddr)>;
|
|
||||||
|
|
||||||
struct TranslationOptions {
|
|
||||||
/// This changes what IR we emit when we translate an unpredictable instruction.
|
|
||||||
/// If this is false, the ExceptionRaised IR instruction is emitted.
|
|
||||||
/// If this is true, we define some behaviour for some instructions.
|
|
||||||
bool define_unpredictable_behaviour = false;
|
|
||||||
|
|
||||||
/// This tells the translator a wall clock will be used, thus allowing it
|
|
||||||
/// to avoid writting certain unnecessary code only needed for cycle timers.
|
|
||||||
bool wall_clock_cntpct = false;
|
|
||||||
|
|
||||||
/// This changes what IR we emit when we translate a hint instruction.
|
|
||||||
/// If this is false, we treat the instruction as a NOP.
|
|
||||||
/// If this is true, we emit an ExceptionRaised instruction.
|
|
||||||
bool hook_hint_instructions = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function translates instructions in memory into our intermediate representation.
|
* This function translates instructions in memory into our intermediate representation.
|
||||||
* @param descriptor The starting location of the basic block. Includes information like PC, FPCR state, &c.
|
* @param descriptor The starting location of the basic block. Includes information like PC, FPCR state, &c.
|
||||||
* @param memory_read_code The function we should use to read emulated memory.
|
* @param memory_read_code The function we should use to read emulated memory.
|
||||||
* @param options Configures how certain instructions are translated.
|
* @param conf Configures how certain instructions are translated.
|
||||||
* @return A translated basic block in the intermediate representation.
|
* @return A translated basic block in the intermediate representation.
|
||||||
*/
|
*/
|
||||||
void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options);
|
void Translate(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function translates a single provided instruction into our intermediate representation.
|
* This function translates a single provided instruction into our intermediate representation.
|
||||||
|
|||||||
@@ -15,17 +15,20 @@
|
|||||||
#include "dynarmic/frontend/A64/a64_types.h"
|
#include "dynarmic/frontend/A64/a64_types.h"
|
||||||
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
||||||
#include "dynarmic/frontend/imm.h"
|
#include "dynarmic/frontend/imm.h"
|
||||||
|
#include "dynarmic/interface/A64/config.h"
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
namespace Dynarmic::A64 {
|
||||||
|
|
||||||
struct TranslatorVisitor final {
|
struct TranslatorVisitor final {
|
||||||
using instruction_return_type = bool;
|
using instruction_return_type = bool;
|
||||||
|
|
||||||
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, TranslationOptions options)
|
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, A64::UserConfig const& conf)
|
||||||
: ir(block, descriptor), options(std::move(options)) {}
|
: ir(block, descriptor)
|
||||||
|
, conf(conf)
|
||||||
|
{}
|
||||||
|
|
||||||
A64::IREmitter ir;
|
A64::IREmitter ir;
|
||||||
TranslationOptions options;
|
A64::UserConfig const& conf;
|
||||||
|
|
||||||
bool UnpredictableInstruction();
|
bool UnpredictableInstruction();
|
||||||
bool DecodeError();
|
bool DecodeError();
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
/* This file is part of the dynarmic project.
|
/* This file is part of the dynarmic project.
|
||||||
* Copyright (c) 2018 MerryMage
|
* Copyright (c) 2018 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
@@ -25,7 +28,7 @@ static bool ExclusiveSharedDecodeAndOperation(TranslatorVisitor& v, bool pair, s
|
|||||||
if (memop == IR::MemOp::LOAD && pair && Rt == *Rt2) {
|
if (memop == IR::MemOp::LOAD && pair && Rt == *Rt2) {
|
||||||
return v.UnpredictableInstruction();
|
return v.UnpredictableInstruction();
|
||||||
} else if (memop == IR::MemOp::STORE && (*Rs == Rt || (pair && *Rs == *Rt2))) {
|
} else if (memop == IR::MemOp::STORE && (*Rs == Rt || (pair && *Rs == *Rt2))) {
|
||||||
if (!v.options.define_unpredictable_behaviour) {
|
if (!v.conf.define_unpredictable_behaviour) {
|
||||||
return v.UnpredictableInstruction();
|
return v.UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
// UNPREDICTABLE: The Constraint_NONE case is executed.
|
// UNPREDICTABLE: The Constraint_NONE case is executed.
|
||||||
|
|||||||
@@ -42,35 +42,35 @@ bool TranslatorVisitor::NOP() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::YIELD() {
|
bool TranslatorVisitor::YIELD() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::Yield);
|
return RaiseException(Exception::Yield);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::WFE() {
|
bool TranslatorVisitor::WFE() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::WaitForEvent);
|
return RaiseException(Exception::WaitForEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::WFI() {
|
bool TranslatorVisitor::WFI() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::WaitForInterrupt);
|
return RaiseException(Exception::WaitForInterrupt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SEV() {
|
bool TranslatorVisitor::SEV() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::SendEvent);
|
return RaiseException(Exception::SendEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SEVL() {
|
bool TranslatorVisitor::SEVL() {
|
||||||
if (!options.hook_hint_instructions) {
|
if (!conf.hook_hint_instructions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RaiseException(Exception::SendEventLocal);
|
return RaiseException(Exception::SendEventLocal);
|
||||||
@@ -129,7 +129,7 @@ bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3
|
|||||||
return true;
|
return true;
|
||||||
case SystemRegisterEncoding::CNTPCT_EL0:
|
case SystemRegisterEncoding::CNTPCT_EL0:
|
||||||
// HACK: Ensure that this is the first instruction in the block it's emitted in, so the cycle count is most up-to-date.
|
// HACK: Ensure that this is the first instruction in the block it's emitted in, so the cycle count is most up-to-date.
|
||||||
if (!ir.block.instructions.empty() && !options.wall_clock_cntpct) {
|
if (!ir.block.instructions.empty() && !conf.wall_clock_cntpct) {
|
||||||
ir.block.CycleCount()--;
|
ir.block.CycleCount()--;
|
||||||
ir.SetTerm(IR::Term::LinkBlock{*ir.current_location});
|
ir.SetTerm(IR::Term::LinkBlock{*ir.current_location});
|
||||||
return false;
|
return false;
|
||||||
|
|||||||