Compare commits

...

1192 Commits

Author SHA1 Message Date
Connor McLaughlin
e9413f6d94 WIP 2021-02-15 02:36:15 +10:00
Connor McLaughlin
0110295f2c Android: Fix some game settings saving/loading incorrectly 2021-02-15 00:21:27 +10:00
Connor McLaughlin
d8ce98a1e2 Bump shader cache version 2021-02-14 19:25:14 +10:00
Connor McLaughlin
2c1999e622 CDROM: Simulate holding position for GetlocP
Fixes lockups in Tomb Raider.
2021-02-14 18:36:21 +10:00
Connor McLaughlin
0d13e1013d GPU: Fix incorrect dither offset [3][0]
Fixes dots in sky in Silent Hill.
2021-02-14 18:36:21 +10:00
Connor McLaughlin
f7426b0988 GL/Context: Support fbdev 2021-02-14 18:36:21 +10:00
Connor McLaughlin
f5d7fec914 NoGUI: Rename DRMHostInterface to VTYHostInterface 2021-02-14 18:36:21 +10:00
Connor McLaughlin
d4143399eb OpenGLHostDisplay: Support fullscreen mode enumeration (DRM only) 2021-02-14 18:36:21 +10:00
Connor McLaughlin
748e2e9a70 DRMDisplay: Add mode queries 2021-02-14 18:36:21 +10:00
Connor McLaughlin
0c71a97e02 FullscreenUI: Add resolution selection 2021-02-14 18:36:21 +10:00
Connor McLaughlin
5a66639d78 HostDisplay: Add virtual method for getting resolutions 2021-02-14 18:36:21 +10:00
Connor McLaughlin
e7fc904cf4 DRMHostInterface: Set surface size to settings fullscreen mode 2021-02-14 18:36:21 +10:00
Connor McLaughlin
e8832bf552 DRMDisplay: Use width/height/refresh rate to select mode 2021-02-14 18:36:21 +10:00
Connor McLaughlin
b811b78c09 Add refresh rate to window/mode info 2021-02-14 18:36:21 +10:00
Max833
935c73fb6c Qt: Update German translation (#1627)
* Update duckstation-qt_de.ts

* Update duckstation-qt_de.ts

* Update duckstation-qt_de.ts

* Update duckstation-qt_de.ts
2021-02-14 18:35:19 +10:00
Connor McLaughlin
8b8dbc6812 Merge pull request #1630 from andercard0/patch-79
Atualização Português do Brasil
2021-02-14 18:34:54 +10:00
Connor McLaughlin
d07d0b7729 Merge pull request #1632 from 6lackmag3/patch-6
Update strings.xml
2021-02-14 18:34:43 +10:00
Connor McLaughlin
dfaf0797f0 Merge pull request #1637 from zkdpower/master
Update Simple-Chinese language file to latest
2021-02-14 18:34:28 +10:00
zkdpower
63ef510a0c Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-02-13 13:24:37 +08:00
6lackmag3
63b04f6479 Update strings.xml
translation for "Show Resolution" added
2021-02-12 15:46:59 +03:00
Anderson_Cardoso
092aaf1597 Atualização Português do Brasil
Update file to latest.
2021-02-11 19:39:16 -03:00
Connor McLaughlin
eabda2979c Qt: Fix Linux compile 2021-02-12 01:10:08 +10:00
Connor McLaughlin
4e10d100db Android: Don't show VRAM resolution in pt-BR 2021-02-12 01:01:30 +10:00
Connor McLaughlin
c6c67b7b27 ImGui: Remove close button from debug windows
They can be closed by unchecking the setting instead, and it stays in
sync with the config this way.
2021-02-12 01:01:30 +10:00
Connor McLaughlin
c8efade20c CommonHostInterface: Don't draw OSD/FPS as windows
Slight performance improvement.
2021-02-12 01:01:30 +10:00
Connor McLaughlin
9f73791343 Android: Add Show Resolution option to display settings 2021-02-12 01:01:30 +10:00
Connor McLaughlin
de688615ff Qt: Add Clear and Reset buttons to cheat manager 2021-02-12 01:01:30 +10:00
Connor McLaughlin
e75f1c1b6d Qt: Add 'Lock Toolbar' option 2021-02-12 01:01:30 +10:00
Anderson_Cardoso
32ee362228 Android Update Strings (#1615)
* Android Update Strings 

Strings updated to latest.

* Update strings.xml

* Update strings.xml

Co-authored-by: Connor McLaughlin <stenzek@gmail.com>
2021-02-11 02:27:41 +10:00
Connor McLaughlin
b9695eb547 Merge pull request #1616 from andercard0/patch-78
Android Update Arrays
2021-02-11 02:20:09 +10:00
shikulja
22963ecbf3 Update duckstation-qt_ru.ts (#1619)
* Update duckstation-qt_ru.ts

small update, add some new strings, minor adjustments

* Update duckstation-qt_ru.ts
2021-02-11 02:19:41 +10:00
Connor McLaughlin
bfa2b72e08 Fix a couple of name typos 2021-02-11 02:17:25 +10:00
Connor McLaughlin
6ab926ab28 System: Make the SBI check a confirm dialog instead of message 2021-02-11 02:04:47 +10:00
Connor McLaughlin
5f6fce9d98 CommonHostInterface: Remove Rewind hotkey on Android
It's not enablable in the UI anywhere.
2021-02-11 01:40:00 +10:00
Anderson_Cardoso
a03eb9f352 Android Update Arrays
Arrays updated to latest.
2021-02-08 22:17:23 -03:00
Connor McLaughlin
2446e945a7 GameSettings: Force icache in Roland Garros French Open 2001 2021-02-09 01:23:53 +10:00
Connor McLaughlin
3b5739eca8 Merge pull request #1600 from 6lackmag3/patch-4
Update strings.xml
2021-02-09 01:11:21 +10:00
Connor McLaughlin
6497aa9f4a Merge pull request #1599 from 6lackmag3/patch-3
Update strings.xml
2021-02-09 01:11:03 +10:00
Connor McLaughlin
d1536fdc62 GameSettings: Disable analog mode in Digimon World 2021-02-09 01:06:48 +10:00
Connor McLaughlin
ef97131c9d Timers: Handle target = 0 case
Fixes Super Gals! Kotobuki Ran Special - Ikemen Get You Gals Party
hanging at boot.
2021-02-09 01:01:36 +10:00
6lackmag3
556913dad3 Update strings.xml
fix typos
2021-02-07 21:56:18 +03:00
6lackmag3
3857d2426d Update strings.xml
fixes
2021-02-07 20:10:37 +03:00
Connor McLaughlin
537f833658 FullscreenUI: Fix binding immediately when activating with controller 2021-02-08 00:57:56 +10:00
Connor McLaughlin
4f75f2d266 Android: Move ImGui NewFrame/EndFrame to correct location 2021-02-08 00:48:18 +10:00
Connor McLaughlin
53fb55ff15 Add evdev controller interface 2021-02-08 00:47:39 +10:00
Connor McLaughlin
ee3aa0dc4d OpenGLHostDisplay: Fix incorrect default for PBO streaming 2021-02-08 00:47:34 +10:00
Connor McLaughlin
d356b95819 Qt: Move ImGui NewFrame/EndFrame to correct location 2021-02-08 00:47:29 +10:00
Connor McLaughlin
515b85fa36 Android: Set navigation bar colour to black 2021-02-08 00:47:24 +10:00
Connor McLaughlin
1b1a5996ec CI: Enable DRM/KMS and Wayland for AppImage builds 2021-02-08 00:45:37 +10:00
Connor McLaughlin
eb993ae330 README: Add Linux packages for DRM/KMS 2021-02-08 00:43:09 +10:00
Connor McLaughlin
18114806f8 Merge pull request #1595 from andercard0/patch-75
Update Strings Pt-Br
2021-02-08 00:36:15 +10:00
Connor McLaughlin
6f22ea0ffa Update strings.xml 2021-02-07 20:44:38 +10:00
Connor McLaughlin
590275a20e Update strings.xml 2021-02-07 20:18:39 +10:00
Connor McLaughlin
8b11511a9b Merge pull request #1597 from zkdpower/master
Update Simple-Chinese language file to latest
2021-02-07 20:16:58 +10:00
Connor McLaughlin
bb5d4017cf Merge pull request #1593 from Max833/master
Qt: Update German translation
2021-02-07 20:16:36 +10:00
Connor McLaughlin
c9b874eeec Merge pull request #1592 from andercard0/patch-73
Atualização Português do Brasil
2021-02-07 20:16:26 +10:00
Connor McLaughlin
8c77c4a493 Merge pull request #1596 from andercard0/patch-76
Update Japanese Language by - Mikakunin
2021-02-07 20:16:07 +10:00
Connor McLaughlin
0d5c0308db Merge pull request #1594 from andercard0/patch-74
Update Arrays Pt-Br
2021-02-07 20:15:37 +10:00
Connor McLaughlin
c043643c4d GPU/HW: Fix typo in –IncludeVRAMDirtyRectangle() name 2021-02-07 20:00:16 +10:00
Connor McLaughlin
4a240958ff GPU/HW: Work around VRAM copy glBlitFramebuffer broken in Mali 2021-02-07 19:59:50 +10:00
zkdpower
e7238c236e Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-02-07 11:57:12 +08:00
Anderson_Cardoso
a47a8daa62 Update Japanese Language by - Mikakunin
Update Japanese Language by - Mikakuni to latest.
2021-02-07 00:19:00 -03:00
Anderson_Cardoso
d17833d6c6 Update Strings Pt-Br
Updated to latest. 

Note: 

- OSD still missing

- There is a "r" letter that i guess need to be removed as follows: 

duckstation / android /app/ src/ main/ res/ values-pt-rBR

Should be: pt-BR only
2021-02-07 00:14:16 -03:00
Anderson_Cardoso
482fdc8f35 Update Arrays Pt-br
Update to latest.
2021-02-07 00:08:48 -03:00
Max833
c700e29c51 Update duckstation-qt_de.ts 2021-02-07 02:11:10 +01:00
Anderson_Cardoso
3a5b24b37e Atualização Português do Brazil
Update file to latest.
2021-02-06 20:20:32 -03:00
Connor McLaughlin
275fedbaf2 Android: Compile fix 2021-02-07 03:42:15 +10:00
Connor McLaughlin
cc0cc6fbb9 Qt: Add disable all enhancements to debug menu 2021-02-07 03:27:48 +10:00
Connor McLaughlin
a77edc6436 Settings: Default console logging on Android to on 2021-02-07 03:27:37 +10:00
Connor McLaughlin
fc578b7ec7 NoGUI: Fix debug assertion firing on renderer switch 2021-02-07 03:15:06 +10:00
Connor McLaughlin
3bc34d40a1 Android: Fix a possible crash when main recreates 2021-02-07 03:10:45 +10:00
Connor McLaughlin
1a63edec27 Android: Use save on exit option as default for resume 2021-02-07 03:10:45 +10:00
Connor McLaughlin
6ad2b72c2e Android: Add graphical save/load state selector 2021-02-07 03:10:43 +10:00
Connor McLaughlin
b560142015 Merge pull request #1588 from RaydenX93/update_20210206
Qt Italian Translation Update
2021-02-07 03:09:20 +10:00
Connor McLaughlin
c0dff8ab0b Merge pull request #1583 from 6lackmag3/patch-2
Update arrays.xml
2021-02-07 03:09:12 +10:00
Connor McLaughlin
ccc25fc131 GL/Context: Filter Mali GPUs based on ARM GL_VENDOR only 2021-02-06 20:25:26 +10:00
Connor McLaughlin
b20b1a2fa8 OpenGLHostDisplay: Only disable streaming PBO on Adreno
It's slightly faster on Mali.
2021-02-06 20:19:10 +10:00
Connor McLaughlin
837fb6128b GPU/HW: Fix mask bit when rendering with transparency and no DSB
Fixes some sprites in Bloody Roar on Mali GPUs.
2021-02-06 20:14:28 +10:00
Connor McLaughlin
011df33fc4 GL/StreamBuffer: Support non-coherent mappings 2021-02-06 19:23:39 +10:00
Connor McLaughlin
d416dbb461 FullscreenUI: Ensure fonts are at least one pixel high 2021-02-06 19:21:39 +10:00
Connor McLaughlin
c03c4cb95a GPU: Elide VRAM copies when they will have no effect
Can provide a performance boost in most games because of the redundant
copy they issue once a frame.
2021-02-06 19:20:14 +10:00
Connor McLaughlin
5a9abd55a1 GL/Context: Disable GL_{EXT,OES}_copy_image on Mali
It is **very** slow because it seems to be implemented on the CPU...
2021-02-06 19:20:09 +10:00
Connor McLaughlin
c6ed19cc7b OpenGLHostDisplay: Don't use PBOs for software upload on GLES 2021-02-06 19:20:05 +10:00
Connor McLaughlin
701edb335a Various warning fixes 2021-02-06 19:19:55 +10:00
Connor McLaughlin
3c910782ca FullscreenUI: Fix heading line width not being scaled 2021-02-06 19:19:21 +10:00
Connor McLaughlin
105376b1b3 FullscreenUI: Don't draw OSD over windows 2021-02-06 19:18:44 +10:00
Connor McLaughlin
d7962fdac7 ImGui: Use safe strcat/scanf on MSVC 2021-02-06 19:16:39 +10:00
RaydenX93
bfdf33868f Update duckstation-qt_it.ts 2021-02-06 09:38:05 +01:00
Connor McLaughlin
8582e2770d CrashHandler: Save minidump on Windows 2021-02-06 13:23:50 +10:00
6lackmag3
76bf5b5aa2 Update arrays.xml
fix misleading translation
2021-02-05 11:22:26 +03:00
Connor McLaughlin
f943aa0489 Merge pull request #1582 from MaddTheSane/printfFixes
Logging fixes
2021-02-05 11:47:38 +10:00
Connor McLaughlin
10daea9faf Merge pull request #1581 from MaddTheSane/printfLike
Add printf-like macro to Writef.
2021-02-05 11:46:39 +10:00
Connor McLaughlin
8b79e2c006 Merge pull request #1580 from MaddTheSane/patch-2
Update shadergen.cpp
2021-02-05 11:45:43 +10:00
C.W. Betts
4591e75f5b Fix the last formatting warning I was able to find. 2021-02-04 18:20:58 -07:00
C.W. Betts
662d6e9711 Fix possible log formatting errors. 2021-02-04 17:54:51 -07:00
C.W. Betts
01b3b5066d Add printf-like macro.
This should help catch some formatting bugs.
2021-02-04 17:15:28 -07:00
C.W. Betts
2c2af6c751 Update shadergen.cpp
Quiets a warning in Clang about copying variables.

Actual warning text: Loop variable '[qualifiers, name]' of type 'const std::__1::pair<const char *, const char *>' creates a copy from type 'const std::__1::pair<const char *, const char *>'
2021-02-04 13:05:59 -07:00
Connor McLaughlin
05545566e7 NoGUI: Fix crash when initialization fails 2021-02-05 02:34:08 +10:00
Connor McLaughlin
39a4aafee5 Android: Make sure EmulationActivity is exported 2021-02-05 02:29:14 +10:00
Connor McLaughlin
43d1495a63 OpenGLHostDisplay: Allow filtering to be toggled for GLES2 path 2021-02-05 02:28:03 +10:00
Connor McLaughlin
d455b61d5e OpenGLHostDisplay: Fix interlaced software renderer output 2021-02-05 02:16:45 +10:00
Connor McLaughlin
7b4650700f StringUtil: Add StrideMemCpy/StrideMemCmp 2021-02-05 02:16:15 +10:00
Connor McLaughlin
d4997c6fb9 Android: Manually scale axis values instead of using motion range 2021-02-05 00:39:42 +10:00
Connor McLaughlin
d0667ba32a NoGUI: Prefer SDL host interface over DRM/KMS if display present 2021-02-04 23:49:21 +10:00
Connor McLaughlin
3e9fdf22bf NoGUI: Move DRM display to GL context
We don't use it for Vulkan.
2021-02-04 19:39:19 +10:00
Connor McLaughlin
8f9bbb0bba Vulkan: Support VK_KHR_display 2021-02-04 19:25:21 +10:00
Connor McLaughlin
469010868e Android: Add missing menu file 2021-02-04 14:09:06 +10:00
Connor McLaughlin
929863e7d6 Merge pull request #1576 from falsepopsky/updateSpanish
updated spanish translation
2021-02-04 13:48:50 +10:00
Connor McLaughlin
2ae6163523 Merge pull request #1562 from andercard0/patch-72
Atualização Português do Brasil
2021-02-04 13:48:37 +10:00
Connor McLaughlin
0d911f1ccd NoGUI: Fix ImGui assertion on confirm/error message 2021-02-04 13:47:16 +10:00
Connor McLaughlin
2029702eda Android: Add option to manually inject a path into the game list 2021-02-04 13:47:16 +10:00
Connor McLaughlin
8647423fe9 Update issue template 2021-02-04 13:47:16 +10:00
falsepopsky
4c0d3c5c9d fixed some misleading translation in android spanish, also updated to latest duckstation-qt_es 2021-02-03 21:59:24 -03:00
Connor McLaughlin
26f942cb2e Merge pull request #1569 from ggrtk/readme-gamecontrollerdb
README.md: Update SDL Game Controller Database section
2021-02-03 16:41:41 +10:00
Albert Liu
b9f72cefc4 README.md: Update SDL Game Controller Database section 2021-02-02 22:19:05 -08:00
Anderson_Cardoso
281af1d23a Atualização Português do Brasil
Update language file to latest and some tiny fixes.
2021-02-01 23:25:21 -03:00
Connor McLaughlin
fd269ec9dd FullscreenUI: Use format string for TextWrapped() 2021-02-02 04:06:57 +10:00
Connor McLaughlin
55b61e9030 Android: Add Russian to language override list 2021-02-02 03:58:21 +10:00
Connor McLaughlin
a50052bd92 Merge pull request #1554 from Max833/master
Qt: Fix incorrect widget help and translation
2021-02-02 03:54:33 +10:00
Connor McLaughlin
62fe03782e Merge pull request #1555 from 6lackmag3/master
Russian translation for Android
2021-02-02 03:54:09 +10:00
Connor McLaughlin
3fec066a92 Merge pull request #1557 from zkdpower/master
Update Simple-Chinese language file to latest
2021-02-02 03:53:14 +10:00
Anderson_Cardoso
adb1857d8c Atualização Pt-br (#1558)
* Atualização Pt-br

Small fixes only.

* Update duckstation-qt_pt-br.ts
2021-02-02 03:52:55 +10:00
Connor McLaughlin
3b85057728 Merge pull request #1553 from 6lackmag3/patch-1
Update strings.xml
2021-02-02 03:52:29 +10:00
Connor McLaughlin
3f981f0ceb Update game settings/compatibility list 2021-02-02 03:51:48 +10:00
Connor McLaughlin
e0dd45c35e FullscreenUI: Fix game list settings not applying 2021-02-02 01:56:28 +10:00
Connor McLaughlin
1e8752759d NoGUI: Set default settings if missing 2021-02-02 01:47:27 +10:00
Connor McLaughlin
c54842830f FullscreenUI: Support modal error/confirmation 2021-02-02 01:40:37 +10:00
Connor McLaughlin
626b2ecec1 GPU/Vulkan: Fix a possible layout violation when displaying
Happened in some games, e.g. Driver.
2021-02-02 00:52:23 +10:00
Connor McLaughlin
43bb69fb6b GPU/SW: Fix 576-line scanout of PAL games 2021-02-01 18:39:36 +10:00
Connor McLaughlin
904680f0df Settings: Make integer and linear upscaling mutually exclusive 2021-02-01 18:39:15 +10:00
zkdpower
b7af4f8d62 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-02-01 10:32:39 +08:00
6lackmag3
c7e08ec420 Create strings.xml
strings for Russian translation
2021-02-01 04:02:10 +03:00
6lackmag3
ad2fd0d682 Create arrays.xml
arrays for Russian translation
2021-02-01 04:00:20 +03:00
Max833
33e8b8230f Update duckstation-qt_de.ts 2021-01-31 23:20:07 +01:00
Max833
276f2e2ceb Update advancedsettingswidget.cpp 2021-01-31 22:02:40 +01:00
6lackmag3
2a6ac1115a Update strings.xml
with -> wish
2021-01-31 23:05:42 +03:00
Connor McLaughlin
91092847f8 CommonHostInterface: Restore display skip on exit/pause
Fixes CPU usage/controller moving too quickly in menus after fast
forwarding in big duck mode.
2021-02-01 02:08:52 +10:00
Connor McLaughlin
cbdf722dd6 GL/ContextEGL: Fix compiling with both DRM/KMS and X11 enabled 2021-02-01 01:45:30 +10:00
Connor McLaughlin
dac9cdd04c GL/Context: Ensure context is destroyed before GBM device
Fixes crash on shutdown when running under DRM/KMS.
2021-02-01 01:28:39 +10:00
Connor McLaughlin
1a9120135f FullscreenUI: Fix some advanced setings not saving 2021-02-01 01:13:05 +10:00
Max833
bd43241f3e Qt: Update German translation and register widget help (based on the new UI) (#1544)
* Update duckstation-qt_de.ts

* Update biossettingswidget.cpp

* Update emulationsettingswidget.cpp

* Update advancedsettingswidget.cpp

* Update displaysettingswidget.cpp
2021-02-01 01:11:49 +10:00
Connor McLaughlin
260e39a516 Merge pull request #1549 from andercard0/patch-70
Atualização Português do Brazil
2021-02-01 01:11:19 +10:00
Connor McLaughlin
590513350c NoGUI: Start in fullscreen when option or command line flag is set 2021-02-01 01:10:32 +10:00
Connor McLaughlin
23e102b90a GPU: Make display texture 720x576 instead of 1024x512
Some PAL games render in the full permissable 576 height, not 512.
2021-02-01 01:10:32 +10:00
Connor McLaughlin
d1a5b89f0a FullscreenUI: Fix some textures leaking at shutdown 2021-02-01 01:10:32 +10:00
Connor McLaughlin
18405a713c FullscreenUI: Fix debug windows not drawing 2021-02-01 01:10:32 +10:00
Connor McLaughlin
51babf4009 AudioStream: Fix assertion failure in debug builds 2021-02-01 01:10:32 +10:00
Anderson_Cardoso
55415d3ce0 Atualização Português do Brazil
Update file to latest
2021-01-31 12:07:14 -03:00
Connor McLaughlin
cc582912b6 Update README.md 2021-01-31 18:25:23 +10:00
Connor McLaughlin
c17fb88426 FullscreenUI: Fix controller binding setting instantly 2021-01-31 18:11:56 +10:00
Connor McLaughlin
bb2e35b732 FullscreenUI: Load covers on demand 2021-01-31 18:11:56 +10:00
Connor McLaughlin
2dabccffc6 CI: Package NoGUI AppImage on Linux instead of SDL 2021-01-31 18:11:56 +10:00
Connor McLaughlin
85b4a02f20 Fix Android build 2021-01-31 17:28:37 +10:00
Connor McLaughlin
98bad30af8 NoGUI: Merge in old branch and use base NoGUI class for SDL 2021-01-31 17:10:27 +10:00
Connor McLaughlin
b09da307b5 Common: Add DRM display helper class and GBM GL context 2021-01-31 17:10:27 +10:00
Connor McLaughlin
b267020d07 dep: Remove nativefiledialog 2021-01-31 17:10:27 +10:00
Connor McLaughlin
dc0eb4cb04 Replace duckstation-sdl with stub directing users to duckstation-qt 2021-01-31 17:10:27 +10:00
Connor McLaughlin
cae5bc1712 Add NoGUI frontend based on old SDL frontend + fullscreen UI 2021-01-31 17:10:27 +10:00
Connor McLaughlin
61e4e6f140 Add "Fullscreen UI" 2021-01-31 17:10:27 +10:00
Connor McLaughlin
0cdd1a70c0 Common/Image: Add helper for loading from stream 2021-01-31 17:10:27 +10:00
Connor McLaughlin
3a7d9f1725 CommonHostInterface: Add controller nav helpers 2021-01-31 17:10:27 +10:00
Connor McLaughlin
61d0af30a2 FileSystem: Add read/write binary stream helpers 2021-01-31 17:10:27 +10:00
Connor McLaughlin
41be96ef93 CommonHostInterface: Make RunLater()/ApplySettings() virtual 2021-01-31 17:10:27 +10:00
Connor McLaughlin
ec60fa3c9d CommonHostInterface: Make fullscreen/exit functions public 2021-01-31 17:10:27 +10:00
Connor McLaughlin
2dbb3325ff CommonHostInterface: Tweak frame boundary for loading screen 2021-01-31 17:10:27 +10:00
Connor McLaughlin
e1bf362d13 CommonHostInterface: Extract ff/turbo hotkeys to functions 2021-01-31 17:10:27 +10:00
Connor McLaughlin
bed1abf0b8 CommonHostInterface: Add media path to save state info 2021-01-31 17:10:27 +10:00
Connor McLaughlin
4540a190c1 CommonHostInterface: Make input profile functions public 2021-01-31 17:10:27 +10:00
Connor McLaughlin
556cd6d168 CommonHostInterface: Add enumerator for OSD messages 2021-01-31 17:10:27 +10:00
Connor McLaughlin
96a36f4850 SDL: Remove gamepad handler from ImGui 2021-01-31 17:10:27 +10:00
Connor McLaughlin
48f78a9c41 GameList: Expose search directories list 2021-01-31 17:10:27 +10:00
Connor McLaughlin
55a1d0437d System: Display message on media change 2021-01-31 17:10:27 +10:00
Connor McLaughlin
98b4101cd7 Settings: Expose Save() method to interface 2021-01-31 17:10:27 +10:00
Connor McLaughlin
9d08f2e277 Settings: Fix show resolution not correctly saving to file 2021-01-31 17:10:27 +10:00
Connor McLaughlin
5875b738dc Common/FileSystem: Add a helper to get root directory list 2021-01-31 17:10:27 +10:00
Connor McLaughlin
7a48bcc585 FrontendCommon: Remove WITH_IMGUI #ifdefs
We never compile FrontendCommon without imgui anyway.
2021-01-31 17:10:27 +10:00
Connor McLaughlin
e697d9aa33 HostDisplay: Move imgui context creation to base class 2021-01-31 17:10:27 +10:00
Connor McLaughlin
e132cac0e5 ImGui: Clear memory for font after creating texture 2021-01-31 17:10:27 +10:00
Connor McLaughlin
e614522de5 Common/String: Add helpers for std::string, std::string_view 2021-01-31 17:10:27 +10:00
Connor McLaughlin
d8ea9c2983 GameSettings: Add helper to query number of user settings 2021-01-31 17:10:27 +10:00
Connor McLaughlin
582c77b604 ImGuiStyle: Return the font we create 2021-01-31 17:10:26 +10:00
Connor McLaughlin
a563f99191 dep/imgui: Update to 9499afdf5e7f22e2cf4bf7c365d18f7e1d07572b 2021-01-31 17:10:10 +10:00
Connor McLaughlin
6f60960a1d dep/imgui: Move internal header to public include 2021-01-31 17:07:32 +10:00
Connor McLaughlin
7d036d6fee CI: Provide Windows build symbols as separate file 2021-01-31 17:00:57 +10:00
Connor McLaughlin
5aeabf028b Qt: Install crash handler on startup 2021-01-31 17:00:57 +10:00
Connor McLaughlin
122cf67bb3 Common: Add crash handler functions for Windows 2021-01-31 17:00:57 +10:00
Connor McLaughlin
35f8ea13d9 AudioStream: Prevent writing too many frames at once and hanging 2021-01-31 17:00:57 +10:00
Connor McLaughlin
ef7d135492 GPU: Fix missing sync when hblank is pending 2021-01-31 16:39:51 +10:00
Connor McLaughlin
9d80c48d6f CPU: Fix icache missing from save state 2021-01-31 16:39:51 +10:00
Anderson_Cardoso
99bedb0f0b Android Updated some missing Strings to latest.
Yo, @stenzek

Please note that I'm really not sure if this is right or not.. if something is wrong please let me know and will redo it.

Added Missing Strings

- Main Menu
Controller Mapping

- Settings
Game Directories / Summary Game Directories

- Theme
Theme / Array

- Sync to host refresh rate
Settings as well as Summary

- Audio
audio resampling / summary

- Controller Mapping
controller mapping / summary

- Enhancements
disable enhancements / summary

Advanced
- Sustained Performance / summary
- Threaded GPU Presentation / summary
- Optimal frame pacing / Summary
2021-01-31 16:39:51 +10:00
Anderson_Cardoso
b43b24ce8d Android Updated Some Missing Arrays
Updated some missing arrays for Portuguese language translation.
2021-01-31 16:39:51 +10:00
Connor McLaughlin
84dd24902c Android: Fix incorrect setting key for FF volume 2021-01-31 16:39:51 +10:00
Connor McLaughlin
678ef7d7b6 Android: Add Spanish to language override selector 2021-01-31 16:39:51 +10:00
Connor McLaughlin
c6ced52bc7 Merge pull request #1541 from PugsyMAME/master
Cheat Database maintenance
2021-01-31 16:23:23 +10:00
Connor McLaughlin
fa2cca1429 Merge pull request #1540 from ggrtk/analog-controller-update
AnalogController: Update behavior based on hardware testing
2021-01-31 16:23:11 +10:00
Connor McLaughlin
c4386d6e71 Merge pull request #1534 from zkdpower/master
Update Simple-Chinese language file to latest
2021-01-31 16:22:56 +10:00
Connor McLaughlin
9abfbdd86f Merge pull request #1531 from falsepopsky/spanishTranslationAndroid
Spanish translation android
2021-01-31 16:22:34 +10:00
Connor McLaughlin
c61dc0dcbe Merge pull request #1522 from andercard0/patch-67
Atualização Português do Brasil
2021-01-31 16:21:23 +10:00
Max833
c10e62e729 Qt: Update German translation (#1524)
* Update duckstation-qt_de.ts

* Update duckstation-qt_de.ts
2021-01-31 16:20:39 +10:00
PugsyMAME
f98f8ed726 Cheat Database maintenance
Cleaned up more cheats and added some more cheats, imported a bunch of widescreen cheats.
2021-01-30 15:37:52 +00:00
Albert Liu
2938c946f9 AnalogController: Improve accuracy of rumble configuration 2021-01-30 00:53:43 -08:00
Albert Liu
c9c2f1bd21 AnalogController: Handle more config mode 0x46 and 0x47 cases 2021-01-29 23:50:45 -08:00
zkdpower
c03f48c907 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-01-29 17:06:21 +08:00
falsepopsky
e8515322f4 added missed strings <display all frames> for values-es 2021-01-28 22:20:48 -03:00
falsepopsky
24c7021d0c new language translation for android => Spanish, also updated and fixed the last duckstation-qt_es translation to latest 2021-01-28 21:54:54 -03:00
Connor McLaughlin
3c2b11fccb System: Don't log rewind pending flag when disabled 2021-01-29 01:27:32 +10:00
Anderson_Cardoso
43a682b358 Atualização Português do Brasil
Update Brazilian Portuguese language to latest.
2021-01-28 12:06:56 -03:00
Connor McLaughlin
84c30703b2 Settings: Disable interlacing by default
The games which require it are auto-disabled by gameini.
2021-01-28 23:52:25 +10:00
Connor McLaughlin
9ada3c8e6f Settings: Rename 'Display All Frames' to 'Optimal Frame Pacing' 2021-01-28 23:50:39 +10:00
Connor McLaughlin
4bb3fb48f9 System: Add a new throttler/pacer which can catch up on lost time
This can result in worse frame pacing, so if you have a decent machine
you'll probably want to turn on "display all frames" in display
settings.

But, it's sadly needed for Android.
2021-01-28 21:04:23 +10:00
Connor McLaughlin
4e583890ea AudioStream: Add option to wait until a full buffer is queued 2021-01-28 21:04:23 +10:00
Connor McLaughlin
9316ce532b Common/Timer: Add SleepUntil() method 2021-01-28 21:04:23 +10:00
Max833
ed4ed259e3 UI: Add missing register widget help (#1515)
* Update displaysettingswidget.cpp

* Update generalsettingswidget.cpp

* Update consolesettingswidget.cpp
2021-01-28 21:03:51 +10:00
Connor McLaughlin
d23474f552 Merge pull request #1516 from falsepopsky/SpanishTranslation
Update Spanish translation file to Latest
2021-01-28 21:02:18 +10:00
falsepopsky
061268e76f Updated Spanish Translation by @falsepopsky 2021-01-26 20:51:54 -03:00
Connor McLaughlin
35dc530b9a Android: Pin emu thread to exclusive cores where supported 2021-01-27 01:21:03 +10:00
Connor McLaughlin
700f916a34 Qt: Update Japanese translation by mikakunin 2021-01-27 01:21:03 +10:00
Connor McLaughlin
b96136a9ec Android: Fix crash when loading input profile ingame 2021-01-27 01:21:03 +10:00
Connor McLaughlin
0b4363679c Android: Block for window changes/surface destruction 2021-01-27 01:21:03 +10:00
Connor McLaughlin
368820d6e9 Vulkan: Default to two swap chain images 2021-01-27 01:21:03 +10:00
Connor McLaughlin
1320e4fdab GameSettings: Fix texture filter setting not loading from ini 2021-01-27 01:21:03 +10:00
Connor McLaughlin
c119ccffc8 Merge pull request #1511 from andercard0/patch-66
Atualização Português do Brasil
2021-01-27 01:14:17 +10:00
Connor McLaughlin
b776541164 Merge pull request #1512 from zkdpower/master
Update Simple-Chinese language file to latest
2021-01-27 01:14:03 +10:00
zkdpower
c5dd0ef2ae Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-01-26 11:31:02 +08:00
Anderson_Cardoso
9e394c31bf Atualização Português do Brasil
Update translation to latest.
2021-01-25 23:06:57 -03:00
Connor McLaughlin
1b6780386f Qt: Update Japanese translation by mikakunin 2021-01-26 03:38:32 +10:00
Connor McLaughlin
a5dfc68ac9 GameSettings: Add runahead as per-game setting 2021-01-26 03:38:32 +10:00
Connor McLaughlin
16a32bf696 Qt: Simplify runahead settings 2021-01-26 03:38:31 +10:00
Connor McLaughlin
1b16ba3d98 Warning fixes 2021-01-26 03:38:31 +10:00
Connor McLaughlin
e79dff1731 System: Use hybrid sleep on Android 2021-01-26 03:38:31 +10:00
Connor McLaughlin
52f5ca7e28 Common/Timer: Add additional sleep functions 2021-01-26 03:38:31 +10:00
Connor McLaughlin
0d473e8681 ImGui: Fix incorrect buffer binding/crash in GLES2 2021-01-26 03:38:31 +10:00
Connor McLaughlin
8cafe856f0 OpenGLHostDisplay: Work around functions unavailable in GLES2 2021-01-26 03:38:31 +10:00
Connor McLaughlin
24dd49e05d GPU: Fix runahead with MSAA enabled in D3D11/Vulkan 2021-01-26 03:22:23 +10:00
Max833
31727b51a7 Update CONTRIBUTORS.md 2021-01-26 03:22:23 +10:00
Max833
8ceadf802c Update german translation 2021-01-26 03:22:23 +10:00
zkdpower
791012d151 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-01-26 03:22:23 +10:00
Connor McLaughlin
12dd62a738 Qt: Add missing minipsf extension to all file types filter 2021-01-25 02:30:28 +10:00
Connor McLaughlin
bcfdb19c36 Merge pull request #1503 from andercard0/patch-65
Atualização Português Brasil
2021-01-25 02:30:15 +10:00
Anderson_Cardoso
557f3c9ca1 Atualização Português Brasil
Updated translation to latest.
2021-01-24 12:59:33 -03:00
Connor McLaughlin
b7752ff30b CDROM: Update position when pausing while seeking instead of erroring
This was causing freezes in FF7 - needs more research.
2021-01-25 01:49:35 +10:00
Connor McLaughlin
f47784cb41 Update latest news/readme 2021-01-25 01:34:13 +10:00
Connor McLaughlin
6eeca57a06 CommonHostInterface: Wrap OSD messages 2021-01-25 01:15:46 +10:00
Connor McLaughlin
b3ce2b21c0 System: Prevent using both runahead and rewind concurrently 2021-01-25 01:15:46 +10:00
Connor McLaughlin
3f96473fb5 System: Reuse existing texture/buffers for runahead/rewind 2021-01-25 01:15:46 +10:00
Connor McLaughlin
e01d66d18e System: Implement runahead 2021-01-25 01:15:46 +10:00
Connor McLaughlin
689b62e065 Qt: Add settings for rewind 2021-01-25 01:15:45 +10:00
Connor McLaughlin
516d685dd0 System: Add memory-only save states and rewind 2021-01-25 01:15:45 +10:00
Connor McLaughlin
6c6fdeb15e HostDisplay: Make textures have levels/layers/samples attributes 2021-01-24 20:41:40 +10:00
Connor McLaughlin
e54ba23c4f Qt: Move speed settings into its own category 2021-01-24 20:41:40 +10:00
Connor McLaughlin
ddcc29c8a6 Qt: Delay showing game list refresh progress
Otherwise we spend more time updating the visuals than actually
scanning.
2021-01-24 18:55:37 +10:00
Connor McLaughlin
a84bf0d8cf Android: Support PSFs in game list 2021-01-24 18:24:07 +10:00
Connor McLaughlin
4a60cc4c1e VulkanHostDisplay: Ensure previous frame is presented before acquiring image 2021-01-24 17:37:09 +10:00
Connor McLaughlin
b1d4d5db5e Vulkan/SwapChain: Recreate semaphores when resizing
Prevents us acquiring an image on an already-signaled semaphore.
2021-01-24 17:37:09 +10:00
Connor McLaughlin
b107cdee53 Android: Add manual disc change from file 2021-01-24 17:37:09 +10:00
Connor McLaughlin
59810bf8db Android: Add game directory list editor 2021-01-24 17:37:09 +10:00
Connor McLaughlin
6a122623fa GameList: Increment progress on each file, not each load 2021-01-24 17:37:09 +10:00
Connor McLaughlin
d62e6ffbb3 Qt: Add icons for unknown region and PSF files in game list 2021-01-24 17:37:09 +10:00
Connor McLaughlin
f61427017d GameList: Remove exe/psf extensions from titles in game list 2021-01-24 17:37:09 +10:00
Connor McLaughlin
76ec38ee47 GameList: Support scanning PSF/MiniPSF files 2021-01-24 17:37:09 +10:00
Connor McLaughlin
41a9231a87 GameList: Use region from exe 2021-01-24 17:37:09 +10:00
Connor McLaughlin
b62f31fd96 System: Use region from exe/psf when booting 2021-01-24 17:37:09 +10:00
Connor McLaughlin
253b115b11 PSFLoader: Detect region from exe 2021-01-24 17:37:09 +10:00
Connor McLaughlin
10135e08a2 PSFLoader: Support loading minipsfs/libraries 2021-01-24 17:37:09 +10:00
Connor McLaughlin
baf8b1af43 Update game settings 2021-01-24 17:37:09 +10:00
Connor McLaughlin
2782172b7e Merge pull request #1500 from CookiePLMonster/update-pl-loc
Update PL translation
2021-01-24 17:33:06 +10:00
Silent
c31ec6d428 Update PL translation 2021-01-23 22:17:08 +01:00
Silent
e8e8fd9ffa InputBindingDialog: Allow to translate the Close button 2021-01-23 22:02:10 +01:00
Connor McLaughlin
3c3bfdea93 Android: Don't call toast methods off UI thread 2021-01-21 13:56:10 +10:00
Connor McLaughlin
4433197665 CPU/Recompiler: Fix hang in AArch32/armv7 2021-01-21 13:20:02 +10:00
Connor McLaughlin
0dee202095 Android: Disable PGXP options when geometry correction disabled 2021-01-21 01:28:25 +10:00
Connor McLaughlin
a0ca20a821 Android: Defer rotation request until after start
Fixes messed-up state when orientation is set.
2021-01-21 01:24:52 +10:00
Connor McLaughlin
5b4aff5edf Android: Fix possible reference overflow when scanning 2021-01-20 21:52:39 +10:00
Connor McLaughlin
63562e4527 Qt: Preserve surface when switching fullscreen and not-render-to-main 2021-01-20 21:40:54 +10:00
Connor McLaughlin
f5188c7fef Android: Default to digital controller type for mapping port 1 2021-01-20 15:04:17 +10:00
Connor McLaughlin
fb48e8f093 Android: Fix a possible exception when refreshing game list 2021-01-20 14:45:04 +10:00
Connor McLaughlin
4e802e90ca SPU: Move voice key off/on outside sample loop
Should be a very tiny performance boost with no difference in behaviour.
2021-01-20 12:32:37 +10:00
Connor McLaughlin
8c8f29c047 CDROM: Double audio FIFO low watermark size
Gives a better chance to catch up in case of desyncs.
2021-01-20 12:09:44 +10:00
Connor McLaughlin
3c012ec6ef SPU: Consider partial ticks when generating pending samples
Fixes hitches in opening FMV in Soul Blade (Europe).
2021-01-20 12:05:06 +10:00
Connor McLaughlin
a927bfbe50 GPU/HW: Flush after each primitive for B-F transparency
Slow, but necessary for some games such as Suikoden II, where it draws
multiple polygons to the same area on screen with different transparency
modes.
2021-01-20 01:08:36 +10:00
Connor McLaughlin
cbee8fab66 CommonHostInterface: Throttle rumble updates to changes or every 100ms
These updates appear to be synchronous, and limit how fast we can fast
forward when controllers are connected via bluetooth.
2021-01-19 00:27:34 +10:00
Connor McLaughlin
d4f52f1ec7 GTE: Force inline a few of the helper functions
Tiny performance improvement.
2021-01-19 00:07:26 +10:00
Connor McLaughlin
914b9bf738 SPU: Drain transfer FIFO when cancelling transfer
The busy bit got stuck on otherwise, which broke the Spanish translation
of Vagrant Story.
2021-01-18 20:43:10 +10:00
Connor McLaughlin
699d599d00 GPU: Clear display when disabling DAC and interlaced
Fixes old output showing up briefly when it's re-enabled.
2021-01-18 03:28:14 +10:00
Connor McLaughlin
9da35be0a8 Qt: Update Japanese translation by mikakunin 2021-01-17 02:48:23 +10:00
Connor McLaughlin
29690c4635 GPU/SW: Fix interlaced output getting corrupted when size changes
Fixes glitches in screen when tilting table in Pro Pinball.
2021-01-17 02:45:13 +10:00
Connor McLaughlin
00512f6cea Merge pull request #1470 from CookiePLMonster/update-pl-loc
Update PL translation
2021-01-17 02:44:35 +10:00
Silent
f74a4ad6ee Update PL translation 2021-01-16 16:32:12 +01:00
Silent
2cd4357a5a Fix size policy for Game List buttons
Allows translations to expand those buttons into
multiple lines.
2021-01-15 18:13:57 +01:00
Connor McLaughlin
6fbd970b55 Common/AudioStream: Fix race condition with resampling reset while reading 2021-01-16 02:56:04 +10:00
Connor McLaughlin
4c9e0299ed Common/FIFOQueue: Fix incorrect assertion failure in debug builds 2021-01-16 02:56:04 +10:00
Connor McLaughlin
e81df6bddd Settings: Disable host refresh rate sync by default 2021-01-16 02:56:04 +10:00
Connor McLaughlin
9c30990f8f Merge pull request #1462 from zkdpower/master
Update Simple-Chinese language file to latest
2021-01-16 02:55:27 +10:00
Connor McLaughlin
eeca8305f4 Merge pull request #1463 from andercard0/patch-64
Atualização Português do Brasil
2021-01-16 02:55:06 +10:00
Anderson_Cardoso
e66d353549 Atualização Português do Brasil
Android - Strings not available for translation as follows:

- Theme
- Downsampling
- Controller Mapping
- Use analog Sticks for D-Pad
- Disable All Enhancements 
- Threaded GPU Presentation
- Clear Bindings (in controller mapping options menu)
- Port 1 / Port 2 (in controller mapping options menu)
- Hotkeys (in controller mapping options menu)
2021-01-15 00:03:48 -03:00
zkdpower
0decadd86d Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-01-15 10:27:04 +08:00
Connor McLaughlin
901f862737 dep/minizip: Don't define 64-bit file macros on Android
Doesn't compile with current NDKs otherwise.
2021-01-14 13:43:10 +10:00
Connor McLaughlin
02948f988d CDROM: Return 0x00 on response FIFO overread
Fixes CyberSled hanging on boot.
2021-01-14 01:51:01 +10:00
Connor McLaughlin
ffa3744b3b Settings: Add 20:9 display aspect ratio 2021-01-14 00:45:46 +10:00
Connor McLaughlin
d44de3a9dc System: Use SetWaitableTimer() for throttling on Windows 2021-01-14 00:40:25 +10:00
Connor McLaughlin
3b433d8d3e Android: Add sustained performance mode option 2021-01-13 20:19:24 +10:00
Connor McLaughlin
93959a9d88 CPU: Fix crash with some block cycle counts on ARM
Fixes crash in Capcom vs SNK Pro.
2021-01-13 20:19:24 +10:00
Connor McLaughlin
6ad8a6666c Android: Enable resampling by default 2021-01-13 20:19:24 +10:00
Connor McLaughlin
434f75658c Android: Fix incorrect code in key list 2021-01-13 20:19:24 +10:00
Connor McLaughlin
a27f220f79 Android: Support binding volume buttons 2021-01-13 19:26:24 +10:00
Connor McLaughlin
37f9f118c4 Android: Add 'Open Pause Menu' hotkey 2021-01-13 19:26:24 +10:00
Connor McLaughlin
60232c390a Android: Use checkbox list for patch codes/cheats 2021-01-13 19:26:24 +10:00
Connor McLaughlin
1ae4b94eb2 AudioStream: Don't hold lock while resampling 2021-01-13 19:25:15 +10:00
Connor McLaughlin
2b5cfb272c Qt: Add dump VRAM and SPU RAM actions 2021-01-13 19:24:41 +10:00
Connor McLaughlin
5746dcdbd4 Android: Fix build 2021-01-13 02:54:54 +10:00
Connor McLaughlin
b5ffbfe826 Qt: Fix audio sliders not applying correctly 2021-01-13 02:37:04 +10:00
Connor McLaughlin
b3fd07e1b5 GameSettings: Adjust crop area for FF7 2021-01-13 02:37:04 +10:00
Connor McLaughlin
220f2f4845 Vulkan: Fix typo causing debug shaders to be used 2021-01-13 02:37:04 +10:00
Connor McLaughlin
d101f7cf9d Merge pull request #1442 from andercard0/patch-63
Atualização Português do Brasil
2021-01-13 02:36:23 +10:00
Anderson_Cardoso
fc58d8e8cc Atualização Português do Brasil
Android - Strings not available for translation as follows:

- Theme
- Downsampling
- Controller Mapping
- Use analog Sticks for D-Pad
- Disable All Enhancements 
- Threaded GPU Presentation
- Clear Bindings (in controller mapping options menu)
- Port 1 / Port 2 (in controller mapping options menu)
- Hotkeys (in controller mapping options menu)
2021-01-11 14:01:45 -03:00
Connor McLaughlin
a0a24c7752 GPU/Vulkan: Only update sample texture when render area dirty
Fixes crash when using Show VRAM in some games with Vulkan.
2021-01-12 02:19:23 +10:00
Connor McLaughlin
16ad54143b HostInterface: Don't sleep when syncing to host refresh 2021-01-12 02:19:23 +10:00
Connor McLaughlin
0884954d10 Merge pull request #1438 from zkdpower/master
Update Simple-Chinese language file to latest
2021-01-12 02:18:29 +10:00
zkdpower
6712f6b649 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-01-11 17:15:52 +08:00
Connor McLaughlin
c18fa06f0c Android: Add 'Sync To Host Refresh Rate' option 2021-01-11 15:42:42 +10:00
Connor McLaughlin
873b9f622a Merge pull request #1432 from andercard0/patch-62
Atualização Português do Brasil
2021-01-11 15:42:23 +10:00
Connor McLaughlin
e5915846a4 Merge pull request #1433 from ggrtk/qt-update-widget-help-text
Qt: Update widget help text
2021-01-11 15:42:12 +10:00
Connor McLaughlin
13cba122ef HostDisplay: Move Windows fallback for refresh rate query to HostInterface 2021-01-11 15:24:38 +10:00
Connor McLaughlin
fd166a4485 ShaderCache: Add a data version field
We can increment this to prevent people's shader caches from growing too
large with shader changes.
2021-01-11 15:24:38 +10:00
Connor McLaughlin
97971464d1 GPU/ShaderGen: Remove texcoord offset
Doesn't seem to be needed anymore, and causes issues in some games (e.g.
flickering polygons in Evil Dead)
2021-01-11 15:12:16 +10:00
Albert Liu
29331ef679 Qt: Update widget help text 2021-01-10 20:49:25 -08:00
Anderson_Cardoso
69f14feec1 Atualização Português do Brasil
Android - Strings not available for translation as follows:

- Theme
- Downsampling
- Controller Mapping
- Use analog Sticks for D-Pad
- Disable All Enhancements 
- Threaded GPU Presentation
- Clear Bindings (in controller mapping options menu)
- Port 1 / Port 2 (in controller mapping options menu)
- Hotkeys (in controller mapping options menu)
2021-01-10 17:32:27 -03:00
Connor McLaughlin
ba2710fb4c Update README.md 2021-01-11 04:01:18 +10:00
Connor McLaughlin
bc5fb850d4 AudioStream: Reset resampler state on emptying buffers 2021-01-11 03:58:14 +10:00
Connor McLaughlin
43d01776dc HostInterface: Add "Sync To Host Refresh Rate" option 2021-01-11 03:50:44 +10:00
Connor McLaughlin
bb572741ae HostDisplay: Add GetHostRefreshRate() function
Only implemented in Windows for now.
2021-01-11 03:50:13 +10:00
Connor McLaughlin
5769830b72 Android: Fix incorrect string refresh in audio settings 2021-01-11 03:49:40 +10:00
Connor McLaughlin
d23645e02f CMake: Fix Linux build 2021-01-11 03:18:30 +10:00
Connor McLaughlin
ce965e89ca Qt/Android: Add help text for resampling, turn on by default 2021-01-11 02:27:14 +10:00
Connor McLaughlin
fdeef65676 Qt: Move emulation speed settings to console settings 2021-01-11 02:12:20 +10:00
Connor McLaughlin
54f5563321 Qt: Add turbo speed setting 2021-01-11 01:57:10 +10:00
Connor McLaughlin
d73fedcef1 Qt: Make about dialog slightly taller 2021-01-11 01:32:19 +10:00
Connor McLaughlin
692eb035ec Qt: Fix flex sizing with >1 flex column 2021-01-11 01:29:31 +10:00
Connor McLaughlin
25847494d5 dep/xxhash: Set XXH_X86DISPATCH_ALLOW_AVX on x86/x64 2021-01-11 01:21:41 +10:00
Connor McLaughlin
5996945b37 Android: Use Java thread for emulation thread 2021-01-11 01:14:32 +10:00
Connor McLaughlin
a5f9aa11e1 Settings: Add audio resampling when running at non-standard speed 2021-01-11 01:14:32 +10:00
Connor McLaughlin
54c7fc6b08 AudioStream: Support resampling input 2021-01-11 01:14:32 +10:00
Connor McLaughlin
1eab296ec3 dep: Add libsamplerate 2021-01-11 01:14:32 +10:00
Connor McLaughlin
bc6444b6ff Update compatibility list and settings 2021-01-11 01:12:32 +10:00
Connor McLaughlin
5d7d848fe6 CMake: Don't disable EGL for Android
Fixes OpenGL renderer being unavailable.
2021-01-11 01:05:26 +10:00
Connor McLaughlin
19032750b4 CDROM: Don't treat no-region discs as audio CDs
Fixes some homebrew games not booting.
2021-01-11 01:05:21 +10:00
Connor McLaughlin
2c2195b116 Qt: Update Polish translation by Zuzia 2021-01-11 01:04:54 +10:00
Connor McLaughlin
11992bde4e TimingEvents: Use function pointers instead of std::function 2021-01-10 01:45:07 +10:00
zkdpower
8c241ed8de Update Simple-Chinese language file to latest (#1424)
* Update Simple-Chinese language file to latest

Update Simple-Chinese language file to latest

* Update Simple-Chinese language file to latest

Update Simple-Chinese language file to latest
2021-01-10 01:43:35 +10:00
Connor McLaughlin
b4d1dcfe4b Merge pull request #1415 from andercard0/patch-61
Atualização Português do Brasil
2021-01-10 01:43:28 +10:00
Connor McLaughlin
15652b4c1f SPU: Fix a few cases where SPU interrupts weren't firing 2021-01-10 01:39:21 +10:00
Connor McLaughlin
df98a0b04e CPU/Recompiler: Fix incorrect speculative byte/halfword reads
Fixes crash on boot in Monkey Magic.
2021-01-10 01:38:35 +10:00
Connor McLaughlin
4fafb34251 CommonHostInterface: Move input map update to frontend
Fixes controller state getting reset when loading input profile.
2021-01-09 14:54:53 +10:00
Connor McLaughlin
ad0d16e243 Qt: Fix failing to load unicode filenames on command line 2021-01-09 12:02:33 +10:00
Connor McLaughlin
64fc560314 Qt: Don't allocate a console when loading settings 2021-01-09 01:53:15 +10:00
Connor McLaughlin
9d7f4523b0 Log: Close C file handles on free (win32)
Fixes toggling console not hiding the window.
2021-01-09 01:52:48 +10:00
Anderson_Cardoso
693b070889 Atualização Português do Brasil
Could you please make the following strings available for translation in Android? 

- Theme
- Downsampling
- Controller Mapping
- Use analog Sticks for D-Pad
- Disable All Enhancements 
- Threaded GPU Presentation
- Clear Bindings (in controller mapping options menu)
- Port 1 / Port 2 (in controller mapping options menu)
- Hotkeys (in controller mapping options menu)
2021-01-08 11:51:46 -03:00
Connor McLaughlin
9951921a6d Log: Enable virtual terminal processing on Win32
This way we don't need to set the registry value.
2021-01-09 00:39:32 +10:00
Connor McLaughlin
b0398f5aa7 Qt: Add shutdown without saving menu option 2021-01-09 00:23:02 +10:00
Connor McLaughlin
6a04803502 Merge pull request #1394 from piepacker/msw_console_behavior
Console: Fix problems when using CLI from MSYS2/GitBash/ConEmu
2021-01-09 00:22:37 +10:00
Connor McLaughlin
5add87c8ad Merge pull request #1410 from ggrtk/get-analog-input-bytes
Controller: Add method for reading analog input bytes
2021-01-09 00:19:38 +10:00
Connor McLaughlin
c6da182232 Merge pull request #1412 from ggrtk/sdl-rumble-duration-fix
CommonHostInterface: Update rumble every frame regardless of change
2021-01-09 00:17:46 +10:00
Connor McLaughlin
8d56a3d186 Merge pull request #1414 from zkdpower/master
Update Simple-Chinese language file to latest
2021-01-09 00:17:18 +10:00
zkdpower
bfd4273f2c Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-01-08 21:56:09 +08:00
Albert Liu
d860c14267 CommonHostInterface: Update rumble every frame regardless of change
Fixes SDL rumble cutting off early when a game sends the same motor
strength values every frame over a long duration.
2021-01-07 18:30:43 -08:00
Albert Liu
5ff3299384 Controller: Add method for reading analog input bytes 2021-01-07 15:04:23 -08:00
Connor McLaughlin
4cc2883224 Add script to pad a BIOS image
Mainly useful for openbios.
2021-01-08 01:38:02 +10:00
Connor McLaughlin
419726f4cc Remove libretro core - core will now be maintained by libretro
libretro have agreed to take over maintenance of the core.

Please see their fork at https://github.com/libretro/duckstation if you
wish to continue to use it.
2021-01-08 01:37:59 +10:00
Connor McLaughlin
573c8370d7 Update game settings
Doom was missing for the PAL and Japanese releases.
2021-01-08 01:28:09 +10:00
Jake Stine
f26b094cf7 Console: Use ANSI escape codes and remove entirely Win32's legacy WriteConsoleA code.
Also fixes android build failure (missing unistd.h)
2021-01-07 07:05:33 -08:00
Connor McLaughlin
24c373245e MemoryCard: Make formatting OSD message translatable 2021-01-07 12:15:57 +10:00
Connor McLaughlin
d86fc03ecb Merge pull request #1391 from andercard0/patch-60
Atualização Português do Brazil
2021-01-07 12:15:24 +10:00
Connor McLaughlin
ee60c02e0a Merge pull request #1402 from zkdpower/master
Update Simple-Chinese language file to latest
2021-01-07 12:15:16 +10:00
Connor McLaughlin
5eca471624 Merge pull request #1403 from RaydenX93/update_it_20210106
Italian Language Update
2021-01-07 12:15:01 +10:00
Connor McLaughlin
e80cd69811 Merge pull request #1395 from CookiePLMonster/add-roboto-glyphs
Register more glyph ranges supported by Roboto
2021-01-07 12:14:48 +10:00
RaydenX93
3f11cb1de1 Update duckstation-qt_it.ts 2021-01-06 18:44:54 +01:00
zkdpower
7de3fafff6 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-01-07 00:43:46 +08:00
Silent
de075fffc3 Register more glyph ranges supported by Roboto
Adds support for Polish, makes Russian use a default font
2021-01-05 18:17:18 +01:00
Jake Stine
c9b8dc13fd Console: Fix problems when using CLI from MSYS2/GitBash/ConEmu
- Fix issue where console output is lost when running from MSYS2/GitBash CLI
 - Fix issue where pipe redirections would be overridden and otuput would always go to the attached console (this affected windows cmd prompt as well as other shell CLIs)
 - Simplify some logic regarding registering of the standard output writer
2021-01-05 07:35:11 -08:00
Connor McLaughlin
f832dca975 Bus: Don't force inline EXP1/EXP2 access 2021-01-06 01:02:30 +10:00
Connor McLaughlin
f3cdfe97a7 Bus/EXP2: Support openbios putc address 2021-01-06 00:56:35 +10:00
Anderson_Cardoso
7f22dc4199 Atualização Português do Brazil
Android - Strings not available for translation as follows:

- Theme
- Down sampling
- Controller Mapping
- Use analog Sticks for D-Pad
- Disable All Enhancements 
- Threaded GPU Presentation
- Clear Bindings (in controller mapping options menu)
- Port 1 / Port 2 (in controller mapping options menu)
- Hotkeys (in controller mapping options menu)
2021-01-05 11:49:36 -03:00
Connor McLaughlin
9afd122f85 GameSettings: Remove a bunch of DMA size overrides 2021-01-06 00:15:42 +10:00
Connor McLaughlin
845cd37835 DMA: Determine slice size based on whether pad is transmitting
Plenty of games seem to suffer from this issue where they have
a linked list DMA going while polling the controller. Using a
too-large slice size will result in the serial timing being off,
and the game thinking the controller is disconnected. So we
don't hurt performance too much for the general case, we reduce
this to equal CPU and DMA time when the controller is
transferring, but otherwise leave it at the higher size.
2021-01-06 00:15:42 +10:00
Connor McLaughlin
98a4e59f52 Qt: Fix some strings not being translatable 2021-01-06 00:15:42 +10:00
Dominus Iniquitatis
b83a9cfe9a Update README.md (#1388) 2021-01-05 18:02:11 +10:00
Bekon241
a5078d7e35 Zuzia pl language support (#1384)
* Update duckstation-qt_pl.ts
2021-01-05 18:01:28 +10:00
Connor McLaughlin
25b0b72566 Merge pull request #1383 from zkdpower/master
Update Simple-Chinese language file to latest
2021-01-05 18:00:25 +10:00
Connor McLaughlin
a6e1b3c4ad Merge pull request #1389 from ggrtk/ps3-bios-size
BIOS: Add check for older BIOS from PS3
2021-01-05 17:59:57 +10:00
Connor McLaughlin
cdefcf7359 HostInterface: Log when all enhancements are disabled by config 2021-01-05 17:58:55 +10:00
Albert Liu
79012d5288 BIOS: Add check for older BIOS from PS3
Same revision number as newer PS3, but different file size and 512KB
hash.
2021-01-04 23:54:42 -08:00
Connor McLaughlin
0534f36b8d D3D11HostDisplay: Fix incorrect format support check
Was resulting in RGB565 textures trying to be created when unsupported.
2021-01-05 17:47:59 +10:00
Connor McLaughlin
e3de44d127 D3D11/Texture: Log attributes when creation fails 2021-01-05 17:19:05 +10:00
Connor McLaughlin
8f5c20bdf5 BIOS: Improve robustness of BIOS searching
Always prefer a known BIOS image over an unknown image. Hopefully this
will stop people getting crashes on startup due to other files in the
BIOS directory confusing it.
2021-01-05 12:22:18 +10:00
Connor McLaughlin
5cd261a5b2 BIOS: Only match PS1 and PS2 BIOS images exactly 2021-01-05 12:22:13 +10:00
Connor McLaughlin
68f97a8116 Update game compatibility/settings 2021-01-05 12:22:01 +10:00
zkdpower
c0dfc49db3 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2021-01-05 03:36:07 +08:00
Connor McLaughlin
c3b0a87029 CommonHostInterface: Move settings filename to start of class 2021-01-05 00:58:32 +10:00
Connor McLaughlin
9056db0a0f Qt: Add Polish translation by Zuzia and Seba 2021-01-05 00:46:41 +10:00
Connor McLaughlin
73f6521452 SPU: Check voice addresses on IRQ re-enable
NASCAR 2001 music depends on the IRQ firing multiple times, when the
voice address is still set to the IRQ address.
2021-01-05 00:46:41 +10:00
Connor McLaughlin
e3262fc0a4 CPU: Compile fix for debug builds 2021-01-05 00:46:41 +10:00
Connor McLaughlin
cc0c41eb11 Update README.md 2021-01-05 00:46:41 +10:00
johnnyruz
f7b0c0f493 Add cli parameter to override default settings file (#1375)
* Add cli parameter to specify alternate settings file

* fix issue with error message string parameter
2021-01-05 00:46:16 +10:00
Connor McLaughlin
35fdae0d95 Merge pull request #1372 from ggrtk/analog-controller-refactor
AnalogController: Refactor data transfer implementation
2021-01-05 00:45:37 +10:00
Connor McLaughlin
5ec8b64aa1 Merge pull request #1377 from andercard0/patch-59
Atualização Português do Brazil
2021-01-05 00:44:24 +10:00
Anderson_Cardoso
2898d27c53 Atualização Português do Brazil
Android - Strings not available for translation as follows:

- Theme
- Downsampling
- Controller Mapping
- Use analog Sticks for D-Pad
- Disable All Enhancements 
- Threaded GPU Presentation
- Clear Bindings (in controller mapping options menu)
- Port 1 / Port 2 (in controller mapping options menu)
- Hotkeys (in controller mapping options menu)
2021-01-03 16:08:42 -03:00
Connor McLaughlin
affffca3da GPU/HW: Set max resolution scale to 32
The UI is intentionally left at 16x. Going too high **will** make you
run out VRAM and your system will start acting strangely. But for those
people who really want to do it, you can go 32x in Vulkan with the SDL
frontend, or by setting it in the ini.
2021-01-04 03:11:14 +10:00
Connor McLaughlin
9ff8130e40 fixup! CPU: Make trace-to-file toggleable at runtime and in release builds 2021-01-04 03:11:14 +10:00
PugsyMAME
c9b75f7490 Updated DebuggerWindow Files for Tracer 2021-01-04 03:11:14 +10:00
Connor McLaughlin
bf1d51b5d8 CPU: Make trace-to-file toggleable at runtime and in release builds 2021-01-04 03:11:14 +10:00
PugsyMAME
4b7820d1e5 Icon For Tracer 2021-01-04 03:11:14 +10:00
Connor McLaughlin
f369e3c476 HostDisplay: Fix vram pixels bleeding into edges of display with linear filtering 2021-01-04 03:11:14 +10:00
Albert Liu
04884257d6 AnalogController: Refactor data transfer implementation 2021-01-03 09:09:49 -08:00
Anderson_Cardoso
498b00a8e8 Update Bug Report Template (#1369)
* Update Bug Report Template
2021-01-04 02:12:59 +10:00
Connor McLaughlin
b3bf9f3f10 GameSettings: Fix compilation with libretro 2021-01-03 19:06:24 +10:00
Connor McLaughlin
f606999a04 Android: Fix analog stick as dpad in digital mode option 2021-01-03 18:39:15 +10:00
Connor McLaughlin
9708332a80 Android: Make tab titles game properties translatable 2021-01-03 18:30:06 +10:00
Connor McLaughlin
fc3780815d Android: Reformat Java sources 2021-01-03 18:30:06 +10:00
Connor McLaughlin
600e8d5dd0 Android: Fix fab background colour in dark mode 2021-01-03 18:30:06 +10:00
Connor McLaughlin
4eee5ebdb7 Android: Add per-game settings and properties UI 2021-01-03 18:30:06 +10:00
Connor McLaughlin
7f008ea5c7 Android: Normalize controller binding text size 2021-01-03 18:30:06 +10:00
Connor McLaughlin
6ff73f35bd GameSettings: Add string key accessors 2021-01-03 17:26:51 +10:00
Connor McLaughlin
2501547acb GameSettings: Force icache for Deadheat Road (Japan)
Fixes graphical corruption in loading screen - the game executes a
memcpy out of uncached ROM while the DMA is occurring, then modifies it
before it finishes.
2021-01-03 16:12:00 +10:00
Connor McLaughlin
0de34d7bf7 DMA: Increase precision for large transfers
Also gets rid of the delay on the GPU side for writing to VRAM (doesn't
make sense), and it's not needed since we slice the block transfers now.

Fixes palette corruption in Vigilante 8, and missing rider in
Championship Motocross 2001 featuring Ricky Carmichael.
2021-01-03 16:11:42 +10:00
Connor McLaughlin
c9ef3ec1a3 DMA: Clear state on shutdown
Fix a rare crash where the GPU starting after a second boot accesses
uninitalized DMA fields.
2021-01-03 14:48:02 +10:00
Connor McLaughlin
2ec26e54b7 GPU/HW: Disable downsampling when using 24-bit display
It's dropped to 1x first anyway.
2021-01-03 12:18:21 +10:00
Connor McLaughlin
0d281538cf CDImageCue: Disable implicit pregap insertion for audio CDs
Fixes supplementary disc detection in Dancing Stage
featuring DREAMS COME TRUE.
2021-01-02 01:33:13 +10:00
Connor McLaughlin
a63a6b7a20 Qt: Update Japanese translation by mikakunin 2021-01-01 19:58:54 +10:00
Connor McLaughlin
40257e5b20 GPU/HW: Don't set m_pgxp_depth_buffer when PGXP is disabled
Fixes text corruption in Castlevania when PGXP is disabled and depth
buffer is enabled.
2021-01-01 17:49:20 +10:00
Connor McLaughlin
c9240eea72 CPU/Recompiler: Use PGXP interpreter for fallback
Fixes holes in geometry with PGXP enabled in Threads of Fate.
2021-01-01 17:16:55 +10:00
Connor McLaughlin
4e87b30b40 System: Skip throttler phase reset when running at <100% 2021-01-01 14:08:09 +10:00
Connor McLaughlin
04a187afb2 CDROM: Fix read error/unlicensed flag getting set on all discs
Regression from 75aa52ab06.
2021-01-01 03:00:16 +10:00
Connor McLaughlin
75aa52ab06 CDROM: Fail reads immediately for audio/unlicensed CDs
Fixes first track being unavailable on audio CDs in Vib-Ribbon.
2021-01-01 01:38:14 +10:00
Connor McLaughlin
9294bf6be3 CDROM: Keep target location even after failed seeks 2021-01-01 01:37:51 +10:00
Connor McLaughlin
187de65f50 CDROM: Reset disc position to start after switching discs 2021-01-01 00:01:13 +10:00
Connor McLaughlin
d588c26cf6 Revert "dep/msvc: Update SDL2 to 2.0.14"
This reverts commit 8debaa34d9.

Seems to be a few regressions, namely XBox Controller Rumble, other
controllers not detecting, etc.
2020-12-31 19:44:46 +10:00
Connor McLaughlin
3ffbbe82e8 SDLControllerInterface: Use SDL_GameControllerRumble where supported
Allows vibration on DualShock 4 without using DS4Windows.
2020-12-31 19:41:51 +10:00
Connor McLaughlin
bea6f0beb4 Android: Fix incorrect version string on build 2020-12-31 19:41:51 +10:00
Connor McLaughlin
4f32f2f915 Merge pull request #1357 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-31 19:41:23 +10:00
Connor McLaughlin
aa0eb5153e Merge pull request #1358 from ggrtk/qt-displaysettings-text
Qt/DisplaySettingsWidget: Fix recommended value not being translated
2020-12-31 19:41:04 +10:00
Albert Liu
dde5a4e2d8 Qt/DisplaySettingsWidget: Fix recommended value not being translated 2020-12-31 01:07:24 -08:00
Connor McLaughlin
6d501bff56 GL/Program: Use glBindFragDataLocationIndexedEXT for GLES 2020-12-31 13:29:41 +10:00
zkdpower
041880df34 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-31 07:47:25 +08:00
Connor McLaughlin
5690aef057 CDROM: Send seek error when read+seeking to audio sector
Fixes hang in Vib-Ribbon when using an audio CD.
2020-12-31 03:19:51 +10:00
Connor McLaughlin
68f3261582 Update game settings and compatibility list 2020-12-31 03:15:18 +10:00
Connor McLaughlin
f911e90e17 CDROM: Hopefully fix crash in debug window when reading lead-out 2020-12-31 02:10:49 +10:00
Connor McLaughlin
02377b1a92 CPU/CodeCache: Fix possible crash on invalidate->recompile->overflow 2020-12-31 02:10:49 +10:00
Connor McLaughlin
9b73f0194c Update README.md 2020-12-31 00:13:35 +10:00
Connor McLaughlin
b2bb9340f9 Merge pull request #1352 from andercard0/patch-57
Atualização Português do Brasil
2020-12-31 00:05:26 +10:00
Anderson_Cardoso
1f10bdd7cd Atualização Português do Brasil
Update Portuguese Brazil language file to latest.
2020-12-30 10:40:23 -03:00
Connor McLaughlin
e464a8c332 CommonHostInterface: Disable some hotkeys on Android 2020-12-30 19:42:14 +10:00
Connor McLaughlin
22bb64e7b0 Android: Add hotkey binding support 2020-12-30 19:42:14 +10:00
Connor McLaughlin
2672e2b505 libretro: Build fix 2020-12-30 19:42:14 +10:00
Connor McLaughlin
7b532ebb7f Merge pull request #1347 from andercard0/patch-56
Atualização Português do Brasil
2020-12-30 18:11:17 +10:00
Connor McLaughlin
f5230fdb14 Merge pull request #1346 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-30 18:10:51 +10:00
Connor McLaughlin
78282d1508 GameSettings: Add downsampling mode 2020-12-30 17:53:51 +10:00
Connor McLaughlin
3cb2cd8235 GPU: Add adaptive and box downsampling modes 2020-12-30 17:41:39 +10:00
Connor McLaughlin
5236583544 Vulkan/Texture: Support transitioning individual mip levels 2020-12-30 17:39:40 +10:00
Connor McLaughlin
2ce5dc3bbe Vulkan: Don't hardcode mipmap samplers to lod0 2020-12-30 17:39:40 +10:00
Connor McLaughlin
59e8363075 D3D11: Support mipmaps in wrapper textures 2020-12-30 17:39:40 +10:00
Connor McLaughlin
68ce959d70 Settings: Add option to temporarily disable all enhancements 2020-12-30 17:39:29 +10:00
Connor McLaughlin
40f241dde3 PlaystationMouse: Fix incorrect translation context for help 2020-12-30 17:03:59 +10:00
Anderson_Cardoso
dd04c5983e Atualização Português do Brasil
Translation updated to latest.
2020-12-29 18:16:54 -03:00
zkdpower
674b26bef7 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-30 04:21:52 +08:00
Connor McLaughlin
c46495e687 Update README.md 2020-12-30 01:02:09 +10:00
Connor McLaughlin
f8dcfabc44 Merge pull request #1344 from guibou/gtk3
Use gtk3 for nativefiledialog
2020-12-30 00:56:11 +10:00
PugsyMAME
3284a18ad3 Add new Cheat Type F4, Find & Replace Bytes (#1345)
* Add new Cheat Type F4, Find & Replace Bytes

Also knows as 'AOB' apparently. Information about how it works will be in the next chtdb.txt header or you can read/ask about it on the discord channel.

* Add new Cheat Type F4, Find & Replace Bytes 

Also knows as 'AOB' apparently. Information about how it works will be in the next chtdb.txt header or you can read/ask about it on the discord channel.

* Added error trapping for cheat type F4

As suggested
2020-12-30 00:55:49 +10:00
Guillaume Bouchard
f30addc70d Use gtk3 for nativefiledialog
Rational: gtk2 is not maintained anymore and the change was simple.

- Update of nativefiledialog/CMakeLists.txt in order to detect and use
  gtk3
- Updated a few files referencing gtk2, especially:
  - github workflow: I tested that the apt-get update works on ubuntu
    18.03 in a docker container
  - Readme.

This was tested in the following nixpkgs PR: https://github.com/NixOS/nixpkgs/pull/107878
2020-12-29 15:13:43 +01:00
Connor McLaughlin
1b99233466 Android: Add analog-stick-as-dpad option to controller settings 2020-12-29 22:49:52 +10:00
Connor McLaughlin
0aa3b6b399 Android: Controller binding support 2020-12-29 22:49:52 +10:00
Connor McLaughlin
6bf37f51be Android: Add controller interface class 2020-12-29 22:49:52 +10:00
Connor McLaughlin
cbcb8b4b89 Android: Add dark theme 2020-12-29 22:49:52 +10:00
Connor McLaughlin
59b9e4b2ef Android: Hook up most of the settings interface mutators 2020-12-29 22:49:52 +10:00
Connor McLaughlin
0945744f9b FrontendCommon: Add DInput controller interface
Still needs force feedback/vibration support.
2020-12-29 22:49:52 +10:00
Connor McLaughlin
a3e4c61a0b CommonHostInterface: Add a method to get top-level window handle 2020-12-29 22:49:52 +10:00
Connor McLaughlin
a894b295b6 CPU/CodeCache: Fix assertion failure when patching in double branch 2020-12-29 22:49:52 +10:00
Connor McLaughlin
b38e4b8ba7 Merge pull request #1341 from ggrtk/hostdisplay-fixes
HostDisplay: Fix some scaling issues
2020-12-29 22:49:29 +10:00
Connor McLaughlin
6f22d5c151 Merge pull request #1333 from andercard0/patch-55
Atualização Português do Brasil
2020-12-29 22:48:25 +10:00
Connor McLaughlin
4fdedf5f14 Merge pull request #1340 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-29 22:48:12 +10:00
Connor McLaughlin
35646df63f Merge pull request #1343 from guibou/patch-1
Readme.md: add git as a build time requirement
2020-12-29 22:47:57 +10:00
Guillaume Bouchard
d6eb8c4b48 Readme.md: add git as a build time requirement 2020-12-29 12:50:22 +01:00
Albert Liu
1c1ca45e4e VulkanHostDisplay: Fix post shader uniform buffer 2020-12-29 01:33:41 -08:00
Albert Liu
11fbf26045 HostDisplay: Use floats internally for draw rectangle calculation 2020-12-29 01:33:41 -08:00
Albert Liu
e0f3a4f17b HostDisplay: Calculate draw rectangle in terms of horizontal scale 2020-12-29 01:33:40 -08:00
Albert Liu
b824844043 HostDisplay: Fix framebuffer screenshot scaling 2020-12-29 01:33:40 -08:00
zkdpower
489169c8ce Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-29 09:41:10 +08:00
Anderson_Cardoso
acaa13aba0 Atualização Português do Brasil 2020-12-28 15:19:57 -03:00
Connor McLaughlin
dfa36e0fa7 Update SDL game controller database 2020-12-29 03:18:43 +10:00
Connor McLaughlin
a48add94f8 Merge pull request #1332 from ggrtk/ps2-bios-size
Update BIOS image handling
2020-12-29 02:19:13 +10:00
Connor McLaughlin
fa7442fddb Qt: Fix mouse-cursor-in-fullscreen regression 2020-12-29 02:00:31 +10:00
Connor McLaughlin
fcec112613 Merge pull request #1329 from RaydenX93/master
Italian Translation Update - PC
2020-12-28 11:56:49 +10:00
Albert Liu
d9096ca12d BIOS: Prevent patching incompatible BIOSes 2020-12-27 16:14:28 -08:00
Albert Liu
0e2276fc7a BIOS: Add support for loading PS2 BIOSes 2020-12-27 15:32:41 -08:00
Albert Liu
4db29f9399 HostInterface: Check all console regions when looking for any BIOS 2020-12-27 15:32:41 -08:00
RaydenX93
7f57d678bd Update duckstation-qt_it.ts 2020-12-27 17:52:44 +01:00
Connor McLaughlin
a845b2c5f8 Merge pull request #1326 from PugsyMAME/master
Cheat Manager Memory Scanner improvements
2020-12-28 02:20:11 +10:00
PugsyMAME
90073ac1d0 Cheat Manager Memory Scanner improvements
Updated Memory Scanner to use sized hexadecimal in results and manual watches.
Enforced Halfword,Word address settings so that it's a valid word or halfword that is being watched.
2020-12-27 16:12:10 +00:00
Connor McLaughlin
f9ac25f2b8 CDROM: Actually fix playing tracks 10+ 2020-12-28 01:40:38 +10:00
Connor McLaughlin
c04d6f9ef8 CDROM: Play command track should be BCD
Fixes tracks >= 10 in BIOS CD player, maybe games?
2020-12-28 01:17:41 +10:00
Connor McLaughlin
8bb5ff47eb PlaystationMouse: Add option to use relative mode 2020-12-28 00:37:04 +10:00
Connor McLaughlin
ca42d027ac Qt: Implement relative mouse mode 2020-12-28 00:37:04 +10:00
Connor McLaughlin
114d4a2c1d Merge pull request #1325 from PugsyMAME/master
Fixed Pattern found address in Debugger Search
2020-12-28 00:36:45 +10:00
Connor McLaughlin
157532b0fe Merge pull request #1320 from andercard0/patch-54
Atualização Português do Brasil
2020-12-28 00:36:20 +10:00
Connor McLaughlin
92ed284499 Merge pull request #1323 from ggrtk/qt-japanese
Qt: Update Japanese translation by mikakunin
2020-12-28 00:36:05 +10:00
PugsyMAME
67f6bd2bcb Fixed Pattern found address in Debugger Search
"Pattern found at 0x%1" was passing a decimal value to %1 instead of a hexadecimal one
2020-12-27 11:20:26 +00:00
Albert Liu
d7e8b5a4c2 Qt: Update Japanese translation by mikakunin 2020-12-27 00:57:55 -08:00
Albert Liu
46239e3d09 Qt/CheatManagerDialog: Fix lupdate warning 2020-12-27 00:57:55 -08:00
Albert Liu
2a1bf9925a Qt: Make Auto (Game Native) aspect ratio string translatable 2020-12-27 00:57:55 -08:00
Anderson_Cardoso
ab2198be28 Atualização Português do Brasil 2020-12-26 14:01:24 -03:00
Connor McLaughlin
f181b45760 libretro: Build fix 2020-12-27 02:41:43 +10:00
Connor McLaughlin
e3ce0530bf Revert "CI: Stop building libretro cores"
This reverts commit 1a6a14fcd4.
2020-12-27 02:21:16 +10:00
Connor McLaughlin
80fb30b564 Qt: Add Boot and Debug option to context menu 2020-12-27 00:54:53 +10:00
Connor McLaughlin
29469077ee Qt: Force display to render after boot
Fixes menu showing through when starting paused.
2020-12-27 00:54:53 +10:00
Connor McLaughlin
cbcbb675d6 System: Fix pause on start 2020-12-27 00:54:53 +10:00
Connor McLaughlin
3cd3d1c09d Qt: Fix opening debugger when system already paused 2020-12-27 00:54:53 +10:00
Connor McLaughlin
dc46d52029 FrontendCommon: Remove unnecessary #ifndef LIBRETRO macros
These were only needed because of ancient compilers on the libretro
buildbot, it still compiles fine with these fields on the latest
compilers.
2020-12-27 00:54:53 +10:00
Connor McLaughlin
702ed21207 HostDisplay: Add threaded presentation for Vulkan renderer
Can add a significant speedup for fast forward. Automatically disabled
when vsync is enabled.
2020-12-27 00:54:53 +10:00
Connor McLaughlin
1a6a14fcd4 CI: Stop building libretro cores
Apparently libretro want to do this themselves now?
2020-12-27 00:50:08 +10:00
Connor McLaughlin
68dc052432 Bus: Don't leak shared memory when starting->stopping->starting 2020-12-27 00:50:08 +10:00
Connor McLaughlin
91995c92db Qt/Debugger: Use Bus helper functions for getting region pointers 2020-12-27 00:50:08 +10:00
Connor McLaughlin
d74d27163c Common/MemoryArena: Add destroy/valid methods 2020-12-27 00:50:08 +10:00
Connor McLaughlin
e71f6aa80a GPU/HW: Improve round-trip accuracy of RGBA5551->RGBA8
Fixes smudging in some games with true colour rendering enabled.
2020-12-27 00:50:08 +10:00
Connor McLaughlin
5451a1f5c3 README/Issue template: Clarify that libretro core is not officially supported 2020-12-27 00:50:08 +10:00
Connor McLaughlin
84181e2a1d CheatS: Support importing/parsing EPSXe cheat files 2020-12-27 00:45:34 +10:00
Connor McLaughlin
cc9c3ea41f Cheats: Fix assertions tripping on unicode characters 2020-12-27 00:45:34 +10:00
Connor McLaughlin
8debaa34d9 dep/msvc: Update SDL2 to 2.0.14 2020-12-27 00:45:34 +10:00
Connor McLaughlin
aa65280ec3 Qt: Fix typo in advanced settings 2020-12-27 00:45:34 +10:00
Connor McLaughlin
7532d5d09a Merge pull request #1306 from andercard0/patch-52
Atualização Português do Brasil
2020-12-27 00:45:04 +10:00
Connor McLaughlin
5ed0c98f37 Merge pull request #1307 from andercard0/patch-53
Android Update Strings to latest
2020-12-27 00:44:51 +10:00
Connor McLaughlin
9c36c9dbdb Merge pull request #1312 from ggrtk/memorycardimage-fix
MemoryCardImage: Fix multi-block file reads
2020-12-27 00:44:41 +10:00
Connor McLaughlin
77093553e1 Merge pull request #1315 from Margen67/appveyor
appveyor.yml improvements
2020-12-27 00:44:27 +10:00
PugsyMAME
31423ef697 Changed debugger "Enter memory address" to accept hex only (#1317)
* Changed debugger "Enter memory address" to accept hex only

The "Enter memory address" prompt by default expects a decimal address unless it's preceded by 0x. Or it expects an number starting with 0 is an octal.
The disassembly address should be hexadecimal regardless as that is how it it displays the address.
Also changed it so that it changes any address entered to be divisible by 4 as there was an observed issue that would cause the disassembly addresses to get locked to a address that was not divisible by 4

* Translation updates for Debugger memory address change

Updated the three translation files that mentioned the original "Invalid address. It should be in hex" string.

* Changed debugger "Enter memory address" to accept hex only

UPDATE TO PR #1316
The "Enter memory address" prompt by default expects a decimal address unless it's preceded by 0x. Or it expects an number starting with 0 is an octal.
The disassembly address should be hexadecimal regardless as that is how it it displays the address.
Also changed it so that it changes any breakpoint or disassembly address entered to be divisible by 4 as there was an observed issue that would cause the disassembly addresses to get locked to a address that was not divisible by 4 and a breakpoint address that is not divisible by 4 would never be hit.
2020-12-27 00:43:43 +10:00
Margen67
f2b1f40763 appveyor.yml improvements
Ignore files like GitHub Actions.
Make image: into one line.
Make submodule update into one line.
Remove whitespace.
Use AppVeyor's build system.
7z:
 Exclude files from the archive instead of deleting them.
 Make archive more consistent with GitHub Actions.
Use artifacts: instead of PushArtifact.
2020-12-26 00:37:36 -08:00
Albert Liu
12bc7a7805 MemoryCardImage: Fix multi-block file reads 2020-12-25 20:01:21 -08:00
Anderson_Cardoso
b67b770c5d Android Update Strings to latest 2020-12-25 16:00:12 -03:00
Anderson_Cardoso
bc9da28f31 Atualização Português do Brasil 2020-12-25 15:20:29 -03:00
Connor McLaughlin
56fc694076 Move older news to NEWS.md and trim list in README.md 2020-12-26 01:14:23 +10:00
Connor McLaughlin
0bded2b06a Update README.md 2020-12-26 01:08:57 +10:00
Connor McLaughlin
a69474ea97 TextureReplacements: Use x86 dispatch for xxhash 2020-12-26 00:47:24 +10:00
Connor McLaughlin
af3b2b0e15 Build: Fix xxhash on non-Windows 2020-12-26 00:47:24 +10:00
Connor McLaughlin
b755798c2a Qt: Update French translation 2020-12-26 00:47:03 +10:00
Connor McLaughlin
d187c8b08d GPU/HW: Fix a potential case where depth isn't cleared on viewport change 2020-12-26 00:47:03 +10:00
Connor McLaughlin
a385573672 Qt: Add texture replacement options to advanced settings 2020-12-26 00:47:03 +10:00
Connor McLaughlin
41b803ed2b FrontendCommon: Add a hotkey to reload texture replacements 2020-12-26 00:47:03 +10:00
Connor McLaughlin
8db961042a GPU: Support replacing VRAM writes with new textures 2020-12-26 00:47:03 +10:00
Connor McLaughlin
a66f14b5c3 Vulkan/Texture: Add UpdateFromBuffer method 2020-12-26 00:47:03 +10:00
Connor McLaughlin
ebaad0f35a Common/GL: Add replace method to texture 2020-12-26 00:47:03 +10:00
Connor McLaughlin
ecbfff3c60 HostDisplay: Fix incorrect extension check for other formats 2020-12-26 00:47:03 +10:00
Connor McLaughlin
f6c0156eea Common/Image: Add save helpers, fix errors 2020-12-26 00:47:03 +10:00
Connor McLaughlin
34dace4506 dep/xxhash: Update to latest version 2020-12-26 00:47:02 +10:00
Connor McLaughlin
6de53054c1 Qt: Move blit swap chain option to display settings 2020-12-26 00:47:02 +10:00
Michael Forney
4bca193ee1 FileSystem: Include <limits.h> for PATH_MAX 2020-12-26 00:47:02 +10:00
Michael Forney
8856099092 Build: Fix threads detection on libc with built-in support
As noted in the FindThreads documentation[0], CMAKE_THREAD_LIBS_INIT
may be empty if no special flags are needed to use thread support.
Instead, use Threads_FOUND to determine if threads are supported.

[0] https://cmake.org/cmake/help/latest/module/FindThreads.html
2020-12-26 00:47:02 +10:00
Michael Forney
7a40a843d4 Common/FileSystem: Fix misspelling of 'separator' 2020-12-26 00:47:02 +10:00
Michael Forney
d0398c8a83 Common/FileSystem: Fix canonicalization of paths beginning with ./
If we don't skip past the following separator when the destination
is empty, then `./file` gets canonicalized as `/file`.

Also, consider the case where we end up with an empty string (for
example, from `foo/..`). Canonicalize this as `.`.
2020-12-26 00:47:02 +10:00
Michael Forney
64c0ca14a3 System: Fix some bugs in GetTitleForPath
The previous implementation had a few issues in certain edge cases:
- If the path contained no '/' or '\', then the string_view constructor
  is called with a count that exceeds the length of the string
  (effectively `title_end - (char *)0`, which is undefined behavior,
  at least in C).
- If the only '/' was the filesystem root, the last character of
  the title was truncated, and the '/' remained. For example,
  "/title.bin" resulted in "/titl".
- At least in C, it is undefined behavior to use the the < operator
  with a null pointer, which is done in std::max if the path did
  not have both '/' and '\'.

The first issue results in a std::bad_alloc exception on my machine.
2020-12-26 00:47:02 +10:00
Connor McLaughlin
fcc6bf0cb7 Update README with dev vs preview builds 2020-12-26 00:47:02 +10:00
Connor McLaughlin
3f410ebbac Cheats: Add additional code types from @PugsyMAME 2020-12-26 00:47:02 +10:00
Jean-Baptiste Boric
7dcacc2cda Qt: Implement GDB server 2020-12-26 00:47:02 +10:00
Jean-Baptiste Boric
abd2399aaf Core: Implement GDB protocol 2020-12-26 00:47:02 +10:00
Jean-Baptiste Boric
9b40c8ffa6 Settings: Add GDB server settings 2020-12-26 00:47:02 +10:00
Jean-Baptiste Boric
9bd28f39a5 StringUtil: Add base support and hexadecimal functions 2020-12-26 00:47:02 +10:00
Connor McLaughlin
fd39f09aa7 scmversion: Second part of beta -> preview 2020-12-25 13:58:50 +10:00
PugsyMAME
c0cc0a371b Fixed Slide Code cheat type
Address increment is a u8 and value increment is a u16. The changes will make this work correctly:-

50000AA4 FFFF
801CC760 0400
which is a example slide code representing:-
801CC760 0400
801CC804 03FF
801CC8A8 03FE
801CC94C 03FD
801CC9F0 03FC
801CCA94 03FB
801CCB38 03FA
801CCBDC 03F9
801CCC80 03F8
801CCD24 03F7
2020-12-25 13:53:28 +10:00
Connor McLaughlin
b468f643fb CI: Remove unused scripts 2020-12-25 13:53:28 +10:00
Connor McLaughlin
e5495b43c6 CI: Rename beta builds to preview builds, stable to development 2020-12-25 13:53:28 +10:00
Connor McLaughlin
add6754381 libretro: Remove guncon/mouse/negcon controller types
These were never supported. Use the standalone version if you want to
use these controller types.
2020-12-25 13:53:28 +10:00
MojoJojoDojo
aedfff7e3f Adding 2 more games that needs CPU PGXP - Alundra 2 and Disney's Aladdin in Nasira's Revenge (#1287)
* Adding PGXP CPU for 2 games

* Revert "Adding PGXP CPU for 2 games"

This reverts commit 35e9ad743f.

* Update gamesettings.ini

Adding 2 more games that need CPU PGXP
2020-12-25 13:51:23 +10:00
Connor McLaughlin
7f6fbd6b80 Merge pull request #1289 from andercard0/patch-51
Atualização Português do Brasil
2020-12-25 13:51:02 +10:00
Connor McLaughlin
8fcb3d6690 Merge pull request #1297 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-25 13:50:51 +10:00
Connor McLaughlin
2e3ce32819 Merge pull request #1301 from ggrtk/cmake-fix-missing-translations
CMake: Fix missing translation files
2020-12-25 13:50:39 +10:00
Albert Liu
f63291b8ec CMake: Fix missing translation files 2020-12-24 12:01:33 -08:00
zkdpower
3f22f55338 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-24 13:05:50 +08:00
Anderson_Cardoso
33fdbe48a5 Atualização Português do Brasil
Update Pt-Br to the latest.
2020-12-22 16:51:05 -03:00
Connor McLaughlin
095bc280cb Qt: Fix default value of PGXP depth buffer 2020-12-23 02:26:47 +10:00
Connor McLaughlin
31f7ec7538 Update README.md 2020-12-23 01:56:18 +10:00
Connor McLaughlin
f798877704 Update README.md 2020-12-23 01:54:44 +10:00
Connor McLaughlin
ee5ba8d90a Merge pull request #1284 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-23 01:44:35 +10:00
Connor McLaughlin
4f9a5d0241 Merge pull request #1285 from CookiePLMonster/memcard-slashes-fix
Memory Card Editor fixes
2020-12-23 01:44:13 +10:00
zkdpower
ce4e9f4f17 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-22 23:41:05 +08:00
Silent
51eb494340 Memcard Editor: Fix relative shared paths not opening in Memcard Editor by default 2020-12-22 16:39:59 +01:00
Connor McLaughlin
744cfbd924 Frontends: Add PGXP Depth Buffer options 2020-12-23 01:39:49 +10:00
Connor McLaughlin
d320d5c830 GameSettings: Add game settings/hotkey for PGXP depth 2020-12-23 01:39:49 +10:00
Connor McLaughlin
aa1543271e GPU: Support emulating a depth buffer from PGXP depth values 2020-12-23 01:39:49 +10:00
Connor McLaughlin
f393ea618e Shaders/Cccalibrator: Fix compile errors 2020-12-23 01:39:49 +10:00
Connor McLaughlin
9384f3a8e9 Qt/CheatManager: Fix checking groups not updating child nodes 2020-12-23 01:34:32 +10:00
Connor McLaughlin
972872a0c8 Merge pull request #1278 from andercard0/patch-50
Atualização Português do Brasil
2020-12-23 01:21:32 +10:00
Silent
bb528fb15c Fix inconsistent forward/backward slashes in Memcard Editor
Memcard Editor looks for an exact string match, so slashes must be
consistent.
2020-12-22 16:14:22 +01:00
Anderson_Cardoso
19980426fb Atualização Português do Brasil
Update language Pt-Br to latest.
2020-12-21 14:53:52 -03:00
Connor McLaughlin
ca84925ff8 HostDisplay: Support screenshotting 16-bit display formats 2020-12-22 03:24:51 +10:00
Albert Liu
189656cbc4 CommonHostInterface: Fully clear controller section before loading profile 2020-12-22 03:24:51 +10:00
Albert Liu
a5f04f2a8e CommonHostInterface: Don't save/load input profile rumble for motorless controller types 2020-12-22 03:24:51 +10:00
Connor McLaughlin
7249825c16 Qt: Support multiple updater channels 2020-12-22 03:24:51 +10:00
Connor McLaughlin
14c227a813 scmversion: Fix incorrect tagging after stable/beta split 2020-12-22 03:24:19 +10:00
Connor McLaughlin
3ab017c32e CI: Set prerelease tag only on beta release 2020-12-22 02:40:27 +10:00
Connor McLaughlin
80ce7bde26 CI: Generate master->beta, stable->latest releases 2020-12-22 02:18:15 +10:00
Connor McLaughlin
b24245dd1d GameList: Bump cache list version
Required due to aspect ratio change.
2020-12-22 02:16:11 +10:00
Connor McLaughlin
d130fc9465 Android: Possible fix for white overlay with controller 2020-12-22 02:15:55 +10:00
PugsyMAME
295f369519 Added PAL games to cheat database + other modifications
1. Cleaned up and added cheats for non-softwarelist games, mainly for PAL regions this has doubled the size of the database.
2. Added information about the various 32 bit by 32 bit cheat types to the cheat file header.
3. Added information for cheat types 31, 32 ,81, 82, 91 & 92 which are BIT set and clear cheat types - I'll do a PR for these in the next week.
4. Grouped some more cheats
2020-12-22 00:58:34 +10:00
Connor McLaughlin
d5d9cb623d GPU/Vulkan: Fix possible framebuffer destroy-while-in-use 2020-12-22 00:56:55 +10:00
Connor McLaughlin
c0d8e44548 Merge pull request #1263 from andercard0/patch-48
Atualização Português do Brasil
2020-12-22 00:53:36 +10:00
Connor McLaughlin
22c15f88dd Merge pull request #1262 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-22 00:53:19 +10:00
Connor McLaughlin
68557eb843 Merge pull request #1266 from Margen67/ar
Use proper 21:9 aspect ratio, add 32:9
2020-12-22 00:52:36 +10:00
Connor McLaughlin
5e5818df54 Merge pull request #1276 from shikulja/master
update ru translation
2020-12-22 00:50:51 +10:00
Connor McLaughlin
f12c60e9b4 Merge pull request #1274 from andercard0/patch-49
Suggestion - Controller Troubleshoot
2020-12-22 00:50:31 +10:00
shikulja
e3c9b75c1a update ru translation 2020-12-21 15:17:05 +03:00
Margen67
b7534015e0 Use proper 21:9 aspect ratio, add 32:9 2020-12-20 19:57:15 -08:00
Anderson_Cardoso
e36bfa567d Suggestion - Controller Troubleshoot 2020-12-20 17:35:49 -03:00
Anderson_Cardoso
2a1e8047fe Atualização Português do Brasil 2020-12-19 10:29:39 -03:00
zkdpower
3b9a9a6308 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-19 17:39:38 +08:00
Connor McLaughlin
6224d0ab89 Qt: Fix crash when switching to cheat list
Regression from 076a2ca307.
2020-12-19 19:09:34 +10:00
Connor McLaughlin
44ea51306a Qt: Add open button to memory card editor 2020-12-19 17:02:02 +10:00
Connor McLaughlin
175bc66c91 Qt: Fix some mouse presses at high click rate not registering 2020-12-19 17:02:02 +10:00
Connor McLaughlin
81aad196e8 HostInterface: Add -nocontroller CLI option to disable controller interface
Can use with buggy drivers where SDL is causing crashes.
2020-12-19 17:02:01 +10:00
Connor McLaughlin
e804fdfdba GPU: Use floating point coordinates for lightgun 2020-12-19 17:02:01 +10:00
Connor McLaughlin
4860313bef NamcoGuncon: Add an option to scale X coordinates
Fixes what appears to be curvature correction at the edges of the
screen.
2020-12-19 17:02:01 +10:00
Connor McLaughlin
fad3d79895 NamcoGuncon: Add button to shoot offscreen 2020-12-19 17:02:01 +10:00
Connor McLaughlin
7ca0d357cb shaders/cccalibrator: Fix GLSL compile error 2020-12-19 17:02:01 +10:00
Connor McLaughlin
faa016eaee Merge pull request #1255 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-19 17:01:44 +10:00
Connor McLaughlin
076a2ca307 Qt/CheatManager: Default to unsigned/hex/halfword 2020-12-19 02:44:46 +10:00
Connor McLaughlin
ca61f989fc DMA: Don't panic on invalid device read/write 2020-12-19 02:44:46 +10:00
Connor McLaughlin
7c7145d1c5 MDEC: Handle invalid commands
Fixes panic in Formula 1.
2020-12-19 02:44:46 +10:00
Connor McLaughlin
980aa0a8bc Qt/CheatManager: Add manual watch address 2020-12-19 02:44:46 +10:00
Connor McLaughlin
a6a0b660d2 GameList: Bump cache version
This should've happened with the aspect ratio changes.
2020-12-19 02:44:46 +10:00
zkdpower
9b20f1ffd9 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-18 16:26:08 +08:00
Connor McLaughlin
208e746467 Merge pull request #1254 from ggrtk/update-bug-report-template
Update bug report issue template
2020-12-18 18:03:39 +10:00
Albert Liu
5e9a4f9bc6 Update bug report issue template 2020-12-17 22:53:48 -08:00
Connor McLaughlin
9e1987063d System: Add a libcrypt game list, and check serials
Nag the user if they're missing a sbi file.
2020-12-18 03:03:22 +10:00
Connor McLaughlin
627008f34c CDImage: Add helper for checking for SBI 2020-12-18 03:03:22 +10:00
Connor McLaughlin
4232ef7bf3 CDImageCue: Try for a file based on the cue filename if bin missing
Should work around people who have renamed the files but not updated the
cuesheet.
2020-12-18 03:03:22 +10:00
Connor McLaughlin
b3edcc5841 CDROM: Don't reset audio decoder state on file/channel change
Star Wars Jedi Power Battles sends constant Setfilter commands, while
playing.
2020-12-18 03:03:21 +10:00
Connor McLaughlin
d2c98639a8 Cheats: Add extension 32-bit instructions variants 2020-12-18 03:03:21 +10:00
Connor McLaughlin
412b5073db Merge pull request #1243 from andercard0/patch-47
Atualização Português do Brasil
2020-12-18 03:03:07 +10:00
Anderson_Cardoso
feb009ce39 Atualização Português do Brasil
Updated translation latest.
2020-12-17 11:38:19 -03:00
Connor McLaughlin
681fccd5e6 Qt: Fix compilation on Qt <5.11 2020-12-17 13:05:17 +10:00
Connor McLaughlin
4b4b97540e Qt: Fix Linux build (again) 2020-12-17 12:54:36 +10:00
Connor McLaughlin
6fdb7fa801 Qt: Fix Linux build 2020-12-17 12:38:32 +10:00
Connor McLaughlin
c1f802c397 Qt: Fix OSD messages not rendering in Japanese translation 2020-12-17 12:15:37 +10:00
Connor McLaughlin
ea996a0305 Qt: Add debugger UI 2020-12-17 12:15:37 +10:00
Connor McLaughlin
3b23542ec9 CPU: Provide debugger/breakpoint/step functionality 2020-12-17 11:57:47 +10:00
Connor McLaughlin
a8af0f7ecb HostInterface: Add debugger message callbacks 2020-12-17 11:57:47 +10:00
Connor McLaughlin
fa0f177e51 HostInterface: Move PauseSystem from common to base 2020-12-17 11:57:47 +10:00
Connor McLaughlin
e044858953 CPU: Add additional instruction decoder helpers 2020-12-17 11:57:46 +10:00
Connor McLaughlin
9fd1d606d7 Bus: Add memory region access helpers 2020-12-17 11:57:46 +10:00
Connor McLaughlin
c95ccbcb5e Android: Add Auto (Game Native) aspect ratio 2020-12-17 11:57:46 +10:00
Connor McLaughlin
6b10a1089c Merge pull request #1240 from ggrtk/qt-japanese
Qt: Add Japanese translation by mikakunin
2020-12-17 11:37:19 +10:00
Connor McLaughlin
a4b6df3e7d Merge pull request #1239 from ggrtk/analog-controller
AnalogController: Fix config mode 0x4C response
2020-12-17 11:36:58 +10:00
Connor McLaughlin
ed304f0dcd Merge pull request #1224 from PavelDurov1488/master
Cccalibrator
2020-12-17 11:36:36 +10:00
Connor McLaughlin
9d7b63923a Merge pull request #1235 from valadaa48/CRTCTicksToSystemTicks_optimization
Small optimization to GPU::SystemTicksToCRTCTicks
2020-12-17 11:36:21 +10:00
Connor McLaughlin
bd8613b120 Merge pull request #1227 from ggrtk/auto-aspect-ratio
GPU: Add auto aspect ratio and various fixes
2020-12-17 11:35:48 +10:00
Albert Liu
4f26150ef1 Qt: Add Japanese translation by mikakunin 2020-12-16 16:11:49 -08:00
Albert Liu
b7bccac71d AnalogController: Fix config mode 0x4C response 2020-12-16 15:11:53 -08:00
Connor McLaughlin
bd7e6954c3 README: Add Google Play link, clarify SBI requirements 2020-12-17 01:35:08 +10:00
Connor McLaughlin
30472b853d Qt: Compile fix 2020-12-17 01:26:07 +10:00
Connor McLaughlin
c0c035ab54 Update compatibility list and settings 2020-12-17 01:20:06 +10:00
Connor McLaughlin
47f0720b93 Controller: Always preserve internal state when loading/resuming
Fixes analog mode getting disabled when loading state.
2020-12-17 01:20:06 +10:00
Connor McLaughlin
b78a6045fc Qt: Make some async method invokes explicitly queued 2020-12-17 01:20:06 +10:00
Connor McLaughlin
7b6d30a994 GPU/HW: Fix possible VRAM corruption when live switching resolutions
Mask bit was getting lost based on guest state.
2020-12-17 01:20:06 +10:00
shikulja
cc5df71af9 update ru translation (#1216)
* update ru translation

added some new lines, fixed small typos

* Update duckstation-qt_ru.ts
2020-12-17 01:04:35 +10:00
Connor McLaughlin
2c35a552d5 Merge pull request #1214 from andercard0/patch-46
Android update Strings to latest
2020-12-17 01:04:20 +10:00
Connor McLaughlin
fb3ee3878f Merge pull request #1213 from andercard0/patch-45
Android Update Arrays to latest.
2020-12-17 01:04:09 +10:00
Albert Liu
de8f03bd75 GPU: Add auto (game native) aspect ratio 2020-12-16 02:40:33 -08:00
valadaa48
f5f12fd76d Small optimization to GPU::SystemTicksToCRTCTicks 2020-12-15 22:31:34 -05:00
Albert Liu
b4fb1e20d8 Settings: Remove unused variables 2020-12-14 19:28:59 -08:00
Albert Liu
2c76ad204a GPU: Fix operator warning 2020-12-14 19:28:59 -08:00
Albert Liu
1c8a896a55 GPU: Wrap display VRAM coordinates properly 2020-12-14 19:28:59 -08:00
Albert Liu
866cbdca4b GPU: Prevent potential overflow in CRTC visible area calculation 2020-12-14 19:28:59 -08:00
Albert Liu
78e42d9b4c GPU: Clean up CRTC variable naming 2020-12-14 19:28:59 -08:00
Albert Liu
b8abf2df95 GPU: Don't apply display offsets when not cropping 2020-12-14 19:28:58 -08:00
PavelDurov1488
9310a736c4 Cccalibrator
Its not complete, i need to add dynamic noise and blur and make saturation tunable
2020-12-15 00:21:42 +08:00
Anderson_Cardoso
2c89178895 Android update Strings to latest 2020-12-13 15:56:49 -03:00
Anderson_Cardoso
e0679b216e Android Update Arrays to latest. 2020-12-13 15:55:59 -03:00
Connor McLaughlin
3ed429772d Android: Fix touchscreen controller being instantiated when disabled 2020-12-14 02:15:25 +10:00
Connor McLaughlin
4bcf8b3ce9 Android: Fix nav/notification bar getting stuck when editing layout 2020-12-14 02:15:25 +10:00
Connor McLaughlin
e85f7da874 Update game compatibility settings 2020-12-14 02:15:25 +10:00
Connor McLaughlin
09f6f6c3ea Merge pull request #1212 from shikulja/master
Update ru translation
2020-12-14 02:15:08 +10:00
shikulja
4e7de5a464 Update ru translation
(LF>CRLF )
2020-12-13 18:58:57 +03:00
Connor McLaughlin
fd0e75ea61 Update compatibility list and settings 2020-12-14 01:39:32 +10:00
Connor McLaughlin
d0e68c7163 GPU: Mask Y coordinates of VRAM transfers to 9-bits
Fixes GPU error and crash in hardware renderers in Remote Control
Dandy.
2020-12-14 01:35:53 +10:00
Connor McLaughlin
5164840c25 CPU/CodeCache: Don't choke on indirect branches in delay slot
Fixes emulator crash/memory usage explosion in Shadow Master.
2020-12-14 01:35:53 +10:00
Connor McLaughlin
d7c3a0137f Android: Support editing touchscreen controller layout 2020-12-14 01:35:53 +10:00
Connor McLaughlin
76c945a6e3 Android: Auto-formatting 2020-12-14 01:35:53 +10:00
Connor McLaughlin
c90ed85d9d Merge pull request #1202 from andercard0/patch-44
Atualização Português do Brasil
2020-12-14 01:35:36 +10:00
Connor McLaughlin
ac2d788e3d Merge pull request #1205 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-14 01:35:16 +10:00
GravuTrad
c37cb54acf Update duckstation-qt_fr.ts (#1210)
* Update duckstation-qt_fr.ts

Update french: all typos errors and few missing translations

* Update duckstation-qt_fr.ts

* Update duckstation-qt_fr.ts
2020-12-14 01:34:53 +10:00
zkdpower
12c294c780 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-13 11:08:04 +08:00
Anderson_Cardoso
bb4be085e4 Atualização Português do Brasil 2020-12-12 16:55:19 -03:00
Connor McLaughlin
5c6ee953d0 libretro: Update compatibility settings 2020-12-13 00:47:26 +10:00
Connor McLaughlin
7e5410fc44 CPU/AArch64: Use scratch register for unfitting intermediate values
Should fix crashes with icache emulation enabled.
2020-12-13 00:36:09 +10:00
Connor McLaughlin
abb0a1987d Android: Fix force analog on reset 2020-12-13 00:18:52 +10:00
Connor McLaughlin
c47efc597f Merge pull request #1194 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-13 00:17:50 +10:00
Blackbird88
57358e3499 GameSettings: Force Digital Controller in Disney's Hercules (Re-release) (#1190)
* GameSettings: Force Digital Controller in Disney's Hercules
2020-12-13 00:17:17 +10:00
Renzo Pigliacampo
35b9143d3e Update spanish translation (#1189) 2020-12-13 00:15:47 +10:00
Connor McLaughlin
d2218f6f1c Merge pull request #1195 from ggrtk/analog-controller
AnalogController: Clarify option for forcing analog mode
2020-12-13 00:15:22 +10:00
Albert Liu
62609b5008 GameSettings: Fix build warning 2020-12-12 01:00:34 -08:00
Albert Liu
def9a98cb9 GameSettings: Disable analog mode forcing instead of forcing digital controller 2020-12-11 19:50:43 -08:00
Albert Liu
8716c33f41 AnalogController: Clarify option for forcing analog mode 2020-12-11 19:50:43 -08:00
Connor McLaughlin
90997d4a8b GameList: Prioritize game title cover image over database title 2020-12-12 12:23:53 +10:00
Connor McLaughlin
6e7f1501b5 SDLAudioStream: Fix volume not applying 2020-12-12 11:50:48 +10:00
Connor McLaughlin
eefbd8f6a6 CubebAudioStream: Use cubeb's volume control 2020-12-12 11:50:37 +10:00
Connor McLaughlin
907e0de35a FrontendCommon: Fix volume hotkeys starting at 0% when muted 2020-12-12 11:50:20 +10:00
Connor McLaughlin
f4d540bcc6 Qt: Fix mute toggle having inverse effect 2020-12-12 11:49:50 +10:00
Connor McLaughlin
58b24d6ac9 Qt: Fix volume controls updating incorrect volume 2020-12-12 11:49:34 +10:00
Connor McLaughlin
420525e672 DigitalController: MSVC warning fix 2020-12-12 11:37:38 +10:00
zkdpower
49fda513ee Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-11 08:33:03 +08:00
Connor McLaughlin
a391ba1622 Android: Clean up local references on emu thread and loops
Should hopefully fix the runtime killing our app on some devices.
2020-12-11 00:32:53 +10:00
Connor McLaughlin
ae9c4c48f4 Android: Fix fast forward volume label 2020-12-11 00:32:53 +10:00
Connor McLaughlin
591f69f771 Merge pull request #1188 from ggrtk/popn-controller
DigitalController: Add option to force as Pop'n Controller
2020-12-11 00:31:32 +10:00
Connor McLaughlin
baa3fe41c6 Merge pull request #1185 from ggrtk/update-cubeb
dep/cubeb: Update to 860bf2b
2020-12-11 00:30:52 +10:00
Connor McLaughlin
2b9f9a21e4 Merge pull request #1181 from DenSinH/master
Update Dutch translation
2020-12-11 00:30:34 +10:00
Albert Liu
191e6b0496 DigitalController: Add option to force as Pop'n Controller 2020-12-09 23:39:11 -08:00
Albert Liu
b9c5d5b8a3 dep/cubeb: Update to 860bf2b 2020-12-09 22:41:24 -08:00
Dennis H
b1d7f7b156 replaced tabs by spaces from copied text 2020-12-09 17:08:41 +01:00
Dennis H
e3744688e1 added missing strings 2020-12-09 17:07:56 +01:00
Connor McLaughlin
c2ceb02610 Update README.md 2020-12-10 01:33:41 +10:00
Connor McLaughlin
b2a6ad143c Update compatibility settings for Moto Racer 2020-12-10 01:29:38 +10:00
Connor McLaughlin
e2a2972b38 Merge pull request #1180 from andercard0/patch-43
Atualização Português do Brasil
2020-12-10 01:22:05 +10:00
Connor McLaughlin
20d4cec4d6 Merge pull request #1179 from andercard0/patch-42
Android Update Pt-Br
2020-12-10 01:21:41 +10:00
Connor McLaughlin
53962b32b0 Merge pull request #1178 from andercard0/patch-41
Android Update Pt-Br
2020-12-10 01:21:31 +10:00
Connor McLaughlin
dcb4769298 Update compatibility list 2020-12-10 01:21:00 +10:00
Connor McLaughlin
523dda47fa Android: Add Dutch translation 2020-12-10 01:16:54 +10:00
Connor McLaughlin
50bcdc0abb MDEC: Adjust 16bpp timing
Fixes jittery movement in Parasite Eve II opening.
2020-12-09 20:29:32 +10:00
Connor McLaughlin
59c338f461 Cheats: Support double conditional D0/D1/D2/D3/E0/E1/E2/E3/D4 2020-12-09 20:22:43 +10:00
Anderson_Cardoso
654c3f2ad6 Atualização Português do Brasil 2020-12-08 21:36:46 -03:00
Anderson_Cardoso
d5df266373 Android Update Pt-Br
Update Settings to latest
2020-12-08 19:37:45 -03:00
Anderson_Cardoso
66013e44d4 Android Update Pt-Br
Arrays update.
2020-12-08 19:36:06 -03:00
Connor McLaughlin
770dd5a600 Update compatibility list/game settings 2020-12-09 01:56:14 +10:00
Connor McLaughlin
d7de578d4a Update compatibility list/game settings 2020-12-09 01:37:28 +10:00
Connor McLaughlin
300510f20a Android: Add language override setting 2020-12-09 01:29:15 +10:00
Connor McLaughlin
98766a490f Log: Change success to verbose and move down in ordering 2020-12-09 01:03:32 +10:00
Connor McLaughlin
678146b907 HostInterface: Add separate volume control for fast forwarding 2020-12-09 01:03:32 +10:00
Connor McLaughlin
6d45d4d579 Merge pull request #1169 from PugsyMAME/master
More Cheat File Housekeeping
2020-12-09 00:23:23 +10:00
Connor McLaughlin
b79d025e66 Merge pull request #1174 from ggrtk/analog-controller
AnalogController: Disallow analog-to-dpad in config mode
2020-12-09 00:22:57 +10:00
Connor McLaughlin
8e79059fe3 Merge pull request #1166 from CookiePLMonster/xinput-button-fix
XInput: Fix mapping buttons to axes
2020-12-09 00:22:14 +10:00
Connor McLaughlin
25fb3c01c3 Andorid: Add partial Italian translation 2020-12-09 00:19:57 +10:00
Connor McLaughlin
03ea80d130 Android: Add threaded rendering to advanced options 2020-12-09 00:19:57 +10:00
Connor McLaughlin
5c2efd880d Android: Add Brazilian Portuguese translation 2020-12-09 00:19:57 +10:00
Connor McLaughlin
419736aaee GPU/Software: Ensure commands are always aligned to 4 bytes 2020-12-09 00:19:57 +10:00
Connor McLaughlin
e340963c99 Android: Replace inline strings with string resource references 2020-12-09 00:19:57 +10:00
Albert Liu
18a4ff76e2 AnalogController: Disallow analog-to-dpad in config mode 2020-12-08 02:36:19 -08:00
PugsyMAME
f2db25e697 More Cheat File Housekeeping
More cheat clean ups and added some more cheats
Added button info to the code format at the top of the file for the R4 type
Added placeholders for the games in the softwarelist with no cheats so that there is somewhere to insert the cheats quickly
2020-12-07 23:42:45 +00:00
Silent
a4124fdc1b Another fix for XInput backend 2020-12-07 18:08:48 +01:00
Connor McLaughlin
98d6b49987 System: Log FPS/frame times every second 2020-12-08 01:47:28 +10:00
Connor McLaughlin
0f8f9bc052 dep/cubeb: Update to 85f1cf4 2020-12-08 01:47:27 +10:00
Connor McLaughlin
7daa169cda Merge pull request #1163 from ggrtk/gpu-tex-palette-reg-y
GPU: Fix GPUTexturePaletteReg y BitField width
2020-12-08 01:42:10 +10:00
Connor McLaughlin
e7ae9b33a1 Merge pull request #1160 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-08 01:41:56 +10:00
Connor McLaughlin
986e52990e Merge pull request #1164 from ggrtk/update-cubeb
dep/cubeb: Update to 70fadbf
2020-12-08 01:41:40 +10:00
Albert Liu
93f46c142c GPU: Fix GPUTexturePaletteReg y BitField width 2020-12-06 22:20:23 -08:00
Albert Liu
47bf9862bc dep/cubeb: Update to 70fadbf 2020-12-06 20:28:41 -08:00
zkdpower
0d2e835637 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-07 01:31:27 +08:00
Connor McLaughlin
50273899c6 Merge pull request #1158 from andercard0/patch-38
Tradução Português do Brasil
2020-12-07 02:48:10 +10:00
Connor McLaughlin
b44a654943 System: Reset throttler when audio buffers underflow
Should hopefully reduce the chances of the audio source ending up out of
phase from the emulation when vsync is disabled.
2020-12-07 02:44:23 +10:00
Connor McLaughlin
c8f33e340b Revert "CommonHostInterface: Don't use sleep throttle when syncing to audio at standard speed"
This reverts commit 922e17f677.
2020-12-07 02:44:23 +10:00
Anderson_Cardoso
8f56d2c659 Tradução Português do Brasil
Update to latest.
2020-12-06 12:42:01 -03:00
Connor McLaughlin
11d2b3a1a8 Merge pull request #1157 from PugsyMAME/master
Added Cheat Code Information & More Housekeeping
2020-12-07 01:11:13 +10:00
Connor McLaughlin
f002b4ca4b Merge pull request #1150 from andercard0/patch-37
Atualização Português do Brasil
2020-12-07 01:09:46 +10:00
Connor McLaughlin
ead1be4728 Android: Add version, GitHub, Discord to app 2020-12-07 01:07:13 +10:00
Connor McLaughlin
e579cd2eb2 CDImageHasher: Only ignore index 0 for track 1 2020-12-07 00:44:48 +10:00
Connor McLaughlin
0fbb69a3ef Qt: Add option to hide the mouse cursor in fullscreen 2020-12-07 00:06:32 +10:00
Connor McLaughlin
a511882cb8 D3D11HostDisplay: Add an option to force a blit/discard swap chain 2020-12-06 23:46:23 +10:00
Connor McLaughlin
3ccfc42b0f D3D11HostDisplay: Use shader cache for postprocessing shaders 2020-12-06 23:37:41 +10:00
Connor McLaughlin
737a87b483 CommonHostInterface: Add a hotkey to toggle all cheats 2020-12-06 23:32:32 +10:00
PugsyMAME
044d806b2a Added Cheat Code Information & More Housekeeping
Added cheat format information to the header of the cheat file and done some more housekeeping - reordering and converting more cheats into groups.
2020-12-06 12:48:24 +00:00
Connor McLaughlin
922e17f677 CommonHostInterface: Don't use sleep throttle when syncing to audio at standard speed 2020-12-06 18:18:18 +10:00
Connor McLaughlin
f5ccb6ea60 CPU: Fall back to mmap'ed buffer if reprotecting code space fails 2020-12-06 18:13:07 +10:00
Connor McLaughlin
09495b1d93 Cheats: Implement C1 command 2020-12-06 15:50:58 +10:00
Connor McLaughlin
ea9829946d Cheats: Implement D4/D5/D6 code types 2020-12-06 15:47:00 +10:00
Anderson_Cardoso
f0c2fb23e3 Atualização Português do Brasil 2020-12-05 13:51:47 -03:00
Connor McLaughlin
fd6462263f Common/Event: Fix TryWait not returning on timeout on Linux
Fixes a potential deadlock in the Qt frontend if initialization on the
emu thread takes too long.
2020-12-06 00:41:07 +10:00
Connor McLaughlin
1e322191ea GameSettings: Force recompiler icache in Suikoden (USA)
This game calls BIOS memmove() in uncached memory a bunch of times,
which takes several frames to complete. Version 1.0 will corrupt
palettes if this completes too quickly.
2020-12-06 00:35:54 +10:00
Connor McLaughlin
a90c25d0e7 SPU: Ignore manually set loop address only on first block
Fixes occasional missing dialogue in Valkyrie Profile.
2020-12-06 00:35:54 +10:00
Connor McLaughlin
d7bd21c06d Timers: Update when sync is used with sysclk source
Fixes hang at boot in Zoku Mikagura Shoujo Tanteidan - Kanketsuhen.
2020-12-06 00:35:54 +10:00
Connor McLaughlin
5e05a14f97 GPU: Fix incorrect draw time approximation of lines
Fixes flickering pre-mission screen in Omega Boost.
2020-12-06 00:35:54 +10:00
Connor McLaughlin
d757056891 GPU: Implement dot clock timer (Timer 0)
Fixes softlock in Evil Dead - Hail to the King.
2020-12-06 00:35:54 +10:00
Connor McLaughlin
8b3426a96e System: Reinitialize code cache on hw settings change/disc swap
Basically, anything which could allocate large amounts of memory and
potentially overlap with our fastmem area.
2020-12-06 00:35:54 +10:00
Connor McLaughlin
1c9d0967b1 GPU/OpenGL: Fix shader compile error on GLES 2020-12-06 00:35:54 +10:00
Connor McLaughlin
6d674175f4 Qt: Add missing documentation for pause-on-focus-loss 2020-12-06 00:35:54 +10:00
Connor McLaughlin
47cd1bc67e Merge pull request #1149 from andercard0/patch-36
Atualização tradução Português do Brasil
2020-12-06 00:35:19 +10:00
RaydenX93
a9b7e295fe Update Italian Translation (#1148)
* Update duckstation-qt_it.ts

* Corrections

On behalf of @hugihadein
2020-12-06 00:35:08 +10:00
Connor McLaughlin
6b147d8a59 Merge pull request #1146 from CookiePLMonster/xinput-axis-fix
XInput: Fix mapping triggers to axes
2020-12-06 00:34:56 +10:00
Anderson_Cardoso
2fc27a6bb2 Atualização tradução Português do Brasil
Updated to latest.
2020-12-05 09:00:19 -03:00
Silent
39768edd74 XInput: Fix mapping triggers to axes 2020-12-04 17:55:01 +01:00
Connor McLaughlin
5575950822 Cheats: Support chaining C0 codes with separator (00000000 FFFF) 2020-12-05 02:08:10 +10:00
Connor McLaughlin
af6b0dc189 Qt: Add option to pause on application focus loss 2020-12-05 02:08:10 +10:00
Connor McLaughlin
2899e2d73c Merge pull request #1145 from PugsyMAME/master
General Cheat File Housekeeping
2020-12-05 02:07:14 +10:00
Connor McLaughlin
0a0243b78e Merge pull request #1141 from andercard0/patch-35
Atualização Português Brasil
2020-12-05 02:05:33 +10:00
Connor McLaughlin
60b7d8e8c0 Merge pull request #1140 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-05 02:05:19 +10:00
PugsyMAME
9556ad8a55 Changed all repetitive D0 codes into shorter C0 codes
Changed all repeating D0 codes with C0 types including a 00000000 FFFF terminator
2020-12-04 15:57:46 +00:00
PugsyMAME
9edf71d4de Merge pull request #1 from PugsyMAME/PugsyMAME-patch-1
General Cheat File Housekeeping #1
2020-12-04 13:31:18 +00:00
PugsyMAME
f561392136 General Housekeeping
Added basic header to top of cheat file. Started work on further cleaning up the cheats to work better with Duckstation -  grouping, re-sorting, fixing typos and format discrepancies, adding some cheats and removing a few duplicate cheats.
2020-12-04 13:26:23 +00:00
Anderson_Cardoso
526c682298 Atualização Português Brasil
Atualizado para versão atual!
2020-12-03 22:02:31 -03:00
zkdpower
822df373bb Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-04 08:54:53 +08:00
Connor McLaughlin
9089c97339 CPU: Drop cache control log to dev level 2020-12-04 01:19:00 +10:00
Connor McLaughlin
52dbcbaca5 PGXP: Treat add rd, rs, zero as moves
Fixes exploding vertices in BIOS intro.

Needs further investigation as to why this fixes it - clearly the actual
oepration is incorrect.
2020-12-04 01:07:36 +10:00
Connor McLaughlin
59ac365b52 GPU/HW: Extend the UV range to all "upscaled" pixels
Extend the UV range to all "upscaled" pixels. This means 1-pixel-high
polygon-based framebuffer effects won't be downsampled.

(e.g. Mega Man Legends 2 haze effect)
2020-12-04 00:33:04 +10:00
Connor McLaughlin
362905e3df GPU: Add display line offset game setting
Use when games need additional cropping.
2020-12-04 00:33:04 +10:00
Connor McLaughlin
c9ca57f013 Merge pull request #1134 from PugsyMAME/master
New conversion of the original database
2020-12-04 00:32:36 +10:00
PugsyMAME
b7b15fe540 New conversion of my original database
Converted MAME format cheats into DS format, fixed issue with some games having multiple headings and made the headers more verbose with square brackets to help them stand out.
2020-12-02 23:33:57 +00:00
Connor McLaughlin
8ad9dcb1ac Android: Add CD-ROM preload option 2020-12-03 00:57:52 +10:00
Connor McLaughlin
c406f0708f Cheats: Implement C0 command (activate codes iff equal) 2020-12-03 00:57:52 +10:00
Connor McLaughlin
3eaf28675a Merge pull request #1126 from andercard0/patch-34
Atualização Português do Brasil
2020-12-03 00:57:30 +10:00
Connor McLaughlin
bc91075bdf Merge pull request #1125 from zkdpower/master
Update Simple-Chinese language file to latest
2020-12-03 00:56:56 +10:00
Anderson_Cardoso
78031afee7 Atualização Português do Brasil
Update to latest.
2020-12-01 14:57:06 -03:00
zkdpower
3a33ada3f9 Update Simple-Chinese language file to latest
Update Simple-Chinese language file to latest
2020-12-02 01:48:46 +08:00
Connor McLaughlin
cd8f17dbd0 Qt: Allow memory card editing from playlist context menu 2020-12-02 00:56:31 +10:00
Connor McLaughlin
0ea2ced46d Qt: Disable game properties for playlist entries 2020-12-02 00:56:15 +10:00
Connor McLaughlin
2a61620dae dep/libchdr: Sync to upstream (82670d5) 2020-12-01 23:34:21 +10:00
Connor McLaughlin
7e944103c2 GPU/OpenGL: Work around rasterization/interplation issue on V3D/Pi4 2020-12-01 15:14:23 +10:00
Connor McLaughlin
a2666de7c8 HostInterface: Make mmap fastmem unavailable a warning instead of OSD message 2020-12-01 13:23:02 +10:00
Connor McLaughlin
977c2f4947 CheatList: Fix games with serial aliases not loading from database 2020-12-01 13:21:07 +10:00
Connor McLaughlin
f8c2d7dafd Merge pull request #1121 from dankcushions/geoshader
OES_geometry_shader and OES_copy_image support
2020-12-01 02:12:51 +10:00
Connor McLaughlin
98f70e9b51 HostDisplay: Add 5:4 and 3:2 aspect ratios 2020-12-01 01:58:46 +10:00
Connor McLaughlin
bccecdbf18 Qt: Fix crash with Vulkan renderer when unsupported 2020-12-01 01:17:26 +10:00
Connor McLaughlin
37c9e69b3e System: Zero downcount at end of frame
Prevents code running after vblank starts, and fixes events getting
delayed in interpreter mode.
2020-12-01 01:16:49 +10:00
dankcushions
e7139fe0d1 OES_copy_image support 2020-11-30 14:08:26 +00:00
Connor McLaughlin
48f3bc7045 Update cheat database 2020-11-30 21:49:48 +10:00
Connor McLaughlin
c3932e945d GameSettings: Fix PGXP culling disabled message showing when PGXP disabled 2020-11-30 01:15:44 +10:00
Connor McLaughlin
b695d3c6ce System: Use existing media if save state media is not found 2020-11-30 01:15:44 +10:00
Connor McLaughlin
eaafd0a00c Cheats: Support parsing built-in database 2020-11-30 01:15:44 +10:00
Connor McLaughlin
d1399fe6a3 Data: Add cheat database
Cheats courtesy of Pugsy.
2020-11-30 01:15:44 +10:00
Connor McLaughlin
39010320ea HostDisplay: Fix possible race when saving screenshots 2020-11-30 01:15:44 +10:00
Connor McLaughlin
53697154f5 Merge pull request #1112 from zkdpower/master
Update duckstation-qt_zh-cn.ts to latest
2020-11-30 01:15:29 +10:00
dankcushions
82b4edfaf4 OES_geometry_shader can be supported by non-GLES 3.2 conformant devices (eg Pi 4) 2020-11-28 17:48:46 +00:00
zkdpower
77552d6904 Update duckstation-qt_zh-cn.ts to latest
Update duckstation-qt_zh-cn.ts to latest
2020-11-28 09:57:37 +08:00
Connor McLaughlin
d1a42df121 GameList: Fix cover image detection based on file title 2020-11-28 02:04:18 +10:00
Connor McLaughlin
cf75282078 Android: Add missing call to ApplyGameSettings 2020-11-28 02:04:18 +10:00
Connor McLaughlin
90d7550104 Update README.md 2020-11-28 01:11:54 +10:00
Connor McLaughlin
b6b2d66d99 Android: Restore ABI filters 2020-11-28 01:00:54 +10:00
Connor McLaughlin
f21d901cf1 Common/FileSystem: Fix macOS build 2020-11-28 00:58:46 +10:00
Connor McLaughlin
16a6c1706e Qt: Fix manual redump database downloading/updating 2020-11-28 00:42:09 +10:00
Connor McLaughlin
a75b6e512a System: Improve translatability of save state error 2020-11-28 00:35:03 +10:00
Connor McLaughlin
bb1e3a0692 Android: Display covers in game list 2020-11-28 00:14:46 +10:00
Connor McLaughlin
3137eb41c4 GameList: Make cover functions const 2020-11-28 00:14:45 +10:00
Connor McLaughlin
38e3b2a28a Android: Display compatibility rating in game list 2020-11-28 00:14:45 +10:00
Connor McLaughlin
5fd5d89b23 Android: Include data files in APK 2020-11-28 00:14:45 +10:00
Connor McLaughlin
744629e9a8 Common/FileSystem: Fix modification time not being set in find
Fixes game list list always re-scanning on Linux/Android.
2020-11-28 00:14:45 +10:00
Connor McLaughlin
12caa79178 Android: Use APK assets for HostInterface::OpenPackagePath 2020-11-28 00:14:45 +10:00
Connor McLaughlin
feadc83050 Common/GrowableMemoryByteStream: Add helper methods 2020-11-28 00:14:45 +10:00
Connor McLaughlin
a902d9b409 Qt: Fix MSAA game settings not updating combo box on open 2020-11-28 00:14:45 +10:00
Connor McLaughlin
263f7b673b GameList: Use shipped redump database/compatibility settings 2020-11-28 00:14:45 +10:00
Connor McLaughlin
4a482875ca Common/FileSystem: Add helpers for ByteStream 2020-11-28 00:14:45 +10:00
Connor McLaughlin
5f69216f70 HostInterface: Add OpenPackageFile method 2020-11-28 00:14:45 +10:00
Connor McLaughlin
57c6e4d5e8 Database: Include redump.org PSX database 2020-11-28 00:14:45 +10:00
Connor McLaughlin
859f23f4d5 libretro: Add compatibility settings loading 2020-11-28 00:14:44 +10:00
Connor McLaughlin
b16e639f0c GameSettings: Remove some duplicate entries 2020-11-28 00:14:44 +10:00
Connor McLaughlin
b73fd7a4e8 SDLControllerInterface: Ship game controller db with builds 2020-11-28 00:14:44 +10:00
Connor McLaughlin
bf584faa32 Merge pull request #1109 from andercard0/patch-33
Atualização Português do Brasil
2020-11-28 00:13:21 +10:00
Connor McLaughlin
1fa0903fa9 Merge pull request #1111 from ggrtk/gpu-sw-fix
GPU/SW: Fix 16-bit wraparound output crashing
2020-11-28 00:12:41 +10:00
Connor McLaughlin
05124fa635 Merge pull request #1110 from ggrtk/limit-save-state-version
System: Limit maximum loadable save state version
2020-11-28 00:12:12 +10:00
Albert Liu
e12c68cf65 GPU/SW: Fix 16-bit wraparound output crashing 2020-11-26 23:58:06 -08:00
Albert Liu
32e47fba93 System: Limit maximum loadable save state version 2020-11-26 19:51:45 -08:00
Anderson_Cardoso
e630868080 Atualização Português do Brasil
Translated

OSD Messages;
CPUFastmemMode;
GamePropertiesDialog;
AdvancedSettingsWidget;
2020-11-26 15:09:42 -03:00
Connor McLaughlin
b2de5945c4 libretro: Disable context caching
It's completely broken in RetroArch, see https://github.com/libretro/RetroArch/issues/11623
2020-11-27 01:40:50 +10:00
Connor McLaughlin
f7a75941b5 GameSettings: Add PGXP tolerance and MSAA 2020-11-27 01:40:50 +10:00
Connor McLaughlin
f0ff7ce231 PGXP: Add geometry tolerance setting 2020-11-27 01:40:50 +10:00
Connor McLaughlin
24fef20485 CommonHostInterface: Compress screenshots in background/use worker thread 2020-11-27 01:40:50 +10:00
Connor McLaughlin
125dfa7c40 HostDisplay: Support resizing/compressing images on worker thread 2020-11-27 01:40:50 +10:00
Connor McLaughlin
df14fa4d75 CommonHostInterface: Fix compatible/old version save states not showing in browser 2020-11-27 01:40:50 +10:00
Connor McLaughlin
dc21f2b5cf GL/Context: Check return value of eglBindApi()
Fixes some Android devices thinking they got a desktop GL context.
2020-11-27 01:40:50 +10:00
Connor McLaughlin
f0e7c744b3 Merge pull request #1108 from ggrtk/analog-controller
AnalogController: Only clear motor state on rumble config if not used
2020-11-27 01:40:35 +10:00
Albert Liu
9ac09d35be AnalogController: Only clear motor state on rumble config if not used 2020-11-26 06:01:08 -08:00
Albert Liu
a4eb4b9280 AnalogController: Set transfer state to idle on reset 2020-11-26 06:01:08 -08:00
Connor McLaughlin
fcbd618783 Merge pull request #1105 from ggrtk/analog-controller
AnalogController: Rumble handling and config mode fixes
2020-11-26 01:43:50 +10:00
Connor McLaughlin
627a3109b3 libretro: Re-query hardware render interface after AV system info change
I suspect the frontend is supposed to call context_reset/destroy here,
but it's not for whatever reason, and this works around it.
2020-11-26 01:34:12 +10:00
Albert Liu
566993c6df AnalogController: Improve DualShock rumble handling
Fixes low vibration in Final Fantasy VIII, missing vibration in Armored
Core Project Phantasma, etc.
2020-11-25 07:33:30 -08:00
Albert Liu
31b41b9ec0 AnalogController: Output zeros for 0x43 when already in config mode 2020-11-25 07:33:30 -08:00
Albert Liu
3f709d97b6 AnalogController: Send full analog response for reads in config mode 2020-11-25 07:33:30 -08:00
Albert Liu
e4820bcbc1 AnalogController: Delay manual mode toggle to transfer state reset 2020-11-25 07:33:30 -08:00
Connor McLaughlin
b45bee5954 libretro: Work around crash in RetroArch Vulkan driver 2020-11-25 23:06:41 +10:00
Connor McLaughlin
917fa5dd0e SPU: Only ignore loop address for not-pending-on voices
Fixes softlocks during dialog in The Misadventures of Tron Bonne.
2020-11-25 22:45:03 +10:00
Connor McLaughlin
ade61d6139 libretro: Fix fastmem defaulting to LUT on 64-bit 2020-11-24 15:14:34 +10:00
Connor McLaughlin
7fd22958ae OpenGLHostDisplay: Fix crash in libretro core 2020-11-24 14:54:06 +10:00
Connor McLaughlin
16bfaad505 Updater/Win32: wWinMain should be WINAPI 2020-11-24 14:52:25 +10:00
Connor McLaughlin
1507824435 Qt: Default of GPU thread is enabled 2020-11-24 14:51:40 +10:00
RaydenX93
694b5abd8d Update Italian Translation (#1096)
* Update duckstation-qt_it.ts

* Update duckstation-qt_it.ts

fix typo ed alcune piccolezze

* Update duckstation-qt_it.ts

lol avevo incollato per sbaglio un link di github

Co-authored-by: Mattia <74111053+hugihadein@users.noreply.github.com>
2020-11-24 14:51:19 +10:00
Connor McLaughlin
764b1ee49d Merge pull request #1099 from stenzek/lut-fastmem-pr
CPU/Recompiler: Implement LUT-based fastmem
2020-11-24 14:50:55 +10:00
Connor McLaughlin
bf2e38aed5 CPU/Recompiler: Implement LUT-based fastmem 2020-11-24 14:49:21 +10:00
Connor McLaughlin
022f7465c4 Update README.md 2020-11-22 15:34:00 +10:00
Connor McLaughlin
44b3c9be6e Common/PageFaultHandler: Fix for Windows/ARM64 2020-11-22 14:49:49 +10:00
Connor McLaughlin
ea355c20ad CI: Fix Windows/ARM64 build 2020-11-22 14:22:01 +10:00
Connor McLaughlin
773d5f5f25 Merge pull request #1095 from zkdpower/master
Update duckstation-qt_zh-cn.ts to latest
2020-11-22 14:08:19 +10:00
Connor McLaughlin
0612fe4ddd Merge pull request #1094 from andercard0/patch-32
Atualização Português do Brasil
2020-11-22 14:07:54 +10:00
Connor McLaughlin
57c1e54a54 CI: Add Windows ARM64 builds 2020-11-22 14:05:37 +10:00
Connor McLaughlin
0793f98c87 CPU/Recompiler: Reduce armv7 code buffer size 2020-11-22 13:59:26 +10:00
Connor McLaughlin
f6bd4bfcf4 Build: Tweak armv7 CFLAGS 2020-11-22 13:57:05 +10:00
Connor McLaughlin
07dbc5a80d GPU/HW: Draw opaque before semitransparent for reverse subtract
Fixes missing shadows in Suikoden II.
2020-11-22 13:46:20 +10:00
Connor McLaughlin
e06f85a328 GPU: Fix VRAM palette changes not being detected in hw renderer
Fixes wall texture animation in Mega Man Legends.
2020-11-22 13:22:29 +10:00
zkdpower
daf3720ba0 Update duckstation-qt_zh-cn.ts to latest
Update duckstation-qt_zh-cn.ts to latest
2020-11-22 05:37:33 +08:00
Anderson_Cardoso
ff2c2e04d8 Atualização Português do Brasil
Translated
Display Settings Widget;
MaindWindow;
OSD Message;
Some fixes.
2020-11-21 15:18:59 -03:00
Connor McLaughlin
b49067d165 Build: Fix Android armv8 performance regression 2020-11-22 02:33:02 +10:00
Connor McLaughlin
e528f3f273 Update README.md 2020-11-22 01:51:32 +10:00
Connor McLaughlin
347a10723f Merge pull request #1090 from hugihadein/patch-1
fix typo in italian translation
2020-11-22 01:25:31 +10:00
Connor McLaughlin
33e277e8d2 Merge pull request #1091 from stenzek/android-armv7
CI armv7 builds
2020-11-22 01:24:54 +10:00
Connor McLaughlin
7e7ec86f91 GPU/Software: Remove a couple of unused variables 2020-11-22 01:24:26 +10:00
Connor McLaughlin
3797d2acbc CI: Generate armv7 libretro cores 2020-11-22 01:24:26 +10:00
Connor McLaughlin
2ee2207106 CI: Output Android apk as duckstation-android.apk 2020-11-22 01:24:25 +10:00
Connor McLaughlin
a6529a9537 Android: Enable armeabi-v7a builds 2020-11-21 23:47:12 +10:00
Connor McLaughlin
497759b4d6 VulkanHostDisplay: Support 16-bit scanout 2020-11-21 21:12:38 +10:00
Mattia
faaa62cfca fix typo in italian translation 2020-11-21 10:21:49 +01:00
Connor McLaughlin
bf82bfc63b Update README.md 2020-11-21 19:13:27 +10:00
Connor McLaughlin
131dc923ed Build: Fix CMake build 2020-11-21 18:59:03 +10:00
Connor McLaughlin
cb407263ea XInputControllerInterface: Fix device connected spam 2020-11-21 18:58:27 +10:00
Connor McLaughlin
c375d04bad Frontends: Add .iso to open disc filter 2020-11-21 18:41:36 +10:00
Connor McLaughlin
402532b8a5 GameSettings: Force PGXP mode for Spyro trilogy 2020-11-21 18:39:04 +10:00
Connor McLaughlin
b554c133ea GPU/OpenGL: Add a version check and display message when unsupported 2020-11-21 18:39:04 +10:00
Connor McLaughlin
7f058169b9 OpenGLHostDisplay: Add a GLES2 render path 2020-11-21 18:39:04 +10:00
Connor McLaughlin
2595e31575 GPU: Split software to frontend/backend 2020-11-21 18:39:04 +10:00
Connor McLaughlin
03d4f80883 GPU: Move enums/types into separate file 2020-11-21 18:39:04 +10:00
Connor McLaughlin
d3d881aa6b GPU/Software: Reduce number of copies by one, enable 16-bit scanout 2020-11-21 18:39:04 +10:00
Connor McLaughlin
beffbaee39 Common/Rectangle: Use memcpy for operator= 2020-11-21 18:39:04 +10:00
Connor McLaughlin
dc53209565 Common/Event: Replace poll event with lock/condvar 2020-11-21 18:39:04 +10:00
Connor McLaughlin
9f3e8bed86 CPU: Add AArch32/armv7 recompiler 2020-11-21 18:39:04 +10:00
Connor McLaughlin
1128836826 CPU/Recompiler: Add GetValueInHostOrScratchRegister helper 2020-11-21 18:39:04 +10:00
Connor McLaughlin
cdd0a5525a CPU/Recompiler: Reduce register pressure of lwl/lwr/swl/swr 2020-11-21 18:39:04 +10:00
Connor McLaughlin
6df5824616 CPU/Recompiler: Support targets where shifts aren't implicitly masked 2020-11-21 18:39:04 +10:00
Connor McLaughlin
053d7fdc4b CPU/Recompiler: Inhibit allocation in mtc0/rfe branches 2020-11-21 18:39:04 +10:00
Connor McLaughlin
028a5c60d7 Bus: Fix failed safe instruction reads raising guest exceptions 2020-11-21 18:39:03 +10:00
Connor McLaughlin
28c88cd69f Build: Fix Win32 compilation of core 2020-11-21 18:39:03 +10:00
Connor McLaughlin
a29669432f Common/PageFaultHandler: Fix compiling on 32-bit Windows 2020-11-21 18:39:03 +10:00
Connor McLaughlin
a03bca2f72 CPU: Make fastmem a compile-time feature (support 32-bit targets) 2020-11-21 18:39:03 +10:00
Connor McLaughlin
dba42cf323 Common/CPUDetect: Use consistant naming for ARM targets 2020-11-21 18:39:03 +10:00
Connor McLaughlin
302b08023e dep/vixl: Fix building for AArch32 2020-11-21 18:39:03 +10:00
Connor McLaughlin
125d104df4 Pad: Fix controller state not being ignored in state load 2020-11-21 18:39:03 +10:00
Connor McLaughlin
53f81d067a CPU/CodeCache: Remove warning about executing uncompiled blocks 2020-11-21 18:39:03 +10:00
Connor McLaughlin
9c9e2bbe27 GL/ContextWGL: Check for ES2 context extension before creating 2020-11-21 18:39:03 +10:00
Connor McLaughlin
aeee649700 Merge pull request #1089 from zkdpower/master
Update duckstation-qt_zh-cn.ts to latest
2020-11-21 18:37:56 +10:00
Connor McLaughlin
0f04763ef6 Merge pull request #1084 from andercard0/patch-30
Update Pt-Br
2020-11-21 18:37:37 +10:00
Connor McLaughlin
3185c5df0f Merge pull request #1078 from CookiePLMonster/sdl-joystick-support
Add SDL_Joystick support
2020-11-21 18:37:20 +10:00
zkdpower
ed8f6aefcf Update duckstation-qt_zh-cn.ts to latest
Update duckstation-qt_zh-cn.ts to latest
2020-11-21 05:13:33 +08:00
Connor McLaughlin
aa3ce14ef3 Update README.md 2020-11-19 15:11:37 +10:00
Anderson_Cardoso
957d40b011 Update Pt-Br
Translated 
- Main Window options
2020-11-18 13:45:33 -03:00
Connor McLaughlin
83db685376 Update rolling-release.yml 2020-11-19 01:09:29 +10:00
Connor McLaughlin
37adc9ff34 GameSettings: Don't force interpreter in Threads of Fate 2020-11-19 00:45:44 +10:00
Connor McLaughlin
be2d52b908 GameSettings: Disable upscaling in Slam 'n Jam '96 featuring Magic & Kareem (USA) 2020-11-19 00:40:02 +10:00
Connor McLaughlin
3f2a9cedbe Qt: Add screenshot to System menu 2020-11-19 00:40:02 +10:00
Connor McLaughlin
46b97dd4a8 Qt: Hook up window size menu 2020-11-19 00:40:02 +10:00
Connor McLaughlin
e4d2b7331b CommonHostInterface: Add resize window to scale functions 2020-11-19 00:40:02 +10:00
Connor McLaughlin
0726ad1275 GPU: Flush partial VRAM writes to backend VRAM 2020-11-19 00:40:02 +10:00
Connor McLaughlin
9e11e5c354 CPU: Make zero register printing consistent with the others 2020-11-19 00:40:02 +10:00
Connor McLaughlin
042bdd9c0c CPU/CodeCache: Fetch second delay slot from first branch for double branches 2020-11-19 00:40:02 +10:00
Connor McLaughlin
3890a539ee CDROM: Clear data FIFO on reset
Fixes Snatcher booting.
2020-11-19 00:40:02 +10:00
Connor McLaughlin
bc98b2470c Merge pull request #1081 from zkdpower/master
Update duckstation-qt_zh-cn.ts to latest
2020-11-19 00:39:33 +10:00
Connor McLaughlin
66e656da79 Merge pull request #1079 from andercard0/patch-29
Update Portuguese Brazilian Translation
2020-11-19 00:39:18 +10:00
zkdpower
04309754a5 Update duckstation-qt_zh-cn.ts to latest
Update duckstation-qt_zh-cn.ts to latest
2020-11-16 19:04:23 +08:00
Anderson_Cardoso
bdac8ffcde Update Pt-Br
Translated
 
- New Controller type;
- Analog Controller;
2020-11-15 14:46:26 -03:00
Connor McLaughlin
71eb578db1 Update compatibility settings/list 2020-11-16 01:14:58 +10:00
Silent
086f251370 Tidy up SDL controller methods interface 2020-11-15 16:12:39 +01:00
Silent
2880b71b48 Support for SDL Joysticks
This enables use of non-controller peripherals,
such as DirectInput steering wheels or flight sticks
2020-11-15 16:12:39 +01:00
Connor McLaughlin
473cfffa0c GPU: Only accept DMA writes when FIFO is empty or command incomplete
Fixes a bunch of games, including Red Asphalt, Little Princess, Vampire
Hunter D main menu when combined with tight DMA sync.
2020-11-16 01:00:55 +10:00
Connor McLaughlin
df12f08ac3 DMA: Add additional tick penalty to DMA chains for page change 2020-11-16 01:00:55 +10:00
Connor McLaughlin
6a2deb6d71 Merge pull request #1072 from ggrtk/analog-joystick
Controller: Add Analog Joystick support
2020-11-16 01:00:10 +10:00
Connor McLaughlin
2c6454972f Merge pull request #1075 from andercard0/patch-28
Update Pt-Br translation (Fixes)
2020-11-16 00:59:12 +10:00
Silent
99ec667b20 Factorize input hooks into reusable monitor classes
Those monitors will need some context so this will be useful
in the nearby future.
2020-11-15 15:31:13 +01:00
Anderson_Cardoso
a0c63705ef Update Pt-Br translation (Fixes)
Nothing special just fixes.
2020-11-14 15:13:12 -03:00
Albert Liu
7ed0477a29 AnalogController: Save buttons and legacy rumble to state 2020-11-14 07:46:26 -08:00
Albert Liu
81a638cabb Pad: Fix loading controllers from save states 2020-11-14 07:46:26 -08:00
Albert Liu
f9d2643d98 Controller: Add Analog Joystick support 2020-11-14 07:46:26 -08:00
Connor McLaughlin
3f9ba4acb6 Merge pull request #1071 from RaydenX93/update_it_20201114
Update Italian Translation
2020-11-15 00:22:38 +10:00
Connor McLaughlin
bb4a7e0e78 CI: Use fixed version of sign-android-release 2020-11-15 00:20:16 +10:00
Connor McLaughlin
13d9702000 HostDisplay: Log errno on file open failure 2020-11-15 00:16:00 +10:00
Connor McLaughlin
5b4cc214c5 libretro: Move some interface init to retro_init
Apparently fixes rumble.
2020-11-15 00:11:50 +10:00
RaydenX93
bb01fbf6c0 Update duckstation-qt_it.ts 2020-11-14 15:06:06 +01:00
Connor McLaughlin
65be904d15 SPU: Only log warning about FIFO lost on writes 2020-11-14 23:20:28 +10:00
Connor McLaughlin
077764ce18 CPU/Interpreter: Handle move instructions in PGXP memory mode 2020-11-14 23:20:28 +10:00
Connor McLaughlin
e1579584ef CPU/Recompiler: Fix PGXP values getting corrupted if cached in caller-saved reg 2020-11-14 23:20:28 +10:00
Connor McLaughlin
3f937a2a39 SPU: Port reverb algorithm changes from Mednafen 2020-11-14 23:20:28 +10:00
Connor McLaughlin
925bb7173f Merge pull request #1067 from ggrtk/analog-axis-scale
ControllerInterface: Move axis scaling into AnalogController class
2020-11-14 23:20:04 +10:00
Connor McLaughlin
aa0c52cea1 Merge pull request #1061 from zkdpower/master
Update duckstation-qt_zh-cn.ts to latest.
2020-11-14 23:18:50 +10:00
Connor McLaughlin
0411a8b437 Merge pull request #1059 from andercard0/patch-27
Atualização Tradução Português do Brasil
2020-11-14 23:18:33 +10:00
Connor McLaughlin
2a00c7e8b8 Merge pull request #1069 from Alaharon123/patch-1
readme: Add Mac and Android to releases text
2020-11-14 23:18:11 +10:00
Alaharon123
39ce06c656 readme: Add Mac and Android to releases text 2020-11-13 21:19:13 -05:00
Albert Liu
3eeab81063 PlayStationMouse: Fix returning incorrect controller type 2020-11-13 01:42:31 -08:00
Albert Liu
ca8fe27954 libretro: Add analog axis scale toggle 2020-11-12 04:16:04 -08:00
Albert Liu
d87ab23fec ControllerInterface: Move axis scaling into AnalogController class 2020-11-11 23:55:23 -08:00
zkdpower
6db847c56f Update duckstation-qt_zh-cn.ts to latest.
Update duckstation-qt_zh-cn.ts to latest.
2020-11-11 12:18:39 +08:00
Anderson_Cardoso
402364ae63 Atualização Tradução Português do Brasil
Translated:

- OSD Message;
- Main Window;
- Cheat Manager Dialog;
- QTHost Interface (MC new option);
2020-11-10 14:03:59 -03:00
Connor McLaughlin
ca14e53c4a GTE: Make widescreen hack use display aspect ratio 2020-11-11 01:02:40 +10:00
Connor McLaughlin
2d3fd621bf Settings: Add 19:9 aspect ratio 2020-11-11 01:02:40 +10:00
Connor McLaughlin
2467dbedd7 CDImage: Handle .iso files the same as .bin files
Very reluctant to add this but people keep complaining...
2020-11-11 01:02:40 +10:00
Connor McLaughlin
ce81d23574 Qt: Add Edit Memory Cards to game list context menu 2020-11-11 01:02:40 +10:00
Connor McLaughlin
6cd991bc57 BIOS: Turn display on with fast boot
Fixes black screen in SaGa Frontier with fast boot disabled.
2020-11-11 01:02:40 +10:00
Connor McLaughlin
d468814a6d GPU: Disable texture filters when dual-source blend is unsupported 2020-11-11 01:02:40 +10:00
Connor McLaughlin
92a4551bb2 GPU/OpenGL: Support GL_EXT_blend_func_extended for dual-source blend 2020-11-11 01:02:40 +10:00
Connor McLaughlin
e3c07b562c Merge pull request #1056 from ggrtk/exp-access
Add support for PS2/PS3-type PS1 BIOSes
2020-11-11 01:02:22 +10:00
Connor McLaughlin
ba2e9d030c Merge branch 'master' into exp-access 2020-11-11 01:02:05 +10:00
Connor McLaughlin
553b9fa5a1 Merge pull request #1047 from Blackbird88/master
PS3's PS1 BIOS images
2020-11-11 01:01:12 +10:00
Connor McLaughlin
a83ac0f0c5 Update issue templates 2020-11-11 00:35:15 +10:00
Albert Liu
d0443e3165 BIOS: Add BIOS image info for PS1 on PS3 2020-11-09 09:02:00 -08:00
Albert Liu
c698519d44 Bus: Log writes to additional POST registers 2020-11-09 09:02:00 -08:00
Albert Liu
f3522b7b70 Bus: Stub out EXP3 and unknown EXP accesses 2020-11-09 09:02:00 -08:00
Connor McLaughlin
c3526adb69 Android: Fix opening controller menu unpausing 2020-11-09 01:18:44 +10:00
Connor McLaughlin
82ffb1bc81 Android: Implement vibrate-on-press and dualshock vibration 2020-11-09 00:38:19 +10:00
Connor McLaughlin
c1a81aefa4 Merge pull request #1054 from zkdpower/master
fix one translation mistake
2020-11-09 00:37:30 +10:00
Connor McLaughlin
c40220f723 Merge pull request #1049 from RaydenX93/update_it_20201107
Update Italian Language
2020-11-09 00:36:33 +10:00
zkdpower
d0b5338663 improve one mistake
improve one mistake
2020-11-08 20:26:51 +08:00
RaydenX93
e6064b6eb6 Update duckstation-qt_it.ts 2020-11-07 19:31:18 +01:00
Connor McLaughlin
cf2d9b86b0 Android: Bump minimum version to 23 (Android 6.0 Marshmellow)
5.0 seems to have various issues...
2020-11-08 00:35:38 +10:00
Connor McLaughlin
e1ffb5e385 Qt: Add missing DMA state to debug menu 2020-11-08 00:27:48 +10:00
Connor McLaughlin
8e0ee7e9c5 Qt: Update Chinese translation from @zkdpower 2020-11-08 00:22:35 +10:00
Connor McLaughlin
44e2a857fa Qt/CheatManager: Add import file/text options 2020-11-08 00:22:35 +10:00
Connor McLaughlin
56ab103559 GameSettings: Fix CD-ROM read speedup incorrectly saved to ini 2020-11-08 00:22:35 +10:00
Connor McLaughlin
3e6bc0e10d Android: Implement disc changing via playlists 2020-11-08 00:22:35 +10:00
Connor McLaughlin
4701d2480d Android: Display game code in list 2020-11-08 00:22:35 +10:00
Connor McLaughlin
c1de8c32c1 Android: Provide game list file title to Java-side 2020-11-08 00:22:35 +10:00
Connor McLaughlin
d23b9b508d Android: Add option to force screen rotation 2020-11-08 00:22:35 +10:00
Connor McLaughlin
fb4ebabee5 Android: Add option to pause when menu is open 2020-11-08 00:22:35 +10:00
Connor McLaughlin
b2c8e9e31e Android: End emulation activity if not valid on returning 2020-11-08 00:22:35 +10:00
Connor McLaughlin
8f74d4718f Android: Fix crash if activity is killed before returning 2020-11-08 00:22:35 +10:00
Connor McLaughlin
c18278e664 Android: Support starting emulation activity externally
Should hopefully work for third-party launchers.
2020-11-08 00:22:35 +10:00
Connor McLaughlin
74942443d3 Android: Add patch code (cheat) import 2020-11-08 00:22:35 +10:00
Connor McLaughlin
8cb89636eb Android: Empty audio buffers when returning from activity 2020-11-08 00:22:35 +10:00
Connor McLaughlin
f68ad7d0c3 Android: Fix wait for emulation thread returning early 2020-11-08 00:22:35 +10:00
Connor McLaughlin
ac89379ca6 GL/ContextEGL: Use pbuffer when surfaceless not supported 2020-11-08 00:22:35 +10:00
Connor McLaughlin
b6ec587e5b CheatList: Allow passing in strings instead of filenames 2020-11-08 00:22:35 +10:00
Connor McLaughlin
6828082f8b CheatList: Add merge list function for importing 2020-11-08 00:22:35 +10:00
Connor McLaughlin
576914cd2c CPU/CodeCache: Backpatch code writes after they exceed 10 faults
Small performance improvement in Driver 2.
2020-11-08 00:22:35 +10:00
Connor McLaughlin
62892b02d1 libretro: Add edge blending texture filtering modes 2020-11-08 00:22:35 +10:00
Connor McLaughlin
5635ee1d7c Android: Add 'No Edge Blending' texture filtering modes 2020-11-08 00:22:35 +10:00
Connor McLaughlin
6922380569 Merge pull request #1040 from andercard0/patch-26
Atualização Tradução Português do Brasil
2020-11-08 00:14:35 +10:00
Connor McLaughlin
9cf38a5740 Merge pull request #1045 from ggrtk/analog-controller
AnalogController: Implement legacy rumble method
2020-11-08 00:13:57 +10:00
Blackbird88
906ca1bbe1 PS3's PS1 BIOS images 2020-11-06 20:04:47 +01:00
Albert Liu
6d4b812b7c AnalogController: Implement legacy rumble method
Fixes missing vibration in Tobal 2, Bushido Blade, etc.
2020-11-04 22:45:58 -08:00
Anderson_Cardoso
722c4196f2 Atualização Tradução Português do Brasil
Translated:

- Enhancement Settings Widget;
- General Settings Widget;
- Main Window nessage;
- Advanced Widget;
- OSD messages;
2020-11-03 12:47:25 -03:00
Connor McLaughlin
a17e15f176 Android: Remove duplicate speed limiter option from settings 2020-11-04 00:49:42 +10:00
Connor McLaughlin
257cc75183 Update generate_appimages.sh 2020-11-04 00:25:41 +10:00
Connor McLaughlin
f94fef11ac Android: Display version in title 2020-11-04 00:07:56 +10:00
Connor McLaughlin
e457d4ca0c Android: Move settings icon to action bar 2020-11-03 22:59:26 +10:00
Connor McLaughlin
8816c5048d Android: Add CPU overclocking option 2020-11-03 22:59:26 +10:00
Connor McLaughlin
2388662cc5 Qt: Fix texture filter setting incorrect value for no-edge-blending 2020-11-03 22:59:26 +10:00
Connor McLaughlin
2b66492ed8 HostInterface: Add proper turbo speed setting 2020-11-03 22:59:26 +10:00
Connor McLaughlin
d5a5969bd4 Revert "Android: Enable sustained performance mode"
This reverts commit 96ff8c87e5.
2020-11-03 17:33:04 +10:00
Connor McLaughlin
3a6ff109be Qt: Update Chinese translation from @zkdpower 2020-11-03 16:17:45 +10:00
Connor McLaughlin
5a93760af9 Android: Fix some crashes reported via Play Store 2020-11-03 16:17:45 +10:00
Connor McLaughlin
efc0a7391d Android: Add presented frame limit option 2020-11-03 16:17:45 +10:00
Connor McLaughlin
96ff8c87e5 Android: Enable sustained performance mode 2020-11-03 16:17:45 +10:00
Connor McLaughlin
7dc71027cf Android: Add chroma smoothing enhancement 2020-11-03 16:17:45 +10:00
Connor McLaughlin
d16b5a6721 Android: Add MSAA to enhancements 2020-11-03 16:17:45 +10:00
Connor McLaughlin
2c8a4ff154 HostDisplay: Add an option to decouple display fps from emulator fps
Makes Android so much faster...
2020-11-03 16:17:45 +10:00
Connor McLaughlin
ae1e4b1b8f GPU: Add chroma smoothing for 24-bit display enhancement 2020-11-03 16:17:45 +10:00
Connor McLaughlin
d102b2facd Qt: Fix selecting fullscreen mode breaking other backend borderless 2020-11-03 16:17:45 +10:00
Connor McLaughlin
863f84e3f6 System: Fix frame limiter on fast systems (when frametime <1ms) 2020-11-03 16:17:45 +10:00
Connor McLaughlin
3cb18d13b0 Merge pull request #1034 from andercard0/patch-25
Update Brazilian Portuguese Translation
2020-11-03 16:17:29 +10:00
Anderson_Cardoso
75a22724b9 Update Brazilian Portuguese Translation
Translated: 

- OSD messages;
- NeGcon controller options;
- GPU Texture Filter new options;
- Display Settings Widget options;
- Fixed not translated res texts i lefted.
2020-11-01 13:53:49 -03:00
Connor McLaughlin
4d5b122772 Update README.md 2020-11-02 00:57:10 +10:00
Connor McLaughlin
121d856b14 Qt: Update Chinese translation from @zkdpower 2020-11-02 00:56:05 +10:00
Connor McLaughlin
2b2a868fef HostInterface: Fix incorrect translation context in CPU mode switch string 2020-11-02 00:56:05 +10:00
Connor McLaughlin
414bc30f24 HostDisplay: Implement exclusive fullscreen for D3D11 renderer 2020-11-02 00:56:05 +10:00
Connor McLaughlin
858f39827d GPU/HW: Add 'Disable Edge Blending' variants of texture filters 2020-11-02 00:56:05 +10:00
Connor McLaughlin
6ddf6784ab GPU/OpenGL: Fix edge blending when texture filtering 2020-11-02 00:56:05 +10:00
Connor McLaughlin
ad6a4d4ec0 Merge pull request #1025 from andercard0/patch-24
Update Brazilian Portuguese Translation
2020-11-02 00:55:51 +10:00
Connor McLaughlin
3dce0d654a Merge pull request #1030 from CookiePLMonster/fix-bios-comparator
Fix bios comparator
2020-11-02 00:52:50 +10:00
Connor McLaughlin
79aa1cece7 Merge pull request #1031 from ggrtk/negcon-deadzone
NeGcon: Add steering axis deadzone setting
2020-11-02 00:52:27 +10:00
Connor McLaughlin
1efcb24886 Merge pull request #1032 from ggrtk/bios-image-infos
BIOS: Add SCPH-1000R image infos
2020-11-02 00:51:54 +10:00
Albert Liu
8b5fde8e6f BIOS: Add SCPH-1000R image infos 2020-11-01 04:21:17 -08:00
Albert Liu
3b51b993f3 NeGcon: Add steering axis deadzone setting 2020-11-01 04:17:18 -08:00
Silent
4ef70ef2aa Fix bios comparator 2020-11-01 13:12:04 +01:00
Anderson_Cardoso
0d6a3ca28d Update Brazilian Portuguese Translation
Translated:.

- GPU Settings Widget; 
- OSD Messages | Multisample;
2020-10-31 19:48:26 -03:00
Connor McLaughlin
b5b1c725c1 GPU: Fix MSAA in OpenGL ES 2020-10-31 15:24:25 +10:00
Connor McLaughlin
4c08624ce5 libretro: Fix Windows build 2020-10-31 15:12:18 +10:00
Connor McLaughlin
f2aa343cae GPU/HW: Fix SSAA being enabled when it's not supported 2020-10-31 15:12:12 +10:00
Connor McLaughlin
4fe1c07b02 GL/Texture: Use texture storage where available 2020-10-31 15:11:53 +10:00
Connor McLaughlin
95dba59826 libretro: Add MSAA options 2020-10-31 14:39:38 +10:00
Connor McLaughlin
f39b3006f2 Qt: Update Chinese translation from @zkdpower 2020-10-31 14:30:38 +10:00
Connor McLaughlin
82e19f7188 Build: Set macOS deployment target to 10.14 2020-10-31 14:29:11 +10:00
Connor McLaughlin
ed0777cd8d OpenGLHostDisplay: Make sure vsync is on at startup 2020-10-31 14:27:58 +10:00
Connor McLaughlin
fdb770a596 ImGui: Get rid of serializing GL calls in OpenGL renderer
Gives a 25% performance improvement on NVIDIA.
2020-10-31 14:27:58 +10:00
Connor McLaughlin
b3c5c0f852 GPU/OpenGL: Eliminate some redundant per-draw state calls 2020-10-31 14:27:58 +10:00
Connor McLaughlin
2eaebd8921 GPU: Implement support for multisample antialiasing 2020-10-31 14:27:58 +10:00
Connor McLaughlin
61a4960380 GPU: Skip zero-width or height fills 2020-10-31 14:27:57 +10:00
Connor McLaughlin
2e53bf914e CPU/CodeCache: Fix crash when jumping to invalid block in recompiler 2020-10-31 14:27:57 +10:00
Connor McLaughlin
8f20ffaed3 Merge pull request #1017 from andercard0/patch-23
Update Brazilian Portuguese Translation
2020-10-31 14:18:28 +10:00
Connor McLaughlin
edce63bf6c CMake: Set macOS deployment target to 10.12 2020-10-30 11:53:39 +10:00
Connor McLaughlin
70fa41431b Merge pull request #1020 from ggrtk/pal-bios-path
HostInterface: Fix PAL BIOS path not being read from settings
2020-10-30 11:37:41 +10:00
Connor McLaughlin
5121426602 Merge pull request #1022 from ggrtk/libretro-core-option-keys
libretro: Fix duplicated core option keys
2020-10-30 11:37:25 +10:00
Albert Liu
fe9680fba8 libretro: Fix duplicated core option keys 2020-10-29 17:56:25 -07:00
Albert Liu
df1c5c0f45 HostInterface: Fix PAL BIOS path not being read from settings 2020-10-29 14:26:07 -07:00
Anderson_Cardoso
88f60a1ca8 Update Brazilian Portuguese Translation
Translated:

- Analog Controller texts;
- Analog Controller Options;
- Enhancement Settings Widget;
2020-10-29 14:21:31 -03:00
Connor McLaughlin
7078f73ecf AnalogController: Fix analog-as-digital applying in analog mode 2020-10-30 02:10:49 +10:00
Connor McLaughlin
fda95fb903 GameSettings: Force interpreter for Spyro 2/3 PAL
Self-modifying code in the same block, evil libcrypt stuff.
2020-10-30 01:12:04 +10:00
Connor McLaughlin
18f8c7bc61 dep/zlib: Mac build fix again 2020-10-30 00:57:15 +10:00
Connor McLaughlin
c01d6ba44b dep/libcue: Mac build fix 2020-10-30 00:52:44 +10:00
Connor McLaughlin
2fb67ee7db AnalogController: Add option to use analog stick as dpad in digital mode 2020-10-30 00:44:40 +10:00
Connor McLaughlin
7210b0826a GameSettings: Make DMA/GPU tweak settings overridable 2020-10-30 00:44:40 +10:00
Connor McLaughlin
be63d893cd CPU: Use partial icache fills for non-line-aligned addresses 2020-10-30 00:44:40 +10:00
Connor McLaughlin
3b3ad0c1cb Bus: Fix icache fills from BIOS failing 2020-10-30 00:44:39 +10:00
Connor McLaughlin
f14270fc4b Bus: Ignore reads to nocash EXP2 area 2020-10-30 00:44:39 +10:00
Connor McLaughlin
b2d224abfc System: Set BIOS before resetting
Fixes incorrect first instruction executing in interpreter mode.
2020-10-30 00:44:39 +10:00
Connor McLaughlin
e081ee4b8e CDROM: Return error to guest instead of panicing for unknown commands 2020-10-30 00:44:39 +10:00
Connor McLaughlin
a6947fbc70 CDROM: Implement fast forward/rewind 2020-10-30 00:44:39 +10:00
Connor McLaughlin
29467d40c8 DMA: Add debug window 2020-10-30 00:44:39 +10:00
Connor McLaughlin
62dbaaf02c Qt: Fix power off button not exiting in batch mode 2020-10-30 00:44:39 +10:00
Connor McLaughlin
3394575dca Merge pull request #1015 from ggrtk/sdl-mute-cd-audio
SDL: Add Mute CD Audio option to settings menu
2020-10-30 00:44:03 +10:00
Albert Liu
b66f212ec3 SDL: Add Mute CD Audio option to settings menu 2020-10-28 15:03:50 -07:00
Connor McLaughlin
87518fbee1 Qt: Linux compile fix 2020-10-29 01:58:08 +10:00
Connor McLaughlin
0552da6be2 CDROM: Stub out VideoCD command 2020-10-29 01:44:44 +10:00
Connor McLaughlin
bde271566b Common/PageFaultHandler: Hook SIGBUS as well as SIGSEGV on AArch64
Apparently this happens too?
2020-10-29 01:42:17 +10:00
Connor McLaughlin
34a808c258 SPU: Zero previous block ADPCM samples on key on
Fixes clicking in background in Breath of Fire III.
2020-10-29 01:30:40 +10:00
Connor McLaughlin
a8171405b1 CPU/CodeCache: Fix incorrect invalidation on non-page-crossing DMA writes
Fixes recompiler mode for Breath of Fire III, probably others.
2020-10-29 01:30:00 +10:00
Connor McLaughlin
451c48406d libretro: Fix runtime aspect ratio changes not applying 2020-10-28 17:32:59 +10:00
Connor McLaughlin
0b84433533 Qt/DisplaySettings: Fix renderer recommended value not translating 2020-10-28 17:32:49 +10:00
Connor McLaughlin
cf630f0592 Qt: Fix incorrect help text for texture filtering 2020-10-28 17:32:24 +10:00
Connor McLaughlin
9bfa27d550 Qt/AudioSettings: Make auto buffer size a multiple of 128 2020-10-28 17:32:01 +10:00
Connor McLaughlin
392c7af738 Bus: Fix assertion failing if booting fails 2020-10-28 17:31:25 +10:00
Connor McLaughlin
7ce55ca800 Android: Fix race/crash when switching away/back to the emulation activity 2020-10-27 11:58:46 +10:00
Connor McLaughlin
80a377d45a Android: Defer renderer changes to restart
Apparently it doesn't like changing surface types.
2020-10-27 11:58:04 +10:00
Connor McLaughlin
be3dd3e06f HostInterface: Fix a possible crash when renderer recreation fails 2020-10-27 11:57:41 +10:00
Connor McLaughlin
a1064f33b3 libretro: Add option to disable fastmem 2020-10-26 22:15:38 +10:00
Connor McLaughlin
7f795d25aa CPU/Recompiler: Don't try fastmem for RAM mirrors 2020-10-26 22:07:52 +10:00
Connor McLaughlin
875b0b91f1 CPU/Recompiler/AArch64: Use scratch for add CPU struct field 2020-10-26 22:02:35 +10:00
Connor McLaughlin
76428887b8 CPU/Recompiler: Fix typo in UninhibitAllocation function name 2020-10-26 22:00:10 +10:00
Connor McLaughlin
cbc7e3d64a CPU/Recompiler: Add register allocation safety check to fastmem 2020-10-26 21:59:29 +10:00
Connor McLaughlin
f2e1159173 Qt: Update Chinese translation from @zkdpower 2020-10-26 01:09:09 +10:00
Connor McLaughlin
b1c78d8bea Update compatibility list/game settings 2020-10-26 01:09:09 +10:00
Connor McLaughlin
3392839795 libretro: Add option to hide OSD messages 2020-10-26 01:09:09 +10:00
Connor McLaughlin
e147327459 GL: Fix window resize not applying under Wayland 2020-10-26 01:09:09 +10:00
Connor McLaughlin
900c01d16f Merge pull request #1002 from andercard0/patch-22
Update Pt-Br Translation
2020-10-26 01:08:45 +10:00
Connor McLaughlin
a036ae92e8 dep/cubeb: Compile fix for MSVC 2020-10-25 00:56:31 +10:00
Connor McLaughlin
f5f3b3f5d1 dep/cubeb: Add missing oss_i4_v4.c test file 2020-10-25 00:26:54 +10:00
Connor McLaughlin
8bf21fd5a0 GameSettings: Add display range override for Buster Bros. Collection 2020-10-25 00:12:32 +10:00
Connor McLaughlin
045866506f dep/cubeb: Update to 1d66483 2020-10-24 21:06:24 +10:00
Connor McLaughlin
1b618b8c46 SPU: Don't block ADPCM loop flag when setting/keying on in same slice
Fixes repeated sounds in Re-Loaded: The Hardcore Sequel.
2020-10-24 20:27:06 +10:00
Connor McLaughlin
98987643b3 SPU: Always reset address on loop end regardless of repeat
Fixes menu music in Madden NFL 99.
2020-10-24 19:42:23 +10:00
Connor McLaughlin
9a7999f158 Android: Format Java code 2020-10-24 16:05:52 +10:00
Connor McLaughlin
076d3d3479 Android: Add Start File to main activity menu 2020-10-24 16:05:52 +10:00
Connor McLaughlin
e22c7608e3 Android: Scan on background thread and show progress 2020-10-24 16:05:52 +10:00
Connor McLaughlin
5084c90e08 Android: Rename cheats to patches 2020-10-24 16:05:52 +10:00
Connor McLaughlin
de3696be4c Android: Add multiple save slots 2020-10-24 16:05:52 +10:00
Anderson_Cardoso
8618c2a214 Update Pt-Br Translation
Translated

- OSD Messages
System messages, Controller / MC type messages.

- System OSD.
2020-10-23 09:02:30 -03:00
Connor McLaughlin
a1453ee8a5 GPU: Skip full CRTC update on GP1(05h) 2020-10-23 19:37:56 +10:00
Connor McLaughlin
e5a0c92336 Merge pull request #999 from ggrtk/gpu-crtc
GPU: CRTC update
2020-10-23 19:36:45 +10:00
Connor McLaughlin
31de96d120 Qt: Fix debug submenus not translating 2020-10-23 19:26:19 +10:00
Connor McLaughlin
ff1e2afc4b Qt: Update Chinese translation from @zkdpower 2020-10-23 19:21:25 +10:00
Connor McLaughlin
6ffcbc9b98 Merge pull request #1001 from andercard0/patch-21
Atualização - Pt-Br | Cheat Manager
2020-10-23 19:14:38 +10:00
Connor McLaughlin
31a6c12952 Merge pull request #1000 from ggrtk/osdmessage-translatable
Core: Make some additional OSD messages translatable
2020-10-23 19:13:59 +10:00
Albert Liu
6bc7cf29cc GPU: Synchronize CRTC on GP1(05h) command
Fixes text flashing briefly after startup PlayStation logo in King's
Field (USA).
2020-10-22 21:41:42 -07:00
Anderson_Cardoso
e2af286554 Atualização - Pt-Br | Cheat Manager
Translated - 

- Cheat Manager Diag.
2020-10-22 10:02:22 -03:00
Albert Liu
f69889264d Core: Make some additional OSD messages translatable 2020-10-22 02:07:48 -07:00
Albert Liu
ca7db7a2d2 GPU: Update CRTC debug window reporting 2020-10-21 23:17:39 -07:00
Albert Liu
1a0b1a3149 GPU: Use accurate VRAM display width rounding
Modified version of Nocash algorithm, confirmed with hardware test.
Relies on proper horizontal display range rounding for correct results.
2020-10-21 23:17:39 -07:00
Albert Liu
bbaebfd4c9 GPU: Round horizontal display range values down to clockdiv multiple
GP1(06h) X1 and X2 are persistent across clockdiv changes, but the GPU
actively uses rounded values for display output. This behavior is
modeled by storing the rounded values in horizontal_display_start and
horizontal_display_end. Verified with hardware test.
2020-10-21 23:17:39 -07:00
Connor McLaughlin
2b2e2f7854 Cheats: Invalidate code pages on memory writes 2020-10-22 11:09:11 +10:00
Connor McLaughlin
3fc9f264d7 CPUCodeCache: Fix extra page being invalidated on writing to edge 2020-10-22 11:08:57 +10:00
Connor McLaughlin
bf46461dd6 Common/Vulkan: Remove unused methods in staging texture 2020-10-21 23:13:34 +10:00
Connor McLaughlin
b6a8da34fe Qt/CheatManager: Add preset address ranges 2020-10-21 22:28:11 +10:00
Connor McLaughlin
13aa5e0554 Cheats: Use internal memory handlers which can't trash MMIO
Safer and faster.
2020-10-21 22:28:11 +10:00
Connor McLaughlin
ffc0a5def4 Qt/CheatManager: Hook up address search range 2020-10-21 22:28:11 +10:00
Connor McLaughlin
2fb611518d Cheats/MemoryScan: Restrict search to RAM/Scratchpad/BIOS 2020-10-21 22:28:11 +10:00
Connor McLaughlin
0d387dfaca Cheats/MemoryScan: Add Any operator 2020-10-21 22:28:11 +10:00
Connor McLaughlin
a83439fd35 Qt/CheatManager: Only display first 5000 search results 2020-10-21 22:28:11 +10:00
Connor McLaughlin
2f5cf91d11 Qt: Remove load/save from quick cheat menu 2020-10-21 22:28:11 +10:00
Connor McLaughlin
1f948b1266 Qt: Add groups to cheat manager 2020-10-21 22:28:11 +10:00
Connor McLaughlin
133639122d Qt: Don't refresh entire list on adding/editing cheat 2020-10-21 22:28:11 +10:00
Connor McLaughlin
cb6ef03775 CheatList: Save additional DuckStation fields in comments 2020-10-21 22:28:11 +10:00
Connor McLaughlin
39a61d2207 CheatList: Preserve comments in PCSXR format files 2020-10-21 22:28:11 +10:00
Connor McLaughlin
abc035b15a CDImage: Fix assert failing on invalid cuesheets 2020-10-21 22:28:11 +10:00
Connor McLaughlin
0acf6e8327 Merge pull request #992 from andercard0/patch-20
Atualização | Tradução Português do Brasil
2020-10-21 22:26:50 +10:00
Anderson_Cardoso
c3a03fc4d8 Atualização | Tradução Português do Brasil
Translated:

- Cheat Manager Options;
- Advanced Settings;
- System;
2020-10-20 20:07:26 -03:00
Connor McLaughlin
8432050094 Update compatibility list 2020-10-21 01:11:30 +10:00
Connor McLaughlin
b694577c38 Qt: Add new cheat manager 2020-10-21 01:11:30 +10:00
Connor McLaughlin
9f0f24a5e5 Merge pull request #989 from ggrtk/hotkeys-pressed
CommonHostInterface: Activate hotkeys on press instead of release
2020-10-21 01:04:12 +10:00
Albert Liu
9b8fbeb087 CommonHostInterface: Activate hotkeys on press instead of release 2020-10-19 16:35:12 -07:00
Connor McLaughlin
7755e238d3 GPU/Vulkan: Fix depth not being updated with VRAM writes
Fixes menu not showing in Dragon Quest VII.
2020-10-19 11:46:45 +10:00
Connor McLaughlin
7a82cae2bd CPU/Recompiler: Use register pairs for pop callee saved too 2020-10-19 02:23:04 +10:00
Connor McLaughlin
11c25c68c5 Build: Skip AArch32 emitter for vixl on AArch64 2020-10-19 02:23:04 +10:00
Connor McLaughlin
0fca011bd4 CPU/Recompiler: Fix OOB in register pairing 2020-10-19 02:23:04 +10:00
Connor McLaughlin
6a4a4c62d7 CPU/Recompiler: Use fastmem instead of global for RAM loads 2020-10-19 02:23:04 +10:00
Connor McLaughlin
622aee7c96 Merge pull request #984 from RaydenX93/update_it_20201018
Weekly Update Italian Translation
2020-10-19 02:22:34 +10:00
RaydenX93
4de911222a Update duckstation-qt_it.ts 2020-10-18 15:23:56 +02:00
Connor McLaughlin
47eede06c8 Android: Move OSD options to Display category 2020-10-18 14:54:38 +10:00
Connor McLaughlin
942df40fe7 Android: Add missing advanced settings tab 2020-10-18 14:54:38 +10:00
Connor McLaughlin
325f83065c SPU: Always inline SPU::ExecuteVoice 2020-10-18 14:54:38 +10:00
Connor McLaughlin
245edd94d7 SPU: Eliminiate conditional in interpolation 2020-10-18 14:54:38 +10:00
Connor McLaughlin
e8d77448c7 CMake: Fix mkdir error when repeatedly building for macOS 2020-10-18 14:54:38 +10:00
Connor McLaughlin
6624660b0d Common/FileSystem: Fix a compile error on macOS 2020-10-18 14:54:38 +10:00
Connor McLaughlin
d3f87dc357 SDL: Fix CPU clock control in menu not applying 2020-10-18 14:54:38 +10:00
Connor McLaughlin
b704c37e91 CPU/Recompiler: Implement speculative constants 2020-10-18 14:54:38 +10:00
Connor McLaughlin
51eff82eb6 CPU/Recompiler: Implement lwl/lwr/swl/swr 2020-10-18 14:54:38 +10:00
Connor McLaughlin
7566c45f64 CPU/Recompiler: Implement fastmem 2020-10-18 14:54:38 +10:00
Connor McLaughlin
ceb67b5018 Common: Add memory arena and page fault handler classes 2020-10-18 14:54:38 +10:00
Connor McLaughlin
11faf6ccfb CPU/Recompiler: Skip calling event update on interrupts 2020-10-18 14:54:38 +10:00
Connor McLaughlin
a16c2f5462 CPU/Recompiler: Skip tracking some more interpreter state 2020-10-18 14:54:38 +10:00
Connor McLaughlin
a6f8dde790 CPU/Recompiler: Faster ASM dispatcher 2020-10-18 14:54:38 +10:00
Connor McLaughlin
cb351a7dbd CPU: Move interrupt check out of inner-most exec loop 2020-10-18 14:54:38 +10:00
Connor McLaughlin
0afdc04d88 CPU/Recompiler: Optimize constant reads (and some writes) 2020-10-18 14:54:38 +10:00
Connor McLaughlin
69b2c3fc2d StateWrapper: Track save state version 2020-10-18 14:54:38 +10:00
Connor McLaughlin
893268bba5 CDImage: Fix crash on invalid cue/chd with no tracks 2020-10-18 14:54:26 +10:00
Connor McLaughlin
95f7821691 Merge pull request #975 from BenjaminSiskoo/master
Typos Fixes Benjamin Siskoo, Zet Sensei and Elcor
2020-10-15 01:28:08 +10:00
Connor McLaughlin
a004ae0d5b Merge pull request #976 from MaddTheSane/icon
Make better icns from Windows icon.
2020-10-15 01:27:43 +10:00
Connor McLaughlin
d6758aacce CDSubchannelReplacement: Fix a crash on invalid input 2020-10-15 01:25:18 +10:00
C.W. Betts
c2eea7776e Make better icns from Windows icon. 2020-10-14 08:49:39 -06:00
Benjamin Siskoo
c04f831b3f Typos Fixes by Benjamin Siskoo
Thanks Zet Sensei and Elcor
2020-10-14 14:45:17 +02:00
Benjamin Siskoo
e22601f3df Update duckstation-qt_fr.ts
Typos fixing
2020-10-14 01:53:33 +02:00
657 changed files with 768117 additions and 43136 deletions

55
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,55 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
Please read before creating a new issue:
1. Make sure there is not already an open issue for this bug.
2. All enhancements **must** be off. To quickly disable all enhancements with affecting your normal config, in advanced options you can check "Disable All Enhancements".
3. All advanced options **must** be at their default values.
4. No cheats may be active. If you were using cheats, they should be disabled, and the game rebooted before reporting the bug.
5. Do not share save state files. Memory cards are okay.
6. Verify your dump, as we can not assist with issues resulting from bad dumps.
7. If playing PAL region software, please check whether or not the game has LibCrypt protection and that if it does, you have a correct SBI file (see https://github.com/stenzek/duckstation#libcrypt-protection-and-sbi-files for more information).
8. Please post your issue report in English as unfortunately this is the only language spoken by the developers. The Discord server has many helpful people if you need help translating.
**Remove everything before and including this line before submitting.**
**Game details**
[Serial Code, Region]
[i.e SLUS-00404 Ace Combat 2 (USA)]
**Description of the issue / bug**
[Describe what you are seeing and/or hearing during gameplay]
**Controller Troubleshoot Report**
1. Have you installed any drivers or wrappers on your system, or do you have any programs like Steam open?
2. Which controller backend are you using in general settings
**Note:**
If you are using Duckstation on Android device please consider the following before report:
Are you using any kind of "memory optimizer" program such as: Ccleaner, Wisecleaner, Clean Master, Boost Android etc. ?
(if so, please, consider create an exception on it first and test; or even remove / uninstall it retest and then, if the problem persists continue with the report.
**Steps to reproduce**
[Try to provide as much detail as possible to reproduce the issue]
**Enhancements information**
[Make sure they are all turned off before report]
**Hardware/software**
[If Android, which phone and Android version]
[If desktop, your CPU, graphics card, and operating system]
[GPU Renderer - D3D11/OpenGL/Vulkan]
**Emulator version**
[Shown in the title bar of the emulator]
**Additional context**
[Add any other context about the problem here]

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,38 +0,0 @@
name: Linux Build
on:
pull_request:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install packages
shell: bash
run: |
sudo apt-get update
sudo apt-get -y install libsdl2-dev libgtk2.0-dev
- name: Compile debug build
shell: bash
run: |
mkdir build-debug
cd build-debug
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_QT_FRONTEND=OFF ..
make
- name: Compile release build
shell: bash
run: |
mkdir build-release
cd build-release
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_QT_FRONTEND=OFF ..
make

View File

@@ -6,13 +6,16 @@ on:
- '**.md'
- 'appveyor.yml'
- 'scripts/*'
- '.github/ISSUE_TEMPLATE/*'
push:
branches:
- master
- dev
paths-ignore:
- '**.md'
- 'appveyor.yml'
- 'scripts/*'
- '.github/ISSUE_TEMPLATE/*'
workflow_dispatch:
jobs:
@@ -24,19 +27,43 @@ jobs:
fetch-depth: 0
submodules: true
- name: Tag as release build
- name: Tag as preview build
if: github.ref == 'refs/heads/master'
shell: cmd
run: |
echo #pragma once > src/scmversion/tag.h
echo #define SCM_RELEASE_TAG "latest" >> src/scmversion/tag.h
echo #define SCM_RELEASE_ASSET "duckstation-windows-x64-release.zip" >> src/scmversion/tag.h
echo #define SCM_RELEASE_TAGS {"latest", "preview"} >> src/scmversion/tag.h
echo #define SCM_RELEASE_TAG "preview" >> src/scmversion/tag.h
- name: Compile release build
- name: Tag as dev build
if: github.ref == 'refs/heads/dev'
shell: cmd
run: |
echo #pragma once > src/scmversion/tag.h
echo #define SCM_RELEASE_ASSET "duckstation-windows-x64-release.zip" >> src/scmversion/tag.h
echo #define SCM_RELEASE_TAGS {"latest", "preview"} >> src/scmversion/tag.h
echo #define SCM_RELEASE_TAG "latest" >> src/scmversion/tag.h
- name: Compile x64 release build
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
msbuild duckstation.sln -t:Build -p:Platform=x64;Configuration=ReleaseLTCG
- name: Create x64 symbols archive
shell: cmd
run: |
"C:\Program Files\7-Zip\7z.exe" a -r duckstation-windows-x64-release-symbols.zip ./bin/x64/*.pdb
- name: Upload x64 release symbols artifact
uses: actions/upload-artifact@v1
with:
name: "windows"
path: "duckstation-windows-x64-release-symbols.zip"
- name: Remove extra bloat before archiving
shell: cmd
run: |
@@ -46,48 +73,86 @@ jobs:
del /Q bin\x64\*.iobj
del /Q bin\x64\*.ipdb
del /Q bin\x64\common-tests*
del /Q bin\x64\duckstation-libretro-*
rename bin\x64\updater-x64-ReleaseLTCG.exe updater.exe
- name: Create release archive
- name: Create x64 release archive
shell: cmd
run: |
"C:\Program Files\7-Zip\7z.exe" a -r duckstation-windows-x64-release.zip ./bin/x64/*
- name: Upload release artifact
- name: Upload x64 release artifact
uses: actions/upload-artifact@v1
with:
name: "windows-x64"
name: "windows"
path: "duckstation-windows-x64-release.zip"
windows-libretro-build:
windows-arm64-build:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2.3.1
with:
fetch-depth: 0
submodules: true
- name: Compile release build
- name: Tag as preview build
if: github.ref == 'refs/heads/master'
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
mkdir build
cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBRETRO_CORE=ON -DCMAKE_C_COMPILER:FILEPATH="%VCToolsInstallDir%\bin\HostX64\x64\cl.exe" -DCMAKE_CXX_COMPILER:FILEPATH="%VCToolsInstallDir%\bin\HostX64\x64\cl.exe" ..
ninja
- name: Create libretro core archive
echo #pragma once > src/scmversion/tag.h
echo #define SCM_RELEASE_ASSET "duckstation-windows-x64-release.zip" >> src/scmversion/tag.h
echo #define SCM_RELEASE_TAGS {"latest", "preview"} >> src/scmversion/tag.h
echo #define SCM_RELEASE_TAG "preview" >> src/scmversion/tag.h
- name: Tag as dev build
if: github.ref == 'refs/heads/dev'
shell: cmd
run: |
cd build
"C:\Program Files\7-Zip\7z.exe" a -r duckstation_libretro.dll.zip ./duckstation_libretro.dll
echo #pragma once > src/scmversion/tag.h
echo #define SCM_RELEASE_ASSET "duckstation-windows-x64-release.zip" >> src/scmversion/tag.h
echo #define SCM_RELEASE_TAGS {"latest", "preview"} >> src/scmversion/tag.h
echo #define SCM_RELEASE_TAG "latest" >> src/scmversion/tag.h
- name: Upload release artifact
- name: Compile arm64 release build
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64
msbuild duckstation.sln -t:Build -p:Platform=ARM64;Configuration=ReleaseLTCG
- name: Create arm64 symbols archive
shell: cmd
run: |
"C:\Program Files\7-Zip\7z.exe" a -r duckstation-windows-arm64-release-symbols.zip ./bin/ARM64/*.pdb
- name: Upload arm64 release symbols artifact
uses: actions/upload-artifact@v1
with:
name: "windows-libretro-x64"
path: "build/duckstation_libretro.dll.zip"
name: "windows-arm64"
path: "duckstation-windows-arm64-release-symbols.zip"
- name: Remove extra bloat before archiving
shell: cmd
run: |
del /Q bin\ARM64\*.pdb
del /Q bin\ARM64\*.exp
del /Q bin\ARM64\*.lib
del /Q bin\ARM64\*.iobj
del /Q bin\ARM64\*.ipdb
del /Q bin\ARM64\common-tests*
rename bin\ARM64\updater-ARM64-ReleaseLTCG.exe updater.exe
- name: Create arm64 release archive
shell: cmd
run: |
"C:\Program Files\7-Zip\7z.exe" a -r duckstation-windows-arm64-release.zip ./bin/ARM64/*
- name: Upload arm64 release artifact
uses: actions/upload-artifact@v1
with:
name: "windows-arm64"
path: "duckstation-windows-arm64-release.zip"
linux-build:
@@ -101,28 +166,28 @@ jobs:
shell: bash
run: |
sudo apt-get update
sudo apt-get -y install cmake ninja-build ccache libsdl2-dev libgtk2.0-dev qtbase5-dev qtbase5-dev-tools qtbase5-private-dev qt5-default qttools5-dev
sudo apt-get -y install cmake ninja-build ccache libsdl2-dev libgtk-3-dev qtbase5-dev qtbase5-dev-tools qtbase5-private-dev qt5-default qttools5-dev libegl1-mesa-dev libevdev-dev libgbm-dev libdrm-dev libwayland-dev libwayland-egl-backend-dev extra-cmake-modules
- name: Compile build
shell: bash
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SDL_FRONTEND=ON -DBUILD_QT_FRONTEND=ON -DUSE_SDL2=ON -G Ninja ..
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_NOGUI_FRONTEND=ON -DBUILD_QT_FRONTEND=ON -DUSE_DRMKMS=ON -DUSE_EGL=ON -DUSE_SDL2=ON -DUSE_WAYLAND=ON -DUSE_X11=ON -G Ninja ..
ninja
../appimage/generate_appimages.sh $(pwd)
- name: Upload SDL AppImage
- name: Upload NoGUI AppImage
uses: actions/upload-artifact@v1
with:
name: "linux-x64-appimage-sdl"
path: "build/duckstation-sdl-x64.AppImage"
name: "linux-x64-appimage-nogui"
path: "build/duckstation-nogui-x64.AppImage"
- name: Upload SDL AppImage zsync
- name: Upload NoGUI AppImage zsync
uses: actions/upload-artifact@v1
with:
name: "linux-x64-appimage-sdl-zsync"
path: "build/duckstation-sdl-x64.AppImage.zsync"
name: "linux-x64-appimage-nogui-zsync"
path: "build/duckstation-nogui-x64.AppImage.zsync"
- name: Upload Qt AppImage
uses: actions/upload-artifact@v1
@@ -137,65 +202,6 @@ jobs:
path: "build/duckstation-qt-x64.AppImage.zsync"
linux-libretro-build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.3.1
with:
fetch-depth: 0
- name: Install packages
shell: bash
run: |
sudo apt-get update
sudo apt-get -y install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
- name: Compile and zip Linux x64 libretro core
shell: bash
run: |
mkdir build-libretro-linux-x64
cd build-libretro-linux-x64
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBRETRO_CORE=ON ..
cmake --build . --parallel 2
zip -j duckstation_libretro_x64.so.zip duckstation_libretro.so
- name: Upload Linux x64 libretro core
uses: actions/upload-artifact@v1
with:
name: "linux-libretro"
path: "build-libretro-linux-x64/duckstation_libretro_x64.so.zip"
- name: Compile and zip Linux AArch64 libretro core
shell: bash
run: |
mkdir build-libretro-linux-aarch64
cd build-libretro-linux-aarch64
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBRETRO_CORE=ON -DCMAKE_TOOLCHAIN_FILE=../CMakeModules/aarch64-cross-toolchain.cmake ..
cmake --build . --parallel 2
zip -j duckstation_libretro_linux_aarch64.so.zip duckstation_libretro.so
- name: Upload Linux AArch64 libretro core
uses: actions/upload-artifact@v1
with:
name: "linux-libretro"
path: "build-libretro-linux-aarch64/duckstation_libretro_linux_aarch64.so.zip"
- name: Compile and zip Android AArch64 libretro core
shell: bash
run: |
mkdir build-libretro-android-aarch64
cd build-libretro-android-aarch64
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBRETRO_CORE=ON -DANDROID_ABI=arm64-v8a -DCMAKE_TOOLCHAIN_FILE=${ANDROID_SDK_ROOT}/ndk-bundle/build/cmake/android.toolchain.cmake ..
cmake --build . --parallel 2
zip -j duckstation_libretro_android_aarch64.so.zip duckstation_libretro_android.so
- name: Upload Android AArch64 libretro core
uses: actions/upload-artifact@v1
with:
name: "linux-libretro"
path: "build-libretro-android-aarch64/duckstation_libretro_android_aarch64.so.zip"
android-build:
runs-on: ubuntu-20.04
steps:
@@ -210,7 +216,7 @@ jobs:
./gradlew assembleRelease
- name: Sign APK
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev'
uses: r0adkll/sign-android-release@v1
with:
releaseDirectory: android/app/build/outputs/apk/release
@@ -220,18 +226,18 @@ jobs:
keyPassword: ${{ secrets.APK_KEY_PASSWORD }}
- name: Rename APK
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev'
shell: bash
run: |
cd android
mv app/build/outputs/apk/release/app-release-unsigned-signed.apk ../duckstation-android-aarch64.apk
mv app/build/outputs/apk/release/app-release-unsigned-signed.apk ../duckstation-android.apk
- name: Upload APK
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev'
uses: actions/upload-artifact@v1
with:
name: "android"
path: "duckstation-android-aarch64.apk"
path: "duckstation-android.apk"
macos-build:
runs-on: macos-10.15
@@ -255,7 +261,8 @@ jobs:
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SDL_FRONTEND=OFF -DBUILD_QT_FRONTEND=ON -DUSE_SDL2=ON -DQt5_DIR=/usr/local/opt/qt/lib/cmake/Qt5 ..
export MACOSX_DEPLOYMENT_TARGET=10.14
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_NOGUI_FRONTEND=OFF -DBUILD_QT_FRONTEND=ON -DUSE_SDL2=ON -DQt5_DIR=/usr/local/opt/qt/lib/cmake/Qt5 ..
cmake --build . --parallel 2
cd bin
zip -r duckstation-mac-release.zip DuckStation.app/
@@ -266,46 +273,31 @@ jobs:
name: "macos-x64"
path: "build/bin/duckstation-mac-release.zip"
- name: Compile libretro core and zip
shell: bash
run: |
mkdir build-libretro
cd build-libretro
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBRETRO_CORE=ON ..
cmake --build . --parallel 2
zip -j duckstation_libretro_mac.dylib.zip duckstation_libretro.dylib
- name: Upload macOS libretro core
uses: actions/upload-artifact@v1
with:
name: "macos-x64"
path: "build-libretro/duckstation_libretro_mac.dylib.zip"
create-release:
needs: [windows-build, windows-libretro-build, linux-build, linux-libretro-build, android-build, macos-build]
needs: [windows-build, windows-arm64-build, linux-build, android-build, macos-build]
runs-on: "ubuntu-latest"
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev'
steps:
- name: Download Windows x64 Artifact
- name: Download Windows Artifacts
uses: actions/download-artifact@v1
with:
name: "windows-x64"
name: "windows"
- name: Download Windows libretro x64 Artifact
- name: Download Windows ARM64 Artifact
uses: actions/download-artifact@v1
with:
name: "windows-libretro-x64"
name: "windows-arm64"
- name: Download SDL AppImage Artifact
- name: Download NoGUI AppImage Artifact
uses: actions/download-artifact@v1
with:
name: "linux-x64-appimage-sdl"
name: "linux-x64-appimage-nogui"
- name: Download SDL AppImage zsync Artifact
- name: Download NoGUI AppImage zsync Artifact
uses: actions/download-artifact@v1
with:
name: "linux-x64-appimage-sdl-zsync"
name: "linux-x64-appimage-nogui-zsync"
- name: Download Qt AppImage Artifact
uses: actions/download-artifact@v1
@@ -317,11 +309,6 @@ jobs:
with:
name: "linux-x64-appimage-qt-zsync"
- name: Download Linux libretro core
uses: actions/download-artifact@v1
with:
name: "linux-libretro"
- name: Download Android APK
uses: actions/download-artifact@v1
with:
@@ -332,23 +319,42 @@ jobs:
with:
name: "macos-x64"
- name: Create release
- name: Create preview release
if: github.ref == 'refs/heads/master'
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "preview"
prerelease: true
title: "Latest Preview Build"
files: |
windows/duckstation-windows-x64-release.zip
windows/duckstation-windows-x64-release-symbols.zip
windows-arm64/duckstation-windows-arm64-release.zip
windows-arm64/duckstation-windows-arm64-release-symbols.zip
linux-x64-appimage-nogui/duckstation-nogui-x64.AppImage
linux-x64-appimage-nogui-zsync/duckstation-nogui-x64.AppImage.zsync
linux-x64-appimage-qt/duckstation-qt-x64.AppImage
linux-x64-appimage-qt-zsync/duckstation-qt-x64.AppImage.zsync
android/duckstation-android.apk
- name: Create dev release
if: github.ref == 'refs/heads/dev'
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
prerelease: false
title: "Latest Development Build"
files: |
windows-x64/duckstation-windows-x64-release.zip
windows-libretro-x64/duckstation_libretro.dll.zip
linux-x64-appimage-sdl/duckstation-sdl-x64.AppImage
linux-x64-appimage-sdl-zsync/duckstation-sdl-x64.AppImage.zsync
windows/duckstation-windows-x64-release.zip
windows/duckstation-windows-x64-release-symbols.zip
windows-arm64/duckstation-windows-arm64-release.zip
windows-arm64/duckstation-windows-arm64-release-symbols.zip
linux-x64-appimage-nogui/duckstation-nogui-x64.AppImage
linux-x64-appimage-nogui-zsync/duckstation-nogui-x64.AppImage.zsync
linux-x64-appimage-qt/duckstation-qt-x64.AppImage
linux-x64-appimage-qt-zsync/duckstation-qt-x64.AppImage.zsync
linux-libretro/duckstation_libretro_x64.so.zip
linux-libretro/duckstation_libretro_linux_aarch64.so.zip
linux-libretro/duckstation_libretro_android_aarch64.so.zip
android/duckstation-android-aarch64.apk
android/duckstation-android.apk
macos-x64/duckstation-mac-release.zip
macos-x64/duckstation_libretro_mac.dylib.zip

View File

@@ -1,38 +0,0 @@
name: Windows Build
on:
pull_request:
push:
branches:
- master
jobs:
build:
runs-on: windows-2019
steps:
- uses: actions/checkout@v1
with:
submodules: true
- name: Compile release build
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
msbuild duckstation.sln -t:Build -p:Platform=x64;Configuration=ReleaseLTCG
- name: Remove extra bloat before archiving
shell: cmd
run: |
del /Q bin\x64\*.pdb
del /Q bin\x64\*.exp
del /Q bin\x64\*.lib
del /Q bin\x64\*.iobj
del /Q bin\x64\*.ipdb
- name: Upload release archive
uses: actions/upload-artifact@v1
with:
name: "duckstation-windows-x64-release"
path: ".\\bin\\x64"

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.8)
cmake_minimum_required(VERSION 3.10)
project(duckstation C CXX)
message("CMake Version: ${CMAKE_VERSION}")
@@ -13,12 +13,14 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(SUPPORTS_WAYLAND TRUE)
endif()
# Set minimum OS version for macOS. 10.14 should work.
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14.0" CACHE STRING "")
# Global options.
if(NOT ANDROID)
option(BUILD_SDL_FRONTEND "Build the SDL frontend" ON)
option(BUILD_SDL_FRONTEND "Build the SDL frontend" OFF)
option(BUILD_NOGUI_FRONTEND "Build the NoGUI frontend" ON)
option(BUILD_QT_FRONTEND "Build the Qt frontend" ON)
option(BUILD_LIBRETRO_CORE "Build a libretro core" OFF)
option(ENABLE_DISCORD_PRESENCE "Build with Discord Rich Presence support" ON)
option(USE_SDL2 "Link with SDL2 for controller support" ON)
endif()
@@ -34,28 +36,35 @@ endif()
if(LINUX OR ANDROID)
option(USE_EGL "Support EGL OpenGL context creation" ON)
endif()
if(LINUX AND NOT ANDROID)
option(USE_DRMKMS "Support DRM/KMS OpenGL contexts" OFF)
option(USE_FBDEV "Support FBDev OpenGL contexts" OFF)
endif()
# Force EGL when using Wayland
if(USE_WAYLAND)
set(USE_EGL ON)
endif()
# When we're building for libretro, everything else is invalid because of PIC.
if(ANDROID OR BUILD_LIBRETRO_CORE)
if(ANDROID)
if(BUILD_SDL_FRONTEND)
message(WARNING "Building for Android or libretro core, disabling SDL frontend")
message(WARNING "Building for Android, disabling SDL frontend")
set(BUILD_SDL_FRONTEND OFF)
endif()
if(BUILD_NOGUI_FRONTEND)
message(WARNING "Building for Android, disabling NoGUI frontend")
set(BUILD_QT_FRONTEND OFF)
endif()
if(BUILD_QT_FRONTEND)
message(WARNING "Building for Android or libretro core, disabling Qt frontend")
message(WARNING "Building for Android, disabling Qt frontend")
set(BUILD_QT_FRONTEND OFF)
endif()
if(ENABLE_DISCORD_PRESENCE)
message("Building for Android or libretro core, disabling Discord Presence support")
message("Building for Android, disabling Discord Presence support")
set(ENABLE_DISCORD_PRESENCE OFF)
endif()
if(USE_SDL2)
message("Building for Android or libretro core, disabling SDL2 support")
message("Building for Android, disabling SDL2 support")
set(USE_SDL2 OFF)
endif()
if(USE_X11)
@@ -64,14 +73,6 @@ if(ANDROID OR BUILD_LIBRETRO_CORE)
if(USE_WAYLAND)
set(USE_WAYLAND OFF)
endif()
if(BUILD_LIBRETRO_CORE AND USE_EGL)
set(USE_EGL OFF)
endif()
# Force PIC when compiling a libretro core.
if(BUILD_LIBRETRO_CORE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
endif()
@@ -115,6 +116,17 @@ if(USE_WAYLAND)
find_package(Wayland REQUIRED Egl)
message(STATUS "Wayland support enabled")
endif()
if(USE_DRMKMS AND USE_FBDEV)
message(FATAL_ERROR "Only one of DRM/KMS and FBDev can be enabled")
endif()
if(USE_DRMKMS)
find_package(GBM REQUIRED)
find_package(Libdrm REQUIRED)
message(STATUS "DRM/KMS support enabled")
endif()
if(USE_FBDEV)
message(STATUS "FBDev Support enabled")
endif()
# Set _DEBUG macro for Debug builds.
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
@@ -145,18 +157,14 @@ if(MSVC)
# Enable LTO/LTCG on Release builds.
if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
if (${CMAKE_VERSION} VERSION_LESS "3.9.0")
message(WARNING "CMake version is less than 3.9.0, we can't enable LTCG/IPO. This will make the build slightly slower, consider updating your CMake version.")
cmake_policy(SET CMP0069 NEW)
include(CheckIPOSupported)
check_ipo_supported(RESULT IPO_IS_SUPPORTED)
if(IPO_IS_SUPPORTED)
message(STATUS "Enabling LTCG/IPO.")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
else()
cmake_policy(SET CMP0069 NEW)
include(CheckIPOSupported)
check_ipo_supported(RESULT IPO_IS_SUPPORTED)
if(IPO_IS_SUPPORTED)
message(STATUS "Enabling LTCG/IPO.")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
else()
message(WARNING "LTCG/IPO is not supported, this will make the build slightly slower.")
endif()
message(WARNING "LTCG/IPO is not supported, this will make the build slightly slower.")
endif()
endif()
endif()
@@ -192,15 +200,24 @@ elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86" OR ${CMAKE_SYSTEM_PROCESSOR} STR
set(CPU_ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
set(CPU_ARCH "aarch64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7-a")
set(CPU_ARCH "arm")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7-a" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7l")
set(CPU_ARCH "aarch32")
if(ANDROID)
# Force ARM mode, since apparently ANDROID_ARM_MODE isn't working..
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -marm")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -marm")
else()
# Enable NEON.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -marm -march=armv7-a")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -marm -march=armv7-a")
endif()
else()
message(FATAL_ERROR "Unknown system processor: " ${CMAKE_SYSTEM_PROCESSOR})
endif()
# Write binaries to a seperate directory.
if(WIN32 AND NOT BUILD_LIBRETRO_CORE)
if(WIN32)
# For Windows, use the source directory, except for libretro.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/${CPU_ARCH}")
else()
@@ -221,6 +238,6 @@ enable_testing()
add_subdirectory(dep)
add_subdirectory(src)
if(ANDROID AND NOT BUILD_LIBRETRO_CORE)
if(ANDROID)
add_subdirectory(android/app/src/cpp)
endif()

View File

@@ -0,0 +1,70 @@
# https://fossies.org/linux/misc/xbmc-18.9-Leia.tar.gz/xbmc-18.9-Leia/cmake/modules/FindGBM.cmake?m=t
# FindGBM
# ----------
# Finds the GBM library
#
# This will define the following variables::
#
# GBM_FOUND - system has GBM
# GBM_INCLUDE_DIRS - the GBM include directory
# GBM_LIBRARIES - the GBM libraries
# GBM_DEFINITIONS - the GBM definitions
#
# and the following imported targets::
#
# GBM::GBM - The GBM library
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_GBM gbm QUIET)
endif()
find_path(GBM_INCLUDE_DIR NAMES gbm.h
PATHS ${PC_GBM_INCLUDEDIR})
find_library(GBM_LIBRARY NAMES gbm
PATHS ${PC_GBM_LIBDIR})
set(GBM_VERSION ${PC_GBM_VERSION})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GBM
REQUIRED_VARS GBM_LIBRARY GBM_INCLUDE_DIR
VERSION_VAR GBM_VERSION)
include(CheckCSourceCompiles)
set(CMAKE_REQUIRED_LIBRARIES ${GBM_LIBRARY})
check_c_source_compiles("#include <gbm.h>
int main()
{
gbm_bo_map(NULL, 0, 0, 0, 0, GBM_BO_TRANSFER_WRITE, NULL, NULL);
}
" GBM_HAS_BO_MAP)
check_c_source_compiles("#include <gbm.h>
int main()
{
gbm_surface_create_with_modifiers(NULL, 0, 0, 0, NULL, 0);
}
" GBM_HAS_MODIFIERS)
if(GBM_FOUND)
set(GBM_LIBRARIES ${GBM_LIBRARY})
set(GBM_INCLUDE_DIRS ${GBM_INCLUDE_DIR})
set(GBM_DEFINITIONS -DHAVE_GBM=1)
if(GBM_HAS_BO_MAP)
list(APPEND GBM_DEFINITIONS -DHAS_GBM_BO_MAP=1)
endif()
if(GBM_HAS_MODIFIERS)
list(APPEND GBM_DEFINITIONS -DHAS_GBM_MODIFIERS=1)
endif()
if(NOT TARGET GBM::GBM)
add_library(GBM::GBM UNKNOWN IMPORTED)
set_target_properties(GBM::GBM PROPERTIES
IMPORTED_LOCATION "${GBM_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${GBM_INCLUDE_DIR}")
endif()
endif()
mark_as_advanced(GBM_INCLUDE_DIR GBM_LIBRARY)

View File

@@ -0,0 +1,33 @@
# - Try to find libevdev
# Once done this will define
# LIBEVDEV_FOUND - System has libevdev
# LIBEVDEV_INCLUDE_DIRS - The libevdev include directories
# LIBEVDEV_LIBRARIES - The libraries needed to use libevdev
find_package(PkgConfig)
pkg_check_modules(PC_LIBEVDEV QUIET libevdev)
FIND_PATH(
LIBEVDEV_INCLUDE_DIR libevdev/libevdev.h
HINTS ${PC_LIBEVDEV_INCLUDEDIR} ${PC_LIBEVDEV_INCLUDE_DIRS}
/usr/include
/usr/local/include
${LIBEVDEV_PATH_INCLUDES}
)
FIND_LIBRARY(
LIBEVDEV_LIBRARY
NAMES evdev libevdev
HINTS ${PC_LIBEVDEV_LIBDIR} ${PC_LIBEVDEV_LIBRARY_DIRS}
PATHS ${ADDITIONAL_LIBRARY_PATHS}
${LIBEVDEV_PATH_LIB}
)
set(LIBEVDEV_LIBRARIES ${LIBEVDEV_LIBRARY} )
set(LIBEVDEV_INCLUDE_DIRS ${LIBEVDEV_INCLUDE_DIR} )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LIBEVDEV DEFAULT_MSG
LIBEVDEV_LIBRARY LIBEVDEV_INCLUDE_DIR)
mark_as_advanced(LIBEVDEV_INCLUDE_DIR LIBEVDEV_LIBRARY )

View File

@@ -0,0 +1,107 @@
# https://raw.githubusercontent.com/KDE/kwin/master/cmake/modules/FindLibdrm.cmake
#.rst:
# FindLibdrm
# -------
#
# Try to find libdrm on a Unix system.
#
# This will define the following variables:
#
# ``Libdrm_FOUND``
# True if (the requested version of) libdrm is available
# ``Libdrm_VERSION``
# The version of libdrm
# ``Libdrm_LIBRARIES``
# This can be passed to target_link_libraries() instead of the ``Libdrm::Libdrm``
# target
# ``Libdrm_INCLUDE_DIRS``
# This should be passed to target_include_directories() if the target is not
# used for linking
# ``Libdrm_DEFINITIONS``
# This should be passed to target_compile_options() if the target is not
# used for linking
#
# If ``Libdrm_FOUND`` is TRUE, it will also define the following imported target:
#
# ``Libdrm::Libdrm``
# The libdrm library
#
# In general we recommend using the imported target, as it is easier to use.
# Bear in mind, however, that if the target is in the link interface of an
# exported library, it must be made available by the package config file.
#=============================================================================
# SPDX-FileCopyrightText: 2014 Alex Merry <alex.merry@kde.org>
# SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
#
# SPDX-License-Identifier: BSD-3-Clause
#=============================================================================
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "CMake 2.8.12 is required by FindLibdrm.cmake")
endif()
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use FindLibdrm.cmake")
endif()
if(NOT WIN32)
# Use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PKG_Libdrm QUIET libdrm)
set(Libdrm_DEFINITIONS ${PKG_Libdrm_CFLAGS_OTHER})
set(Libdrm_VERSION ${PKG_Libdrm_VERSION})
find_path(Libdrm_INCLUDE_DIR
NAMES
xf86drm.h
HINTS
${PKG_Libdrm_INCLUDE_DIRS}
)
find_library(Libdrm_LIBRARY
NAMES
drm
HINTS
${PKG_Libdrm_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libdrm
FOUND_VAR
Libdrm_FOUND
REQUIRED_VARS
Libdrm_LIBRARY
Libdrm_INCLUDE_DIR
VERSION_VAR
Libdrm_VERSION
)
if(Libdrm_FOUND AND NOT TARGET Libdrm::Libdrm)
add_library(Libdrm::Libdrm UNKNOWN IMPORTED)
set_target_properties(Libdrm::Libdrm PROPERTIES
IMPORTED_LOCATION "${Libdrm_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${Libdrm_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${Libdrm_INCLUDE_DIR}"
INTERFACE_INCLUDE_DIRECTORIES "${Libdrm_INCLUDE_DIR}/libdrm"
)
endif()
mark_as_advanced(Libdrm_LIBRARY Libdrm_INCLUDE_DIR)
# compatibility variables
set(Libdrm_LIBRARIES ${Libdrm_LIBRARY})
set(Libdrm_INCLUDE_DIRS ${Libdrm_INCLUDE_DIR} "${Libdrm_INCLUDE_DIR}/libdrm")
set(Libdrm_VERSION_STRING ${Libdrm_VERSION})
else()
message(STATUS "FindLibdrm.cmake cannot find libdrm on Windows systems.")
set(Libdrm_FOUND FALSE)
endif()
include(FeatureSummary)
set_package_properties(Libdrm PROPERTIES
URL "https://wiki.freedesktop.org/dri/"
DESCRIPTION "Userspace interface to kernel DRM services."
)

View File

@@ -238,7 +238,7 @@ endif()
# But for non-OSX systems, I will use the CMake Threads package.
if(NOT APPLE)
find_package(Threads QUIET)
if(NOT CMAKE_THREAD_LIBS_INIT AND NOT WIN32)
if(NOT Threads_FOUND AND NOT WIN32)
set(SDL2_THREADS_NOT_FOUND "Could NOT find Threads (Threads is required by SDL2).")
if(SDL2_FIND_REQUIRED)
message(FATAL_ERROR ${SDL2_THREADS_NOT_FOUND})

View File

@@ -0,0 +1,14 @@
# Source: https://github.com/stenzek/duckstation/issues/626#issuecomment-660718306
# Target system
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR armv7l)
SET(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_CROSSCOMPILING TRUE)
# Cross compiler
SET(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_LIBRARY_ARCHITECTURE arm-linux-gnueabihf)
set(THREADS_PTHREAD_ARG "0" CACHE STRING "Result from TRY_RUN" FORCE)

View File

@@ -9,14 +9,21 @@ The following people have contributed to the project in some way, and are credit
## Translators
- Anderson Cardoso - Portuguese (Br)
- @bajolzas - Portuguese (Pt)
- posix - @Richard-L - German
- posix - @Richard-L, blexx - German
- @phoe-nix, @zkdpower - Chinese (Simplified)
- Sorer - @MojoJojoDojo - Hebrew
- Hipnosis183 - Spanish
- Hipnosis - @Hipnosis183, MrHomunculus, @falsepopsky - Spanish
- @RaydenX93 - Italian
- @r57zone - Russian
- @6lackmag3 - Russian (Android)
- @DenSinH - Dutch
- @BenjaminSiskoo - French
- mikakunin - Japanese
- Zuzia, Seba - Polish
## Cheat Database
- Pugsy
- Unicorngoulash
## Game Compatibility Database
- @Zet-sensei
@@ -37,6 +44,14 @@ The following people have contributed to the project in some way, and are credit
- @Richard-L
- @pan2marumie3
- @CookiePLMonster
- @LoStraniero91
- @JFD62780
- @lmarciano9
- @Facepalm38
- @Alien-Grey
- @dmlipat
- @Krusher97
- @AngryScotsmanGaming
## Special Thanks
The following people did not directly contribute to the emulator, but it would not be in the state if not for them.

53
NEWS.md Normal file
View File

@@ -0,0 +1,53 @@
- 2021/01/24: Runahead added - work around input lag in some games by running frames ahead of time and backtracking on input. DuckStation's implementation works with upscaling and the hardware renderers, but you still require a powerful computer for higher frame counts.
- 2021/01/24: Rewind added - you can now "smooth rewind" (but not for long), or "skip rewind" (for much long) while playing.
- 2021/01/10: Option to sync to host refresh rate added (enabled by default). This will give the smoothest animation possible with zero duped frames, at the cost of running the game <1% faster. Users with variable refresh rate (GSync/FreeSync) displays will want to disable the option.
- 2021/01/10: Audio resampling added when fast forwarding to fixed speeds. Instead of crackling audio, you'll now get pitch altered audio.
- 2021/01/03: Per game settings and game properties added to Android version.
- 2020/12/30: Box and Adaptive downsampling modes added. Adaptive downsampling will smooth 2D backgrounds but attempt to preserve 3D geometry via pixel similarity (only supported in D3D11/Vulkan). Box is a simple average filter which will downsample to native resolution.
- 2020/12/30: Hotkey binding added to Android version. You can now bind hotkeys such as fast forward, save state, etc to controller buttons. The ability to bind multi-button combinations will be added in the future.
- 2020/12/29: Controller mapping/binding added for Android version. By default mappings will be clear and you will have to set them, you can do this from `Settings -> Controllers -> Controller Mapping`. Profiles can be saved and loaded as well.
- 2020/12/29: Dark theme added for Android. By default it will follow your system theme (Android 10+), but can be overridden in settings.
- 2020/12/29: DirectInput/DInput controller interface added for Windows. You can use this if you are having difficulties with SDL. Vibration is not supported yet.
- 2020/12/25: Partial texture replacement support added. For now, this is only applicable to a small number of games which upload backgrounds to video RAM every frame. Dumping and replacement options are available in `Advanced Settings`.
- 2020/12/22: PGXP Depth Buffer enhancement added. This enhancement can eliminate "polygon fighting" in games, by giving the PS1 the depth buffer it never had. Compatibility is rather low at the moment, but for the games it does work in, it works very well. The depth buffer will be made available to postprocessing shaders in the future, enabling effects such as SSAO.
- 2020/12/21: DuckStation now has two releases - Development and Preview. New features will appear in Preview first, and make their way to the Development release a few days later. To switch to preview, update to the latest development build (older builds will update to development), change the channel from `latest` to `preview` in general settings, and click `Check for Updates`.
- 2020/12/16: Integrated CPU debugger added in Qt frontend.
- 2020/12/13: Button layout for the touchscreen controller in the Android version can now be customized.
- 2020/12/10: Translation support added for Android version. Currently Brazillian Portuguese, Italian, and Dutch are available.
- 2020/11/27: Cover support added for game list in Android version. Procedure is the same as the desktop version, except you should place cover images in `<storage>/duckstation/covers` (see [Adding Game Covers](https://github.com/stenzek/duckstation/wiki/Adding-Game-Covers)).
- 2020/11/27: Disc database is shipped with desktop and Android versions courtesy of redump.org. This will provide titles for games on Android, where it was not possible previously.
- 2020/11/27: Compatibility databases added to libretro core - broken enhancements will be automatically disabled. You can turn this off by disabling "Apply Compatibility Settings" in the core options.
- 2020/11/27: SDL game controller database is included with desktop versions courtesy of https://github.com/gabomdq/SDL_GameControllerDB.
- 2020/11/21: OpenGL ES 2.0 host display support added. You cannot use the hardware renderer with GLES2, it still requires GLES3, but GLES2 GPUs can now use the software renderer.
- 2020/11/21: Threaded renderer for software renderer added. Can result in a significant speed boost depending on the game.
- 2020/11/21: AArch32/armv7 recompiler added. Android and Linux builds will follow after further testing, but for now you can build it yourself.
- 2020/11/18: Window size (resize window to Nx content resolution) added to Qt and SDL frontends.
- 2020/11/10: Widescreen hack now renders in the display aspect ratio instead of always 16:9.
- 2020/11/01: Exclusive fullscreen option added for Windows D3D11 users. Enjoy buttery smooth PAL games.
- 2020/10/31: Multisample antialiasing added as an enhancement.
- 2020/10/30: Option to use analog stick as d-pad for analog controller added.
- 2020/10/20: New cheat manager with memory scanning added. More features will be added over time.
- 2020/10/05: CD-ROM read speedup enhancement added.
- 2020/09/30: CPU overclocking is now supported. Use with caution as it will break games and increase system requirements. It can be set globally or per-game.
- 2020/09/25: Cheat support added for libretro core.
- 2020/09/23: Game covers added to Qt frontend (see [Adding Game Covers](https://github.com/stenzek/duckstation/wiki/Adding-Game-Covers)).
- 2020/09/19: Memory card importer/editor added to Qt frontend.
- 2020/09/13: Support for chaining post processing shaders added.
- 2020/09/12: Additional texture filtering options added.
- 2020/09/09: Basic cheat support added. Not all instructions/commands are supported yet.
- 2020/09/01: Many additional user settings available, including memory cards and enhancements. Now you can set these per-game.
- 2020/08/25: Automated builds for macOS now available.
- 2020/08/22: XInput controller backend added.
- 2020/08/20: Per-game setting overrides added. Mostly for compatibility, but some options are customizable.
- 2020/08/19: CPU PGXP mode added. It is very slow and incompatible with the recompiler, only use for games which need it.
- 2020/08/15: Playlist support/single memcard for multi-disc games in Qt frontend added.
- 2020/08/07: Automatic updater for standalone Windows builds.
- 2020/08/01: Initial PGXP (geometry/perspective correction) support.
- 2020/07/28: Qt frontend supports displaying interface in multiple languages.
- 2020/07/23: m3u multi-disc support for libretro core.
- 2020/07/22: Support multiple bindings for each controller button/axis.
- 2020/07/18: Widescreen hack enhancement added.
- 2020/07/04: Vulkan renderer now available in libretro core.
- 2020/07/02: Now available as a libretro core.
- 2020/07/01: Lightgun support with custom crosshairs.
- 2020/06/19: Vulkan hardware renderer added.

165
README.md
View File

@@ -1,57 +1,57 @@
# DuckStation - PlayStation 1, aka. PSX Emulator
[Latest News](#latest-news) | [Features](#features) | [Screenshots](#screenshots) | [Downloading and Running](#downloading-and-running) | [Libretro Core](#libretro-core) | [Building](#building) | [Disclaimers](#disclaimers)
[Latest News](#latest-news) | [Features](#features) | [Screenshots](#screenshots) | [Downloading and Running](#downloading-and-running) | [Building](#building) | [Disclaimers](#disclaimers)
**Discord Server:** https://discord.gg/Buktv3t
**Latest Windows, Linux (AppImage), and Libretro Builds:** https://github.com/stenzek/duckstation/releases/tag/latest
**Latest Windows, Linux (AppImage), Mac, Android** https://github.com/stenzek/duckstation/releases/tag/latest
**Available on Google Play:** https://play.google.com/store/apps/details?id=com.github.stenzek.duckstation&hl=en_AU&gl=US
**Game Compatibility List:** https://docs.google.com/spreadsheets/d/1H66MxViRjjE5f8hOl5RQmF5woS1murio2dsLn14kEqo/edit?usp=sharing
**Wiki:** https://www.duckstation.org/wiki/
DuckStation is an simulator/emulator of the Sony PlayStation(TM) console, focusing on playability, speed, and long-term maintainability. The goal is to be as accurate as possible while maintaining performance suitable for low-end devices. "Hack" options are discouraged, the default configuration should support all playable games with only some of the enhancements having compatibility issues.
A "BIOS" ROM image is required to to start the emulator and to play games. You can use an image from any hardware version or region, although mismatching game regions and BIOS regions may have compatibility issues. A ROM image is not provided with the emulator for legal reasons, you should dump this from your own console using Caetla or other means.
## Latest News
Older entries are available at https://github.com/stenzek/duckstation/blob/master/NEWS.md
- 2020/10/05: CD-ROM read speedup enhancement added.
- 2020/09/30: CPU overclocking is now supported. Use with caution as it will break games and increase system requirements. It can be set globally or per-game.
- 2020/09/25: Cheat support added for libretro core.
- 2020/09/23: Game covers added to Qt frontend (see [Adding Game Covers](https://github.com/stenzek/duckstation/wiki/Adding-Game-Covers)).
- 2020/09/19: Memory card importer/editor added to Qt frontend.
- 2020/09/13: Support for chaining post processing shaders added.
- 2020/09/12: Additional texture filtering options added.
- 2020/09/09: Basic cheat support added. Not all instructions/commands are supported yet.
- 2020/09/01: Many additional user settings available, including memory cards and enhancements. Now you can set these per-game.
- 2020/08/25: Automated builds for macOS now available.
- 2020/08/22: XInput controller backend added.
- 2020/08/20: Per-game setting overrides added. Mostly for compatibility, but some options are customizable.
- 2020/08/19: CPU PGXP mode added. It is very slow and incompatible with the recompiler, only use for games which need it.
- 2020/08/15: Playlist support/single memcard for multi-disc games in Qt frontend added.
- 2020/08/07: Automatic updater for standalone Windows builds.
- 2020/08/01: Initial PGXP (geometry/perspective correction) support.
- 2020/07/28: Qt frontend supports displaying interface in multiple languages.
- 2020/07/23: m3u multi-disc support for libretro core.
- 2020/07/22: Support multiple bindings for each controller button/axis.
- 2020/07/18: Widescreen hack enhancement added.
- 2020/07/04: Vulkan renderer now available in libretro core.
- 2020/07/02: Now available as a libretro core.
- 2020/07/01: Lightgun support with custom crosshairs.
- 2020/06/19: Vulkan hardware renderer added.
- 2021/01/31: "Fullscreen UI" added, aka "Big Duck/TV Mode". This interface is fully navigatible with a controller. Currently it's limited to the NoGUI frontend, but it will be available directly in the Qt frontend in the near future, with more features being added (e.g. game grid) as well.
- 2021/01/24: Runahead added - work around input lag in some games by running frames ahead of time and backtracking on input. DuckStation's implementation works with upscaling and the hardware renderers, but you still require a powerful computer for higher frame counts.
- 2021/01/24: Rewind added - you can now "smooth rewind" (but not for long), or "skip rewind" (for much long) while playing.
- 2021/01/10: Option to sync to host refresh rate added (enabled by default). This will give the smoothest animation possible with zero duped frames, at the cost of running the game <1% faster. Users with variable refresh rate (GSync/FreeSync) displays will want to disable the option.
- 2021/01/10: Audio resampling added when fast forwarding to fixed speeds. Instead of crackling audio, you'll now get pitch altered audio.
- 2021/01/03: Per game settings and game properties added to Android version.
- 2020/12/30: Box and Adaptive downsampling modes added. Adaptive downsampling will smooth 2D backgrounds but attempt to preserve 3D geometry via pixel similarity (only supported in D3D11/Vulkan). Box is a simple average filter which will downsample to native resolution.
- 2020/12/30: Hotkey binding added to Android version. You can now bind hotkeys such as fast forward, save state, etc to controller buttons. The ability to bind multi-button combinations will be added in the future.
- 2020/12/29: Controller mapping/binding added for Android version. By default mappings will be clear and you will have to set them, you can do this from `Settings -> Controllers -> Controller Mapping`. Profiles can be saved and loaded as well.
- 2020/12/29: Dark theme added for Android. By default it will follow your system theme (Android 10+), but can be overridden in settings.
- 2020/12/29: DirectInput/DInput controller interface added for Windows. You can use this if you are having difficulties with SDL. Vibration is not supported yet.
- 2020/12/25: Partial texture replacement support added. For now, this is only applicable to a small number of games which upload backgrounds to video RAM every frame. Dumping and replacement options are available in `Advanced Settings`.
- 2020/12/22: PGXP Depth Buffer enhancement added. This enhancement can eliminate "polygon fighting" in games, by giving the PS1 the depth buffer it never had. Compatibility is rather low at the moment, but for the games it does work in, it works very well. The depth buffer will be made available to postprocessing shaders in the future, enabling effects such as SSAO.
- 2020/12/21: DuckStation now has two releases - Development and Preview. New features will appear in Preview first, and make their way to the Development release a few days later. To switch to preview, update to the latest development build (older builds will update to development), change the channel from `latest` to `preview` in general settings, and click `Check for Updates`.
- 2020/12/16: Integrated CPU debugger added in Qt frontend.
- 2020/12/13: Button layout for the touchscreen controller in the Android version can now be customized.
- 2020/12/10: Translation support added for Android version. Currently Brazillian Portuguese, Italian, and Dutch are available.
## Features
DuckStation features a fully-featured frontend built using Qt (pictured), as well as a simplified frontend based on SDL and Dear ImGui. An Android version has been started, but is not yet feature complete.
DuckStation features a fully-featured frontend built using Qt, as well as a fullscreen/TV UI based on Dear ImGui. An Android version has been started, but is not yet feature complete.
<p align="center">
<img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/main-qt.png" alt="Main Window Screenshot" />
<img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/bigduck.png" alt="Fullscreen UI Screenshot" />
</p>
Other features include:
- CPU Recompiler/JIT (x86-64 and AArch64)
- CPU Recompiler/JIT (x86-64, armv7/AArch32 and AArch64)
- Hardware (D3D11, OpenGL, Vulkan) and software rendering
- Upscaling, texture filtering, and true colour (24-bit) in hardware renderers
- PGXP for geometry precision and texture correction
- PGXP for geometry precision, texture correction, and depth buffer emulation
- Adaptive downsampling filter
- Post processing shader chains
- "Fast boot" for skipping BIOS splash/intro
- Save state support
@@ -62,23 +62,22 @@ Other features include:
- Digital and analog controllers for input (rumble is forwarded to host)
- Namco GunCon lightgun support (simulated with mouse)
- NeGcon support
- Qt and SDL frontends for desktop
- libretro core for Windows and Linux
- Qt and NoGUI frontends for desktop
- Automatic updates for Windows builds
- Automatic content scanning - game titles/regions are provided by redump.org
- Optional automatic switching of memory cards for each game
- Supports loading cheats from libretro or PCSXR format lists
- Memory card editor and save importer
- Emulated CPU overclocking
- Integrated and remote debugging
## System Requirements
- A CPU faster than a potato. But it needs to be 64-bit (either x86_64 or AArch64/ARMv8) otherwise you won't get a recompiler and it'll be slow. There are no plans to add any 32-bit recompilers.
- For the hardware renderers, a GPU capable of OpenGL 3.0/OpenGL ES 3.0/Direct3D 11 Feature Level 10.0 (or Vulkan 1.0) and above. So, basically anything made in the last 10 years or so.
- SDL or XInput compatible game controller (e.g. XB360/XBOne). DualShock 3 users on Windows will need to install the official DualShock 3 drivers included as part of PlayStation Now.
- Optional [SDL game contoller database files](#sdl-game-controller-database) are also supported.
- A CPU faster than a potato. But it needs to be x86_64, AArch32/armv7, or AArch64/ARMv8, otherwise you won't get a recompiler and it'll be slow.
- For the hardware renderers, a GPU capable of OpenGL 3.1/OpenGL ES 3.0/Direct3D 11 Feature Level 10.0 (or Vulkan 1.0) and above. So, basically anything made in the last 10 years or so.
- SDL, XInput or DInput compatible game controller (e.g. XB360/XBOne). DualShock 3 users on Windows will need to install the official DualShock 3 drivers included as part of PlayStation Now.
## Downloading and running
Binaries of DuckStation for Windows 64-bit, x86_64 Linux x86_64 (in AppImage format), and Android ARMv8/AArch64 are available via GitHub Releases and are automatically built with every commit/push. Binaries or packages distributed through other sources may be out of date and are not supported by the developer.
Binaries of DuckStation for Windows x64/ARM64, x86_64 Linux x86_64 (in AppImage format), and Android ARMv8/AArch64 are available via GitHub Releases and are automatically built with every commit/push. Binaries or packages distributed through other sources may be out of date and are not supported by the developer.
### Windows
@@ -89,10 +88,10 @@ To download:
- Alternatively, direct download link: https://github.com/stenzek/duckstation/releases/download/latest/duckstation-windows-x64-release.zip
- Extract the archive **to a subdirectory**. The archive has no root subdirectory, so extracting to the current directory will drop a bunch of files in your download directory if you do not extract to a subdirectory.
Once downloaded and extracted, you can launch the Qt frontend from `duckstation-qt-x64-ReleaseLTCG.exe`, or the SDL frontend from `duckstation-sdl-x64-ReleaseLTCG.exe`.
Once downloaded and extracted, you can launch the emulator with `duckstation-qt-x64-ReleaseLTCG.exe`.
To set up:
1. Either configure the path to a BIOS image in the settings, or copy one or more PlayStation BIOS images to the bios/ subdirectory. On Windows, by default this will be located in `C:\Users\YOUR_USERNAME\Documents\DuckStation\bios`. If you don't want to use the Documents directory to save the BIOS/memory cards/etc, you can use portable mode. See [User directory](#user-directories).
2. If using the SDL frontend, add the directories containing your disc images by clicking `Settings->Add Game Directory`.
2. If using the Qt frontend, add the directories containing your disc images by clicking `Settings->Add Game Directory`.
2. Select a game from the list, or open a disc image file and enjoy.
**If you get an error about `vcruntime140_1.dll` being missing, you will need to update your Visual C++ runtime.** You can do that from this page: https://support.microsoft.com/en-au/help/2977003/the-latest-supported-visual-c-downloads. Specifically, you want the x64 runtime, which can be downloaded from https://aka.ms/vs/16/release/vc_redist.x64.exe.
@@ -106,7 +105,7 @@ Prebuilt binaries for 64-bit Linux distros are available for download in the App
**Linux users are encouraged to build from source when possible and optionally create their own AppImages for features such as desktop integration if desired.**
To download:
- Go to https://github.com/stenzek/duckstation/releases/tag/latest, and download either `duckstation-qt-x64.AppImage` or `duckstation-sdl-x64.AppImage` for your desired frontend. Keep in mind that keyboard/controller bindings are currently not customizable through the SDL frontend and should be customized through the Qt frontend instead.
- Go to https://github.com/stenzek/duckstation/releases/tag/latest, and download either `duckstation-qt-x64.AppImage` or `duckstation-nogui-x64.AppImage` for your desired frontend.
- Run `chmod a+x` on the downloaded AppImage -- following this step, the AppImage can be run like a typical executable.
- Optionally use a program such as [appimaged](https://github.com/AppImage/appimaged) or [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher) for desktop integration. [AppImageUpdate](https://github.com/AppImage/AppImageUpdate) can be used alongside appimaged to easily update your DuckStation AppImage.
@@ -126,27 +125,21 @@ they are investigated.
### Android
A prebuilt APK is now available for Android. However, please keep in mind that the Android version is not yet feature complete, it is more of a preview of things to come. You will need a device running a 64-bit AArch64 userland (anything made in the last few years).
A prebuilt APK is now available for Android. However, please keep in mind that the Android version does not contain all features present in the desktop version yet. You will need a device with armv7 (32-bit ARM) or AArch64 (64-bit ARM). 64-bit is preferred, the requirements are higher for 32-bit, you'll probably want at least a 1.5GHz CPU.
Download link: https://github.com/stenzek/duckstation/releases/download/latest/duckstation-android-aarch64.apk
The main limitations are:
- User directory is currently hardcoded to `<external storage path>/duckstation`. This is usually `/storage/emulated/0` or `/sdcard`'. So BIOS files go in `/sdcard/duckstation/bios`.
- Lack of options in menu when emulator is running.
- Performance is currently lower than the desktop x86_64 counterpart.
Download link: https://github.com/stenzek/duckstation/releases/download/latest/duckstation-android.apk
To use:
- Install and run the app for the first time.
- This will create `/sdcard/duckstation`. Drop your BIOS files in `/sdcard/duckstation/bios`.
- Add game directories by hitting the `+` icon and selecting a directory.
- Map your controller buttons and axes by going into `Controller Mapping` under `Controllers` in `Settings`.
- Tap a game to start.
### Title Information
PlayStation game discs do not contain title information. For game titles, we use the redump.org database cross-referenced with the game's executable code.
This database can be manually downloaded and added as `cache/redump.dat`, or automatically downloaded by going into the `Game List Settings` in the Qt Frontend,
and clicking `Update Redump Database`.
PlayStation game discs do not contain title information. For game titles, we use the redump.org database cross-referenced with the game's executable code. A version of the database is included with the DuckStation download, but you can replace this with a different database by saving it as `cache/redump.dat` in your user directory, or updated by going into the `Game List Settings` in the Qt Frontend, and clicking `Update Redump Database`.
### Region detection and BIOS images
By default, DuckStation will emulate the region check present in the CD-ROM controller of the console. This means that when the region of the console does not match the disc, it will refuse to boot, giving a "Please insert PlayStation CD-ROM" message. DuckStation supports automatic detection disc regions, and if you set the console region to auto-detect as well, this should never be a problem.
@@ -161,7 +154,11 @@ Mismatching the disc and console regions with the check disabled is supported, b
### LibCrypt protection and SBI files
A number of PAL region games use LibCrypt protection, requiring additional CD subchannel information to run properly. For these games, make sure that the CD image and its corresponding SBI (.sbi) file have the same name and are placed in the same directory. DuckStation will automatically load the SBI file when it is found next to the CD image.
A number of PAL region games use LibCrypt protection, requiring additional CD subchannel information to run properly. libcrypt not functioning usually manifests as hanging or crashing, but can sometimes affect gameplay too, depending on how the game implemented it.
For these games, make sure that the CD image and its corresponding SBI (.sbi) file have the same name and are placed in the same directory. DuckStation will automatically load the SBI file when it is found next to the CD image.
For example, if your disc image was named `Spyro3.cue`, you would place the SBI file in the same directory, and name it `Spyro3.sbi`.
## Building
@@ -169,25 +166,28 @@ A number of PAL region games use LibCrypt protection, requiring additional CD su
Requirements:
- Visual Studio 2019
1. Clone the respository with submodules (`git clone --recursive` or `git clone` and `git submodule update --init`).
1. Clone the respository with submodules (`git clone --recursive https://github.com/stenzek/duckstation.git -b dev`).
2. Open the Visual Studio solution `duckstation.sln` in the root, or "Open Folder" for cmake build.
3. Build solution.
4. Binaries are located in `bin/x64`.
5. Run `duckstation-sdl-x64-Release.exe`/`duckstation-qt-x64-Release.exe` or whichever config you used.
5. Run `duckstation-qt-x64-Release.exe` or whichever config you used.
### Linux
Requirements (Debian/Ubuntu package names):
- CMake (`cmake`)
- SDL2 (`libsdl2-dev`)
- GTK2.0 for file selector (`libgtk2.0-dev`)
- pkgconfig (`pkg-config`)
- Qt 5 (`qtbase5-dev`, `qtbase5-private-dev`, `qtbase5-dev-tools`, `qttools5-dev`)
- libevdev (`libevdev-dev`)
- git (`git`) (Note: needed to clone the repository and at build time)
- Optional for faster building: Ninja (`ninja-build`)
- Optional for framebuffer output: DRM/GBM (`libgbm-dev`, `libdrm-dev`)
1. Clone the repository. Submodules aren't necessary, there is only one and it is only used for Windows.
1. Clone the repository. Submodules aren't necessary, there is only one and it is only used for Windows (`git clone https://github.com/stenzek/duckstation.git -b dev`).
2. Create a build directory, either in-tree or elsewhere.
3. Run cmake to configure the build system. Assuming a build subdirectory of `build-release`, `cd build-release && cmake -DCMAKE_BUILD_TYPE=Release -GNinja ..`.
4. Compile the source code. For the example above, run `ninja`.
5. Run the binary, located in the build directory under `bin/duckstation-sdl`, or `bin/duckstation-qt`.
5. Run the binary, located in the build directory under `bin/duckstation-qt`.
### macOS
**NOTE:** macOS is highly experimental and not tested by the developer. Use at your own risk, things may be horribly broken.
@@ -197,16 +197,14 @@ Requirements:
- SDL2 (`brew install sdl2`)
- Qt 5 (`brew install qt5`)
1. Clone the repository. Submodules aren't necessary, there is only one and it is only used for Windows.
1. Clone the repository. Submodules aren't necessary, there is only one and it is only used for Windows (`git clone https://github.com/stenzek/duckstation.git -b dev`).
2. Clone the mac externals repository (for MoltenVK): `git clone https://github.com/stenzek/duckstation-ext-mac.git dep/mac`.
2. Create a build directory, either in-tree or elsewhere, e.g. `mkdir build-release`, `cd build-release`.
3. Run cmake to configure the build system: `cmake -DCMAKE_BUILD_TYPE=Release -DQt5_DIR=/usr/local/opt/qt/lib/cmake/Qt5 ..`. You may need to tweak `Qt5_DIR` depending on your system.
4. Compile the source code: `make`. Use `make -jN` where `N` is the number of CPU cores in your system for a faster build.
5. Run the binary, located in the build directory under `bin/duckstation-sdl`, or `bin/DuckStation.app` for Qt.
5. Run the binary, located in the build directory under `bin/DuckStation.app`.
### Android
**NOTE:** The Android frontend is still incomplete, not all functionality is available yet. User directory is hardcoded to `/sdcard/duckstation` for now.
Requirements:
- Android Studio with the NDK and CMake installed
@@ -232,32 +230,21 @@ If you wish to use a "portable" build, where the user directory is the same as w
in the same directory as the DuckStation executable.
## Bindings for Qt frontend
Your keyboard and any SDL-compatible game controller can be used to simulate the PS Controller. To bind keys/controllers to buttons, go to
`Settings -> Port Settings`. Each of the buttons will be listed, along with the corresponding key it is bound to. To re-bind the button to a new key,
click the button next to button name, and press the key/button you want to use within 5 seconds.
Your keyboard or game controller can be used to simulate a variety of PlayStation controllers. Controller input is supported through DInput, XInput, and SDL backends and can be changed through `Settings -> General Settings`.
**Currently, it is only possible to bind one input to each controller button/axis. Multiple bindings per button are planned for the future.**
## Bindings for SDL frontend
Keyboard bindings in the SDL frontend are currently not customizable in the frontend itself. You should use the Qt frontend to set up your key/controller bindings first.
To bind your input device, go to `Settings -> Controller Settings`. Each of the buttons/axes for the simulated controller will be listed, alongside the corresponding key/button on your device that it is currently bound to. To rebind, click the box next to the button/axis name, and press the key or button on your input device that you wish to bind to. When binding rumble, simply press any button on the controller you wish to send rumble to.
## SDL Game Controller Database
DuckStation uses the SDL2 GameController API for input handling which requires controller devices to have known input mappings.
SDL2 provides an embedded database of recognised controllers in its own source code, however it is rather small and thus limited in practice.
DuckStation releases ship with a database of game controller mappings for the SDL controller backend, courtesy of https://github.com/gabomdq/SDL_GameControllerDB. The included `gamecontrollerdb.txt` file can be found in the `database` subdirectory of the DuckStation program directory.
There is an officially endorsed [community sourced database](https://github.com/gabomdq/SDL_GameControllerDB) that can be used to support a much broader range of game controllers in DuckStation.
If your controller is not recognized by DuckStation but can be found in the community database above, just download a recent copy of the `gamecontrollerdb.txt` database file and place it in your [User directory](#user-directories). Your controller should now be recognized by DuckStation.
Alternatively, you can also create your own custom controller mappings from scratch easily using readily available tools. See the referenced community database repository for more information.
Using a mappings database is specially useful when using non-XInput game controllers with DuckStation.
If you are experiencing issues binding your controller with the SDL controller backend, you may need to add a custom mapping to the database file. Make a copy of `gamecontrollerdb.txt` and place it in your [user directory](#user-directories) (or directly in the program directory, if running in portable mode) and then follow the instructions in the [SDL_GameControllerDB repository](https://github.com/gabomdq/SDL_GameControllerDB) for creating a new mapping. Add this mapping to the new copy of `gamecontrollerdb.txt` and your controller should then be recognized properly.
## Default bindings
Controller 1:
- **D-Pad:** W/A/S/D
- **Triangle/Square/Circle/Cross:** Numpad8/Numpad4/Numpad6/Numpad2
- **L1/R1:** Q/E
- **L2/L2:** 1/3
- **L2/R2:** 1/3
- **Start:** Enter
- **Select:** Backspace
@@ -269,27 +256,6 @@ Hotkeys:
- **Page Up/Down:** Increase/decrease resolution scale in hardware renderers
- **End:** Toggle software renderer
## Libretro Core
DuckStation is available as a libretro core, which can be loaded into a frontend such as RetroArch. It supports most features of the full frontend, within the constraints and limitations of being a libretro core.
Prebuilt binaries for 64-bit Windows, Linux and Android can be found on the releases page. Direct links:
- 64-bit Windows: https://github.com/stenzek/duckstation/releases/download/latest/duckstation_libretro.dll.zip
- 64-bit Linux: https://github.com/stenzek/duckstation/releases/download/latest/duckstation_libretro_x64.so.zip
- AArch64 Linux: https://github.com/stenzek/duckstation/releases/download/latest/duckstation_libretro_linux_aarch64.so.zip
- AArch64 Android: https://github.com/stenzek/duckstation/releases/download/latest/duckstation_libretro_android_aarch64.so.zip
To use, download and extract, and install the core file in RetroArch or your preferred frontend.
To build on Windows, use cmake using the following commands from a `x64 Native Tools Command Prompt for VS 2019`:
- mkdir build
- cd build
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBRETRO_CORE=ON ..
You should then have a file named `duckstation_libretro.dll` which can be loaded as a core.
To build on Linux, follow the same instructions as for a normal build, but for cmake use `cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBRETRO_CORE=ON ..`. The shared library will be named `duckstation_libretro.so` in the current directory.
## Tests
- Passes amidog's CPU and GTE tests in both interpreter and recompiler modes, partial passing of CPX tests
@@ -302,9 +268,10 @@ To build on Linux, follow the same instructions as for a normal build, but for c
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/croc.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/croc.jpg" alt="Croc" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/croc2.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/croc2.jpg" alt="Croc 2" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff7.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff7.jpg" alt="Final Fantasy 7" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff8.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff8.jpg" alt="Final Fantasy 8" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/main.png"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/main.png" alt="SDL Frontend" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/spyro.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/spyro.jpg" alt="Spyro 2" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/mm8.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/mm8.jpg" alt="Mega Man 8" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff8.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff8.jpg" alt="Final Fantasy 8 in Fullscreen UI" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/spyro.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/spyro.jpg" alt="Spyro in Fullscreen UI" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/tof.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/tof.jpg" alt="Threads of Fate in Fullscreen UI" width="400" /></a>
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/gamegrid.png"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/gamegrid.png" alt="Game Grid" width="400" /></a>
</p>

View File

@@ -14,6 +14,7 @@
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@@ -5,7 +5,7 @@ android {
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.github.stenzek.duckstation"
minSdkVersion 21
minSdkVersion 23
targetSdkVersion 29
versionCode(getBuildVersionCode())
versionName "${getVersion()}"
@@ -30,11 +30,14 @@ android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
abiFilters "arm64-v8a"
arguments "-DCMAKE_BUILD_TYPE=Release"
abiFilters "arm64-v8a", "armeabi-v7a"
}
}
}
sourceSets {
main.assets.srcDirs += "../../data"
}
}
dependencies {
@@ -56,7 +59,7 @@ def getVersion() {
def versionNumber = '0.0-unknown'
try {
versionNumber = 'git describe --tags --exclude latest'.execute([], project.rootDir).text
versionNumber = 'git describe --tags --exclude latest --exclude preview'.execute([], project.rootDir).text
.trim()
.replaceAll(/(-0)?-[^-]+$/, "")
} catch (Exception e) {

View File

@@ -1,6 +1,10 @@
set(SRCS
android_controller_interface.cpp
android_controller_interface.h
android_host_interface.cpp
android_host_interface.h
android_progress_callback.cpp
android_progress_callback.h
android_settings_interface.cpp
android_settings_interface.h
)

View File

@@ -0,0 +1,186 @@
#include "android_controller_interface.h"
#include "common/assert.h"
#include "common/file_system.h"
#include "common/log.h"
#include "core/controller.h"
#include "core/host_interface.h"
#include "core/system.h"
#include <cmath>
Log_SetChannel(AndroidControllerInterface);
AndroidControllerInterface::AndroidControllerInterface() = default;
AndroidControllerInterface::~AndroidControllerInterface() = default;
ControllerInterface::Backend AndroidControllerInterface::GetBackend() const
{
return ControllerInterface::Backend::Android;
}
bool AndroidControllerInterface::Initialize(CommonHostInterface* host_interface)
{
if (!ControllerInterface::Initialize(host_interface))
return false;
return true;
}
void AndroidControllerInterface::Shutdown()
{
ControllerInterface::Shutdown();
}
void AndroidControllerInterface::PollEvents() {}
void AndroidControllerInterface::ClearBindings()
{
for (ControllerData& cd : m_controllers)
{
cd.axis_mapping.fill({});
cd.button_mapping.fill({});
cd.axis_button_mapping.fill({});
cd.button_axis_mapping.fill({});
}
}
bool AndroidControllerInterface::BindControllerAxis(int controller_index, int axis_number, AxisSide axis_side,
AxisCallback callback)
{
if (static_cast<u32>(controller_index) >= m_controllers.size())
return false;
if (axis_number < 0 || axis_number >= NUM_AXISES)
return false;
m_controllers[controller_index].axis_mapping[axis_number][axis_side] = std::move(callback);
return true;
}
bool AndroidControllerInterface::BindControllerButton(int controller_index, int button_number, ButtonCallback callback)
{
if (static_cast<u32>(controller_index) >= m_controllers.size())
return false;
if (button_number < 0 || button_number >= NUM_BUTTONS)
return false;
m_controllers[controller_index].button_mapping[button_number] = std::move(callback);
return true;
}
bool AndroidControllerInterface::BindControllerAxisToButton(int controller_index, int axis_number, bool direction,
ButtonCallback callback)
{
if (static_cast<u32>(controller_index) >= m_controllers.size())
return false;
if (axis_number < 0 || axis_number >= NUM_AXISES)
return false;
m_controllers[controller_index].axis_button_mapping[axis_number][BoolToUInt8(direction)] = std::move(callback);
return true;
}
bool AndroidControllerInterface::BindControllerHatToButton(int controller_index, int hat_number,
std::string_view hat_position, ButtonCallback callback)
{
// Hats don't exist in XInput
return false;
}
bool AndroidControllerInterface::BindControllerButtonToAxis(int controller_index, int button_number,
AxisCallback callback)
{
if (static_cast<u32>(controller_index) >= m_controllers.size())
return false;
if (button_number < 0 || button_number >= NUM_BUTTONS)
return false;
m_controllers[controller_index].button_axis_mapping[button_number] = std::move(callback);
return true;
}
bool AndroidControllerInterface::HandleAxisEvent(u32 index, u32 axis, float value)
{
Log_DevPrintf("controller %u axis %u %f", index, static_cast<u32>(axis), value);
DebugAssert(index < NUM_CONTROLLERS);
if (DoEventHook(Hook::Type::Axis, index, static_cast<u32>(axis), value))
return true;
const AxisCallback& cb = m_controllers[index].axis_mapping[static_cast<u32>(axis)][AxisSide::Full];
if (cb)
{
cb(value);
return true;
}
// set the other direction to false so large movements don't leave the opposite on
const bool outside_deadzone = (std::abs(value) >= m_controllers[index].deadzone);
const bool positive = (value >= 0.0f);
const ButtonCallback& other_button_cb =
m_controllers[index].axis_button_mapping[static_cast<u32>(axis)][BoolToUInt8(!positive)];
const ButtonCallback& button_cb =
m_controllers[index].axis_button_mapping[static_cast<u32>(axis)][BoolToUInt8(positive)];
if (button_cb)
{
button_cb(outside_deadzone);
if (other_button_cb)
other_button_cb(false);
return true;
}
else if (other_button_cb)
{
other_button_cb(false);
return true;
}
else
{
return false;
}
}
bool AndroidControllerInterface::HandleButtonEvent(u32 index, u32 button, bool pressed)
{
Log_DevPrintf("controller %u button %u %s", index, button, pressed ? "pressed" : "released");
DebugAssert(index < NUM_CONTROLLERS);
if (DoEventHook(Hook::Type::Button, index, button, pressed ? 1.0f : 0.0f))
return true;
const ButtonCallback& cb = m_controllers[index].button_mapping[button];
if (cb)
{
cb(pressed);
return true;
}
const AxisCallback& axis_cb = m_controllers[index].button_axis_mapping[button];
if (axis_cb)
{
axis_cb(pressed ? 1.0f : -1.0f);
}
return true;
}
u32 AndroidControllerInterface::GetControllerRumbleMotorCount(int controller_index)
{
return 0;
}
void AndroidControllerInterface::SetControllerRumbleStrength(int controller_index, const float* strengths,
u32 num_motors)
{
}
bool AndroidControllerInterface::SetControllerDeadzone(int controller_index, float size /* = 0.25f */)
{
if (static_cast<u32>(controller_index) >= NUM_CONTROLLERS)
return false;
m_controllers[static_cast<u32>(controller_index)].deadzone = std::clamp(std::abs(size), 0.01f, 0.99f);
Log_InfoPrintf("Controller %d deadzone size set to %f", controller_index,
m_controllers[static_cast<u32>(controller_index)].deadzone);
return true;
}

View File

@@ -0,0 +1,67 @@
#pragma once
#include "frontend-common/controller_interface.h"
#include "core/types.h"
#include <array>
#include <functional>
#include <mutex>
#include <vector>
class AndroidControllerInterface final : public ControllerInterface
{
public:
AndroidControllerInterface();
~AndroidControllerInterface() override;
Backend GetBackend() const override;
bool Initialize(CommonHostInterface* host_interface) override;
void Shutdown() override;
// Removes all bindings. Call before setting new bindings.
void ClearBindings() override;
// Binding to events. If a binding for this axis/button already exists, returns false.
bool BindControllerAxis(int controller_index, int axis_number, AxisSide axis_side, AxisCallback callback) override;
bool BindControllerButton(int controller_index, int button_number, ButtonCallback callback) override;
bool BindControllerAxisToButton(int controller_index, int axis_number, bool direction,
ButtonCallback callback) override;
bool BindControllerHatToButton(int controller_index, int hat_number, std::string_view hat_position,
ButtonCallback callback) override;
bool BindControllerButtonToAxis(int controller_index, int button_number, AxisCallback callback) override;
// Changing rumble strength.
u32 GetControllerRumbleMotorCount(int controller_index) override;
void SetControllerRumbleStrength(int controller_index, const float* strengths, u32 num_motors) override;
// Set deadzone that will be applied on axis-to-button mappings
bool SetControllerDeadzone(int controller_index, float size = 0.25f) override;
void PollEvents() override;
bool HandleAxisEvent(u32 index, u32 axis, float value);
bool HandleButtonEvent(u32 index, u32 button, bool pressed);
private:
enum : u32
{
NUM_CONTROLLERS = 1,
NUM_AXISES = 12,
NUM_BUTTONS = 23
};
struct ControllerData
{
float deadzone = 0.25f;
std::array<std::array<AxisCallback, 3>, NUM_AXISES> axis_mapping;
std::array<ButtonCallback, NUM_BUTTONS> button_mapping;
std::array<std::array<ButtonCallback, 2>, NUM_AXISES> axis_button_mapping;
std::array<AxisCallback, NUM_BUTTONS> button_axis_mapping;
};
using ControllerDataArray = std::array<ControllerData, NUM_CONTROLLERS>;
ControllerDataArray m_controllers;
std::mutex m_event_intercept_mutex;
Hook::Callback m_event_intercept_callback;
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,9 @@
#pragma once
#include "android_settings_interface.h"
#include "common/byte_stream.h"
#include "common/event.h"
#include "common/progress_callback.h"
#include "core/host_display.h"
#include "frontend-common/common_host_interface.h"
#include <array>
#include <atomic>
@@ -21,11 +24,14 @@ public:
AndroidHostInterface(jobject java_object, jobject context_object, std::string user_directory);
~AndroidHostInterface() override;
ALWAYS_INLINE ANativeWindow* GetSurface() const { return m_surface; }
bool Initialize() override;
void Shutdown() override;
const char* GetFrontendName() const override;
void RequestExit() override;
void RunLater(std::function<void()> func) override;
void ReportError(const char* message) override;
void ReportMessage(const char* message) override;
@@ -34,44 +40,63 @@ public:
bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false) override;
int GetIntSettingValue(const char* section, const char* key, int default_value = 0) override;
float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f) override;
std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) override;
bool GetMainDisplayRefreshRate(float* refresh_rate) override;
bool IsEmulationThreadRunning() const { return m_emulation_thread.joinable(); }
bool IsEmulationThreadRunning() const { return m_emulation_thread_running.load(); }
bool IsEmulationThreadPaused() const;
bool StartEmulationThread(jobject emulation_activity, ANativeWindow* initial_surface,
SystemBootParameters boot_params, bool resume_state);
bool IsOnEmulationThread() const;
void RunOnEmulationThread(std::function<void()> function, bool blocking = false);
void PauseEmulationThread(bool paused);
void StopEmulationThread();
void StopEmulationThreadLoop();
void EmulationThreadEntryPoint(JNIEnv* env, jobject emulation_activity, SystemBootParameters boot_params,
bool resume_state);
void SurfaceChanged(ANativeWindow* surface, int format, int width, int height);
void SetDisplayAlignment(HostDisplay::Alignment alignment);
void SetControllerType(u32 index, std::string_view type_name);
void SetControllerButtonState(u32 index, s32 button_code, bool pressed);
void SetControllerAxisState(u32 index, s32 button_code, float value);
void HandleControllerButtonEvent(u32 controller_index, u32 button_index, bool pressed);
void HandleControllerAxisEvent(u32 controller_index, u32 axis_index, float value);
void SetFastForwardEnabled(bool enabled);
void RefreshGameList(bool invalidate_cache, bool invalidate_database);
void ApplySettings(bool display_osd_messages);
void RefreshGameList(bool invalidate_cache, bool invalidate_database, ProgressCallback* progress_callback);
void ApplySettings(bool display_osd_messages) override;
bool ImportPatchCodesFromString(const std::string& str);
jobjectArray GetInputProfileNames(JNIEnv* env) const;
bool ApplyInputProfile(const char* profile_name);
bool SaveInputProfile(const char* profile_name);
protected:
void SetUserDirectory() override;
void LoadSettings() override;
void UpdateInputMap() override;
void RegisterHotkeys() override;
bool AcquireHostDisplay() override;
void ReleaseHostDisplay() override;
std::unique_ptr<AudioStream> CreateAudioStream(AudioBackend backend) override;
void UpdateControllerInterface() override;
void OnSystemPaused(bool paused) override;
void OnSystemDestroyed() override;
void OnRunningGameChanged() override;
private:
void EmulationThreadEntryPoint(jobject emulation_activity, ANativeWindow* initial_surface,
SystemBootParameters boot_params, bool resume_state);
void EmulationThreadLoop();
void EmulationThreadLoop(JNIEnv* env);
void CreateImGuiContext();
void DestroyImGuiContext();
void LoadAndConvertSettings();
void SetVibration(bool enabled);
void UpdateVibration();
jobject m_java_object = {};
jobject m_emulation_activity_object = {};
@@ -82,13 +107,68 @@ private:
std::mutex m_mutex;
std::condition_variable m_sleep_cv;
std::deque<std::function<void()>> m_callback_queue;
std::atomic_bool m_callbacks_outstanding{false};
std::thread m_emulation_thread;
std::atomic_bool m_emulation_thread_stop_request{false};
std::atomic_bool m_emulation_thread_running{false};
std::thread::id m_emulation_thread_id{};
HostDisplay::Alignment m_display_alignment = HostDisplay::Alignment::Center;
u64 m_last_vibration_update_time = 0;
bool m_last_vibration_state = false;
bool m_vibration_enabled = false;
};
namespace AndroidHelpers {
JNIEnv* GetJNIEnv();
AndroidHostInterface* GetNativeClass(JNIEnv* env, jobject obj);
std::string JStringToString(JNIEnv* env, jstring str);
std::unique_ptr<GrowableMemoryByteStream> ReadInputStreamToMemory(JNIEnv* env, jobject obj, u32 chunk_size = 65536);
jclass GetStringClass();
} // namespace AndroidHelpers
template<typename T>
class LocalRefHolder
{
public:
LocalRefHolder() : m_env(nullptr), m_object(nullptr) {}
LocalRefHolder(JNIEnv* env, T object) : m_env(env), m_object(object) {}
LocalRefHolder(const LocalRefHolder<T>&) = delete;
LocalRefHolder(LocalRefHolder&& move) : m_env(move.m_env), m_object(move.m_object)
{
move.m_env = nullptr;
move.m_object = {};
}
~LocalRefHolder()
{
if (m_object)
m_env->DeleteLocalRef(m_object);
}
operator T() const { return m_object; }
T operator*() const { return m_object; }
LocalRefHolder& operator=(const LocalRefHolder&) = delete;
LocalRefHolder& operator=(LocalRefHolder&& move)
{
if (m_object)
m_env->DeleteLocalRef(m_object);
m_env = move.m_env;
m_object = move.m_object;
move.m_env = nullptr;
move.m_object = {};
return *this;
}
T Get() const { return m_object; }
private:
JNIEnv* m_env;
T m_object;
};

View File

@@ -0,0 +1,113 @@
#include "android_progress_callback.h"
#include "android_host_interface.h"
#include "common/log.h"
#include "common/assert.h"
Log_SetChannel(AndroidProgressCallback);
AndroidProgressCallback::AndroidProgressCallback(JNIEnv* env, jobject java_object)
: m_java_object(java_object)
{
jclass cls = env->GetObjectClass(java_object);
m_set_title_method = env->GetMethodID(cls, "setTitle", "(Ljava/lang/String;)V");
m_set_status_text_method = env->GetMethodID(cls, "setStatusText", "(Ljava/lang/String;)V");
m_set_progress_range_method = env->GetMethodID(cls, "setProgressRange", "(I)V");
m_set_progress_value_method = env->GetMethodID(cls, "setProgressValue", "(I)V");
m_modal_error_method = env->GetMethodID(cls, "modalError", "(Ljava/lang/String;)V");
m_modal_information_method = env->GetMethodID(cls, "modalInformation", "(Ljava/lang/String;)V");
m_modal_confirmation_method = env->GetMethodID(cls, "modalConfirmation", "(Ljava/lang/String;)Z");
Assert(m_set_status_text_method && m_set_progress_range_method && m_set_progress_value_method && m_modal_error_method && m_modal_information_method && m_modal_confirmation_method);
}
AndroidProgressCallback::~AndroidProgressCallback() = default;
bool AndroidProgressCallback::IsCancelled() const
{
return false;
}
void AndroidProgressCallback::SetCancellable(bool cancellable)
{
if (m_cancellable == cancellable)
return;
BaseProgressCallback::SetCancellable(cancellable);
}
void AndroidProgressCallback::SetTitle(const char* title)
{
Assert(title);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> text_jstr(env, env->NewStringUTF(title));
env->CallVoidMethod(m_java_object, m_set_title_method, text_jstr.Get());
}
void AndroidProgressCallback::SetStatusText(const char* text)
{
Assert(text);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> text_jstr(env, env->NewStringUTF(text));
env->CallVoidMethod(m_java_object, m_set_status_text_method, text_jstr.Get());
}
void AndroidProgressCallback::SetProgressRange(u32 range)
{
BaseProgressCallback::SetProgressRange(range);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
env->CallVoidMethod(m_java_object, m_set_progress_range_method, static_cast<jint>(range));
}
void AndroidProgressCallback::SetProgressValue(u32 value)
{
const u32 old_value = m_progress_value;
BaseProgressCallback::SetProgressValue(value);
if (old_value == m_progress_value)
return;
JNIEnv* env = AndroidHelpers::GetJNIEnv();
env->CallVoidMethod(m_java_object, m_set_progress_value_method, static_cast<jint>(value));
}
void AndroidProgressCallback::DisplayError(const char* message)
{
Log_ErrorPrintf("%s", message);
}
void AndroidProgressCallback::DisplayWarning(const char* message)
{
Log_WarningPrintf("%s", message);
}
void AndroidProgressCallback::DisplayInformation(const char* message)
{
Log_InfoPrintf("%s", message);
}
void AndroidProgressCallback::DisplayDebugMessage(const char* message)
{
Log_DevPrintf("%s", message);
}
void AndroidProgressCallback::ModalError(const char* message)
{
Assert(message);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> message_jstr(env, env->NewStringUTF(message));
env->CallVoidMethod(m_java_object, m_modal_error_method, message_jstr.Get());
}
bool AndroidProgressCallback::ModalConfirmation(const char* message)
{
Assert(message);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> message_jstr(env, env->NewStringUTF(message));
return env->CallBooleanMethod(m_java_object, m_modal_confirmation_method, message_jstr.Get());
}
void AndroidProgressCallback::ModalInformation(const char* message)
{
Assert(message);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> message_jstr(env, env->NewStringUTF(message));
env->CallVoidMethod(m_java_object, m_modal_information_method, message_jstr.Get());
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include "common/progress_callback.h"
#include <jni.h>
class AndroidProgressCallback final : public BaseProgressCallback
{
public:
AndroidProgressCallback(JNIEnv* env, jobject java_object);
~AndroidProgressCallback();
bool IsCancelled() const override;
void SetCancellable(bool cancellable) override;
void SetTitle(const char* title) override;
void SetStatusText(const char* text) override;
void SetProgressRange(u32 range) override;
void SetProgressValue(u32 value) override;
void DisplayError(const char* message) override;
void DisplayWarning(const char* message) override;
void DisplayInformation(const char* message) override;
void DisplayDebugMessage(const char* message) override;
void ModalError(const char* message) override;
bool ModalConfirmation(const char* message) override;
void ModalInformation(const char* message) override;
private:
jobject m_java_object;
jmethodID m_set_title_method;
jmethodID m_set_status_text_method;
jmethodID m_set_progress_range_method;
jmethodID m_set_progress_value_method;
jmethodID m_modal_error_method;
jmethodID m_modal_confirmation_method;
jmethodID m_modal_information_method;
};

View File

@@ -16,33 +16,76 @@ AndroidSettingsInterface::AndroidSettingsInterface(jobject java_context)
{
JNIEnv* env = AndroidHelpers::GetJNIEnv();
jclass c_preference_manager = env->FindClass("androidx/preference/PreferenceManager");
jclass c_preference_editor = env->FindClass("android/content/SharedPreferences$Editor");
jclass c_set = env->FindClass("java/util/Set");
jclass c_helper = env->FindClass("com/github/stenzek/duckstation/PreferenceHelpers");
jmethodID m_get_default_shared_preferences =
env->GetStaticMethodID(c_preference_manager, "getDefaultSharedPreferences",
"(Landroid/content/Context;)Landroid/content/SharedPreferences;");
Assert(c_preference_manager && c_set && m_get_default_shared_preferences);
Assert(c_preference_manager && c_preference_editor && c_set && c_helper && m_get_default_shared_preferences);
m_set_class = reinterpret_cast<jclass>(env->NewGlobalRef(c_set));
m_shared_preferences_editor_class = reinterpret_cast<jclass>(env->NewGlobalRef(c_preference_editor));
m_helper_class = reinterpret_cast<jclass>(env->NewGlobalRef(c_helper));
Assert(m_set_class && m_shared_preferences_editor_class && m_helper_class);
m_java_shared_preferences =
env->DeleteLocalRef(c_set);
env->DeleteLocalRef(c_preference_editor);
env->DeleteLocalRef(c_helper);
jobject shared_preferences =
env->CallStaticObjectMethod(c_preference_manager, m_get_default_shared_preferences, java_context);
Assert(shared_preferences);
m_java_shared_preferences = env->NewGlobalRef(shared_preferences);
Assert(m_java_shared_preferences);
m_java_shared_preferences = env->NewGlobalRef(m_java_shared_preferences);
jclass c_shared_preferences = env->GetObjectClass(m_java_shared_preferences);
env->DeleteLocalRef(c_preference_manager);
env->DeleteLocalRef(shared_preferences);
m_get_boolean = env->GetMethodID(c_shared_preferences, "getBoolean", "(Ljava/lang/String;Z)Z");
m_get_int = env->GetMethodID(c_shared_preferences, "getInt", "(Ljava/lang/String;I)I");
m_get_float = env->GetMethodID(c_shared_preferences, "getFloat", "(Ljava/lang/String;F)F");
m_get_string =
env->GetMethodID(c_shared_preferences, "getString", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
jclass c_shared_preferences = env->GetObjectClass(m_java_shared_preferences);
m_shared_preferences_class = reinterpret_cast<jclass>(env->NewGlobalRef(c_shared_preferences));
Assert(m_shared_preferences_class);
env->DeleteLocalRef(c_shared_preferences);
m_get_boolean = env->GetMethodID(m_shared_preferences_class, "getBoolean", "(Ljava/lang/String;Z)Z");
m_get_int = env->GetMethodID(m_shared_preferences_class, "getInt", "(Ljava/lang/String;I)I");
m_get_float = env->GetMethodID(m_shared_preferences_class, "getFloat", "(Ljava/lang/String;F)F");
m_get_string = env->GetMethodID(m_shared_preferences_class, "getString",
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
m_get_string_set =
env->GetMethodID(c_shared_preferences, "getStringSet", "(Ljava/lang/String;Ljava/util/Set;)Ljava/util/Set;");
m_set_to_array = env->GetMethodID(c_set, "toArray", "()[Ljava/lang/Object;");
env->GetMethodID(m_shared_preferences_class, "getStringSet", "(Ljava/lang/String;Ljava/util/Set;)Ljava/util/Set;");
m_set_to_array = env->GetMethodID(m_set_class, "toArray", "()[Ljava/lang/Object;");
Assert(m_get_boolean && m_get_int && m_get_float && m_get_string && m_get_string_set && m_set_to_array);
m_edit = env->GetMethodID(m_shared_preferences_class, "edit", "()Landroid/content/SharedPreferences$Editor;");
m_edit_set_string = env->GetMethodID(m_shared_preferences_editor_class, "putString", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/SharedPreferences$Editor;");
m_edit_commit = env->GetMethodID(m_shared_preferences_editor_class, "commit", "()Z");
m_edit_remove = env->GetMethodID(m_shared_preferences_editor_class, "remove", "(Ljava/lang/String;)Landroid/content/SharedPreferences$Editor;");
Assert(m_edit && m_edit_set_string && m_edit_commit && m_edit_remove);
m_helper_clear_section = env->GetStaticMethodID(m_helper_class, "clearSection", "(Landroid/content/SharedPreferences;Ljava/lang/String;)V");
m_helper_add_to_string_list = env->GetStaticMethodID(m_helper_class, "addToStringList", "(Landroid/content/SharedPreferences;Ljava/lang/String;Ljava/lang/String;)Z");
m_helper_remove_from_string_list = env->GetStaticMethodID(m_helper_class, "removeFromStringList", "(Landroid/content/SharedPreferences;Ljava/lang/String;Ljava/lang/String;)Z");
m_helper_set_string_list = env->GetStaticMethodID(m_helper_class, "setStringList", "(Landroid/content/SharedPreferences;Ljava/lang/String;[Ljava/lang/String;)V");
Assert(m_helper_clear_section && m_helper_add_to_string_list && m_helper_remove_from_string_list && m_helper_set_string_list);
}
AndroidSettingsInterface::~AndroidSettingsInterface()
{
JNIEnv* env = AndroidHelpers::GetJNIEnv();
if (m_java_shared_preferences)
AndroidHelpers::GetJNIEnv()->DeleteGlobalRef(m_java_shared_preferences);
env->DeleteGlobalRef(m_java_shared_preferences);
if (m_shared_preferences_editor_class)
env->DeleteGlobalRef(m_shared_preferences_editor_class);
if (m_shared_preferences_class)
env->DeleteGlobalRef(m_shared_preferences_class);
if (m_set_class)
env->DeleteGlobalRef(m_set_class);
if (m_helper_class)
env->DeleteGlobalRef(m_helper_class);
}
bool AndroidSettingsInterface::Save()
{
return true;
}
void AndroidSettingsInterface::Clear()
@@ -52,25 +95,28 @@ void AndroidSettingsInterface::Clear()
int AndroidSettingsInterface::GetIntValue(const char* section, const char* key, int default_value /*= 0*/)
{
JNIEnv* env = AndroidHelpers::GetJNIEnv();
// Some of these settings are string lists...
jstring string_object = reinterpret_cast<jstring>(
env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)),
env->NewStringUTF(TinyString::FromFormat("%d", default_value))));
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> default_value_string(env, env->NewStringUTF(TinyString::FromFormat("%d", default_value)));
LocalRefHolder<jstring> string_object(
env, reinterpret_cast<jstring>(env->CallObjectMethod(m_java_shared_preferences, m_get_string, key_string.Get(),
default_value_string.Get())));
if (env->ExceptionCheck())
{
env->ExceptionClear();
// it might actually be an int (e.g. seek bar preference)
const int int_value = static_cast<int>(env->CallIntMethod(m_java_shared_preferences, m_get_int,
env->NewStringUTF(GetSettingKey(section, key)), default_value));
const int int_value =
static_cast<int>(env->CallIntMethod(m_java_shared_preferences, m_get_int, key_string.Get(), default_value));
if (env->ExceptionCheck())
{
env->ExceptionClear();
Log_DevPrintf("GetIntValue(%s, %s) -> %d (exception)", section, key, default_value);
return default_value;
}
Log_DevPrintf("GetIntValue(%s, %s) -> %d (int)", section, key, int_value);
return int_value;
}
@@ -79,6 +125,7 @@ int AndroidSettingsInterface::GetIntValue(const char* section, const char* key,
const char* data = env->GetStringUTFChars(string_object, nullptr);
Assert(data != nullptr);
Log_DevPrintf("GetIntValue(%s, %s) -> %s", section, key, data);
std::optional<int> value = StringUtil::FromChars<int>(data);
env->ReleaseStringUTFChars(string_object, data);
@@ -88,77 +135,213 @@ int AndroidSettingsInterface::GetIntValue(const char* section, const char* key,
float AndroidSettingsInterface::GetFloatValue(const char* section, const char* key, float default_value /*= 0.0f*/)
{
JNIEnv* env = AndroidHelpers::GetJNIEnv();
#if 0
return static_cast<float>(env->CallFloatMethod(m_java_shared_preferences, m_get_float,
env->NewStringUTF(GetSettingKey(section, key)), default_value));
#else
// Some of these settings are string lists...
jstring string_object = reinterpret_cast<jstring>(
env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)),
env->NewStringUTF(TinyString::FromFormat("%f", default_value))));
if (!string_object)
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> default_value_string(env, env->NewStringUTF(TinyString::FromFormat("%f", default_value)));
LocalRefHolder<jstring> string_object(
env, reinterpret_cast<jstring>(env->CallObjectMethod(m_java_shared_preferences, m_get_string, key_string.Get(),
default_value_string.Get())));
if (env->ExceptionCheck())
{
env->ExceptionClear();
Log_DevPrintf("GetFloatValue(%s, %s) -> %f (exception)", section, key, default_value);
return default_value;
}
if (!string_object)
{
Log_DevPrintf("GetFloatValue(%s, %s) -> %f (null)", section, key, default_value);
return default_value;
}
const char* data = env->GetStringUTFChars(string_object, nullptr);
Assert(data != nullptr);
Log_DevPrintf("GetFloatValue(%s, %s) -> %s", section, key, data);
std::optional<float> value = StringUtil::FromChars<float>(data);
env->ReleaseStringUTFChars(string_object, data);
return value.value_or(default_value);
#endif
}
bool AndroidSettingsInterface::GetBoolValue(const char* section, const char* key, bool default_value /*= false*/)
{
JNIEnv* env = AndroidHelpers::GetJNIEnv();
return static_cast<bool>(env->CallBooleanMethod(m_java_shared_preferences, m_get_boolean,
env->NewStringUTF(GetSettingKey(section, key)), default_value));
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
jboolean bool_value = static_cast<bool>(
env->CallBooleanMethod(m_java_shared_preferences, m_get_boolean, key_string.Get(), default_value));
if (env->ExceptionCheck())
{
Log_DevPrintf("GetBoolValue(%s, %s) -> %u (exception)", section, key, static_cast<unsigned>(default_value));
env->ExceptionClear();
return default_value;
}
Log_DevPrintf("GetBoolValue(%s, %s) -> %u", section, key, static_cast<unsigned>(bool_value));
return bool_value;
}
std::string AndroidSettingsInterface::GetStringValue(const char* section, const char* key,
const char* default_value /*= ""*/)
{
JNIEnv* env = AndroidHelpers::GetJNIEnv();
jobject string_object =
env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)),
env->NewStringUTF(default_value));
return AndroidHelpers::JStringToString(env, reinterpret_cast<jstring>(string_object));
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> default_value_string(env, env->NewStringUTF(default_value));
LocalRefHolder<jstring> string_object(
env, reinterpret_cast<jstring>(env->CallObjectMethod(m_java_shared_preferences, m_get_string, key_string.Get(),
default_value_string.Get())));
if (env->ExceptionCheck())
{
env->ExceptionClear();
Log_DevPrintf("GetStringValue(%s, %s) -> %s (exception)", section, key, default_value);
return default_value;
}
if (!string_object)
{
Log_DevPrintf("GetStringValue(%s, %s) -> %s (null)", section, key, default_value);
return default_value;
}
const std::string ret(AndroidHelpers::JStringToString(env, string_object));
Log_DevPrintf("GetStringValue(%s, %s) -> %s", section, key, ret.c_str());
return ret;
}
jobject AndroidSettingsInterface::GetPreferencesEditor(JNIEnv* env)
{
return env->CallObjectMethod(m_java_shared_preferences, m_edit);
}
void AndroidSettingsInterface::CheckForException(JNIEnv *env, const char *task)
{
if (!env->ExceptionCheck())
return;
Log_ErrorPrintf("JNI exception during %s", task);
env->ExceptionClear();
}
void AndroidSettingsInterface::SetIntValue(const char* section, const char* key, int value)
{
Log_ErrorPrintf("SetIntValue(\"%s\", \"%s\", %d) not implemented", section, key, value);
Log_DevPrintf("SetIntValue(\"%s\", \"%s\", %d)", section, key, value);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jobject> editor(env, GetPreferencesEditor(env));
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> str_value(env, env->NewStringUTF(TinyString::FromFormat("%d", value)));
LocalRefHolder<jobject> dummy(env, env->CallObjectMethod(editor, m_edit_set_string, key_string.Get(), str_value.Get()));
env->CallBooleanMethod(editor, m_edit_commit);
CheckForException(env, "SetIntValue");
}
void AndroidSettingsInterface::SetFloatValue(const char* section, const char* key, float value)
{
Log_ErrorPrintf("SetFloatValue(\"%s\", \"%s\", %f) not implemented", section, key, value);
Log_DevPrintf("SetFloatValue(\"%s\", \"%s\", %f)", section, key, value);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jobject> editor(env, GetPreferencesEditor(env));
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> str_value(env, env->NewStringUTF(TinyString::FromFormat("%f", value)));
LocalRefHolder<jobject> dummy(env, env->CallObjectMethod(editor, m_edit_set_string, key_string.Get(), str_value.Get()));
env->CallBooleanMethod(editor, m_edit_commit);
CheckForException(env, "SetFloatValue");
}
void AndroidSettingsInterface::SetBoolValue(const char* section, const char* key, bool value)
{
Log_ErrorPrintf("SetBoolValue(\"%s\", \"%s\", %u) not implemented", section, key, static_cast<unsigned>(value));
Log_DevPrintf("SetBoolValue(\"%s\", \"%s\", %u)", section, key, static_cast<unsigned>(value));
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jobject> editor(env, GetPreferencesEditor(env));
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> str_value(env, env->NewStringUTF(value ? "true" : "false"));
LocalRefHolder<jobject> dummy(env, env->CallObjectMethod(editor, m_edit_set_string, key_string.Get(), str_value.Get()));
env->CallBooleanMethod(editor, m_edit_commit);
CheckForException(env, "SetBoolValue");
}
void AndroidSettingsInterface::SetStringValue(const char* section, const char* key, const char* value)
{
Log_ErrorPrintf("SetStringValue(\"%s\", \"%s\", \"%s\") not implemented", section, key, value);
Log_DevPrintf("SetStringValue(\"%s\", \"%s\", \"%s\")", section, key, value);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jobject> editor(env, GetPreferencesEditor(env));
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> str_value(env, env->NewStringUTF(value));
LocalRefHolder<jobject> dummy(env, env->CallObjectMethod(editor, m_edit_set_string, key_string.Get(), str_value.Get()));
env->CallBooleanMethod(editor, m_edit_commit);
CheckForException(env, "SetStringValue");
}
void AndroidSettingsInterface::DeleteValue(const char* section, const char* key)
{
Log_ErrorPrintf("DeleteValue(\"%s\", \"%s\") not implemented", section, key);
Log_DevPrintf("DeleteValue(\"%s\", \"%s\")", section, key);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jobject> editor(env, GetPreferencesEditor(env));
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jobject> dummy(env, env->CallObjectMethod(editor, m_edit_remove, key_string.Get()));
env->CallBooleanMethod(editor, m_edit_commit);
CheckForException(env, "DeleteValue");
}
void AndroidSettingsInterface::ClearSection(const char* section)
{
Log_DevPrintf("ClearSection(\"%s\")", section);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> str_section(env, env->NewStringUTF(section));
env->CallStaticVoidMethod(m_helper_class, m_helper_clear_section, m_java_shared_preferences, str_section.Get());
CheckForException(env, "ClearSection");
}
std::vector<std::string> AndroidSettingsInterface::GetStringList(const char* section, const char* key)
{
JNIEnv* env = AndroidHelpers::GetJNIEnv();
jobject values_set = env->CallObjectMethod(m_java_shared_preferences, m_get_string_set,
env->NewStringUTF(GetSettingKey(section, key)), nullptr);
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jobject> values_set(
env, env->CallObjectMethod(m_java_shared_preferences, m_get_string_set, key_string.Get(), nullptr));
if (env->ExceptionCheck())
{
env->ExceptionClear();
// this might just be a string, not a string set
LocalRefHolder<jstring> string_object(
env, reinterpret_cast<jstring>(env->CallObjectMethod(m_java_shared_preferences, m_get_string, key_string.Get(), nullptr)));
if (!env->ExceptionCheck()) {
std::vector<std::string> ret;
if (string_object)
ret.push_back(AndroidHelpers::JStringToString(env, string_object));
return ret;
}
env->ExceptionClear();
return {};
}
if (!values_set)
return {};
jobjectArray values_array = reinterpret_cast<jobjectArray>(env->CallObjectMethod(values_set, m_set_to_array));
LocalRefHolder<jobjectArray> values_array(
env, reinterpret_cast<jobjectArray>(env->CallObjectMethod(values_set, m_set_to_array)));
if (env->ExceptionCheck())
{
env->ExceptionClear();
return {};
}
if (!values_array)
return {};
@@ -166,8 +349,11 @@ std::vector<std::string> AndroidSettingsInterface::GetStringList(const char* sec
std::vector<std::string> values;
values.reserve(size);
for (jsize i = 0; i < size; i++)
values.push_back(
AndroidHelpers::JStringToString(env, reinterpret_cast<jstring>(env->GetObjectArrayElement(values_array, i))));
{
jstring str = reinterpret_cast<jstring>(env->GetObjectArrayElement(values_array, i));
values.push_back(AndroidHelpers::JStringToString(env, str));
env->DeleteLocalRef(str);
}
return values;
}
@@ -175,17 +361,47 @@ std::vector<std::string> AndroidSettingsInterface::GetStringList(const char* sec
void AndroidSettingsInterface::SetStringList(const char* section, const char* key,
const std::vector<std::string>& items)
{
Log_ErrorPrintf("SetStringList(\"%s\", \"%s\") not implemented", section, key);
Log_DevPrintf("SetStringList(\"%s\", \"%s\")", section, key);
if (items.empty())
{
DeleteValue(section, key);
return;
}
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jobjectArray> items_array(env, env->NewObjectArray(static_cast<jsize>(items.size()), AndroidHelpers::GetStringClass(), nullptr));
for (size_t i = 0; i < items.size(); i++)
{
LocalRefHolder<jstring> item_jstr(env, env->NewStringUTF(items[i].c_str()));
env->SetObjectArrayElement(items_array, static_cast<jsize>(i), item_jstr);
}
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
env->CallStaticVoidMethod(m_helper_class, m_helper_set_string_list, m_java_shared_preferences, key_string.Get(), items_array.Get());
CheckForException(env, "SetStringList");
}
bool AndroidSettingsInterface::RemoveFromStringList(const char* section, const char* key, const char* item)
{
Log_ErrorPrintf("RemoveFromStringList(\"%s\", \"%s\", \"%s\") not implemented", section, key, item);
return false;
Log_DevPrintf("RemoveFromStringList(\"%s\", \"%s\", \"%s\")", section, key, item);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> item_string(env, env->NewStringUTF(item));
const bool result = env->CallStaticBooleanMethod(m_helper_class, m_helper_remove_from_string_list, m_java_shared_preferences, key_string.Get(), item_string.Get());
CheckForException(env, "RemoveFromStringList");
return result;
}
bool AndroidSettingsInterface::AddToStringList(const char* section, const char* key, const char* item)
{
Log_ErrorPrintf("AddToStringList(\"%s\", \"%s\", \"%s\") not implemented", section, key, item);
return false;
Log_DevPrintf("AddToStringList(\"%s\", \"%s\", \"%s\")", section, key, item);
JNIEnv* env = AndroidHelpers::GetJNIEnv();
LocalRefHolder<jstring> key_string(env, env->NewStringUTF(GetSettingKey(section, key)));
LocalRefHolder<jstring> item_string(env, env->NewStringUTF(item));
const bool result = env->CallStaticBooleanMethod(m_helper_class, m_helper_add_to_string_list, m_java_shared_preferences, key_string.Get(), item_string.Get());
CheckForException(env, "AddToStringList");
return result;
}

View File

@@ -8,6 +8,7 @@ public:
AndroidSettingsInterface(jobject java_context);
~AndroidSettingsInterface();
bool Save() override;
void Clear() override;
int GetIntValue(const char* section, const char* key, int default_value = 0) override;
@@ -20,6 +21,7 @@ public:
void SetBoolValue(const char* section, const char* key, bool value) override;
void SetStringValue(const char* section, const char* key, const char* value) override;
void DeleteValue(const char* section, const char* key) override;
void ClearSection(const char* section) override;
std::vector<std::string> GetStringList(const char* section, const char* key) override;
void SetStringList(const char* section, const char* key, const std::vector<std::string>& items) override;
@@ -27,11 +29,26 @@ public:
bool AddToStringList(const char* section, const char* key, const char* item) override;
private:
jobject GetPreferencesEditor(JNIEnv* env);
void CheckForException(JNIEnv* env, const char* task);
jclass m_set_class{};
jclass m_shared_preferences_class{};
jclass m_shared_preferences_editor_class{};
jclass m_helper_class{};
jobject m_java_shared_preferences{};
jmethodID m_get_boolean{};
jmethodID m_get_int{};
jmethodID m_get_float{};
jmethodID m_get_string{};
jmethodID m_get_string_set{};
jmethodID m_edit{};
jmethodID m_edit_set_string{};
jmethodID m_edit_commit{};
jmethodID m_edit_remove{};
jmethodID m_set_to_array{};
jmethodID m_helper_clear_section{};
jmethodID m_helper_add_to_string_list{};
jmethodID m_helper_remove_from_string_list{};
jmethodID m_helper_set_string_list{};
};

View File

@@ -3,6 +3,7 @@
package="com.github.stenzek.duckstation">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
@@ -13,13 +14,18 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".GameDirectoriesActivity"
android:label="@string/title_activity_game_directories"
android:theme="@style/AppTheme.NoActionBar"></activity>
<activity
android:name=".EmulationActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:immersive="true"
android:label="@string/title_activity_emulation"
android:parentActivityName=".MainActivity"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
android:immersive="true">
android:exported="true">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.github.stenzek.duckstation.MainActivity" />
@@ -33,6 +39,24 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="com.github.stenzek.duckstation.MainActivity" />
</activity>
<activity
android:name=".ControllerMappingActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/title_activity_settings"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.github.stenzek.duckstation.MainActivity" />
</activity>
<activity
android:name=".GamePropertiesActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/activity_game_properties"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.github.stenzek.duckstation.MainActivity" />
</activity>
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"

View File

@@ -1,12 +1,17 @@
package com.github.stenzek.duckstation;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.os.Environment;
import android.os.Process;
import android.util.Log;
import android.view.Surface;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
public class AndroidHostInterface {
public final static int DISPLAY_ALIGNMENT_TOP_OR_LEFT = 0;
@@ -16,8 +21,6 @@ public class AndroidHostInterface {
private long mNativePointer;
private Context mContext;
static public native AndroidHostInterface create(Context context, String userDirectory);
public AndroidHostInterface(Context context) {
this.mContext = context;
}
@@ -30,15 +33,35 @@ public class AndroidHostInterface {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
public InputStream openAssetStream(String path) {
try {
return mContext.getAssets().open(path, AssetManager.ACCESS_STREAMING);
} catch (IOException e) {
return null;
}
}
public void setContext(Context context) {
mContext = context;
}
static public native String getScmVersion();
static public native String getFullScmVersion();
static public native boolean setThreadAffinity(int[] cpus);
static public native AndroidHostInterface create(Context context, String userDirectory);
public native boolean isEmulationThreadRunning();
public native boolean startEmulationThread(EmulationActivity emulationActivity, Surface surface, String filename, boolean resumeState, String state_filename);
public native boolean runEmulationThread(EmulationActivity emulationActivity, String filename, boolean resumeState, String state_filename);
public native boolean isEmulationThreadPaused();
public native void pauseEmulationThread(boolean paused);
public native void stopEmulationThread();
public native void stopEmulationThreadLoop();
public native boolean hasSurface();
@@ -55,10 +78,32 @@ public class AndroidHostInterface {
public static native int getControllerAxisCode(String controllerType, String axisName);
public native void refreshGameList(boolean invalidateCache, boolean invalidateDatabase);
public static native String[] getControllerButtonNames(String controllerType);
public static native String[] getControllerAxisNames(String controllerType);
public native void handleControllerButtonEvent(int controllerIndex, int buttonIndex, boolean pressed);
public native void handleControllerAxisEvent(int controllerIndex, int axisIndex, float value);
public native String[] getInputProfileNames();
public native boolean loadInputProfile(String name);
public native boolean saveInputProfile(String name);
public native HotkeyInfo[] getHotkeyInfoList();
public native void refreshGameList(boolean invalidateCache, boolean invalidateDatabase, AndroidProgressCallback progressCallback);
public native GameListEntry[] getGameListEntries();
public native GameListEntry getGameListEntry(String path);
public native String getGameSettingValue(String path, String key);
public native void setGameSettingValue(String path, String key, String value);
public native void resetSystem();
public native void loadState(boolean global, int slot);
@@ -71,14 +116,32 @@ public class AndroidHostInterface {
public native void setDisplayAlignment(int alignment);
public native CheatCode[] getCheatList();
public native void setCheatEnabled(int index, boolean enabled);
public native PatchCode[] getPatchCodeList();
public native void setPatchCodeEnabled(int index, boolean enabled);
public native boolean importPatchCodesFromString(String str);
public native void addOSDMessage(String message, float duration);
public native boolean hasAnyBIOSImages();
public native String importBIOSImage(byte[] data);
public native boolean isFastForwardEnabled();
public native void setFastForwardEnabled(boolean enabled);
public native String[] getMediaPlaylistPaths();
public native int getMediaPlaylistIndex();
public native boolean setMediaPlaylistIndex(int index);
public native boolean setMediaFilename(String filename);
public native SaveStateInfo[] getSaveStateInfo(boolean includeEmpty);
static {
System.loadLibrary("duckstation-native");
}
@@ -104,4 +167,8 @@ public class AndroidHostInterface {
static public AndroidHostInterface getInstance() {
return mInstance;
}
static public boolean hasInstanceAndEmulationThreadIsRunning() {
return hasInstance() && getInstance().isEmulationThreadRunning();
}
}

View File

@@ -0,0 +1,139 @@
package com.github.stenzek.duckstation;
import android.app.Activity;
import android.app.ProgressDialog;
import androidx.appcompat.app.AlertDialog;
public class AndroidProgressCallback {
private Activity mContext;
private ProgressDialog mDialog;
public AndroidProgressCallback(Activity context) {
mContext = context;
mDialog = new ProgressDialog(context);
mDialog.setMessage(context.getString(R.string.android_progress_callback_please_wait));
mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mDialog.setIndeterminate(false);
mDialog.setMax(100);
mDialog.setProgress(0);
mDialog.show();
}
public void dismiss() {
mDialog.dismiss();
}
public void setTitle(String text) {
mContext.runOnUiThread(() -> {
mDialog.setTitle(text);
});
}
public void setStatusText(String text) {
mContext.runOnUiThread(() -> {
mDialog.setMessage(text);
});
}
public void setProgressRange(int range) {
mContext.runOnUiThread(() -> {
mDialog.setMax(range);
});
}
public void setProgressValue(int value) {
mContext.runOnUiThread(() -> {
mDialog.setProgress(value);
});
}
public void modalError(String message) {
Object lock = new Object();
mContext.runOnUiThread(() -> {
new AlertDialog.Builder(mContext)
.setTitle("Error")
.setMessage(message)
.setPositiveButton(mContext.getString(R.string.android_progress_callback_ok), (dialog, button) -> {
dialog.dismiss();
})
.setOnDismissListener((dialogInterface) -> {
synchronized (lock) {
lock.notify();
}
})
.create()
.show();
});
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
}
}
}
public void modalInformation(String message) {
Object lock = new Object();
mContext.runOnUiThread(() -> {
new AlertDialog.Builder(mContext)
.setTitle(mContext.getString(R.string.android_progress_callback_information))
.setMessage(message)
.setPositiveButton(mContext.getString(R.string.android_progress_callback_ok), (dialog, button) -> {
dialog.dismiss();
})
.setOnDismissListener((dialogInterface) -> {
synchronized (lock) {
lock.notify();
}
})
.create()
.show();
});
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
}
}
}
private class ConfirmationResult {
public boolean result = false;
}
public boolean modalConfirmation(String message) {
ConfirmationResult result = new ConfirmationResult();
mContext.runOnUiThread(() -> {
new AlertDialog.Builder(mContext)
.setTitle(mContext.getString(R.string.android_progress_callback_confirmation))
.setMessage(message)
.setPositiveButton(mContext.getString(R.string.android_progress_callback_yes), (dialog, button) -> {
result.result = true;
dialog.dismiss();
})
.setNegativeButton(mContext.getString(R.string.android_progress_callback_no), (dialog, button) -> {
result.result = false;
dialog.dismiss();
})
.setOnDismissListener((dialogInterface) -> {
synchronized (result) {
result.notify();
}
})
.create()
.show();
});
synchronized (result) {
try {
result.wait();
} catch (InterruptedException e) {
}
}
return result.result;
}
}

View File

@@ -1,17 +0,0 @@
package com.github.stenzek.duckstation;
public class CheatCode {
private int mIndex;
private String mName;
private boolean mEnabled;
public CheatCode(int index, String name, boolean enabled) {
mIndex = index;
mName = name;
mEnabled = enabled;
}
public int getIndex() { return mIndex; }
public String getName() { return mName; }
public boolean isEnabled() { return mEnabled; }
}

View File

@@ -0,0 +1,157 @@
package com.github.stenzek.duckstation;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.ArraySet;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
import java.util.HashMap;
public class ControllerBindingDialog extends AlertDialog {
private boolean mIsAxis;
private String mSettingKey;
private String mCurrentBinding;
public ControllerBindingDialog(Context context, String buttonName, String settingKey, String currentBinding, boolean isAxis) {
super(context);
mIsAxis = isAxis;
mSettingKey = settingKey;
mCurrentBinding = currentBinding;
if (mCurrentBinding == null)
mCurrentBinding = getContext().getString(R.string.controller_binding_dialog_no_binding);
setTitle(buttonName);
updateMessage();
setButton(BUTTON_POSITIVE, context.getString(R.string.controller_binding_dialog_cancel), (dialogInterface, button) -> dismiss());
setButton(BUTTON_NEGATIVE, context.getString(R.string.controller_binding_dialog_clear), (dialogInterface, button) -> {
mCurrentBinding = null;
updateBinding();
dismiss();
});
setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (onKeyDown(keyCode, event))
return true;
return false;
}
});
}
private void updateMessage() {
setMessage(String.format(getContext().getString(R.string.controller_binding_dialog_message), mCurrentBinding));
}
private void updateBinding() {
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
if (mCurrentBinding != null) {
ArraySet<String> values = new ArraySet<>();
values.add(mCurrentBinding);
editor.putStringSet(mSettingKey, values);
} else {
try {
editor.remove(mSettingKey);
} catch (Exception e) {
}
}
editor.commit();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (mIsAxis || !EmulationSurfaceView.isDPadOrButtonEvent(event))
return super.onKeyUp(keyCode, event);
int buttonIndex = EmulationSurfaceView.getButtonIndexForKeyCode(keyCode);
if (buttonIndex < 0)
return super.onKeyUp(keyCode, event);
// TODO: Multiple controllers
final int controllerIndex = 0;
mCurrentBinding = String.format("Controller%d/Button%d", controllerIndex, buttonIndex);
updateMessage();
updateBinding();
dismiss();
return true;
}
private int mUpdatedAxisCode = -1;
private void setAxisCode(int axisCode, boolean positive) {
final int axisIndex = EmulationSurfaceView.getAxisIndexForAxisCode(axisCode);
if (mUpdatedAxisCode >= 0 || axisIndex < 0)
return;
mUpdatedAxisCode = axisCode;
final int controllerIndex = 0;
if (mIsAxis)
mCurrentBinding = String.format("Controller%d/Axis%d", controllerIndex, axisIndex);
else
mCurrentBinding = String.format("Controller%d/%cAxis%d", controllerIndex, (positive) ? '+' : '-', axisIndex);
updateBinding();
updateMessage();
dismiss();
}
final static float DETECT_THRESHOLD = 0.25f;
private HashMap<Integer, float[]> mStartingAxisValues = new HashMap<>();
private boolean doAxisDetection(MotionEvent event) {
if ((event.getSource() & (InputDevice.SOURCE_JOYSTICK | InputDevice.SOURCE_GAMEPAD | InputDevice.SOURCE_DPAD)) == 0)
return false;
final int[] axisCodes = EmulationSurfaceView.getKnownAxisCodes();
final int deviceId = event.getDeviceId();
if (!mStartingAxisValues.containsKey(deviceId)) {
final float[] axisValues = new float[axisCodes.length];
for (int axisIndex = 0; axisIndex < axisCodes.length; axisIndex++) {
final int axisCode = axisCodes[axisIndex];
// these are binary, so start at zero
if (axisCode == MotionEvent.AXIS_HAT_X || axisCode == MotionEvent.AXIS_HAT_Y)
axisValues[axisIndex] = 0.0f;
else
axisValues[axisIndex] = event.getAxisValue(axisCode);
}
mStartingAxisValues.put(deviceId, axisValues);
}
final float[] axisValues = mStartingAxisValues.get(deviceId);
for (int axisIndex = 0; axisIndex < axisCodes.length; axisIndex++) {
final float newValue = event.getAxisValue(axisCodes[axisIndex]);
if (Math.abs(newValue - axisValues[axisIndex]) >= DETECT_THRESHOLD) {
setAxisCode(axisCodes[axisIndex], newValue >= 0.0f);
break;
}
}
return true;
}
@Override
public boolean onGenericMotionEvent(@NonNull MotionEvent event) {
if (doAxisDetection(event))
return true;
return super.onGenericMotionEvent(event);
}
}

View File

@@ -0,0 +1,178 @@
package com.github.stenzek.duckstation;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceViewHolder;
import java.util.Set;
public class ControllerBindingPreference extends Preference {
private enum Type {
BUTTON,
AXIS,
HOTKEY
}
private String mBindingName;
private String mValue;
private TextView mValueView;
private Type mType = Type.BUTTON;
private static int getIconForButton(String buttonName) {
if (buttonName.equals("Up")) {
return R.drawable.ic_controller_up_button_pressed;
} else if (buttonName.equals("Right")) {
return R.drawable.ic_controller_right_button_pressed;
} else if (buttonName.equals("Down")) {
return R.drawable.ic_controller_down_button_pressed;
} else if (buttonName.equals("Left")) {
return R.drawable.ic_controller_left_button_pressed;
} else if (buttonName.equals("Triangle")) {
return R.drawable.ic_controller_triangle_button_pressed;
} else if (buttonName.equals("Circle")) {
return R.drawable.ic_controller_circle_button_pressed;
} else if (buttonName.equals("Cross")) {
return R.drawable.ic_controller_cross_button_pressed;
} else if (buttonName.equals("Square")) {
return R.drawable.ic_controller_square_button_pressed;
} else if (buttonName.equals("Start")) {
return R.drawable.ic_controller_start_button_pressed;
} else if (buttonName.equals("Select")) {
return R.drawable.ic_controller_select_button_pressed;
} else if (buttonName.equals("L1")) {
return R.drawable.ic_controller_l1_button_pressed;
} else if (buttonName.equals("L2")) {
return R.drawable.ic_controller_l2_button_pressed;
} else if (buttonName.equals("R1")) {
return R.drawable.ic_controller_r1_button_pressed;
} else if (buttonName.equals("R2")) {
return R.drawable.ic_controller_r2_button_pressed;
}
return R.drawable.ic_baseline_radio_button_unchecked_24;
}
private static int getIconForAxis(String axisName) {
return R.drawable.ic_baseline_radio_button_checked_24;
}
private static int getIconForHotkey(String hotkeyDisplayName) {
return R.drawable.ic_baseline_category_24;
}
public ControllerBindingPreference(Context context, AttributeSet attrs) {
this(context, attrs, 0);
setWidgetLayoutResource(R.layout.layout_controller_binding_preference);
setIconSpaceReserved(false);
}
public ControllerBindingPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setWidgetLayoutResource(R.layout.layout_controller_binding_preference);
setIconSpaceReserved(false);
}
public ControllerBindingPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setWidgetLayoutResource(R.layout.layout_controller_binding_preference);
setIconSpaceReserved(false);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
ImageView iconView = ((ImageView) holder.findViewById(R.id.controller_binding_icon));
TextView nameView = ((TextView) holder.findViewById(R.id.controller_binding_name));
mValueView = ((TextView) holder.findViewById(R.id.controller_binding_value));
int drawableId = R.drawable.ic_baseline_radio_button_checked_24;
switch (mType) {
case BUTTON:
drawableId = getIconForButton(mBindingName);
break;
case AXIS:
drawableId = getIconForAxis(mBindingName);
break;
case HOTKEY:
drawableId = getIconForHotkey(mBindingName);
break;
}
iconView.setImageDrawable(ContextCompat.getDrawable(getContext(), drawableId));
nameView.setText(mBindingName);
updateValue();
}
@Override
protected void onClick() {
ControllerBindingDialog dialog = new ControllerBindingDialog(getContext(), mBindingName, getKey(), mValue, (mType == Type.AXIS));
dialog.setOnDismissListener((dismissedDialog) -> updateValue());
dialog.show();
}
public void initButton(int controllerIndex, String buttonName) {
mBindingName = buttonName;
mType = Type.BUTTON;
setKey(String.format("Controller%d/Button%s", controllerIndex, buttonName));
updateValue();
}
public void initAxis(int controllerIndex, String axisName) {
mBindingName = axisName;
mType = Type.AXIS;
setKey(String.format("Controller%d/Axis%s", controllerIndex, axisName));
updateValue();
}
public void initHotkey(HotkeyInfo hotkeyInfo) {
mBindingName = hotkeyInfo.getDisplayName();
mType = Type.HOTKEY;
setKey(hotkeyInfo.getBindingConfigKey());
updateValue();
}
private void updateValue(String value) {
mValue = value;
if (mValueView != null) {
if (value != null)
mValueView.setText(value);
else
mValueView.setText(getContext().getString(R.string.controller_binding_dialog_no_binding));
}
}
public void updateValue() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
Set<String> values = PreferenceHelpers.getStringSet(prefs, getKey());
if (values != null) {
StringBuilder sb = new StringBuilder();
for (String value : values) {
if (sb.length() > 0)
sb.append(", ");
sb.append(value);
}
updateValue(sb.toString());
} else {
updateValue(null);
}
}
public void clearBinding(SharedPreferences.Editor prefEditor) {
try {
prefEditor.remove(getKey());
} catch (Exception e) {
}
updateValue(null);
}
}

View File

@@ -0,0 +1,271 @@
package com.github.stenzek.duckstation;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
public class ControllerMappingActivity extends AppCompatActivity {
private static final int NUM_CONTROLLER_PORTS = 2;
private ArrayList<ControllerBindingPreference> mPreferences = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings, new SettingsCollectionFragment(this))
.commit();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.controller_mapping_activity_title);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_controller_mapping, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
final int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_load_profile) {
doLoadProfile();
return true;
} else if (id == R.id.action_save_profile) {
doSaveProfile();
return true;
} else if (id == R.id.action_clear_bindings) {
doClearBindings();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
private void displayError(String text) {
new AlertDialog.Builder(this)
.setTitle(R.string.emulation_activity_error)
.setMessage(text)
.setNegativeButton(R.string.main_activity_ok, ((dialog, which) -> dialog.dismiss()))
.create()
.show();
}
private void doLoadProfile() {
final String[] profileNames = AndroidHostInterface.getInstance().getInputProfileNames();
if (profileNames == null) {
displayError(getString(R.string.controller_mapping_activity_no_profiles_found));
return;
}
new AlertDialog.Builder(this)
.setTitle(R.string.controller_mapping_activity_select_input_profile)
.setItems(profileNames, (dialog, choice) -> {
doLoadProfile(profileNames[choice]);
dialog.dismiss();
})
.setNegativeButton("Cancel", ((dialog, which) -> dialog.dismiss()))
.create()
.show();
}
private void doLoadProfile(String profileName) {
if (!AndroidHostInterface.getInstance().loadInputProfile(profileName)) {
displayError(String.format(getString(R.string.controller_mapping_activity_failed_to_load_profile), profileName));
return;
}
updateAllBindings();
}
private void doSaveProfile() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
final EditText input = new EditText(this);
builder.setTitle(R.string.controller_mapping_activity_input_profile_name);
builder.setView(input);
builder.setPositiveButton(R.string.controller_mapping_activity_save, (dialog, which) -> {
final String name = input.getText().toString();
if (name.isEmpty()) {
displayError(getString(R.string.controller_mapping_activity_name_must_be_provided));
return;
}
if (!AndroidHostInterface.getInstance().saveInputProfile(name)) {
displayError(getString(R.string.controller_mapping_activity_failed_to_save_input_profile));
return;
}
Toast.makeText(ControllerMappingActivity.this, String.format(ControllerMappingActivity.this.getString(R.string.controller_mapping_activity_input_profile_saved), name),
Toast.LENGTH_LONG).show();
});
builder.setNegativeButton(R.string.controller_mapping_activity_cancel, (dialog, which) -> dialog.dismiss());
builder.create().show();
}
private void doClearBindings() {
SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(this).edit();
for (ControllerBindingPreference pref : mPreferences)
pref.clearBinding(prefEdit);
prefEdit.commit();
}
private void updateAllBindings() {
for (ControllerBindingPreference pref : mPreferences)
pref.updateValue();
}
public static class ControllerPortFragment extends PreferenceFragmentCompat {
private ControllerMappingActivity activity;
private int controllerIndex;
public ControllerPortFragment(ControllerMappingActivity activity, int controllerIndex) {
this.activity = activity;
this.controllerIndex = controllerIndex;
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
final SharedPreferences sp = getPreferenceManager().getSharedPreferences();
final String defaultControllerType = controllerIndex == 0 ? "DigitalController" : "None";
String controllerType = sp.getString(String.format("Controller%d/Type", controllerIndex), defaultControllerType);
String[] controllerButtons = AndroidHostInterface.getControllerButtonNames(controllerType);
String[] axisButtons = AndroidHostInterface.getControllerAxisNames(controllerType);
final PreferenceScreen ps = getPreferenceManager().createPreferenceScreen(getContext());
if (controllerButtons != null) {
for (String buttonName : controllerButtons) {
final ControllerBindingPreference cbp = new ControllerBindingPreference(getContext(), null);
cbp.initButton(controllerIndex, buttonName);
ps.addPreference(cbp);
activity.mPreferences.add(cbp);
}
}
if (axisButtons != null) {
for (String axisName : axisButtons) {
final ControllerBindingPreference cbp = new ControllerBindingPreference(getContext(), null);
cbp.initAxis(controllerIndex, axisName);
ps.addPreference(cbp);
activity.mPreferences.add(cbp);
}
}
setPreferenceScreen(ps);
}
}
public static class HotkeyFragment extends PreferenceFragmentCompat {
private ControllerMappingActivity activity;
private HotkeyInfo[] mHotkeyInfo;
public HotkeyFragment(ControllerMappingActivity activity) {
this.activity = activity;
this.mHotkeyInfo = AndroidHostInterface.getInstance().getHotkeyInfoList();
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
final PreferenceScreen ps = getPreferenceManager().createPreferenceScreen(getContext());
if (mHotkeyInfo != null) {
for (HotkeyInfo hotkeyInfo : mHotkeyInfo) {
final ControllerBindingPreference cbp = new ControllerBindingPreference(getContext(), null);
cbp.initHotkey(hotkeyInfo);
ps.addPreference(cbp);
activity.mPreferences.add(cbp);
}
}
setPreferenceScreen(ps);
}
}
public static class SettingsCollectionFragment extends Fragment {
private ControllerMappingActivity activity;
private SettingsCollectionAdapter adapter;
private ViewPager2 viewPager;
public SettingsCollectionFragment(ControllerMappingActivity activity) {
this.activity = activity;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_controller_mapping, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
adapter = new SettingsCollectionAdapter(activity, this);
viewPager = view.findViewById(R.id.view_pager);
viewPager.setAdapter(adapter);
TabLayout tabLayout = view.findViewById(R.id.tab_layout);
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
if (position == NUM_CONTROLLER_PORTS)
tab.setText("Hotkeys");
else
tab.setText(String.format("Port %d", position + 1));
}).attach();
}
}
public static class SettingsCollectionAdapter extends FragmentStateAdapter {
private ControllerMappingActivity activity;
public SettingsCollectionAdapter(@NonNull ControllerMappingActivity activity, @NonNull Fragment fragment) {
super(fragment);
this.activity = activity;
}
@NonNull
@Override
public Fragment createFragment(int position) {
if (position != NUM_CONTROLLER_PORTS)
return new ControllerPortFragment(activity, position + 1);
else
return new HotkeyFragment(activity);
}
@Override
public int getItemCount() {
return NUM_CONTROLLER_PORTS + 1;
}
}
}

View File

@@ -1,31 +1,31 @@
package com.github.stenzek.duckstation;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.hardware.input.InputManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.AndroidException;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.MenuItem;
import android.widget.FrameLayout;
import android.widget.Toast;
import androidx.appcompat.widget.PopupMenu;
import androidx.preference.PreferenceManager;
/**
@@ -39,7 +39,6 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
private SharedPreferences mPreferences;
private boolean mWasDestroyed = false;
private boolean mStopRequested = false;
private boolean mWasPausedOnSurfaceLoss = false;
private boolean mApplySettingsOnSurfaceRestored = false;
private String mGameTitle = null;
private EmulationSurfaceView mContentView;
@@ -64,6 +63,19 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
editor.apply();
}
private void reportErrorOnUIThread(String message) {
// Toast.makeText(this, message, Toast.LENGTH_LONG);
new AlertDialog.Builder(this)
.setTitle(R.string.emulation_activity_error)
.setMessage(message)
.setPositiveButton(R.string.emulation_activity_ok, (dialog, button) -> {
dialog.dismiss();
enableFullscreenImmersive();
})
.create()
.show();
}
public void reportError(String message) {
Log.e("EmulationActivity", message);
@@ -71,10 +83,11 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
runOnUiThread(() -> {
// Toast.makeText(this, message, Toast.LENGTH_LONG);
new AlertDialog.Builder(this)
.setTitle("Error")
.setTitle(R.string.emulation_activity_error)
.setMessage(message)
.setPositiveButton("OK", (dialog, button) -> {
.setPositiveButton(R.string.emulation_activity_ok, (dialog, button) -> {
dialog.dismiss();
enableFullscreenImmersive();
synchronized (lock) {
lock.notify();
}
@@ -91,19 +104,25 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
}
}
public void reportMessage(String message) {
Log.i("EmulationActivity", message);
runOnUiThread(() -> {
Toast.makeText(this, message, Toast.LENGTH_SHORT);
});
private EmulationThread mEmulationThread;
private void stopEmulationThread() {
if (mEmulationThread == null)
return;
mEmulationThread.stopAndJoin();
mEmulationThread = null;
}
public void onEmulationStarted() {
runOnUiThread(() -> {
updateRequestedOrientation();
updateOrientation();
});
}
public void onEmulationStopped() {
runOnUiThread(() -> {
AndroidHostInterface.getInstance().stopEmulationThread();
if (!mWasDestroyed && !mStopRequested)
finish();
});
@@ -115,14 +134,53 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
});
}
public float getRefreshRate() {
WindowManager windowManager = getWindowManager();
if (windowManager == null) {
windowManager = ((WindowManager) getSystemService(Context.WINDOW_SERVICE));
if (windowManager == null)
return -1.0f;
}
Display display = windowManager.getDefaultDisplay();
if (display == null)
return -1.0f;
return display.getRefreshRate();
}
public void openPauseMenu() {
runOnUiThread(() -> {
showMenu();
});
}
private void doApplySettings() {
AndroidHostInterface.getInstance().applySettings();
updateRequestedOrientation();
updateControllers();
updateSustainedPerformanceMode();
}
private void applySettings() {
if (!AndroidHostInterface.getInstance().isEmulationThreadRunning())
return;
if (AndroidHostInterface.getInstance().hasSurface())
AndroidHostInterface.getInstance().applySettings();
else
if (AndroidHostInterface.getInstance().hasSurface()) {
doApplySettings();
} else {
mApplySettingsOnSurfaceRestored = true;
}
}
/// Ends the activity if it was restored without properly being created.
private boolean checkActivityIsValid() {
if (!AndroidHostInterface.hasInstance() || !AndroidHostInterface.getInstance().isEmulationThreadRunning()) {
finish();
return false;
}
return true;
}
@Override
@@ -132,61 +190,67 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Once we get a surface, we can boot.
if (AndroidHostInterface.getInstance().isEmulationThreadRunning()) {
final boolean hadSurface = AndroidHostInterface.getInstance().hasSurface();
AndroidHostInterface.getInstance().surfaceChanged(holder.getSurface(), format, width, height);
AndroidHostInterface.getInstance().surfaceChanged(holder.getSurface(), format, width, height);
if (mEmulationThread != null) {
updateOrientation();
if (holder.getSurface() != null && !hadSurface && AndroidHostInterface.getInstance().isEmulationThreadPaused() && !mWasPausedOnSurfaceLoss) {
AndroidHostInterface.getInstance().pauseEmulationThread(false);
}
if (mApplySettingsOnSurfaceRestored) {
AndroidHostInterface.getInstance().applySettings();
mApplySettingsOnSurfaceRestored = false;
doApplySettings();
}
return;
}
final String bootPath = getIntent().getStringExtra("bootPath");
final boolean resumeState = getIntent().getBooleanExtra("resumeState", false);
final boolean saveStateOnExit = getBooleanSetting("Main/SaveStateOnExit", true);
final boolean resumeState = getIntent().getBooleanExtra("resumeState", saveStateOnExit);
final String bootSaveStatePath = getIntent().getStringExtra("saveStatePath");
AndroidHostInterface.getInstance().startEmulationThread(this, holder.getSurface(), bootPath, resumeState, bootSaveStatePath);
updateOrientation();
mEmulationThread = EmulationThread.create(this, bootPath, resumeState, bootSaveStatePath);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (!AndroidHostInterface.getInstance().isEmulationThreadRunning())
return;
Log.i("EmulationActivity", "Surface destroyed");
// Save the resume state in case we never get back again...
if (!mStopRequested)
if (AndroidHostInterface.getInstance().isEmulationThreadRunning() && !mStopRequested)
AndroidHostInterface.getInstance().saveResumeState(true);
mWasPausedOnSurfaceLoss = AndroidHostInterface.getInstance().isEmulationThreadPaused();
AndroidHostInterface.getInstance().pauseEmulationThread(true);
AndroidHostInterface.getInstance().surfaceChanged(null, 0, 0, 0);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
super.onCreate(savedInstanceState);
Log.i("EmulationActivity", "OnCreate");
// we might be coming from a third-party launcher if the host interface isn't setup
if (!AndroidHostInterface.hasInstance() && !AndroidHostInterface.createInstance(this)) {
finish();
return;
}
enableFullscreenImmersive();
setContentView(R.layout.activity_emulation);
mContentView = findViewById(R.id.fullscreen_content);
mContentView.getHolder().addCallback(this);
mContentView.setFocusableInTouchMode(true);
mContentView.setFocusable(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mContentView.setFocusedByDefault(true);
}
mContentView.requestFocus();
// Sort out rotation.
updateOrientation();
updateSustainedPerformanceMode();
// Hook up controller input.
updateControllers();
registerInputDeviceListener();
@@ -208,9 +272,9 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
protected void onDestroy() {
super.onDestroy();
Log.i("EmulationActivity", "OnStop");
if (AndroidHostInterface.getInstance().isEmulationThreadRunning()) {
if (mEmulationThread != null) {
mWasDestroyed = true;
AndroidHostInterface.getInstance().stopEmulationThread();
stopEmulationThread();
}
unregisterInputDeviceListener();
@@ -220,9 +284,29 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (!checkActivityIsValid()) {
// we must've got killed off in the background :(
return;
}
if (requestCode == REQUEST_CODE_SETTINGS) {
if (AndroidHostInterface.getInstance().isEmulationThreadRunning())
if (AndroidHostInterface.getInstance().isEmulationThreadRunning()) {
applySettings();
}
} else if (requestCode == REQUEST_IMPORT_PATCH_CODES) {
if (data == null)
return;
importPatchesFromFile(data.getData());
} else if (requestCode == REQUEST_CHANGE_DISC_FILE) {
if (data == null)
return;
String path = GameDirectoriesActivity.getPathFromUri(this, data.getData());
if (path == null)
return;
AndroidHostInterface.getInstance().setMediaFilename(path);
}
}
@@ -231,10 +315,43 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
showMenu();
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (mContentView.onKeyDown(event.getKeyCode(), event))
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
if (mContentView.onKeyUp(event.getKeyCode(), event))
return true;
}
return super.dispatchKeyEvent(event);
}
@Override
public boolean dispatchGenericMotionEvent(MotionEvent ev) {
if (mContentView.onGenericMotionEvent(ev))
return true;
return super.dispatchGenericMotionEvent(ev);
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateOrientation(newConfig.orientation);
if (checkActivityIsValid())
updateOrientation(newConfig.orientation);
}
private void updateRequestedOrientation() {
final String orientation = getStringSetting("Main/EmulationScreenOrientation", "unspecified");
if (orientation.equals("portrait"))
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT);
else if (orientation.equals("landscape"))
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE);
else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
private void updateOrientation() {
@@ -243,17 +360,16 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
}
private void updateOrientation(int newOrientation) {
if (!AndroidHostInterface.getInstance().isEmulationThreadRunning())
return;
if (newOrientation == Configuration.ORIENTATION_PORTRAIT)
AndroidHostInterface.getInstance().setDisplayAlignment(AndroidHostInterface.DISPLAY_ALIGNMENT_TOP_OR_LEFT);
else
AndroidHostInterface.getInstance().setDisplayAlignment(AndroidHostInterface.DISPLAY_ALIGNMENT_CENTER);
if (mTouchscreenController != null)
mTouchscreenController.updateOrientation();
}
private void enableFullscreenImmersive()
{
private void enableFullscreenImmersive() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
@@ -266,32 +382,43 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
}
private static final int REQUEST_CODE_SETTINGS = 0;
private static final int REQUEST_IMPORT_PATCH_CODES = 1;
private static final int REQUEST_CHANGE_DISC_FILE = 2;
private void onMenuClosed() {
enableFullscreenImmersive();
if (AndroidHostInterface.getInstance().isEmulationThreadPaused())
AndroidHostInterface.getInstance().pauseEmulationThread(false);
}
private void showMenu() {
if (getBooleanSetting("Main/PauseOnMenu", false) &&
!AndroidHostInterface.getInstance().isEmulationThreadPaused()) {
AndroidHostInterface.getInstance().pauseEmulationThread(true);
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
if (mGameTitle != null && !mGameTitle.isEmpty())
builder.setTitle(mGameTitle);
builder.setItems(R.array.emulation_menu, (dialogInterface, i) -> {
switch (i)
{
case 0: // Quick Load
switch (i) {
case 0: // Load State
{
AndroidHostInterface.getInstance().loadState(false, 0);
showSaveStateMenu(false);
return;
}
case 1: // Quick Save
case 1: // Save State
{
AndroidHostInterface.getInstance().saveState(false, 0);
showSaveStateMenu(true);
return;
}
case 2: // Toggle Speed Limiter
case 2: // Toggle Fast Forward
{
boolean newSetting = !getBooleanSetting("Main/SpeedLimiterEnabled", true);
setBooleanSetting("Main/SpeedLimiterEnabled", newSetting);
applySettings();
AndroidHostInterface.getInstance().setFastForwardEnabled(!AndroidHostInterface.getInstance().isFastForwardEnabled());
onMenuClosed();
return;
}
@@ -309,42 +436,67 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
}
}
});
builder.setOnDismissListener(dialogInterface -> enableFullscreenImmersive());
builder.setOnCancelListener(dialogInterface -> onMenuClosed());
builder.create().show();
}
private void showSaveStateMenu(boolean saving) {
final SaveStateInfo[] infos = AndroidHostInterface.getInstance().getSaveStateInfo(true);
if (infos == null) {
onMenuClosed();
return;
}
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
final ListView listView = new ListView(this);
listView.setAdapter(new SaveStateInfo.ListAdapter(this, infos));
builder.setView(listView);
builder.setOnDismissListener((dialog) -> {
onMenuClosed();
});
final AlertDialog dialog = builder.create();
listView.setOnItemClickListener((parent, view, position, id) -> {
SaveStateInfo info = infos[position];
if (saving) {
AndroidHostInterface.getInstance().saveState(info.isGlobal(), info.getSlot());
} else {
AndroidHostInterface.getInstance().loadState(info.isGlobal(), info.getSlot());
}
dialog.dismiss();
});
dialog.show();
}
private void showMoreMenu() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
if (mGameTitle != null && !mGameTitle.isEmpty())
builder.setTitle(mGameTitle);
builder.setItems(R.array.emulation_more_menu, (dialogInterface, i) -> {
switch (i)
{
switch (i) {
case 0: // Reset
{
AndroidHostInterface.getInstance().resetSystem();
onMenuClosed();
return;
}
case 1: // Cheats
case 1: // Patch Codes
{
showCheatsMenu();
showPatchesMenu();
return;
}
case 2: // Change Disc
{
showDiscChangeMenu();
return;
}
case 3: // Change Touchscreen Controller
{
showTouchscreenControllerMenu();
return;
}
case 4: // Settings
case 3: // Settings
{
Intent intent = new Intent(EmulationActivity.this, SettingsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -352,14 +504,23 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
return;
}
case 5: // Quit
case 4: // Change Touchscreen Controller
{
finish();
showTouchscreenControllerMenu();
return;
}
case 5: // Edit Touchscreen Controller Layout
{
if (mTouchscreenController != null)
mTouchscreenController.startLayoutEditing();
onMenuClosed();
return;
}
}
});
builder.setOnDismissListener(dialogInterface -> enableFullscreenImmersive());
builder.setOnCancelListener(dialogInterface -> onMenuClosed());
builder.create().show();
}
@@ -369,28 +530,78 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
String[] values = getResources().getStringArray(R.array.settings_touchscreen_controller_view_values);
setStringSetting("Controller1/TouchscreenControllerView", values[i]);
updateControllers();
onMenuClosed();
});
builder.setOnDismissListener(dialogInterface -> enableFullscreenImmersive());
builder.setOnCancelListener(dialogInterface -> onMenuClosed());
builder.create().show();
}
private void showCheatsMenu() {
final CheatCode[] cheats = AndroidHostInterface.getInstance().getCheatList();
if (cheats == null) {
AndroidHostInterface.getInstance().addOSDMessage("No cheats are loaded.", 5.0f);
return;
private void showPatchesMenu() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
final PatchCode[] codes = AndroidHostInterface.getInstance().getPatchCodeList();
if (codes != null) {
CharSequence[] items = new CharSequence[codes.length];
boolean[] itemsChecked = new boolean[codes.length];
for (int i = 0; i < codes.length; i++) {
final PatchCode cc = codes[i];
items[i] = cc.getDescription();
itemsChecked[i] = cc.isEnabled();
}
builder.setMultiChoiceItems(items, itemsChecked, (dialogInterface, i, checked) -> {
AndroidHostInterface.getInstance().setPatchCodeEnabled(i, checked);
});
}
builder.setNegativeButton(R.string.emulation_activity_ok, (dialogInterface, i) -> {
dialogInterface.dismiss();
});
builder.setNeutralButton(R.string.emulation_activity_import_patch_codes, (dialogInterface, i) -> {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, getString(R.string.emulation_activity_choose_patch_code_file)), REQUEST_IMPORT_PATCH_CODES);
});
builder.setOnDismissListener(dialogInterface -> onMenuClosed());
builder.create().show();
}
private void importPatchesFromFile(Uri uri) {
String str = FileUtil.readFileFromUri(this, uri, 512 * 1024);
if (str == null || !AndroidHostInterface.getInstance().importPatchCodesFromString(str)) {
reportErrorOnUIThread(getString(R.string.emulation_activity_failed_to_import_patch_codes));
}
}
private void showDiscChangeMenu() {
final String[] paths = AndroidHostInterface.getInstance().getMediaPlaylistPaths();
final int currentPath = AndroidHostInterface.getInstance().getMediaPlaylistIndex();
final int numPaths = (paths != null) ? paths.length : 0;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
CharSequence[] items = new CharSequence[cheats.length];
for (int i = 0; i < cheats.length; i++) {
final CheatCode cc = cheats[i];
items[i] = String.format("%s %s", cc.isEnabled() ? "(ON)" : "(OFF)", cc.getName());
}
CharSequence[] items = new CharSequence[numPaths + 1];
for (int i = 0; i < numPaths; i++)
items[i] = GameListEntry.getFileNameForPath(paths[i]);
items[numPaths] = "Select New File...";
builder.setItems(items, (dialogInterface, i) -> AndroidHostInterface.getInstance().setCheatEnabled(i, !cheats[i].isEnabled()));
builder.setOnDismissListener(dialogInterface -> enableFullscreenImmersive());
builder.setSingleChoiceItems(items, (currentPath < numPaths) ? currentPath : -1, (dialogInterface, i) -> {
dialogInterface.dismiss();
onMenuClosed();
if (i < numPaths) {
AndroidHostInterface.getInstance().setMediaPlaylistIndex(i);
} else {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, getString(R.string.main_activity_choose_disc_image)), REQUEST_CHANGE_DISC_FILE);
}
});
builder.setOnCancelListener(dialogInterface -> onMenuClosed());
builder.create().show();
}
@@ -403,6 +614,8 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
final String controllerType = getStringSetting("Controller1/Type", "DigitalController");
final String viewType = getStringSetting("Controller1/TouchscreenControllerView", "digital");
final boolean autoHideTouchscreenController = getBooleanSetting("Controller1/AutoHideTouchscreenController", false);
final boolean hapticFeedback = getBooleanSetting("Controller1/HapticFeedback", false);
final boolean vibration = getBooleanSetting("Controller1/Vibration", false);
final FrameLayout activityLayout = findViewById(R.id.frameLayout);
Log.i("EmulationActivity", "Controller type: " + controllerType);
@@ -410,22 +623,27 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
final boolean hasAnyControllers = mContentView.initControllerMapping(controllerType);
if (controllerType == "none" || viewType == "none" || (hasAnyControllers && autoHideTouchscreenController)) {
if (controllerType.equals("none") || viewType.equals("none") || (hasAnyControllers && autoHideTouchscreenController)) {
if (mTouchscreenController != null) {
activityLayout.removeView(mTouchscreenController);
mTouchscreenController = null;
mVibratorService = null;
}
} else {
if (mTouchscreenController == null) {
mTouchscreenController = new TouchscreenControllerView(this);
if (vibration)
mVibratorService = (Vibrator) getSystemService(VIBRATOR_SERVICE);
activityLayout.addView(mTouchscreenController);
}
mTouchscreenController.init(0, controllerType, viewType);
mTouchscreenController.init(0, controllerType, viewType, hapticFeedback);
}
}
private InputManager.InputDeviceListener mInputDeviceListener;
private void registerInputDeviceListener() {
if (mInputDeviceListener != null)
return;
@@ -450,18 +668,53 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
}
};
InputManager inputManager = ((InputManager)getSystemService(Context.INPUT_SERVICE));
InputManager inputManager = ((InputManager) getSystemService(Context.INPUT_SERVICE));
if (inputManager != null)
inputManager.registerInputDeviceListener(mInputDeviceListener, null);
}
private void unregisterInputDeviceListener() {
if (mInputDeviceListener == null)
return;
InputManager inputManager = ((InputManager)getSystemService(Context.INPUT_SERVICE));
InputManager inputManager = ((InputManager) getSystemService(Context.INPUT_SERVICE));
if (inputManager != null)
inputManager.unregisterInputDeviceListener(mInputDeviceListener);
mInputDeviceListener = null;
}
private Vibrator mVibratorService;
public void setVibration(boolean enabled) {
if (mVibratorService == null)
return;
runOnUiThread(() -> {
if (mVibratorService == null)
return;
if (enabled)
mVibratorService.vibrate(1000);
else
mVibratorService.cancel();
});
}
private boolean mSustainedPerformanceModeEnabled = false;
private void updateSustainedPerformanceMode() {
final boolean enabled = getBooleanSetting("Main/SustainedPerformanceMode", false);
if (mSustainedPerformanceModeEnabled == enabled)
return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
getWindow().setSustainedPerformanceMode(enabled);
Log.i("EmulationActivity", String.format("%s sustained performance mode.", enabled ? "enabling" : "disabling"));
} else {
Log.e("EmulationActivity", "Sustained performance mode not supported.");
}
mSustainedPerformanceModeEnabled = enabled;
}
}

View File

@@ -1,17 +1,18 @@
package com.github.stenzek.duckstation;
import android.content.Context;
import android.hardware.input.InputManager;
import android.util.ArrayMap;
import android.content.SharedPreferences;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceView;
import androidx.core.util.Pair;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class EmulationSurfaceView extends SurfaceView {
@@ -27,71 +28,98 @@ public class EmulationSurfaceView extends SurfaceView {
super(context, attrs, defStyle);
}
private boolean isDPadOrButtonEvent(KeyEvent event) {
public static boolean isDPadOrButtonEvent(KeyEvent event) {
final int source = event.getSource();
return (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD ||
(source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD ||
(source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (isDPadOrButtonEvent(event) && event.getRepeatCount() == 0 &&
handleControllerKey(event.getDeviceId(), keyCode, true)) {
return true;
}
private boolean isExternalKeyCode(int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_HOME:
case KeyEvent.KEYCODE_MENU:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE:
case KeyEvent.KEYCODE_POWER:
case KeyEvent.KEYCODE_CAMERA:
case KeyEvent.KEYCODE_CALL:
case KeyEvent.KEYCODE_ENDCALL:
case KeyEvent.KEYCODE_VOICE_ASSIST:
return true;
return super.onKeyDown(keyCode, event);
default:
return false;
}
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (isDPadOrButtonEvent(event) && event.getRepeatCount() == 0 &&
handleControllerKey(event.getDeviceId(), keyCode, false)) {
return true;
private static final int[] buttonKeyCodes = new int[]{
KeyEvent.KEYCODE_BUTTON_A, // 0/Cross
KeyEvent.KEYCODE_BUTTON_B, // 1/Circle
KeyEvent.KEYCODE_BUTTON_X, // 2/Square
KeyEvent.KEYCODE_BUTTON_Y, // 3/Triangle
KeyEvent.KEYCODE_BUTTON_SELECT, // 4/Select
KeyEvent.KEYCODE_BUTTON_MODE, // 5/Analog
KeyEvent.KEYCODE_BUTTON_START, // 6/Start
KeyEvent.KEYCODE_BUTTON_THUMBL, // 7/L3
KeyEvent.KEYCODE_BUTTON_THUMBR, // 8/R3
KeyEvent.KEYCODE_BUTTON_L1, // 9/L1
KeyEvent.KEYCODE_BUTTON_R1, // 10/R1
KeyEvent.KEYCODE_DPAD_UP, // 11/Up
KeyEvent.KEYCODE_DPAD_DOWN, // 12/Down
KeyEvent.KEYCODE_DPAD_LEFT, // 13/Left
KeyEvent.KEYCODE_DPAD_RIGHT, // 14/Right
KeyEvent.KEYCODE_BUTTON_L2, // 15
KeyEvent.KEYCODE_BUTTON_R2, // 16
KeyEvent.KEYCODE_BUTTON_C, // 17
KeyEvent.KEYCODE_BUTTON_Z, // 18
KeyEvent.KEYCODE_VOLUME_DOWN, // 19
KeyEvent.KEYCODE_VOLUME_UP, // 20
KeyEvent.KEYCODE_MENU, // 21
KeyEvent.KEYCODE_CAMERA, // 22
};
private static final int[] axisCodes = new int[]{
MotionEvent.AXIS_X, // 0/LeftX
MotionEvent.AXIS_Y, // 1/LeftY
MotionEvent.AXIS_Z, // 2/RightX
MotionEvent.AXIS_RZ, // 3/RightY
MotionEvent.AXIS_LTRIGGER, // 4/L2
MotionEvent.AXIS_RTRIGGER, // 5/R2
MotionEvent.AXIS_RX, // 6
MotionEvent.AXIS_RY, // 7
MotionEvent.AXIS_HAT_X, // 8
MotionEvent.AXIS_HAT_Y, // 9
MotionEvent.AXIS_GAS, // 10
MotionEvent.AXIS_BRAKE, // 11
};
public static int getButtonIndexForKeyCode(int keyCode) {
for (int buttonIndex = 0; buttonIndex < buttonKeyCodes.length; buttonIndex++) {
if (buttonKeyCodes[buttonIndex] == keyCode)
return buttonIndex;
}
return super.onKeyDown(keyCode, event);
Log.e("EmulationSurfaceView", String.format("Button code %d not found", keyCode));
return -1;
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
final int source = event.getSource();
if ((source & InputDevice.SOURCE_JOYSTICK) == 0)
return super.onGenericMotionEvent(event);
public static int[] getKnownAxisCodes() {
return axisCodes;
}
final int deviceId = event.getDeviceId();
for (AxisMapping mapping : mControllerAxisMapping) {
if (mapping.deviceId != deviceId)
continue;
final float axisValue = event.getAxisValue(mapping.deviceAxisOrButton);
float emuValue;
if (mapping.deviceMotionRange != null) {
final float transformedValue = (axisValue - mapping.deviceMotionRange.getMin()) / mapping.deviceMotionRange.getRange();
emuValue = (transformedValue * 2.0f) - 1.0f;
} else {
emuValue = axisValue;
}
Log.d("EmulationSurfaceView", String.format("axis %d value %f emuvalue %f", mapping.deviceAxisOrButton, axisValue, emuValue));
if (mapping.axisMapping >= 0) {
AndroidHostInterface.getInstance().setControllerAxisState(0, mapping.axisMapping, emuValue);
}
final float DEAD_ZONE = 0.25f;
if (mapping.negativeButton >= 0) {
AndroidHostInterface.getInstance().setControllerButtonState(0, mapping.negativeButton, (emuValue <= -DEAD_ZONE));
}
if (mapping.positiveButton >= 0) {
AndroidHostInterface.getInstance().setControllerButtonState(0, mapping.positiveButton, (emuValue >= DEAD_ZONE));
}
public static int getAxisIndexForAxisCode(int axisCode) {
for (int axisIndex = 0; axisIndex < axisCodes.length; axisIndex++) {
if (axisCodes[axisIndex] == axisCode)
return axisIndex;
}
return true;
Log.e("EmulationSurfaceView", String.format("Axis code %d not found", axisCode));
return -1;
}
private class ButtonMapping {
public ButtonMapping(int deviceId, int deviceButton, int controllerIndex, int button) {
this.deviceId = deviceId;
@@ -139,16 +167,110 @@ public class EmulationSurfaceView extends SurfaceView {
private ArrayList<ButtonMapping> mControllerKeyMapping;
private ArrayList<AxisMapping> mControllerAxisMapping;
private void addControllerKeyMapping(int deviceId, int keyCode, int controllerIndex, String controllerType, String buttonName) {
int mapping = AndroidHostInterface.getControllerButtonCode(controllerType, buttonName);
Log.i("EmulationSurfaceView", String.format("Map %d to %d (%s)", keyCode, mapping,
buttonName));
if (mapping >= 0) {
mControllerKeyMapping.add(new ButtonMapping(deviceId, keyCode, controllerIndex, mapping));
private boolean handleControllerKey(int deviceId, int keyCode, int repeatCount, boolean pressed) {
boolean result = false;
for (ButtonMapping mapping : mControllerKeyMapping) {
if (mapping.deviceId != deviceId || mapping.deviceAxisOrButton != keyCode)
continue;
if (repeatCount == 0) {
AndroidHostInterface.getInstance().handleControllerButtonEvent(0, mapping.buttonMapping, pressed);
Log.d("EmulationSurfaceView", String.format("handleControllerKey %d -> %d %d", keyCode, mapping.buttonMapping, pressed ? 1 : 0));
}
result = true;
}
return result;
}
private void addControllerAxisMapping(int deviceId, List<InputDevice.MotionRange> motionRanges, int axis, int controllerIndex, String controllerType, String axisName, String negativeButtonName, String positiveButtonName) {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (!isDPadOrButtonEvent(event))
return false;
if (handleControllerKey(event.getDeviceId(), keyCode, event.getRepeatCount(), true))
return true;
// eat non-external button events anyway
return !isExternalKeyCode(keyCode);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (!isDPadOrButtonEvent(event))
return false;
if (handleControllerKey(event.getDeviceId(), keyCode, 0, false))
return true;
// eat non-external button events anyway
return !isExternalKeyCode(keyCode);
}
private float clamp(float value, float min, float max) {
return (value < min) ? min : ((value > max) ? max : value);
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
final int source = event.getSource();
if ((source & (InputDevice.SOURCE_JOYSTICK | InputDevice.SOURCE_GAMEPAD | InputDevice.SOURCE_DPAD)) == 0)
return false;
final int deviceId = event.getDeviceId();
for (AxisMapping mapping : mControllerAxisMapping) {
if (mapping.deviceId != deviceId)
continue;
final float axisValue = event.getAxisValue(mapping.deviceAxisOrButton);
float emuValue;
switch (mapping.deviceAxisOrButton) {
case MotionEvent.AXIS_BRAKE:
case MotionEvent.AXIS_GAS:
case MotionEvent.AXIS_LTRIGGER:
case MotionEvent.AXIS_RTRIGGER:
// Scale 0..1 -> -1..1.
emuValue = (clamp(axisValue, 0.0f, 1.0f) * 2.0f) - 1.0f;
break;
default:
// Everything else should already by -1..1 as per Android documentation.
emuValue = clamp(axisValue, -1.0f, 1.0f);
break;
}
Log.d("EmulationSurfaceView", String.format("axis %d value %f emuvalue %f", mapping.deviceAxisOrButton, axisValue, emuValue));
if (mapping.axisMapping >= 0) {
AndroidHostInterface.getInstance().handleControllerAxisEvent(0, mapping.axisMapping, emuValue);
}
final float DEAD_ZONE = 0.25f;
if (mapping.negativeButton >= 0) {
AndroidHostInterface.getInstance().handleControllerButtonEvent(0, mapping.negativeButton, (emuValue <= -DEAD_ZONE));
}
if (mapping.positiveButton >= 0) {
AndroidHostInterface.getInstance().handleControllerButtonEvent(0, mapping.positiveButton, (emuValue >= DEAD_ZONE));
}
}
return true;
}
private boolean addControllerKeyMapping(int deviceId, int keyCode, int controllerIndex) {
int mapping = getButtonIndexForKeyCode(keyCode);
Log.i("EmulationSurfaceView", String.format("Map %d to %d", keyCode, mapping));
if (mapping >= 0) {
mControllerKeyMapping.add(new ButtonMapping(deviceId, keyCode, controllerIndex, mapping));
return true;
}
return false;
}
private boolean addControllerAxisMapping(int deviceId, List<InputDevice.MotionRange> motionRanges, int axis, int controllerIndex) {
InputDevice.MotionRange range = null;
for (InputDevice.MotionRange curRange : motionRanges) {
if (curRange.getAxis() == axis) {
@@ -157,26 +279,26 @@ public class EmulationSurfaceView extends SurfaceView {
}
}
if (range == null)
return;
return false;
if (axisName != null) {
int mapping = AndroidHostInterface.getControllerAxisCode(controllerType, axisName);
Log.i("EmulationSurfaceView", String.format("Map axis %d to %d (%s)", axis, mapping, axisName));
if (mapping >= 0) {
mControllerAxisMapping.add(new AxisMapping(deviceId, axis, range, controllerIndex, mapping));
return;
}
int mapping = getAxisIndexForAxisCode(axis);
int negativeButton = -1;
int positiveButton = -1;
if (mapping >= 0) {
Log.i("EmulationSurfaceView", String.format("Map axis %d to %d", axis, mapping));
mControllerAxisMapping.add(new AxisMapping(deviceId, axis, range, controllerIndex, mapping));
return true;
}
if (negativeButtonName != null && positiveButtonName != null) {
final int negativeMapping = AndroidHostInterface.getControllerButtonCode(controllerType, negativeButtonName);
final int positiveMapping = AndroidHostInterface.getControllerButtonCode(controllerType, positiveButtonName);
Log.i("EmulationSurfaceView", String.format("Map axis %d to %d %d (button %s %s)", axis, negativeMapping, positiveMapping,
negativeButtonName, positiveButtonName));
if (negativeMapping >= 0 && positiveMapping >= 0) {
mControllerAxisMapping.add(new AxisMapping(deviceId, axis, range, controllerIndex, positiveMapping, negativeMapping));
}
if (negativeButton >= 0 && negativeButton >= 0) {
Log.i("EmulationSurfaceView", String.format("Map axis %d to buttons %d %d", axis, negativeButton, positiveButton));
mControllerAxisMapping.add(new AxisMapping(deviceId, axis, range, controllerIndex, positiveButton, negativeButton));
return true;
}
Log.w("EmulationSurfaceView", String.format("Axis %d was not mapped", axis));
return false;
}
private static boolean isJoystickDevice(int deviceId) {
@@ -194,10 +316,7 @@ public class EmulationSurfaceView extends SurfaceView {
if ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
return true;
if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD)
return true;
return false;
return (sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD;
}
public boolean initControllerMapping(String controllerType) {
@@ -213,48 +332,18 @@ public class EmulationSurfaceView extends SurfaceView {
List<InputDevice.MotionRange> motionRanges = device.getMotionRanges();
int controllerIndex = 0;
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_DPAD_UP, controllerIndex, controllerType, "Up");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_DPAD_RIGHT, controllerIndex, controllerType, "Right");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_DPAD_DOWN, controllerIndex, controllerType, "Down");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_DPAD_LEFT, controllerIndex, controllerType, "Left");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_L1, controllerIndex, controllerType, "L1");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_L2, controllerIndex, controllerType, "L2");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_SELECT, controllerIndex, controllerType, "Select");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_START, controllerIndex, controllerType, "Start");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_Y, controllerIndex, controllerType, "Triangle");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_B, controllerIndex, controllerType, "Circle");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_A, controllerIndex, controllerType, "Cross");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_X, controllerIndex, controllerType, "Square");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_R1, controllerIndex, controllerType, "R1");
addControllerKeyMapping(deviceId, KeyEvent.KEYCODE_BUTTON_R2, controllerIndex, controllerType, "R2");
for (int keyCode : buttonKeyCodes) {
addControllerKeyMapping(deviceId, keyCode, controllerIndex);
}
if (motionRanges != null) {
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_X, controllerIndex, controllerType, "LeftX", null, null);
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_Y, controllerIndex, controllerType, "LeftY", null, null);
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_RX, controllerIndex, controllerType, "RightX", null, null);
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_RY, controllerIndex, controllerType, "RightY", null, null);
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_Z, controllerIndex, controllerType, "RightX", null, null);
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_RZ, controllerIndex, controllerType, "RightY", null, null);
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_LTRIGGER, controllerIndex, controllerType, "L2", "L2", "L2");
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_RTRIGGER, controllerIndex, controllerType, "R2", "R2", "R2");
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_HAT_X, controllerIndex, controllerType, null, "Left", "Right");
addControllerAxisMapping(deviceId, motionRanges, MotionEvent.AXIS_HAT_Y, controllerIndex, controllerType, null, "Up", "Down");
for (int axisCode : axisCodes) {
addControllerAxisMapping(deviceId, motionRanges, axisCode, controllerIndex);
}
}
}
return !mControllerKeyMapping.isEmpty() || !mControllerKeyMapping.isEmpty();
}
private boolean handleControllerKey(int deviceId, int keyCode, boolean pressed) {
boolean result = false;
for (ButtonMapping mapping : mControllerKeyMapping) {
if (mapping.deviceId != deviceId || mapping.deviceAxisOrButton != keyCode)
continue;
AndroidHostInterface.getInstance().setControllerButtonState(0, mapping.buttonMapping, pressed);
Log.d("EmulationSurfaceView", String.format("handleControllerKey %d -> %d %d", keyCode, mapping.buttonMapping, pressed ? 1 : 0));
result = true;
}
return result;
}
}

View File

@@ -0,0 +1,67 @@
package com.github.stenzek.duckstation;
import android.os.Build;
import android.os.Process;
import android.util.Log;
import android.view.Surface;
import androidx.annotation.NonNull;
public class EmulationThread extends Thread {
private EmulationActivity emulationActivity;
private String filename;
private boolean resumeState;
private String stateFilename;
private EmulationThread(EmulationActivity emulationActivity, String filename, boolean resumeState, String stateFilename) {
super("EmulationThread");
this.emulationActivity = emulationActivity;
this.filename = filename;
this.resumeState = resumeState;
this.stateFilename = stateFilename;
}
public static EmulationThread create(EmulationActivity emulationActivity, String filename, boolean resumeState, String stateFilename) {
Log.i("EmulationThread", String.format("Starting emulation thread (%s)...", filename));
EmulationThread thread = new EmulationThread(emulationActivity, filename, resumeState, stateFilename);
thread.start();
return thread;
}
private void setExclusiveCores() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
int[] cores = Process.getExclusiveCores();
if (cores == null || cores.length == 0)
throw new Exception("Invalid return value from getExclusiveCores()");
AndroidHostInterface.setThreadAffinity(cores);
}
} catch (Exception e) {
Log.e("EmulationThread", "getExclusiveCores() failed");
}
}
@Override
public void run() {
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);
setExclusiveCores();
} catch (Exception e) {
Log.i("EmulationThread", "Failed to set priority for emulation thread: " + e.getMessage());
}
AndroidHostInterface.getInstance().runEmulationThread(emulationActivity, filename, resumeState, stateFilename);
Log.i("EmulationThread", "Emulation thread exiting.");
}
public void stopAndJoin() {
AndroidHostInterface.getInstance().stopEmulationThreadLoop();
try {
join();
} catch (InterruptedException e) {
Log.i("EmulationThread", "join() interrupted: " + e.getMessage());
}
}
}

View File

@@ -13,8 +13,14 @@ import android.provider.DocumentsContract;
import androidx.annotation.Nullable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public final class FileUtil {
static String TAG = "TAG";
@@ -40,9 +46,11 @@ public final class FileUtil {
} else return volumePath;
}
@SuppressLint("ObsoleteSdkInt")
private static String getVolumePath(final String volumeId, Context context) {
if (volumeId == null)
return null;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return null;
try {
StorageManager mStorageManager =
@@ -91,4 +99,77 @@ public final class FileUtil {
if ((split.length >= 2) && (split[1] != null)) return split[1];
else return File.separator;
}
@Nullable
public static String getFullPathFromUri(@Nullable final Uri treeUri, Context con) {
if (treeUri == null) return null;
String volumePath = getVolumePath(getVolumeIdFromUri(treeUri), con);
if (volumePath == null) return File.separator;
if (volumePath.endsWith(File.separator))
volumePath = volumePath.substring(0, volumePath.length() - 1);
String documentPath = getDocumentPathFromUri(treeUri);
if (documentPath.endsWith(File.separator))
documentPath = documentPath.substring(0, documentPath.length() - 1);
if (documentPath.length() > 0) {
if (documentPath.startsWith(File.separator))
return volumePath + documentPath;
else
return volumePath + File.separator + documentPath;
} else return volumePath;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getVolumeIdFromUri(final Uri treeUri) {
try {
final String docId = DocumentsContract.getDocumentId(treeUri);
final String[] split = docId.split(":");
if (split.length > 0) return split[0];
else return null;
} catch (Exception e) {
return null;
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getDocumentPathFromUri(final Uri treeUri) {
try {
final String docId = DocumentsContract.getDocumentId(treeUri);
final String[] split = docId.split(":");
if ((split.length >= 2) && (split[1] != null)) return split[1];
else return File.separator;
} catch (Exception e) {
return null;
}
}
public static String readFileFromUri(final Context context, final Uri uri, int maxSize) {
InputStream stream = null;
try {
stream = context.getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
return null;
}
StringBuilder os = new StringBuilder();
try {
char[] buffer = new char[1024];
InputStreamReader reader = new InputStreamReader(stream, Charset.forName(StandardCharsets.UTF_8.name()));
int len;
while ((len = reader.read(buffer)) > 0) {
os.append(buffer, 0, len);
if (os.length() > maxSize)
return null;
}
} catch (IOException e) {
return null;
}
if (os.length() == 0)
return null;
return os.toString();
}
}

View File

@@ -0,0 +1,331 @@
package com.github.stenzek.duckstation;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.util.Property;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.ListFragment;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
public class GameDirectoriesActivity extends AppCompatActivity {
private static final int REQUEST_ADD_DIRECTORY_TO_GAME_LIST = 1;
private class DirectoryListAdapter extends RecyclerView.Adapter {
private class Entry {
private String mPath;
private boolean mRecursive;
public Entry(String path, boolean recursive) {
mPath = path;
mRecursive = recursive;
}
public String getPath() {
return mPath;
}
public boolean isRecursive() {
return mRecursive;
}
public void toggleRecursive() {
mRecursive = !mRecursive;
}
}
private class EntryComparator implements Comparator<Entry> {
@Override
public int compare(Entry left, Entry right) {
return left.getPath().compareTo(right.getPath());
}
}
private Context mContext;
private Entry[] mEntries;
public DirectoryListAdapter(Context context) {
mContext = context;
reload();
}
public void reload() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
ArrayList<Entry> entries = new ArrayList<>();
try {
Set<String> paths = prefs.getStringSet("GameList/Paths", null);
if (paths != null) {
for (String path : paths)
entries.add(new Entry(path, false));
}
} catch (Exception e) {
}
try {
Set<String> paths = prefs.getStringSet("GameList/RecursivePaths", null);
if (paths != null) {
for (String path : paths)
entries.add(new Entry(path, true));
}
} catch (Exception e) {
}
mEntries = new Entry[entries.size()];
entries.toArray(mEntries);
Arrays.sort(mEntries, new EntryComparator());
notifyDataSetChanged();
}
private class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private int mPosition;
private Entry mEntry;
private TextView mPathView;
private TextView mRecursiveView;
private ImageButton mToggleRecursiveView;
private ImageButton mRemoveView;
public ViewHolder(View rootView) {
super(rootView);
mPathView = rootView.findViewById(R.id.path);
mRecursiveView = rootView.findViewById(R.id.recursive);
mToggleRecursiveView = rootView.findViewById(R.id.toggle_recursive);
mToggleRecursiveView.setOnClickListener(this);
mRemoveView = rootView.findViewById(R.id.remove);
mRemoveView.setOnClickListener(this);
}
public void bindData(int position, Entry entry) {
mPosition = position;
mEntry = entry;
updateText();
}
private void updateText() {
mPathView.setText(mEntry.getPath());
mRecursiveView.setText(getString(mEntry.isRecursive() ? R.string.game_directories_scanning_subdirectories : R.string.game_directories_not_scanning_subdirectories));
mToggleRecursiveView.setImageDrawable(getDrawable(mEntry.isRecursive() ? R.drawable.ic_baseline_folder_24 : R.drawable.ic_baseline_folder_open_24));
}
@Override
public void onClick(View v) {
if (mToggleRecursiveView == v) {
removeSearchDirectory(mContext, mEntry.getPath(), mEntry.isRecursive());
mEntry.toggleRecursive();
addSearchDirectory(mContext, mEntry.getPath(), mEntry.isRecursive());
updateText();
} else if (mRemoveView == v) {
removeSearchDirectory(mContext, mEntry.getPath(), mEntry.isRecursive());
reload();
}
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
((ViewHolder) holder).bindData(position, mEntries[position]);
}
@Override
public int getItemViewType(int position) {
return R.layout.layout_game_directory_entry;
}
@Override
public long getItemId(int position) {
return mEntries[position].getPath().hashCode();
}
@Override
public int getItemCount() {
return mEntries.length;
}
}
DirectoryListAdapter mDirectoryListAdapter;
RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_directories);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
mDirectoryListAdapter = new DirectoryListAdapter(this);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setAdapter(mDirectoryListAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
findViewById(R.id.fab).setOnClickListener((v) -> startAddGameDirectory());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_edit_game_directories, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
if (item.getItemId() == R.id.add_directory) {
startAddGameDirectory();
return true;
} else if (item.getItemId() == R.id.add_path) {
startAddPath();
return true;
}
return super.onOptionsItemSelected(item);
}
public static String getPathFromTreeUri(Context context, Uri treeUri) {
String path = FileUtil.getFullPathFromTreeUri(treeUri, context);
if (path.length() < 5) {
new AlertDialog.Builder(context)
.setTitle(R.string.main_activity_error)
.setMessage(R.string.main_activity_get_path_from_directory_error)
.setPositiveButton(R.string.main_activity_ok, (dialog, button) -> {
})
.create()
.show();
return null;
}
return path;
}
public static String getPathFromUri(Context context, Uri uri) {
String path = FileUtil.getFullPathFromUri(uri, context);
if (path.length() < 5) {
new AlertDialog.Builder(context)
.setTitle(R.string.main_activity_error)
.setMessage(R.string.main_activity_get_path_from_file_error)
.setPositiveButton(R.string.main_activity_ok, (dialog, button) -> {
})
.create()
.show();
return null;
}
return path;
}
public static void addSearchDirectory(Context context, String path, boolean recursive) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final String key = recursive ? "GameList/RecursivePaths" : "GameList/Paths";
PreferenceHelpers.addToStringList(prefs, key, path);
Log.i("GameDirectoriesActivity", "Added path '" + path + "' to game list search directories");
}
public static void removeSearchDirectory(Context context, String path, boolean recursive) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final String key = recursive ? "GameList/RecursivePaths" : "GameList/Paths";
PreferenceHelpers.removeFromStringList(prefs, key, path);
Log.i("GameDirectoriesActivity", "Removed path '" + path + "' from game list search directories");
}
private void startAddGameDirectory() {
Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(i, getString(R.string.main_activity_choose_directory)),
REQUEST_ADD_DIRECTORY_TO_GAME_LIST);
}
private void startAddPath() {
final EditText text = new EditText(this);
text.setSingleLine();
new AlertDialog.Builder(this)
.setTitle(R.string.edit_game_directories_add_path)
.setMessage(R.string.edit_game_directories_add_path_summary)
.setView(text)
.setPositiveButton("Add", (dialog, which) -> {
final String path = text.getText().toString();
if (!path.isEmpty()) {
addSearchDirectory(GameDirectoriesActivity.this, path, true);
mDirectoryListAdapter.reload();
}
})
.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss())
.show();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_ADD_DIRECTORY_TO_GAME_LIST: {
if (resultCode != RESULT_OK)
return;
String path = getPathFromTreeUri(this, data.getData());
if (path == null)
return;
addSearchDirectory(this, path, true);
mDirectoryListAdapter.reload();
}
break;
}
}
}

View File

@@ -1,27 +1,22 @@
package com.github.stenzek.duckstation;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.ArraySet;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import androidx.preference.PreferenceManager;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;
public class GameList {
private Context mContext;
private Activity mContext;
private GameListEntry[] mEntries;
private ListViewAdapter mAdapter;
public GameList(Context context) {
public GameList(Activity context) {
mContext = context;
mAdapter = new ListViewAdapter();
mEntries = new GameListEntry[0];
@@ -35,12 +30,25 @@ public class GameList {
}
public void refresh(boolean invalidateCache, boolean invalidateDatabase) {
public void refresh(boolean invalidateCache, boolean invalidateDatabase, Activity parentActivity) {
// Search and get entries from native code
AndroidHostInterface.getInstance().refreshGameList(invalidateCache, invalidateDatabase);
mEntries = AndroidHostInterface.getInstance().getGameListEntries();
Arrays.sort(mEntries, new GameListEntryComparator());
mAdapter.notifyDataSetChanged();
AndroidProgressCallback progressCallback = new AndroidProgressCallback(mContext);
AsyncTask.execute(() -> {
AndroidHostInterface.getInstance().refreshGameList(invalidateCache, invalidateDatabase, progressCallback);
GameListEntry[] newEntries = AndroidHostInterface.getInstance().getGameListEntries();
Arrays.sort(newEntries, new GameListEntryComparator());
mContext.runOnUiThread(() -> {
try {
progressCallback.dismiss();
} catch (Exception e) {
Log.e("GameList", "Exception dismissing refresh progress");
e.printStackTrace();
}
mEntries = newEntries;
mAdapter.notifyDataSetChanged();
});
});
}
public int getEntryCount() {

View File

@@ -1,5 +1,6 @@
package com.github.stenzek.duckstation;
import android.os.AsyncTask;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -9,7 +10,9 @@ import androidx.core.content.ContextCompat;
public class GameListEntry {
public enum EntryType {
Disc,
PSExe
PSExe,
Playlist,
PSF
}
public enum CompatibilityRating {
@@ -24,20 +27,23 @@ public class GameListEntry {
private String mPath;
private String mCode;
private String mTitle;
private String mFileTitle;
private long mSize;
private String mModifiedTime;
private DiscRegion mRegion;
private EntryType mType;
private CompatibilityRating mCompatibilityRating;
private String mCoverPath;
public GameListEntry(String path, String code, String title, long size, String modifiedTime, String region,
String type, String compatibilityRating) {
public GameListEntry(String path, String code, String title, String fileTitle, long size, String modifiedTime, String region,
String type, String compatibilityRating, String coverPath) {
mPath = path;
mCode = code;
mTitle = title;
mFileTitle = fileTitle;
mSize = size;
mModifiedTime = modifiedTime;
mCoverPath = coverPath;
try {
mRegion = DiscRegion.valueOf(region);
@@ -70,6 +76,10 @@ public class GameListEntry {
return mTitle;
}
public String getFileTitle() {
return mFileTitle;
}
public String getModifiedTime() {
return mModifiedTime;
}
@@ -86,25 +96,39 @@ public class GameListEntry {
return mCompatibilityRating;
}
public static String getFileNameForPath(String path) {
int lastSlash = path.lastIndexOf('/');
if (lastSlash > 0 && lastSlash < path.length() - 1)
return path.substring(lastSlash + 1);
else
return path;
}
private String getSubTitle() {
String fileName = getFileNameForPath(mPath);
String sizeString = String.format("%.2f MB", (double) mSize / 1048576.0);
return String.format("%s (%s)", fileName, sizeString);
}
public void fillView(View view) {
((TextView) view.findViewById(R.id.game_list_view_entry_title)).setText(mTitle);
((TextView) view.findViewById(R.id.game_list_view_entry_path)).setText(mPath);
String sizeString = String.format("%.2f MB", (double) mSize / 1048576.0);
((TextView) view.findViewById(R.id.game_list_view_entry_size)).setText(sizeString);
((TextView) view.findViewById(R.id.game_list_view_entry_subtitle)).setText(getSubTitle());
int regionDrawableId;
switch (mRegion) {
case NTSC_J:
regionDrawableId = R.drawable.flag_jp;
break;
case PAL:
regionDrawableId = R.drawable.flag_eu;
break;
case Other:
regionDrawableId = R.drawable.ic_baseline_help_24;
break;
case NTSC_U:
default:
regionDrawableId = R.drawable.flag_us;
break;
case PAL:
regionDrawableId = R.drawable.flag_eu;
break;
}
((ImageView) view.findViewById(R.id.game_list_view_entry_region_icon))
@@ -112,17 +136,55 @@ public class GameListEntry {
int typeDrawableId;
switch (mType) {
case PSExe:
typeDrawableId = R.drawable.ic_emblem_system;
break;
case Playlist:
typeDrawableId = R.drawable.ic_baseline_playlist_play_24;
break;
case PSF:
typeDrawableId = R.drawable.ic_baseline_library_music_24;
break;
case Disc:
default:
typeDrawableId = R.drawable.ic_media_cdrom;
break;
}
case PSExe:
typeDrawableId = R.drawable.ic_emblem_system;
ImageView icon = ((ImageView) view.findViewById(R.id.game_list_view_entry_type_icon));
icon.setImageDrawable(ContextCompat.getDrawable(view.getContext(), typeDrawableId));
if (mCoverPath != null) {
new ImageLoadTask(icon).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mCoverPath);
}
int compatibilityDrawableId;
switch (mCompatibilityRating) {
case DoesntBoot:
compatibilityDrawableId = R.drawable.ic_star_1;
break;
case CrashesInIntro:
compatibilityDrawableId = R.drawable.ic_star_2;
break;
case CrashesInGame:
compatibilityDrawableId = R.drawable.ic_star_3;
break;
case GraphicalAudioIssues:
compatibilityDrawableId = R.drawable.ic_star_4;
break;
case NoIssues:
compatibilityDrawableId = R.drawable.ic_star_5;
break;
case Unknown:
default:
compatibilityDrawableId = R.drawable.ic_star_0;
break;
}
((ImageView) view.findViewById(R.id.game_list_view_entry_type_icon))
.setImageDrawable(ContextCompat.getDrawable(view.getContext(), typeDrawableId));
((ImageView) view.findViewById(R.id.game_list_view_compatibility_icon))
.setImageDrawable(ContextCompat.getDrawable(view.getContext(), compatibilityDrawableId));
}
}

View File

@@ -0,0 +1,249 @@
package com.github.stenzek.duckstation;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Property;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.ListFragment;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
public class GamePropertiesActivity extends AppCompatActivity {
PropertyListAdapter mPropertiesListAdapter;
GameListEntry mGameListEntry;
public ListAdapter getPropertyListAdapter() {
if (mPropertiesListAdapter != null)
return mPropertiesListAdapter;
mPropertiesListAdapter = new PropertyListAdapter(this);
mPropertiesListAdapter.addItem("title", "Title", mGameListEntry.getTitle());
mPropertiesListAdapter.addItem("filetitle", "File Title", mGameListEntry.getFileTitle());
mPropertiesListAdapter.addItem("serial", "Serial", mGameListEntry.getCode());
mPropertiesListAdapter.addItem("type", "Type", mGameListEntry.getType().toString());
mPropertiesListAdapter.addItem("path", "Path", mGameListEntry.getPath());
mPropertiesListAdapter.addItem("region", "Region", mGameListEntry.getRegion().toString());
mPropertiesListAdapter.addItem("compatibility", "Compatibility Rating", mGameListEntry.getCompatibilityRating().toString());
return mPropertiesListAdapter;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String path = getIntent().getStringExtra("path");
if (path == null || path.isEmpty()) {
finish();
return;
}
mGameListEntry = AndroidHostInterface.getInstance().getGameListEntry(path);
if (mGameListEntry == null) {
finish();
return;
}
setContentView(R.layout.settings_activity);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings, new SettingsCollectionFragment(this))
.commit();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
setTitle(mGameListEntry.getTitle());
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void displayError(String text) {
new AlertDialog.Builder(this)
.setTitle(R.string.emulation_activity_error)
.setMessage(text)
.setNegativeButton(R.string.main_activity_ok, ((dialog, which) -> dialog.dismiss()))
.create()
.show();
}
private void createBooleanGameSetting(PreferenceScreen ps, String key, int titleId) {
GameSettingPreference pref = new GameSettingPreference(ps.getContext(), mGameListEntry.getPath(), key, titleId);
ps.addPreference(pref);
}
private void createListGameSetting(PreferenceScreen ps, String key, int titleId, int entryId, int entryValuesId) {
GameSettingPreference pref = new GameSettingPreference(ps.getContext(), mGameListEntry.getPath(), key, titleId, entryId, entryValuesId);
ps.addPreference(pref);
}
public static class GameSettingsFragment extends PreferenceFragmentCompat {
private GamePropertiesActivity activity;
public GameSettingsFragment(GamePropertiesActivity activity) {
this.activity = activity;
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
final PreferenceScreen ps = getPreferenceManager().createPreferenceScreen(getContext());
activity.createListGameSetting(ps, "CPUOverclock", R.string.settings_cpu_overclocking, R.array.settings_advanced_cpu_overclock_entries, R.array.settings_advanced_cpu_overclock_values);
activity.createListGameSetting(ps, "CDROMReadSpeedup", R.string.settings_cdrom_read_speedup, R.array.settings_cdrom_read_speedup_entries, R.array.settings_cdrom_read_speedup_values);
activity.createListGameSetting(ps, "DisplayAspectRatio", R.string.settings_aspect_ratio, R.array.settings_display_aspect_ratio_names, R.array.settings_display_aspect_ratio_values);
activity.createListGameSetting(ps, "DisplayCropMode", R.string.settings_crop_mode, R.array.settings_display_crop_mode_entries, R.array.settings_display_crop_mode_values);
activity.createListGameSetting(ps, "GPUDownsampleMode", R.string.settings_downsample_mode, R.array.settings_downsample_mode_entries, R.array.settings_downsample_mode_values);
activity.createBooleanGameSetting(ps, "DisplayLinearUpscaling", R.string.settings_linear_upscaling);
activity.createBooleanGameSetting(ps, "DisplayIntegerUpscaling", R.string.settings_integer_upscaling);
activity.createBooleanGameSetting(ps, "DisplayForce4_3For24Bit", R.string.settings_force_4_3_for_24bit);
activity.createListGameSetting(ps, "GPUResolutionScale", R.string.settings_gpu_resolution_scale, R.array.settings_gpu_resolution_scale_entries, R.array.settings_gpu_resolution_scale_values);
activity.createListGameSetting(ps, "GPUMSAA", R.string.settings_msaa, R.array.settings_gpu_msaa_entries, R.array.settings_gpu_msaa_values);
activity.createBooleanGameSetting(ps, "GPUTrueColor", R.string.settings_true_color);
activity.createBooleanGameSetting(ps, "GPUScaledDithering", R.string.settings_scaled_dithering);
activity.createListGameSetting(ps, "GPUTextureFilter", R.string.settings_texture_filtering, R.array.settings_gpu_texture_filter_names, R.array.settings_gpu_texture_filter_values);
activity.createBooleanGameSetting(ps, "GPUForceNTSCTimings", R.string.settings_force_ntsc_timings);
activity.createBooleanGameSetting(ps, "GPUWidescreenHack", R.string.settings_widescreen_hack);
activity.createBooleanGameSetting(ps, "GPUPGXP", R.string.settings_pgxp_geometry_correction);
activity.createBooleanGameSetting(ps, "GPUPGXPDepthBuffer", R.string.settings_pgxp_depth_buffer);
setPreferenceScreen(ps);
}
}
public static class ControllerSettingsFragment extends PreferenceFragmentCompat {
private GamePropertiesActivity activity;
public ControllerSettingsFragment(GamePropertiesActivity activity) {
this.activity = activity;
}
private void createInputProfileSetting(PreferenceScreen ps) {
final GameSettingPreference pref = new GameSettingPreference(ps.getContext(), activity.mGameListEntry.getPath(), "InputProfileName", R.string.settings_input_profile);
final String[] inputProfileNames = AndroidHostInterface.getInstance().getInputProfileNames();
pref.setEntries(inputProfileNames);
pref.setEntryValues(inputProfileNames);
ps.addPreference(pref);
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
final PreferenceScreen ps = getPreferenceManager().createPreferenceScreen(getContext());
activity.createListGameSetting(ps, "Controller1Type", R.string.settings_controller_type, R.array.settings_controller_type_entries, R.array.settings_controller_type_values);
activity.createListGameSetting(ps, "MemoryCard1Type", R.string.settings_memory_card_1_type, R.array.settings_memory_card_mode_entries, R.array.settings_memory_card_mode_values);
activity.createListGameSetting(ps, "MemoryCard2Type", R.string.settings_memory_card_2_type, R.array.settings_memory_card_mode_entries, R.array.settings_memory_card_mode_values);
createInputProfileSetting(ps);
setPreferenceScreen(ps);
}
}
public static class SettingsCollectionFragment extends Fragment {
private GamePropertiesActivity activity;
private SettingsCollectionAdapter adapter;
private ViewPager2 viewPager;
public SettingsCollectionFragment(GamePropertiesActivity activity) {
this.activity = activity;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_controller_mapping, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
adapter = new SettingsCollectionAdapter(activity, this);
viewPager = view.findViewById(R.id.view_pager);
viewPager.setAdapter(adapter);
TabLayout tabLayout = view.findViewById(R.id.tab_layout);
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
switch (position) {
case 0:
tab.setText(R.string.game_properties_tab_summary);
break;
case 1:
tab.setText(R.string.game_properties_tab_game_settings);
break;
case 2:
tab.setText(R.string.game_properties_tab_controller_settings);
break;
}
}).attach();
}
}
public static class SettingsCollectionAdapter extends FragmentStateAdapter {
private GamePropertiesActivity activity;
public SettingsCollectionAdapter(@NonNull GamePropertiesActivity activity, @NonNull Fragment fragment) {
super(fragment);
this.activity = activity;
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0: { // Summary
ListFragment lf = new ListFragment();
lf.setListAdapter(activity.getPropertyListAdapter());
return lf;
}
case 1: { // Game Settings
return new GameSettingsFragment(activity);
}
case 2: { // Controller Settings
return new ControllerSettingsFragment(activity);
}
// TODO: Memory Card Editor
default:
return null;
}
}
@Override
public int getItemCount() {
return 3;
}
}
}

View File

@@ -0,0 +1,83 @@
package com.github.stenzek.duckstation;
import android.content.Context;
import android.util.AttributeSet;
import androidx.preference.ListPreference;
public class GameSettingPreference extends ListPreference {
private String mGamePath;
/**
* Creates a boolean game property preference.
*/
public GameSettingPreference(Context context, String gamePath, String settingKey, int titleId) {
super(context);
mGamePath = gamePath;
setPersistent(false);
setTitle(titleId);
setKey(settingKey);
setIconSpaceReserved(false);
setSummaryProvider(SimpleSummaryProvider.getInstance());
setEntries(R.array.settings_boolean_entries);
setEntryValues(R.array.settings_boolean_values);
updateValue();
}
/**
* Creates a list game property preference.
*/
public GameSettingPreference(Context context, String gamePath, String settingKey, int titleId, int entryArray, int entryValuesArray) {
super(context);
mGamePath = gamePath;
setPersistent(false);
setTitle(titleId);
setKey(settingKey);
setIconSpaceReserved(false);
setSummaryProvider(SimpleSummaryProvider.getInstance());
setEntries(entryArray);
setEntryValues(entryValuesArray);
updateValue();
}
private void updateValue() {
final String value = AndroidHostInterface.getInstance().getGameSettingValue(mGamePath, getKey());
if (value == null)
super.setValue("null");
else
super.setValue(value);
}
@Override
public void setValue(String value) {
super.setValue(value);
if (value.equals("null"))
AndroidHostInterface.getInstance().setGameSettingValue(mGamePath, getKey(), null);
else
AndroidHostInterface.getInstance().setGameSettingValue(mGamePath, getKey(), value);
}
@Override
public void setEntries(CharSequence[] entries) {
final int length = (entries != null) ? entries.length : 0;
CharSequence[] newEntries = new CharSequence[length + 1];
newEntries[0] = getContext().getString(R.string.game_properties_preference_use_global_setting);
if (entries != null)
System.arraycopy(entries, 0, newEntries, 1, entries.length);
super.setEntries(newEntries);
}
@Override
public void setEntryValues(CharSequence[] entryValues) {
final int length = (entryValues != null) ? entryValues.length : 0;
CharSequence[] newEntryValues = new CharSequence[length + 1];
newEntryValues[0] = "null";
if (entryValues != null)
System.arraycopy(entryValues, 0, newEntryValues, 1, length);
super.setEntryValues(newEntryValues);
}
}

View File

@@ -0,0 +1,29 @@
package com.github.stenzek.duckstation;
public class HotkeyInfo {
private String mCategory;
private String mName;
private String mDisplayName;
public HotkeyInfo(String category, String name, String displayName) {
mCategory = category;
mName = name;
mDisplayName = displayName;
}
public String getCategory() {
return mCategory;
}
public String getName() {
return mName;
}
public String getDisplayName() {
return mDisplayName;
}
public String getBindingConfigKey() {
return String.format("Hotkeys/%s", mName);
}
}

View File

@@ -0,0 +1,32 @@
package com.github.stenzek.duckstation;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;
import java.lang.ref.WeakReference;
public class ImageLoadTask extends AsyncTask<String, Void, Bitmap> {
private WeakReference<ImageView> mView;
public ImageLoadTask(ImageView view) {
mView = new WeakReference<>(view);
}
@Override
protected Bitmap doInBackground(String... strings) {
try {
return BitmapFactory.decodeFile(strings[0]);
} catch (Exception e) {
return null;
}
}
@Override
protected void onPostExecute(Bitmap bitmap) {
ImageView iv = mView.get();
if (iv != null)
iv.setImageBitmap(bitmap);
}
}

View File

@@ -1,71 +1,116 @@
package com.github.stenzek.duckstation;
import android.Manifest;
import android.content.ContentResolver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.documentfile.provider.DocumentFile;
import androidx.preference.PreferenceManager;
import android.content.Intent;
import androidx.collection.ArraySet;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.prefs.Preferences;
import static com.google.android.material.snackbar.Snackbar.make;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_EXTERNAL_STORAGE_PERMISSIONS = 1;
private static final int REQUEST_ADD_DIRECTORY_TO_GAME_LIST = 2;
private static final int REQUEST_IMPORT_BIOS_IMAGE = 3;
private static final int REQUEST_START_FILE = 4;
private static final int REQUEST_SETTINGS = 5;
private static final int REQUEST_EDIT_GAME_DIRECTORIES = 6;
private GameList mGameList;
private ListView mGameListView;
private boolean mHasExternalStoragePermissions = false;
private void setLanguage() {
String language = PreferenceManager.getDefaultSharedPreferences(this).getString("Main/Language", "none");
if (language == null || language.equals("none")) {
return;
}
String[] parts = language.split("-");
if (parts.length < 2)
return;
Locale locale = new Locale(parts[0], parts[1]);
Locale.setDefault(locale);
Resources res = getResources();
Configuration config = res.getConfiguration();
config.setLocale(locale);
res.updateConfiguration(config, res.getDisplayMetrics());
}
private void setTheme() {
String theme = PreferenceManager.getDefaultSharedPreferences(this).getString("Main/Theme", "follow_system");
if (theme == null)
return;
if (theme.equals("follow_system")) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
} else if (theme.equals("light")) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
} else if (theme.equals("dark")) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}
}
private void loadSettings() {
setLanguage();
setTheme();
}
private boolean shouldResumeStateByDefault() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
return prefs.getBoolean("Main/SaveStateOnExit", true);
}
private static String getTitleString() {
String scmVersion = AndroidHostInterface.getScmVersion();
final int gitHashPos = scmVersion.indexOf("-g");
if (gitHashPos > 0)
scmVersion = scmVersion.substring(0, gitHashPos);
return String.format("DuckStation %s", scmVersion);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadSettings();
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(getTitleString());
findViewById(R.id.fab_add_game_directory).setOnClickListener(new View.OnClickListener() {
@Override
@@ -107,6 +152,9 @@ public class MainActivity extends AppCompatActivity {
} else if (id == R.id.game_list_entry_menu_resume_game) {
startEmulation(mGameList.getEntry(position).getPath(), true);
return true;
} else if (id == R.id.game_list_entry_menu_properties) {
openGameProperties(mGameList.getEntry(position).getPath());
return true;
}
return false;
}
@@ -127,7 +175,8 @@ public class MainActivity extends AppCompatActivity {
throw new RuntimeException("Failed to create host interface");
}
mGameList.refresh(false, false);
AndroidHostInterface.getInstance().setContext(this);
mGameList.refresh(false, false, this);
}
private void startAddGameDirectory() {
@@ -137,7 +186,7 @@ public class MainActivity extends AppCompatActivity {
Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(i, "Choose directory"),
startActivityForResult(Intent.createChooser(i, getString(R.string.main_activity_choose_directory)),
REQUEST_ADD_DIRECTORY_TO_GAME_LIST);
}
@@ -160,18 +209,35 @@ public class MainActivity extends AppCompatActivity {
startEmulation(null, true);
} else if (id == R.id.action_start_bios) {
startEmulation(null, false);
} else if (id == R.id.action_add_game_directory) {
startAddGameDirectory();
} else if (id == R.id.action_start_file) {
startStartFile();
} else if (id == R.id.action_edit_game_directories) {
Intent intent = new Intent(this, GameDirectoriesActivity.class);
startActivityForResult(intent, REQUEST_EDIT_GAME_DIRECTORIES);
return true;
} else if (id == R.id.action_scan_for_new_games) {
mGameList.refresh(false, false);
mGameList.refresh(false, false, this);
} else if (id == R.id.action_rescan_all_games) {
mGameList.refresh(true, true);
mGameList.refresh(true, true, this);
} else if (id == R.id.action_import_bios) {
importBIOSImage();
} else if (id == R.id.action_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivityForResult(intent, REQUEST_SETTINGS);
return true;
} else if (id == R.id.action_controller_mapping) {
Intent intent = new Intent(this, ControllerMappingActivity.class);
startActivity(intent);
return true;
} else if (id == R.id.action_show_version) {
showVersion();
return true;
} else if (id == R.id.action_github_respository) {
openGithubRepository();
return true;
} else if (id == R.id.action_discord_server) {
openDiscordServer();
return true;
}
return super.onOptionsItemSelected(item);
@@ -186,31 +252,12 @@ public class MainActivity extends AppCompatActivity {
if (resultCode != RESULT_OK)
return;
Uri treeUri = data.getData();
String path = FileUtil.getFullPathFromTreeUri(treeUri, this);
if (path.length() < 5) {
new AlertDialog.Builder(this)
.setTitle("Error")
.setMessage("Failed to get path for the selected directory. Please make sure the directory is in internal/external storage.\n\n" +
"Tap the overflow button in the directory selector.\nSelect \"Show Internal Storage\".\n" +
"Tap the menu button and select your device name or SD card.")
.setPositiveButton("OK", (dialog, button) -> {})
.create()
.show();
String path = GameDirectoriesActivity.getPathFromTreeUri(this, data.getData());
if (path == null)
return;
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
Set<String> currentValues = prefs.getStringSet("GameList/RecursivePaths", null);
if (currentValues == null)
currentValues = new HashSet<String>();
currentValues.add(path);
SharedPreferences.Editor editor = prefs.edit();
editor.putStringSet("GameList/RecursivePaths", currentValues);
editor.apply();
Log.i("MainActivity", "Added path '" + path + "' to game list search directories");
mGameList.refresh(false, false);
GameDirectoriesActivity.addSearchDirectory(this, path, true);
mGameList.refresh(false, false, this);
}
break;
@@ -221,6 +268,28 @@ public class MainActivity extends AppCompatActivity {
onImportBIOSImageResult(data.getData());
}
break;
case REQUEST_START_FILE: {
if (resultCode != RESULT_OK)
return;
String path = GameDirectoriesActivity.getPathFromUri(this, data.getData());
if (path == null)
return;
startEmulation(path, shouldResumeStateByDefault());
}
break;
case REQUEST_SETTINGS: {
loadSettings();
}
break;
case REQUEST_EDIT_GAME_DIRECTORIES: {
mGameList.refresh(false, false, this);
}
break;
}
}
@@ -251,13 +320,20 @@ public class MainActivity extends AppCompatActivity {
}
} else {
Toast.makeText(this,
"External storage permissions are required to use DuckStation.",
R.string.main_activity_external_storage_permissions_error,
Toast.LENGTH_LONG);
finish();
}
}
}
private boolean openGameProperties(String path) {
Intent intent = new Intent(this, GamePropertiesActivity.class);
intent.putExtra("path", path);
startActivity(intent);
return true;
}
private boolean startEmulation(String bootPath, boolean resumeState) {
if (!doBIOSCheck())
return false;
@@ -269,15 +345,23 @@ public class MainActivity extends AppCompatActivity {
return true;
}
private void startStartFile() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, getString(R.string.main_activity_choose_disc_image)), REQUEST_START_FILE);
}
private boolean doBIOSCheck() {
if (AndroidHostInterface.getInstance().hasAnyBIOSImages())
return true;
new AlertDialog.Builder(this)
.setTitle("Missing BIOS Image")
.setMessage("No BIOS image was found in DuckStation's bios directory. Do you with to locate and import a BIOS image now?")
.setPositiveButton("Yes", (dialog, button) -> importBIOSImage())
.setNegativeButton("No", (dialog, button) -> {})
.setTitle(R.string.main_activity_missing_bios_image)
.setMessage(R.string.main_activity_missing_bios_image_prompt)
.setPositiveButton(R.string.main_activity_yes, (dialog, button) -> importBIOSImage())
.setNegativeButton(R.string.main_activity_no, (dialog, button) -> {
})
.create()
.show();
@@ -288,7 +372,7 @@ public class MainActivity extends AppCompatActivity {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, "Choose BIOS Image"), REQUEST_IMPORT_BIOS_IMAGE);
startActivityForResult(Intent.createChooser(intent, getString(R.string.main_activity_choose_bios_image)), REQUEST_IMPORT_BIOS_IMAGE);
}
private void onImportBIOSImageResult(Uri uri) {
@@ -299,7 +383,7 @@ public class MainActivity extends AppCompatActivity {
try {
stream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
Toast.makeText(this, "Failed to open BIOS image.", Toast.LENGTH_LONG);
Toast.makeText(this, R.string.main_activity_failed_to_open_bios_image, Toast.LENGTH_LONG);
return;
}
@@ -310,25 +394,55 @@ public class MainActivity extends AppCompatActivity {
while ((len = stream.read(buffer)) > 0) {
os.write(buffer, 0, len);
if (os.size() > MAX_BIOS_SIZE) {
throw new IOException("BIOS image is too large.");
throw new IOException(getString(R.string.main_activity_bios_image_too_large));
}
}
} catch (IOException e) {
new AlertDialog.Builder(this)
.setMessage("Failed to read BIOS image: " + e.getMessage())
.setPositiveButton("OK", (dialog, button) -> {})
.setMessage(getString(R.string.main_activity_failed_to_read_bios_image_prefix) + e.getMessage())
.setPositiveButton(R.string.main_activity_ok, (dialog, button) -> {
})
.create()
.show();
return;
}
String importResult = AndroidHostInterface.getInstance().importBIOSImage(os.toByteArray());
String message = (importResult == null) ? "This BIOS image is invalid, or has already been imported." : ("BIOS '" + importResult + "' imported.");
String message = (importResult == null) ? getString(R.string.main_activity_invalid_error) : ("BIOS '" + importResult + "' imported.");
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", (dialog, button) -> {})
.create()
.show();
.setMessage(message)
.setPositiveButton(R.string.main_activity_ok, (dialog, button) -> {
})
.create()
.show();
}
private void showVersion() {
final String message = AndroidHostInterface.getFullScmVersion();
new AlertDialog.Builder(this)
.setTitle(R.string.main_activity_show_version_title)
.setMessage(message)
.setPositiveButton(R.string.main_activity_ok, (dialog, button) -> {
})
.setNeutralButton(R.string.main_activity_copy, (dialog, button) -> {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
if (clipboard != null)
clipboard.setPrimaryClip(ClipData.newPlainText(getString(R.string.main_activity_show_version_title), message));
})
.create()
.show();
}
private void openGithubRepository() {
final String url = "https://github.com/stenzek/duckstation";
final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
}
private void openDiscordServer() {
final String url = "https://discord.gg/Buktv3t";
final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
}
}

View File

@@ -0,0 +1,25 @@
package com.github.stenzek.duckstation;
public class PatchCode {
private int mIndex;
private String mDescription;
private boolean mEnabled;
public PatchCode(int index, String description, boolean enabled) {
mIndex = index;
mDescription = description;
mEnabled = enabled;
}
public int getIndex() {
return mIndex;
}
public String getDescription() {
return mDescription;
}
public boolean isEnabled() {
return mEnabled;
}
}

View File

@@ -0,0 +1,85 @@
package com.github.stenzek.duckstation;
import android.content.SharedPreferences;
import android.util.ArraySet;
import java.util.Set;
public class PreferenceHelpers {
/**
* Clears all preferences in the specified section (starting with sectionName/).
* We really don't want to have to do this with JNI...
*
* @param prefs Preferences object.
* @param sectionName Section to clear keys for.
*/
public static void clearSection(SharedPreferences prefs, String sectionName) {
String testSectionName = sectionName + "/";
SharedPreferences.Editor editor = prefs.edit();
for (String keyName : prefs.getAll().keySet()) {
if (keyName.startsWith(testSectionName)) {
editor.remove(keyName);
}
}
editor.commit();
}
public static Set<String> getStringSet(SharedPreferences prefs, String keyName) {
Set<String> values = null;
try {
values = prefs.getStringSet(keyName, null);
} catch (Exception e) {
try {
String singleValue = prefs.getString(keyName, null);
if (singleValue != null) {
values = new ArraySet<>();
values.add(singleValue);
}
} catch (Exception e2) {
}
}
return values;
}
public static boolean addToStringList(SharedPreferences prefs, String keyName, String valueToAdd) {
Set<String> values = getStringSet(prefs, keyName);
if (values == null) {
values = new ArraySet<>();
} else {
// We need to copy it otherwise the put doesn't save.
Set<String> valuesCopy = new ArraySet<>();
valuesCopy.addAll(values);
values = valuesCopy;
}
final boolean result = values.add(valueToAdd);
prefs.edit().putStringSet(keyName, values).commit();
return result;
}
public static boolean removeFromStringList(SharedPreferences prefs, String keyName, String valueToRemove) {
Set<String> values = getStringSet(prefs, keyName);
if (values == null)
return false;
// We need to copy it otherwise the put doesn't save.
Set<String> valuesCopy = new ArraySet<>();
valuesCopy.addAll(values);
values = valuesCopy;
final boolean result = values.remove(valueToRemove);
prefs.edit().putStringSet(keyName, values).commit();
return result;
}
public static void setStringList(SharedPreferences prefs, String keyName, String[] values) {
Set<String> valueSet = new ArraySet<String>();
for (String value : values)
valueSet.add(value);
prefs.edit().putStringSet(keyName, valueSet).commit();
}
}

View File

@@ -0,0 +1,84 @@
package com.github.stenzek.duckstation;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class PropertyListAdapter extends BaseAdapter {
private class Item {
public String key;
public String title;
public String value;
Item(String key, String title, String value) {
this.key = key;
this.title = title;
this.value = value;
}
}
private Context mContext;
private ArrayList<Item> mItems = new ArrayList<>();
public PropertyListAdapter(Context context) {
mContext = context;
}
public Item getItemByKey(String key) {
for (Item it : mItems) {
if (it.key.equals(key))
return it;
}
return null;
}
public int addItem(String key, String title, String value) {
if (getItemByKey(key) != null)
return -1;
Item it = new Item(key, title, value);
int position = mItems.size();
mItems.add(it);
return position;
}
public boolean removeItem(Item item) {
return mItems.remove(item);
}
@Override
public int getCount() {
return mItems.size();
}
@Override
public Object getItem(int position) {
return mItems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext)
.inflate(R.layout.layout_game_property_entry, parent, false);
}
TextView titleView = (TextView) convertView.findViewById(R.id.property_title);
TextView valueView = (TextView) convertView.findViewById(R.id.property_value);
Item prop = mItems.get(position);
titleView.setText(prop.title);
valueView.setText(prop.value);
return convertView;
}
}

View File

@@ -0,0 +1,151 @@
package com.github.stenzek.duckstation;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.nio.ByteBuffer;
public class SaveStateInfo {
private String mPath;
private String mGameTitle;
private String mGameCode;
private String mMediaPath;
private String mTimestamp;
private int mSlot;
private boolean mGlobal;
private Bitmap mScreenshot;
public SaveStateInfo(String path, String gameTitle, String gameCode, String mediaPath, String timestamp, int slot, boolean global,
int screenshotWidth, int screenshotHeight, byte[] screenshotData) {
mPath = path;
mGameTitle = gameTitle;
mGameCode = gameCode;
mMediaPath = mediaPath;
mTimestamp = timestamp;
mSlot = slot;
mGlobal = global;
if (screenshotData != null) {
try {
mScreenshot = Bitmap.createBitmap(screenshotWidth, screenshotHeight, Bitmap.Config.ARGB_8888);
mScreenshot.copyPixelsFromBuffer(ByteBuffer.wrap(screenshotData));
} catch (Exception e) {
mScreenshot = null;
}
}
}
public boolean exists() {
return mPath != null;
}
public String getPath() {
return mPath;
}
public String getGameTitle() {
return mGameTitle;
}
public String getGameCode() {
return mGameCode;
}
public String getMediaPath() {
return mMediaPath;
}
public String getTimestamp() {
return mTimestamp;
}
public int getSlot() {
return mSlot;
}
public boolean isGlobal() {
return mGlobal;
}
public Bitmap getScreenshot() {
return mScreenshot;
}
private void fillView(Context context, View view) {
ImageView imageView = (ImageView) view.findViewById(R.id.image);
TextView summaryView = (TextView) view.findViewById(R.id.summary);
TextView gameView = (TextView) view.findViewById(R.id.game);
TextView pathView = (TextView) view.findViewById(R.id.path);
TextView timestampView = (TextView) view.findViewById(R.id.timestamp);
if (mScreenshot != null)
imageView.setImageBitmap(mScreenshot);
else
imageView.setImageDrawable(context.getDrawable(R.drawable.ic_baseline_not_interested_60));
String summaryText;
if (mGlobal)
summaryView.setText(String.format(context.getString(R.string.save_state_info_global_save_n), mSlot));
else if (mSlot == 0)
summaryView.setText(R.string.save_state_info_quick_save);
else
summaryView.setText(String.format(context.getString(R.string.save_state_info_game_save_n), mSlot));
if (exists()) {
gameView.setText(String.format("%s - %s", mGameCode, mGameTitle));
int lastSlashPosition = mMediaPath.lastIndexOf('/');
if (lastSlashPosition >= 0)
pathView.setText(mMediaPath.substring(lastSlashPosition + 1));
else
pathView.setText(mMediaPath);
timestampView.setText(mTimestamp);
} else {
gameView.setText(R.string.save_state_info_slot_is_empty);
pathView.setText("");
timestampView.setText("");
}
}
public static class ListAdapter extends BaseAdapter {
private final Context mContext;
private final SaveStateInfo[] mInfos;
public ListAdapter(Context context, SaveStateInfo[] infos) {
mContext = context;
mInfos = infos;
}
@Override
public int getCount() {
return mInfos.length;
}
@Override
public Object getItem(int position) {
return mInfos[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.save_state_view_entry, parent, false);
}
mInfos[position].fillView(mContext, convertView);
return convertView;
}
}
}

View File

@@ -46,6 +46,7 @@ public class SettingsActivity extends AppCompatActivity {
public static class SettingsFragment extends PreferenceFragmentCompat {
private int resourceId;
public SettingsFragment(int resourceId) {
this.resourceId = resourceId;
}
@@ -113,7 +114,7 @@ public class SettingsActivity extends AppCompatActivity {
@Override
public int getItemCount() {
return 5;
return 6;
}
}
}

View File

@@ -4,10 +4,9 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class TouchscreenControllerAxisView extends View {
public final class TouchscreenControllerAxisView extends View {
private Drawable mBaseDrawable;
private Drawable mStickUnpressedDrawable;
private Drawable mStickPressedDrawable;
@@ -18,6 +17,7 @@ public class TouchscreenControllerAxisView extends View {
private int mDrawXPos = 0;
private int mDrawYPos = 0;
private String mConfigName;
private int mControllerIndex = -1;
private int mXAxisCode = -1;
private int mYAxisCode = -1;
@@ -50,6 +50,14 @@ public class TouchscreenControllerAxisView extends View {
mStickPressedDrawable.setCallback(this);
}
public String getConfigName() {
return mConfigName;
}
public void setConfigName(String configName) {
mConfigName = configName;
}
public void setControllerAxis(int controllerIndex, int xCode, int yCode) {
mControllerIndex = controllerIndex;
mXAxisCode = xCode;
@@ -84,21 +92,21 @@ public class TouchscreenControllerAxisView extends View {
}
public void setPressed(int pointerId, float pointerX, float pointerY) {
final float dx = pointerX - (float)(getX() + (float)(getWidth() / 2));
final float dy = pointerY - (float)(getY() + (float)(getHeight() / 2));
final float dx = pointerX - (float) (getX() + (float) (getWidth() / 2));
final float dy = pointerY - (float) (getY() + (float) (getHeight() / 2));
// Log.i("SetPressed", String.format("px=%f,py=%f dx=%f,dy=%f", pointerX, pointerY, dx, dy));
final float pointerDistance = Math.max(Math.abs(dx), Math.abs(dy));
final float angle = (float)Math.atan2((double)dy, (double)dx);
final float angle = (float) Math.atan2((double) dy, (double) dx);
final float maxDistance = (float)Math.min((getWidth() - getPaddingLeft() - getPaddingRight()) / 2, (getHeight() - getPaddingTop() - getPaddingBottom()) / 2);
final float maxDistance = (float) Math.min((getWidth() - getPaddingLeft() - getPaddingRight()) / 2, (getHeight() - getPaddingTop() - getPaddingBottom()) / 2);
final float length = Math.min(pointerDistance / maxDistance, 1.0f);
// Log.i("SetPressed", String.format("pointerDist=%f,angle=%f,w=%d,h=%d,maxDist=%f,length=%f", pointerDistance, angle, getWidth(), getHeight(), maxDistance, length));
final float xValue = (float)Math.cos((double)angle) * length;
final float yValue = (float)Math.sin((double)angle) * length;
mDrawXPos = (int)(xValue * maxDistance);
mDrawYPos = (int)(yValue * maxDistance);
final float xValue = (float) Math.cos((double) angle) * length;
final float yValue = (float) Math.sin((double) angle) * length;
mDrawXPos = (int) (xValue * maxDistance);
mDrawYPos = (int) (yValue * maxDistance);
boolean doUpdate = (pointerId != mPointerId || !mPressed || (xValue != mXValue || yValue != mYValue));
mPointerId = pointerId;
@@ -128,7 +136,7 @@ public class TouchscreenControllerAxisView extends View {
hostInterface.setControllerButtonState(mControllerIndex, mRightButtonCode, (mXValue >= BUTTON_THRESHOLD));
if (mUpButtonCode >= 0)
hostInterface.setControllerButtonState(mControllerIndex, mUpButtonCode, (mYValue <= -BUTTON_THRESHOLD));
if (mDownButtonCode >= 0)
if (mDownButtonCode >= 0)
hostInterface.setControllerButtonState(mControllerIndex, mDownButtonCode, (mYValue >= BUTTON_THRESHOLD));
}

View File

@@ -5,19 +5,20 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.HapticFeedbackConstants;
import android.view.View;
/**
* TODO: document your custom view class.
*/
public class TouchscreenControllerButtonView extends View {
public final class TouchscreenControllerButtonView extends View {
private Drawable mUnpressedDrawable;
private Drawable mPressedDrawable;
private boolean mPressed = false;
private boolean mHapticFeedback = false;
private int mControllerIndex = -1;
private int mButtonCode = -1;
private String mConfigName;
public TouchscreenControllerButtonView(Context context) {
super(context);
@@ -83,6 +84,10 @@ public class TouchscreenControllerButtonView extends View {
mPressed = pressed;
invalidate();
updateControllerState();
if (mHapticFeedback) {
performHapticFeedback(pressed ? HapticFeedbackConstants.VIRTUAL_KEY : HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
}
}
public void setButtonCode(int controllerIndex, int code) {
@@ -90,6 +95,18 @@ public class TouchscreenControllerButtonView extends View {
mButtonCode = code;
}
public void setConfigName(String name) {
mConfigName = name;
}
public String getConfigName() {
return mConfigName;
}
public void setHapticFeedback(boolean enabled) {
mHapticFeedback = enabled;
}
private void updateControllerState() {
if (mButtonCode >= 0)
AndroidHostInterface.getInstance().setControllerButtonState(mControllerIndex, mButtonCode, mPressed);

View File

@@ -1,13 +1,22 @@
package com.github.stenzek.duckstation;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.preference.PreferenceManager;
import java.util.ArrayList;
@@ -17,12 +26,23 @@ import java.util.ArrayList;
public class TouchscreenControllerView extends FrameLayout {
private int mControllerIndex;
private String mControllerType;
private String mViewType;
private View mMainView;
private ArrayList<TouchscreenControllerButtonView> mButtonViews = new ArrayList<>();
private ArrayList<TouchscreenControllerAxisView> mAxisViews = new ArrayList<>();
private boolean mHapticFeedback;
private String mLayoutOrientation;
private boolean mEditingLayout = false;
private View mMovingView = null;
private String mMovingName = null;
private float mMovingLastX = 0.0f;
private float mMovingLastY = 0.0f;
private ConstraintLayout mEditLayout = null;
public TouchscreenControllerView(Context context) {
super(context);
setFocusable(false);
setFocusableInTouchMode(false);
}
public TouchscreenControllerView(Context context, AttributeSet attrs) {
@@ -33,17 +53,108 @@ public class TouchscreenControllerView extends FrameLayout {
super(context, attrs, defStyle);
}
public void init(int controllerIndex, String controllerType, String viewType) {
private String getConfigKeyForXTranslation(String name) {
return String.format("TouchscreenController/%s/%s%sXTranslation", mViewType, name, mLayoutOrientation);
}
private String getConfigKeyForYTranslation(String name) {
return String.format("TouchscreenController/%s/%s%sYTranslation", mViewType, name, mLayoutOrientation);
}
private void saveTranslationForButton(String name, float xTranslation, float yTranslation) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
final SharedPreferences.Editor editor = prefs.edit();
editor.putFloat(getConfigKeyForXTranslation(name), xTranslation);
editor.putFloat(getConfigKeyForYTranslation(name), yTranslation);
editor.commit();
}
private void clearTranslationForAllButtons() {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
final SharedPreferences.Editor editor = prefs.edit();
for (TouchscreenControllerButtonView buttonView : mButtonViews) {
editor.remove(getConfigKeyForXTranslation(buttonView.getConfigName()));
editor.remove(getConfigKeyForYTranslation(buttonView.getConfigName()));
buttonView.setTranslationX(0.0f);
buttonView.setTranslationY(0.0f);
}
for (TouchscreenControllerAxisView axisView : mAxisViews) {
editor.remove(getConfigKeyForXTranslation(axisView.getConfigName()));
editor.remove(getConfigKeyForYTranslation(axisView.getConfigName()));
axisView.setTranslationX(0.0f);
axisView.setTranslationY(0.0f);
}
editor.commit();
requestLayout();
}
private void reloadButtonTranslation() {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
for (TouchscreenControllerButtonView buttonView : mButtonViews) {
try {
buttonView.setTranslationX(prefs.getFloat(getConfigKeyForXTranslation(buttonView.getConfigName()), 0.0f));
buttonView.setTranslationY(prefs.getFloat(getConfigKeyForYTranslation(buttonView.getConfigName()), 0.0f));
//Log.i("TouchscreenController", String.format("Translation for %s %f %f", buttonView.getConfigName(),
// buttonView.getTranslationX(), buttonView.getTranslationY()));
} catch (ClassCastException ex) {
}
}
for (TouchscreenControllerAxisView axisView : mAxisViews) {
try {
axisView.setTranslationX(prefs.getFloat(getConfigKeyForXTranslation(axisView.getConfigName()), 0.0f));
axisView.setTranslationY(prefs.getFloat(getConfigKeyForYTranslation(axisView.getConfigName()), 0.0f));
} catch (ClassCastException ex) {
}
}
}
private String getOrientationString() {
switch (getContext().getResources().getConfiguration().orientation) {
case Configuration.ORIENTATION_PORTRAIT:
return "Portrait";
case Configuration.ORIENTATION_LANDSCAPE:
default:
return "Landscape";
}
}
/**
* Checks if the orientation of the layout has changed, and if so, reloads button translations.
*/
public void updateOrientation() {
String newOrientation = getOrientationString();
if (mLayoutOrientation != null && mLayoutOrientation.equals(newOrientation))
return;
Log.i("TouchscreenController", "New orientation: " + newOrientation);
mLayoutOrientation = newOrientation;
reloadButtonTranslation();
requestLayout();
}
public void init(int controllerIndex, String controllerType, String viewType, boolean hapticFeedback) {
mControllerIndex = controllerIndex;
mControllerType = controllerType;
mViewType = viewType;
mHapticFeedback = hapticFeedback;
mLayoutOrientation = getOrientationString();
if (mEditingLayout)
endLayoutEditing();
mButtonViews.clear();
mAxisViews.clear();
removeAllViews();
LayoutInflater inflater = LayoutInflater.from(getContext());
switch (viewType)
{
switch (viewType) {
case "digital":
mMainView = inflater.inflate(R.layout.layout_touchscreen_controller_digital, this, true);
break;
@@ -66,40 +177,49 @@ public class TouchscreenControllerView extends FrameLayout {
return;
mMainView.setOnTouchListener((view1, event) -> {
return handleTouchEvent(event);
if (mEditingLayout)
return handleEditingTouchEvent(event);
else
return handleTouchEvent(event);
});
linkButton(mMainView, R.id.controller_button_up, "Up");
linkButton(mMainView, R.id.controller_button_right, "Right");
linkButton(mMainView, R.id.controller_button_down, "Down");
linkButton(mMainView, R.id.controller_button_left, "Left");
linkButton(mMainView, R.id.controller_button_l1, "L1");
linkButton(mMainView, R.id.controller_button_l2, "L2");
linkButton(mMainView, R.id.controller_button_select, "Select");
linkButton(mMainView, R.id.controller_button_start, "Start");
linkButton(mMainView, R.id.controller_button_triangle, "Triangle");
linkButton(mMainView, R.id.controller_button_circle, "Circle");
linkButton(mMainView, R.id.controller_button_cross, "Cross");
linkButton(mMainView, R.id.controller_button_square, "Square");
linkButton(mMainView, R.id.controller_button_r1, "R1");
linkButton(mMainView, R.id.controller_button_r2, "R2");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
if (!linkAxis(mMainView, R.id.controller_axis_left, "Left"))
linkAxisToButtons(mMainView, R.id.controller_axis_left, "");
linkButton(mMainView, R.id.controller_button_up, "UpButton", "Up");
linkButton(mMainView, R.id.controller_button_right, "RightButton", "Right");
linkButton(mMainView, R.id.controller_button_down, "DownButton", "Down");
linkButton(mMainView, R.id.controller_button_left, "LeftButton", "Left");
linkButton(mMainView, R.id.controller_button_l1, "L1Button", "L1");
linkButton(mMainView, R.id.controller_button_l2, "L2Button", "L2");
linkButton(mMainView, R.id.controller_button_select, "SelectButton", "Select");
linkButton(mMainView, R.id.controller_button_start, "StartButton", "Start");
linkButton(mMainView, R.id.controller_button_triangle, "TriangleButton", "Triangle");
linkButton(mMainView, R.id.controller_button_circle, "CircleButton", "Circle");
linkButton(mMainView, R.id.controller_button_cross, "CrossButton", "Cross");
linkButton(mMainView, R.id.controller_button_square, "SquareButton", "Square");
linkButton(mMainView, R.id.controller_button_r1, "R1Button", "R1");
linkButton(mMainView, R.id.controller_button_r2, "R2Button", "R2");
linkAxis(mMainView, R.id.controller_axis_right, "Right");
if (!linkAxis(mMainView, R.id.controller_axis_left, "LeftAxis", "Left"))
linkAxisToButtons(mMainView, R.id.controller_axis_left, "LeftAxis", "");
linkAxis(mMainView, R.id.controller_axis_right, "RightAxis", "Right");
reloadButtonTranslation();
requestLayout();
}
private void linkButton(View view, int id, String buttonName) {
private void linkButton(View view, int id, String configName, String buttonName) {
TouchscreenControllerButtonView buttonView = (TouchscreenControllerButtonView) view.findViewById(id);
if (buttonView == null)
return;
int code = AndroidHostInterface.getInstance().getControllerButtonCode(mControllerType, buttonName);
int code = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonName);
Log.i("TouchscreenController", String.format("%s -> %d", buttonName, code));
if (code >= 0) {
buttonView.setConfigName(configName);
buttonView.setButtonCode(mControllerIndex, code);
buttonView.setHapticFeedback(mHapticFeedback);
mButtonViews.add(buttonView);
} else {
Log.e("TouchscreenController", String.format("Unknown button name '%s' " +
@@ -107,31 +227,32 @@ public class TouchscreenControllerView extends FrameLayout {
}
}
private boolean linkAxis(View view, int id, String axisName) {
private boolean linkAxis(View view, int id, String configName, String axisName) {
TouchscreenControllerAxisView axisView = (TouchscreenControllerAxisView) view.findViewById(id);
if (axisView == null)
return false;
int xCode = AndroidHostInterface.getInstance().getControllerAxisCode(mControllerType, axisName + "X");
int yCode = AndroidHostInterface.getInstance().getControllerAxisCode(mControllerType, axisName + "Y");
int xCode = AndroidHostInterface.getControllerAxisCode(mControllerType, axisName + "X");
int yCode = AndroidHostInterface.getControllerAxisCode(mControllerType, axisName + "Y");
Log.i("TouchscreenController", String.format("%s -> %d/%d", axisName, xCode, yCode));
if (xCode < 0 && yCode < 0)
return false;
axisView.setConfigName(configName);
axisView.setControllerAxis(mControllerIndex, xCode, yCode);
mAxisViews.add(axisView);
return true;
}
private boolean linkAxisToButtons(View view, int id, String buttonPrefix) {
private boolean linkAxisToButtons(View view, int id, String configName, String buttonPrefix) {
TouchscreenControllerAxisView axisView = (TouchscreenControllerAxisView) view.findViewById(id);
if (axisView == null)
return false;
int leftCode = AndroidHostInterface.getInstance().getControllerButtonCode(mControllerType, buttonPrefix + "Left");
int rightCode = AndroidHostInterface.getInstance().getControllerButtonCode(mControllerType, buttonPrefix + "Right");
int upCode = AndroidHostInterface.getInstance().getControllerButtonCode(mControllerType, buttonPrefix + "Up");
int downCode = AndroidHostInterface.getInstance().getControllerButtonCode(mControllerType, buttonPrefix + "Down");
int leftCode = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonPrefix + "Left");
int rightCode = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonPrefix + "Right");
int upCode = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonPrefix + "Up");
int downCode = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonPrefix + "Down");
Log.i("TouchscreenController", String.format("%s(ButtonAxis) -> %d,%d,%d,%d", buttonPrefix, leftCode, rightCode, upCode, downCode));
if (leftCode < 0 && rightCode < 0 && upCode < 0 && downCode < 0)
return false;
@@ -141,11 +262,117 @@ public class TouchscreenControllerView extends FrameLayout {
return true;
}
private int dpToPixels(float dp) {
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()));
}
public void startLayoutEditing() {
if (mEditLayout == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
mEditLayout = (ConstraintLayout) inflater.inflate(R.layout.layout_touchscreen_controller_edit, this, false);
((Button) mEditLayout.findViewById(R.id.stop_editing)).setOnClickListener((view) -> endLayoutEditing());
((Button) mEditLayout.findViewById(R.id.reset_layout)).setOnClickListener((view) -> clearTranslationForAllButtons());
addView(mEditLayout);
}
mEditingLayout = true;
}
public void endLayoutEditing() {
if (mEditLayout != null) {
((ViewGroup) mMainView).removeView(mEditLayout);
mEditLayout = null;
}
mEditingLayout = false;
mMovingView = null;
mMovingName = null;
mMovingLastX = 0.0f;
mMovingLastY = 0.0f;
}
private boolean handleEditingTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_UP: {
if (mMovingView != null) {
// save position
saveTranslationForButton(mMovingName, mMovingView.getTranslationX(), mMovingView.getTranslationY());
mMovingView = null;
mMovingName = null;
mMovingLastX = 0.0f;
mMovingLastY = 0.0f;
}
return true;
}
case MotionEvent.ACTION_DOWN: {
if (mMovingView != null) {
// already moving a button
return true;
}
Rect rect = new Rect();
final float x = event.getX();
final float y = event.getY();
for (TouchscreenControllerButtonView buttonView : mButtonViews) {
buttonView.getHitRect(rect);
if (rect.contains((int) x, (int) y)) {
mMovingView = buttonView;
mMovingName = buttonView.getConfigName();
mMovingLastX = x;
mMovingLastY = y;
return true;
}
}
for (TouchscreenControllerAxisView axisView : mAxisViews) {
axisView.getHitRect(rect);
if (rect.contains((int) x, (int) y)) {
mMovingView = axisView;
mMovingName = axisView.getConfigName();
mMovingLastX = x;
mMovingLastY = y;
return true;
}
}
// nothing..
return true;
}
case MotionEvent.ACTION_MOVE: {
if (mMovingView == null)
return true;
final float x = event.getX();
final float y = event.getY();
final float dx = x - mMovingLastX;
final float dy = y - mMovingLastY;
mMovingLastX = x;
mMovingLastY = y;
final float posX = mMovingView.getX() + dx;
final float posY = mMovingView.getY() + dy;
//Log.d("Position", String.format("%f %f -> (%f %f) %f %f",
// mMovingView.getX(), mMovingView.getY(), dx, dy, posX, posY));
mMovingView.setX(posX);
mMovingView.setY(posY);
mMovingView.invalidate();
mMainView.requestLayout();
return true;
}
}
return false;
}
private boolean handleTouchEvent(MotionEvent event) {
switch (event.getActionMasked())
{
case MotionEvent.ACTION_UP:
{
switch (event.getActionMasked()) {
case MotionEvent.ACTION_UP: {
if (!AndroidHostInterface.hasInstanceAndEmulationThreadIsRunning())
return false;
for (TouchscreenControllerButtonView buttonView : mButtonViews) {
buttonView.setPressed(false);
}
@@ -160,8 +387,10 @@ public class TouchscreenControllerView extends FrameLayout {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_MOVE:
{
case MotionEvent.ACTION_MOVE: {
if (!AndroidHostInterface.hasInstanceAndEmulationThreadIsRunning())
return false;
Rect rect = new Rect();
final int pointerCount = event.getPointerCount();
final int liftedPointerIndex = (event.getActionMasked() == MotionEvent.ACTION_POINTER_UP) ? event.getActionIndex() : -1;

View File

@@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2l-5.5,9h11z" />
<path
android:fillColor="@android:color/white"
android:pathData="M17.5,17.5m-4.5,0a4.5,4.5 0,1 1,9 0a4.5,4.5 0,1 1,-9 0" />
<path
android:fillColor="@android:color/white"
android:pathData="M3,13.5h8v8H3z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M20,6h-8l-2,-2L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,8c0,-1.1 -0.9,-2 -2,-2zM20,18L4,18L4,8h16v10z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M15,7.5V2H9v5.5l3,3 3,-3zM7.5,9H2v6h5.5l3,-3 -3,-3zM9,16.5V22h6v-5.5l-3,-3 -3,3zM16.5,9l-3,3 3,3H22V9h-5.5z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,7h-3v5.5c0,1.38 -1.12,2.5 -2.5,2.5S10,13.88 10,12.5s1.12,-2.5 2.5,-2.5c0.57,0 1.08,0.19 1.5,0.51L14,5h4v2zM4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:height="60dp" android:tint="?attr/colorControlNormal"
android:viewportHeight="24" android:viewportWidth="24"
android:width="60dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8 0,-1.85 0.63,-3.55 1.69,-4.9L16.9,18.31C15.55,19.37 13.85,20 12,20zM18.31,16.9L7.1,5.69C8.45,4.63 10.15,4 12,4c4.42,0 8,3.58 8,8 0,1.85 -0.63,3.55 -1.69,4.9z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M4,10h12v2L4,12zM4,6h12v2L4,8zM4,14h8v2L4,16zM14,14v6l5,-3z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z" />
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z" />
</vector>

View File

@@ -3,19 +3,19 @@
android:height="194.89dp"
android:viewportWidth="194.89"
android:viewportHeight="194.89">
<path
android:pathData="M194.89,97.445A97.445,97.445 0,0 1,97.445 194.89,97.445 97.445,0 0,1 0,97.445 97.445,97.445 0,0 1,97.445 0,97.445 97.445,0 0,1 194.89,97.445Z"
android:strokeAlpha="0.50645"
android:fillColor="#1a1a1a"
android:fillAlpha="0.504414"/>
<path
android:pathData="M178.82,97.445A81.381,81.381 0,0 1,97.439 178.826,81.381 81.381,0 0,1 16.058,97.445 81.381,81.381 0,0 1,97.439 16.064,81.381 81.381,0 0,1 178.82,97.445Z"
android:strokeAlpha="0.50645"
android:fillColor="#333333"
android:fillAlpha="0.504414"/>
<path
android:pathData="M159.05,97.445A61.609,61.609 0,0 1,97.441 159.054,61.609 61.609,0 0,1 35.832,97.445 61.609,61.609 0,0 1,97.441 35.836,61.609 61.609,0 0,1 159.05,97.445Z"
android:strokeAlpha="0.50645"
android:fillColor="#1a1a1a"
android:fillAlpha="0.504414"/>
<path
android:pathData="M194.89,97.445A97.445,97.445 0,0 1,97.445 194.89,97.445 97.445,0 0,1 0,97.445 97.445,97.445 0,0 1,97.445 0,97.445 97.445,0 0,1 194.89,97.445Z"
android:strokeAlpha="0.50645"
android:fillColor="#1a1a1a"
android:fillAlpha="0.504414" />
<path
android:pathData="M178.82,97.445A81.381,81.381 0,0 1,97.439 178.826,81.381 81.381,0 0,1 16.058,97.445 81.381,81.381 0,0 1,97.439 16.064,81.381 81.381,0 0,1 178.82,97.445Z"
android:strokeAlpha="0.50645"
android:fillColor="#333333"
android:fillAlpha="0.504414" />
<path
android:pathData="M159.05,97.445A61.609,61.609 0,0 1,97.441 159.054,61.609 61.609,0 0,1 35.832,97.445 61.609,61.609 0,0 1,97.441 35.836,61.609 61.609,0 0,1 159.05,97.445Z"
android:strokeAlpha="0.50645"
android:fillColor="#1a1a1a"
android:fillAlpha="0.504414" />
</vector>

View File

@@ -3,9 +3,9 @@
android:height="191.756dp"
android:viewportWidth="191.756"
android:viewportHeight="191.756">
<path
android:pathData="M191.756,95.878A95.878,95.878 0,0 1,95.878 191.756,95.878 95.878,0 0,1 0,95.878 95.878,95.878 0,0 1,95.878 0,95.878 95.878,0 0,1 191.756,95.878Z"
android:strokeAlpha="0.8"
android:fillColor="#666666"
android:fillAlpha="0.796784"/>
<path
android:pathData="M191.756,95.878A95.878,95.878 0,0 1,95.878 191.756,95.878 95.878,0 0,1 0,95.878 95.878,95.878 0,0 1,95.878 0,95.878 95.878,0 0,1 191.756,95.878Z"
android:strokeAlpha="0.8"
android:fillColor="#666666"
android:fillAlpha="0.796784" />
</vector>

View File

@@ -3,9 +3,9 @@
android:height="191.756dp"
android:viewportWidth="191.756"
android:viewportHeight="191.756">
<path
android:pathData="M191.756,95.878A95.878,95.878 0,0 1,95.878 191.756,95.878 95.878,0 0,1 0,95.878 95.878,95.878 0,0 1,95.878 0,95.878 95.878,0 0,1 191.756,95.878Z"
android:strokeAlpha="0.50645"
android:fillColor="#666666"
android:fillAlpha="0.504414"/>
<path
android:pathData="M191.756,95.878A95.878,95.878 0,0 1,95.878 191.756,95.878 95.878,0 0,1 0,95.878 95.878,95.878 0,0 1,95.878 0,95.878 95.878,0 0,1 191.756,95.878Z"
android:strokeAlpha="0.50645"
android:fillColor="#666666"
android:fillAlpha="0.504414" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -0,0 +1,9 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/settings"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".GameDirectoriesActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/activity_main">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:backgroundTint="@color/fab_background"
app:srcCompat="@android:drawable/ic_input_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -42,7 +42,7 @@
android:layout_gravity="bottom|end"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_marginRight="96dp"
app:backgroundTint="@android:color/background_light"
app:backgroundTint="@color/fab_background"
app:srcCompat="@drawable/ic_baseline_play_arrow_24" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
@@ -51,7 +51,7 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:backgroundTint="@android:color/background_light"
app:backgroundTint="@color/fab_background"
app:srcCompat="@android:drawable/ic_input_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextAppearance="@style/TabTextAppearance"
app:tabMode="fixed" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>

View File

@@ -22,7 +22,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="8dp"
android:layout_marginRight="64dp"
android:layout_marginRight="80dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Game Title"
@@ -32,11 +32,11 @@
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/game_list_view_entry_path"
android:id="@+id/game_list_view_entry_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="64dp"
android:layout_marginRight="80dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:paddingBottom="8px"
@@ -46,17 +46,16 @@
app:layout_constraintStart_toEndOf="@+id/game_list_view_entry_type_icon"
app:layout_constraintTop_toBottomOf="@+id/game_list_view_entry_title" />
<TextView
android:id="@+id/game_list_view_entry_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<ImageView
android:id="@+id/game_list_view_compatibility_icon"
android:layout_width="64dp"
android:layout_height="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="123.4 MB"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textSize="12sp"
app:srcCompat="@drawable/ic_star_5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -64,13 +63,13 @@
android:id="@+id/game_list_view_entry_region_icon"
android:layout_width="32dp"
android:layout_height="28dp"
android:layout_marginTop="8px"
android:layout_marginEnd="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="24dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:paddingBottom="8px"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/game_list_view_entry_size"
app:layout_constraintTop_toBottomOf="@+id/game_list_view_compatibility_icon"
app:srcCompat="@drawable/flag_jp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/controller_binding_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="0dp"
android:layout_alignParentTop="true"
tools:srcCompat="@drawable/ic_media_cdrom" />
<TextView
android:id="@+id/controller_binding_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="0dp"
android:text="Up"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/controller_binding_icon" />
<TextView
android:id="@+id/controller_binding_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="Controller0/Button0"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:layout_toRightOf="@id/controller_binding_icon"
android:layout_below="@id/controller_binding_name" />
</RelativeLayout>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginStart="10dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/recursive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:layout_below="@id/path"
android:layout_alignParentStart="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="TextView" />
<ImageButton
android:id="@+id/remove"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:background="?android:selectableItemBackground"
app:srcCompat="@drawable/ic_baseline_delete_24" />
<ImageButton
android:id="@+id/toggle_recursive"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:layout_toStartOf="@id/remove"
android:background="?android:selectableItemBackground"
app:srcCompat="@drawable/ic_baseline_folder_24" />
</RelativeLayout>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/property_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginStart="10dp"
android:layout_alignParentTop="true"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/property_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:layout_below="@id/property_title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="TextView" />
</RelativeLayout>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/stop_editing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/touchscreen_controller_stop_editing"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/reset_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:text="@string/touchscreen_controller_reset_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="80dp"
android:layout_height="60dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="4dp"
android:layout_marginLeft="15dp"
android:layout_alignParentTop="true"
android:scaleType="fitXY"
tools:srcCompat="@drawable/ic_media_cdrom" />
<TextView
android:id="@+id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="8dp"
android:text="Game Slot 1"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/image" />
<TextView
android:id="@+id/game"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="0dp"
android:text="SCES-0000 - Game Name"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:layout_below="@id/summary"
android:layout_toRightOf="@id/image" />
<TextView
android:id="@+id/path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="0dp"
android:text="Dump Name.chd"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:layout_below="@id/game"
android:layout_toRightOf="@id/image" />
<TextView
android:id="@+id/timestamp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="14dp"
android:text="Saved at Timestamp"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:layout_below="@id/path"
android:layout_toRightOf="@id/image" />
</RelativeLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_load_profile"
android:title="Load Profile"
android:icon="@drawable/ic_baseline_folder_open_24"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_save_profile"
android:title="Save Profile"
android:icon="@drawable/ic_baseline_save_24"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_clear_bindings"
android:title="Clear Bindings" />
</menu>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/add_directory"
android:title="@string/menu_edit_game_directories_add_directory" />
<item
android:id="@+id/add_path"
android:title="@string/menu_edit_game_directories_add_path" />
</menu>

View File

@@ -3,8 +3,11 @@
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/game_list_entry_menu_start_game"
android:title="Start Game" />
android:title="@string/menu_game_list_entry_start_game" />
<item
android:id="@+id/game_list_entry_menu_resume_game"
android:title="Resume Game" />
android:title="@string/menu_game_list_entry_resume_game" />
<item
android:id="@+id/game_list_entry_menu_properties"
android:title="Game Properties" />
</menu>

View File

@@ -5,28 +5,46 @@
<group android:id="@+id/start_menu">
<item
android:id="@+id/action_resume"
android:title="Resume Last Session" />
android:title="@string/menu_main_resume_last_session" />
<item
android:id="@+id/action_start_file"
android:title="@string/menu_main_start_file" />
<item
android:id="@+id/action_start_bios"
android:title="Start BIOS" />
android:title="@string/menu_main_start_bios" />
</group>
<group android:id="@+id/game_list">
<item
android:id="@+id/action_add_game_directory"
android:title="Add Game Directory" />
android:id="@+id/action_edit_game_directories"
android:title="@string/menu_main_edit_game_directories" />
<item
android:id="@+id/action_scan_for_new_games"
android:title="Scan For New Games" />
android:title="@string/menu_main_scan_for_new_games" />
<item
android:id="@+id/action_rescan_all_games"
android:title="Rescan All Games" />
android:title="@string/menu_main_rescan_all_games" />
<item
android:id="@+id/action_import_bios"
android:title="Import BIOS" />
android:title="@string/menu_main_import_bios" />
<item
android:id="@+id/action_show_version"
android:title="@string/menu_main_show_version" />
<item
android:id="@+id/action_github_respository"
android:title="@string/menu_main_github_repository" />
<item
android:id="@+id/action_discord_server"
android:title="@string/menu_main_discord_server" />
</group>
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
android:id="@+id/action_controller_mapping"
android:icon="@drawable/ic_baseline_gamepad_24"
android:orderInCategory="100"
app:showAsAction="never" />
android:title="@string/action_controller_mapping" />
<item
android:id="@+id/action_settings"
android:icon="@drawable/ic_baseline_settings_24"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="ifRoom" />
</menu>

View File

@@ -0,0 +1,235 @@
<resources>
<string-array name="settings_console_region_entries">
<item>Auto-Detectar</item>
<item>NTSC-J (Japón)</item>
<item>NTSC-U (US)</item>
<item>PAL (Europa, Australia)</item>
</string-array>
<string-array name="settings_cpu_execution_mode_entries">
<item>Intérprete (El más lento)</item>
<item>Intérprete en Caché (Rápido)</item>
<item>Recompilador (Más rápido)</item>
</string-array>
<string-array name="settings_cpu_fastmem_mode_entries">
<item>Deshabilitado (El más lento)</item>
<item>MMap (Hardware, Más rápido, 64-Bit Solamente)</item>
<item>LUT (Rápido)</item>
</string-array>
<string-array name="gpu_renderer_entries">
<item>Hardware (OpenGL)</item>
<item>Hardware (Vulkan)</item>
<item>Software</item>
</string-array>
<string-array name="settings_gpu_resolution_scale_entries">
<item>1x</item>
<item>2x</item>
<item>3x (para 720p)</item>
<item>4x</item>
<item>5x (para 1080p)</item>
<item>6x (para 1440p)</item>
<item>7x</item>
<item>8x</item>
<item>9x (para 4K)</item>
<item>10x</item>
<item>11x</item>
<item>12x</item>
<item>13x</item>
<item>14x</item>
<item>15x</item>
<item>16x</item>
</string-array>
<string-array name="settings_display_crop_mode_entries">
<item>Ninguno</item>
<item>Sólo área de sobreescaneo</item>
<item>Todos los bordes</item>
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Nativo del juego)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>
<item>19:9</item>
<item>20:9</item>
<item>21:9</item>
<item>32:9</item>
<item>8:7</item>
<item>5:4</item>
<item>3:2</item>
<item>2:1 (VRAM 1:1)</item>
<item>1:1</item>
<item>PAR 1:1</item>
</string-array>
<string-array name="settings_gpu_texture_filter_names">
<item>Nearest-Neighbor</item>
<item>Bilinear</item>
<item>Bilinear (Sin unión de bordes)</item>
<item>JINC2</item>
<item>JINC2 (Sin unión de bordes)</item>
<item>xBR</item>
<item>xBR (Sin unión de bordes)</item>
</string-array>
<string-array name="settings_controller_type_entries">
<item>Control Digital (Mando)</item>
<item>Control Analógico (DualShock)</item>
</string-array>
<string-array name="settings_memory_card_mode_entries">
<item>Sin tarjeta de memoria</item>
<item>Compartido entre todos los juegos</item>
<item>Tarjeta separada por juego (Código)</item>
<item>Tarjeta separada por juego (Título)</item>
</string-array>
<string-array name="emulation_menu">
<item>Cargar Estado</item>
<item>Guardar Estado</item>
<item>Activar Avance Rápido</item>
<item>Más Opciones</item>
<item>Salir</item>
</string-array>
<string-array name="emulation_more_menu">
<item>Reiniciar</item>
<item>Código de Trucos</item>
<item>Cambiar Disco</item>
<item>Configuraciones</item>
<item>Cambiar Control de Pantalla Tactil</item>
<item>Editar Diseño del Control de Pantalla Tactil</item>
</string-array>
<string-array name="settings_cdrom_read_speedup_entries">
<item>Ninguno (Velocidad Doble)</item>
<item>2x (Velocidad Cuádruple)</item>
<item>3x (6x Velocidad)</item>
<item>4x (8x Velocidad)</item>
<item>5x (10x Velocidad)</item>
<item>6x (12x Velocidad)</item>
<item>7x (14x Velocidad)</item>
<item>8x (16x Velocidad)</item>
<item>9x (18x Velocidad)</item>
<item>10x (20x Velocidad)</item>
</string-array>
<string-array name="settings_touchscreen_controller_view_entries">
<item>Ninguno</item>
<item>Digital Pad</item>
<item>Pad Analógico Unico</item>
<item>Pad Analógico Dual</item>
</string-array>
<string-array name="settings_audio_backend_entries">
<item>Nulo (Sin Salida)</item>
<item>Cubeb</item>
<item>OpenSL ES (Recomendado)</item>
</string-array>
<string-array name="settings_audio_buffer_size_entries">
<item>1024 Fotogramas (23.22ms)</item>
<item>2048 Fotogramas (46.44ms, Recomendado)</item>
<item>3072 Fotogramas (69.66ms)</item>
<item>4096 Fotogramas (92.88ms)</item>
</string-array>
<string-array name="settings_log_level_entries">
<item>Ninguno</item>
<item>Error</item>
<item>Alerta</item>
<item>Alertas de Rendimiento</item>
<item>Información</item>
<item>Detalles</item>
<item>Desarrollador</item>
<item>Perfil</item>
<item>Depurar</item>
<item>Seguimiento</item>
</string-array>
<string-array name="settings_tabs">
<item>General</item>
<item>Pantalla</item>
<item>Audio</item>
<item>Mejoras</item>
<item>Controles</item>
<item>Avanzado</item>
</string-array>
<string-array name="settings_gpu_msaa_entries">
<item>Deshabilitado</item>
<item>2x MSAA</item>
<item>4x MSAA</item>
<item>8x MSAA</item>
<item>2x SSAA</item>
<item>4x SSAA</item>
<item>8x SSAA</item>
</string-array>
<string-array name="settings_advanced_display_fps_limit_entries">
<item>Ilimitado (Mostrar fotogramas)</item>
<item>10 FPS</item>
<item>15 FPS</item>
<item>30 FPS</item>
<item>45 FPS</item>
<item>60 FPS</item>
<item>75 FPS</item>
<item>90 FPS</item>
</string-array>
<string-array name="settings_emulation_speed_entries">
<item>Ilimitado</item>
<item>10% [6 FPS (NTSC) / 5 FPS (PAL)]</item>
<item>20% [12 FPS (NTSC) / 10 FPS (PAL)]</item>
<item>30% [18 FPS (NTSC) / 15 FPS (PAL)]</item>
<item>40% [24 FPS (NTSC) / 20 FPS (PAL)]</item>
<item>50% [30 FPS (NTSC) / 25 FPS (PAL)]</item>
<item>60% [36 FPS (NTSC) / 30 FPS (PAL)]</item>
<item>70% [42 FPS (NTSC) / 35 FPS (PAL)]</item>
<item>80% [48 FPS (NTSC) / 40 FPS (PAL)]</item>
<item>90% [54 FPS (NTSC) / 45 FPS (PAL)]</item>
<item>100% [60 FPS (NTSC) / 50 FPS (PAL), Defecto]</item>
<item>125% [75 FPS (NTSC) / 62 FPS (PAL)]</item>
<item>150% [90 FPS (NTSC) / 75 FPS (PAL)]</item>
<item>175% [105 FPS (NTSC) / 87 FPS (PAL)]</item>
<item>200% [120 FPS (NTSC) / 100 FPS (PAL)]</item>
<item>250% [150 FPS (NTSC) / 125 FPS (PAL)]</item>
<item>300% [180 FPS (NTSC) / 150 FPS (PAL)]</item>
<item>350% [210 FPS (NTSC) / 175 FPS (PAL)]</item>
<item>400% [240 FPS (NTSC) / 200 FPS (PAL)]</item>
<item>450% [270 FPS (NTSC) / 225 FPS (PAL)]</item>
<item>500% [300 FPS (NTSC) / 250 FPS (PAL)]</item>
<item>600% [360 FPS (NTSC) / 300 FPS (PAL)]</item>
<item>700% [420 FPS (NTSC) / 350 FPS (PAL)]</item>
<item>800% [480 FPS (NTSC) / 400 FPS (PAL)]</item>
<item>900% [540 FPS (NTSC) / 450 FPS (PAL)]</item>
<item>1000% [600 FPS (NTSC) / 500 FPS (PAL)]</item>
</string-array>
<string-array name="settings_advanced_cpu_overclock_entries">
<item>25% (8MHz)</item>
<item>50% (16MHz)</item>
<item>75% (24MHz)</item>
<item>100% (33MHz, Defecto)</item>
<item>125% (41MHz)</item>
<item>150% (49MHz)</item>
<item>175% (57MHz)</item>
<item>200% (66MHz)</item>
<item>225% (74MHz)</item>
<item>250% (82MHz)</item>
<item>275% (90MHz)</item>
<item>300% (99MHz)</item>
<item>350% (115MHz)</item>
<item>400% (132MHz)</item>
<item>450% (148MHz)</item>
<item>500% (165MHz)</item>
<item>500% (165MHz)</item>
<item>600% (198MHz)</item>
<item>700% (231MHz)</item>
<item>800% (264MHz)</item>
<item>900% (297MHz)</item>
<item>1000% (330MHz)</item>
</string-array>
<string-array name="settings_emulation_screen_orientation_entries">
<item>Usar configuración del dipositivo</item>
<item>Vertical</item>
<item>Horizontal</item>
</string-array>
<string-array name="settings_theme_entries">
<item>Usar configuración del Sistema</item>
<item>Claro</item>
<item>Oscuro</item>
</string-array>
<string-array name="settings_downsample_mode_entries">
<item>Deshabilitado</item>
<item>Cuadro (Reducir Resolución 3D/Suavizar todo)</item>
<item>Adaptable (Preservar 3D/Suavizar 2D)</item>
</string-array>
<string-array name="settings_boolean_entries">
<item>Deshabilitado</item>
<item>Halibtado</item>
</string-array>
</resources>

View File

@@ -0,0 +1,205 @@
<resources>
<string name="app_name">DuckStation</string>
<string name="action_settings">Configuraciones</string>
<string name="action_controller_mapping">Mapeado del Control</string>
<string name="title_activity_settings">Configuraciones</string>
<string name="settings_console_region">Región de Consola</string>
<string name="settings_console_tty_output">Habilitar Salida TTY</string>
<string name="settings_console_fast_boot">Inicio Rápido</string>
<string name="settings_osd_show_messages">Mostrar Mensajes</string>
<string name="settings_osd_show_speed">Mostrar Velocidad de Emulación</string>
<string name="settings_osd_show_show_fps">Mostrar FPS</string>
<string name="settings_osd_show_show_vps">Mostrar VPS</string>
<string name="settings_cpu_execution_mode">Modo de Ejecución de CPU</string>
<string name="settings_gpu_renderer">Renderizador de GPU</string>
<string name="settings_gpu_resolution_scale">Escala de Resolución</string>
<string name="title_activity_emulation">Actividad de Emulación</string>
<string name="settings_emulation_speed">Velocidad de Emulación</string>
<string name="settings_fast_forward_speed">Velocidad de Avance Rápido</string>
<string name="settings_save_state_on_exit">Guardar Estado al Salir</string>
<string name="settings_pause_when_menu_opened">Pausar cuando el menu se abre</string>
<string name="settings_emulation_screen_orientation">Orientación de pantalla del Emulador</string>
<string name="settings_load_patch_codes">Cargar Códigos de Parche</string>
<string name="settings_summary_save_state_on_exit">Guarda automáticamente el estado del emulador al apagar o salir. Después puedes continuar desde donde lo dejaste la última vez.</string>
<string name="settings_summary_pause_when_menu_opened">Pausa la emulación dentro del juego cuando el menú es abierto.</string>
<string name="settings_summary_load_patch_codes"><![CDATA[Cargar Códigos de Parche de trucos/<game name>.cht en formato PCSXR. Los códigos pueden ser activados dentro del juego.]]></string>
<string name="settings_apply_compatibility_settings">Aplicar configuración de compatiblidad</string>
<string name="settings_summary_apply_compatibility_settings">Desactiva las mejoras automáticamente cuando no son compatibles con los juegos.</string>
<string name="settings_summary_video_sync">Habilita esta opción para coincidir la tasa de refresco de DuckStation con la de tu pantalla. La VSync se deshabilita automáticamente cuando no sea posible (ejemplo, no llegar al 100% de la velocidad).</string>
<string name="settings_video_sync">Sincronizar Video</string>
<string name="settings_cpu_overclocking">CPU Overclocking</string>
<string name="settings_cdrom_region_check">Chequeo Regional de CD-ROM</string>
<string name="settings_summary_cdrom_region_check">Evita que el emulador lea discos de regiones incorrectas. Comúnmente es seguro desactivarlo.</string>
<string name="settings_cdrom_preload_image_to_ram">Precargar imagen a RAM de CD-ROM</string>
<string name="settings_summary_preload_image_to_ram">Carga la imagen del juego en la RAM. Útil para cuando se usan directorios a través de una red. En algunas ocasiones puede eliminar las pausas que se generan cuando el juego inicia la reproducción de una pista de audio.</string>
<string name="settings_pgxp_vertex_cache">Caché de vértices PGXP</string>
<string name="settings_summary_pgxp_vertex_cache">Utiliza las coordenadas de la pantalla como respaldo cuando falla el seguimiento de vértices a través de la memoria. Puede mejorar la compatibilidad con PGXP.</string>
<string name="settings_pgxp_cpu_mode">Modo PGXP CPU</string>
<string name="settings_summary_pgxp_cpu_mode">Intenta rastrear la manipulación de vértices a través del CPU. Algunos juegos requieren esta opción para que PGXP sea efectivo. Muy lento e incompatible con el recompilador.</string>
<string name="settings_cpu_recompiler_icache">CPU Recompilado ICache</string>
<string name="settings_summary_cpu_recompiler_icache">Determina si la caché de instrucciones del CPU se simula en el recompilador. Mejora la precisión con un pequeño coste de rendimiento. Si los juegos corren demasiado rápido, intenta habilitar esta opción.</string>
<string name="settings_cpu_recompiler_fastmem">CPU Recompilador de acceso rápido a la memoria</string>
<string name="settings_summary_cpu_recompiler_fastmem">Hace que el acceso de memoria de los invitados sea más eficiente mediante el uso de errores de página y parches. Desactívalo si es inestable en tu dispositivo.</string>
<string name="settings_presented_frame_limit">Límite de fotogramas presentados</string>
<string name="settings_logging_level">Nivel de Registro</string>
<string name="settings_log_to_file">Registrar en Archivo</string>
<string name="settings_summary_log_to_file">Escribe los mensajes de registros duckstation.log en tu directorio de Usuario. Usarlo solamente para depurar, ya que ralentiza la emulación.</string>
<string name="settings_log_to_logcat">Registrar en Logcat</string>
<string name="settings_summary_log_to_logcat">Escribe los mensajes de registros en el registrador de mensajes de Android. Solo es útil cuando se conecta a una computadora con adb.</string>
<string name="settings_volume">Volumen</string>
<string name="settings_summary_volume">Controla el volumen de salida de audio del emulador.</string>
<string name="settings_fast_forward_volume">Volumen de Avance Rápido</string>
<string name="settings_summary_fast_forward_volume">Controla el volumen de salida de audio del emulador que durante el avance rápido.</string>
<string name="settings_mute_all_sound">Silenciar todo</string>
<string name="settings_summary_mute_all_sound">Evita que el emulador emita cualquier sonido.</string>
<string name="settings_mute_cd_audio">Silenciar audio de CD</string>
<string name="settings_summary_mute_cd_audio">Silecia a la fuerza el audio CD-DA y XA del CD-ROM. Puede usarse para deshabilitar la música de fondo en algunos juegos.</string>
<string name="settings_audio_backend">Motor de Audio</string>
<string name="settings_audio_buffer_size">Tamaño del Búfer de Audio</string>
<string name="settings_summary_audio_buffer_size">Determina la latencia entre el audio que se genera y de salida por altavoces. Los valores más pequeños reducen la latencia, pero las variaciones en la velocidad de emulación causarán problemas.</string>
<string name="settings_audio_sync">Sincronizar Audio</string>
<string name="settings_summary_audio_sync">Acelera la velocidad de la emulación basado en los fotogramas de audio enviados por el motor de audio. Esto ayuda a eliminar ruidos o distorsiones si la emulación es muy rápida. La sincronización se desabilitará automáticamente si la velocidad no es del 100%.</string>
<string name="settings_controller_type">Tipo de Control</string>
<string name="settings_enable_analog_mode_on_reset">Habilitar el Modo Analógico al Reiniciar</string>
<string name="settings_touchscreen_controller_view">Vista de Control de Pantalla Táctil</string>
<string name="settings_auto_hide_touchscreen_controller">Auto-Ocultar el control de pantalla táctil</string>
<string name="settings_summary_auto_hide_touchscreen_controller">Oculta el control de pantalla táctil cuando un control externo es detectado.</string>
<string name="settings_vibrate_on_press">Vibrar al presionar</string>
<string name="settings_summary_vibrate_on_press">Permite una vibración corta cuando un botón en la pantalla táctil es presionado. Requiere que \"Vibrar al presionar\" esté habilitado en tu dispositivo.</string>
<string name="settings_enable_vibration">Activar Vibración</string>
<string name="settings_summary_enable_vibration">Reenvía el ruido del juego al motor de vibración del teléfono..</string>
<string name="settings_memory_card_1_type">Tarjeta de Memoria Tipo 1</string>
<string name="settings_memory_card_2_type">Tarjeta de Memoria Tipo 2</string>
<string name="settings_crop_mode">Modo de recorte</string>
<string name="settings_aspect_ratio">Relación de Aspecto</string>
<string name="settings_linear_upscaling">Escalado Lineal</string>
<string name="settings_integer_upscaling">Escalado Entero</string>
<string name="settings_summary_linear_upscaling">Suaviza la imagen al escalar la consola a la pantalla.</string>
<string name="settings_summary_integer_upscaling">Añade relleno en la pantalla para asegurarse que la relación entre los pixeles de la consola y del anfitrión es un número entero. Puede resultar en una imagen más nítida en algunos juegos 2D.</string>
<string name="settings_summary_osd_show_messages">Muestra mensajes en pantalla cuando ocurren eventos como crear o cargar estados guardados, tomar capturas, etc.</string>
<string name="settings_summary_osd_show_speed">Establece la velocidad de emulación de destino. No se asegura que esa velocidad se vaya a alcanzar, y de no hacerlo, el emulador va a correr lo más rápido que pueda.</string>
<string name="settings_summary_osd_show_fps">Muestra la velocidad de fotogramas interna del juego en la esquina superior derecha de la pantalla.</string>
<string name="settings_summary_osd_show_vps">Muestra el número de fotogramas (o sincronizaciones verticales) mostradas por segundo por el sistema en la esquina superior derecha de la pantalla.</string>
<string name="settings_cdrom_read_speedup">CD-ROM Aceleración de lectura</string>
<string name="settings_summary_cdrom_read_speedup">Acelera la lectura del CD-ROM para el valor especificado. Sólo se aplica a lecturas de doble velocidad, y se ignora cuando se está reproduciendo audio. Puede mejorar las velocidades de carga en algunos juegos, mientras que puede interrumpir otros.</string>
<string name="settings_summary_console_fast_boot">Omite el BIOS shell/intro, iniciando directamente en el juego. Normalmente es seguro habilitarlo, pero algunos juegos se tildan.</string>
<string name="settings_msaa">Anti-aliasing de muestreo múltiple</string>
<string name="settings_true_color">Renderizado de color verdadero (24-bit, deshabilita el tramado)</string>
<string name="settings_summary_true_color">Esto produce mejores gradientes al costo de hacer algunos colores diferentes. Deshabilitar esta opción también activa el tramado. La mayoría de los juegos son compatibles con esta opción.</string>
<string name="settings_scaled_dithering">Escalado de tramado (escalar patrón de tramado a resolución)</string>
<string name="settings_summary_scaled_dithering">Escala el patrón del tramado a la escala de resolución de la GPU emulada. Esto disimula el tramado en altas resoluciones. Usualmente es seguro habilitarlo, y sólo está soportado por los renderizadores de hardware.</string>
<string name="settings_disable_interlacing">Deshabilitar tramado (fuerza progresivamente renderizado/escaneo)</string>
<string name="settings_summary_disable_interlacing">Fuerza el renderizado y visualización de fotogramas en modo progresivo. Esto elimina el efecto \"peine\" visto en juegos con 480i renderizándolos en 480p. Normalmente es seguro habilitarlo.</string>
<string name="settings_texture_filtering">Filtrado de textura</string>
<string name="settings_force_ntsc_timings">Forzar tiempos NTSC (60hz en PAL)</string>
<string name="settings_summary_force_ntsc_timings">Usa los tiempos de fotograma del modo NTSC cuando la consola está en modo PAL, forzando los juegos PAL a correr a 60Hz.</string>
<string name="settings_widescreen_hack">Hack de Pantalla Panorámica</string>
<string name="settings_summary_widescreen_hack">Escala las posiciones de vértices en pantalla a una relación de aspecto panorámica, incrementando el campo de visión de 4:3 a 16:9 en juegos 3D. Tal vez no sea compatible con todos los juegos.</string>
<string name="settings_force_4_3_for_24bit">Forzar 4:3 para escenas 24-bit</string>
<string name="settings_summary_force_4_3_for_24bit">Cambia al modo de pantalla 4:3 cuando se muestra contenido de 24-bit, generalmente FMVs.</string>
<string name="settings_chroma_smoothing_24bit">Suavizado de croma para escenas 24-bit</string>
<string name="settings_summary_chrome_smoothing_24bit">Suaviza el efecto pixelado que se produce entre las transiciones de colores en contenido de 24-bit, generalmente en FMVs. Sólo se aplica a los renderizadores de hardware.</string>
<string name="settings_pgxp_geometry_correction">PGXP Corrección de Geometría</string>
<string name="settings_summary_pgxp_geometry_correction"><![CDATA[Reduce los polígonos \"temblorosos\" y las texturas \"deformadas\" que son comunes en juegos de PS1. >Solo funciona con los renderizadores de hardware. Tal vez no sea compatible con todos los juegos.]]></string>
<string name="settings_pgxp_culling_correction">PGXP Correción de Culling</string>
<string name="settings_summary_pgxp_culling_correction">Incrementa la precisión del culling de polígonos, reduciendo el número de huecos en la geometría. Requiere la correción de geometría activada.</string>
<string name="settings_pgxp_texture_correction">PGXP Corrección de Texturas</string>
<string name="settings_summary_pgxp_texture_correction">Usa interpolación con perspectiva correcta para las coordenadas de texturas y colores, enderezando texturas deformadas. Requiere la correción de geometría activada.</string>
<string name="settings_pgxp_preserve_projection_precision">PGXP Conservar la precisión de proyección</string>
<string name="settings_summary_pgxp_preserve_projection_precision">Permite precisión adicional para PGXP. Puede mejorar las imágenes en algunos juegos pero fallar en otros.</string>
<string name="settings_pgxp_depth_buffer">PGXP Búfer de Profundidad</string>
<string name="settings_summary_pgxp_depth_buffer">Intenta reducir los polígonos en el eje Z probando píxeles con los valores de profundidad de PGXP. Tiene baja compatibilidad, pero puede funcionar bien en algunos juegos.</string>
<string name="menu_main_resume_last_session">Reanudar la última sesión</string>
<string name="menu_main_start_file">Iniciar Archivo</string>
<string name="menu_main_start_bios">Iniciar BIOS</string>
<string name="menu_main_edit_game_directories">Editar Directorios de Juego</string>
<string name="menu_main_scan_for_new_games">Escanear para juegos nuevos</string>
<string name="menu_main_rescan_all_games">Reescanear todos los juegos</string>
<string name="menu_main_import_bios">Importar BIOS</string>
<string name="menu_main_show_version">Mostrar Versión</string>
<string name="menu_main_github_repository">Repositorio de GitHub</string>
<string name="menu_main_discord_server">Servidor de Discord</string>
<string name="menu_game_list_entry_start_game">Iniciar Juego</string>
<string name="menu_game_list_entry_resume_game">Reanudar Juego</string>
<string name="android_progress_callback_please_wait">Cargando...</string>
<string name="android_progress_callback_ok">OK</string>
<string name="android_progress_callback_information">Información</string>
<string name="android_progress_callback_confirmation">Confirmación</string>
<string name="android_progress_callback_yes">Si</string>
<string name="android_progress_callback_no">No</string>
<string name="emulation_activity_error">Error</string>
<string name="emulation_activity_ok">OK</string>
<string name="emulation_activity_import_patch_codes">Importar códigos de parche...</string>
<string name="emulation_activity_patch_on">(ENCENDIDO)</string>
<string name="emulation_activity_patch_off">(APAGADO)</string>
<string name="emulation_activity_choose_patch_code_file">Seleccionar Archivo con Códigos de Parche</string>
<string name="emulation_activity_failed_to_import_patch_codes">Fallo al importar códigos de parche. Asegúrese de seleccionar un archivo con formato PCSXR o Libretro.</string>
<string name="main_activity_choose_directory">Elegir Directorio</string>
<string name="main_activity_error">Error</string>
<string name="main_activity_get_path_from_file_error">No se pudo obtener la ruta del archivo seleccionado. Asegúrese de que el archivo esté un almacenamiento interno/externo.\n\nToque el botón que sobresale en el selector de directorio.\nSeleccione "Mostrar Almacenamiento Interno".\nToque el botón de menú y seleccione el nombre de su dispositivo o tarjeta SD .</string>
<string name="main_activity_ok">OK</string>
<string name="main_activity_get_path_from_directory_error">No se pudo obtener la ruta del directorio seleccionado. Asegúrese de que el directorio esté un almacenamiento interno/externo.\n\nToque el botón que sobresale en el selector de directorio.\nSeleccione \"Mostrar Almacenamiento Interno\".\nToque el botón de menú y seleccione el nombre de su dispositivo o tarjeta SD .</string>
<string name="main_activity_external_storage_permissions_error">Se requieren permisos de almacenamiento externo para usar DuckStation.</string>
<string name="main_activity_choose_disc_image">Seleccionar Imagen de Disco</string>
<string name="main_activity_missing_bios_image_prompt">No se encontró ninguna imagen de BIOS en el directorio BIOS de DuckStation. ¿Quiere localizar e importar una imagen de BIOS ahora?</string>
<string name="main_activity_missing_bios_image">Imagen BIOS Ausente</string>
<string name="main_activity_yes">Si</string>
<string name="main_activity_no">No</string>
<string name="main_activity_choose_bios_image">Elegir Imagen BIOS</string>
<string name="main_activity_failed_to_open_bios_image">Fallo al cargar la imagen BIOS.</string>
<string name="main_activity_failed_to_read_bios_image_prefix">\"Fallo al leer la imagen BIOS: \"</string>
<string name="main_activity_bios_image_too_large">La imagen de BIOS es demasiado grande.</string>
<string name="main_activity_invalid_error">Esta Imagen BIOS es incorrecta, o ya ha sido importado.</string>
<string name="main_activity_show_version_title">Version</string>
<string name="main_activity_copy">Copiar</string>
<string name="settings_gpu_thread">Renderizado de GPU con Hilos</string>
<string name="settings_summary_gpu_thread">Usa un segundo hilo para dibujar los gráficos. Actualmente solo está disponible para el renderizador por software, pero puede dar un aumento significante de velocidad, y es seguro de usar.</string>
<string name="settings_gpu_threaded_presentation">Presentación de GPU con subprocesos</string>
<string name="settings_summary_gpu_threaded_presentation">Presenta fotogramas en un hilo de fondo cuando el Avance Rápido o VSync está desactivado. Esto puede mejorar considerablemente el rendimiento en el renderizador Vulkan.</string>
<string name="settings_language">Idioma (reiniciar para aplicar)</string>
<string name="touchscreen_controller_stop_editing">Dejar de editar</string>
<string name="touchscreen_controller_reset_layout">Reiniciar Modelo</string>
<string name="emulation_activity_touchscreen_controller_not_active">El control de pantalla táctil no está activo.</string>
<string name="settings_theme">Tema</string>
<string name="settings_controller_mapping_summary">Permite asignar botones/ejes del control externo al controlador emulado.</string>
<string name="settings_controller_mapping">Mapeado de Control</string>
<string name="controller_binding_dialog_message">Presiona un botón del control para seleccionar una nueva asignación.\n\nAsignación Actual: %s</string>
<string name="controller_binding_dialog_no_binding"><![CDATA[<Sin Asignar>]]></string>
<string name="controller_binding_dialog_cancel">Cancelar</string>
<string name="controller_binding_dialog_clear">Limpiar</string>
<string name="controller_mapping_activity_title">Mapeado de Control</string>
<string name="controller_mapping_activity_no_profiles_found">No se encontraron perfiles.</string>
<string name="controller_mapping_activity_select_input_profile">Seleccionar perfil de control</string>
<string name="controller_mapping_activity_failed_to_load_profile">Fallo al cargar el perfil \'%s\'</string>
<string name="controller_mapping_activity_input_profile_name">Ingrese Nombre de Perfil:</string>
<string name="controller_mapping_activity_save">Guardar</string>
<string name="controller_mapping_activity_name_must_be_provided">Debe proporcionarse un nombre.</string>
<string name="controller_mapping_activity_failed_to_save_input_profile">Fallo al guardar perfil de control.</string>
<string name="controller_mapping_activity_input_profile_saved">Perfil de control \'%s\' guardado.</string>
<string name="controller_mapping_activity_cancel">Cancelar</string>
<string name="settings_use_analog_sticks_for_dpad">Usar las palancas analógicas como cruceta en el modo digital</string>
<string name="settings_summary_enable_analog_mode_on_reset">Fuerza el control al modo analógico cuando la consola se reinicia/enciende</string>
<string name="settings_summary_use_analog_sticks_for_dpad">Te permite usar las palancas analógicas para controlar la cruceta y los botones en modo digital.</string>
<string name="settings_disable_all_enhancements">Desactiva todas las mejoras</string>
<string name="settings_summary_disable_all_enhancements">Temporalmente desactiva todas las mejoras, el cual puede ser útil al depurar problemas.</string>
<string name="settings_downsample_mode">Submuestreo</string>
<string name="activity_game_properties">Propiedades del Juego</string>
<string name="game_properties_preference_use_global_setting">Usar configuración global</string>
<string name="settings_input_profile">Perfil de Control</string>
<string name="game_properties_tab_summary">Resumen</string>
<string name="game_properties_tab_game_settings">Configuraciones de juego</string>
<string name="game_properties_tab_controller_settings">Configuraciones de Control</string>
<string name="settings_audio_resampling">Remuestreo de Audio</string>
<string name="settings_summary_audio_resampling">Cuando se ejecuta por encima del 100% de velocidad, vuelve a muestrear el audio de la velocidad objetivo en lugar de eliminar fotogramas. Produce un audio de avance/desaceleración mucho más agradable a un pequeño costo del rendimiento.</string>
<string name="settings_general_sync_to_host_refresh_rate">Sincronizar con la velocidad de actualización del anfitrión</string>
<string name="settings_summary_general_sync_to_host_refresh_rate">Ajusta la velocidad de emulación para que la frecuencia de actualización de la consola coincida con la frecuencia de actualización del anfitrión cuando las configuraciones de VSync y Remuestreo de audio estén habilitados. Esto da como resultado las animaciones más suaves posibles, a costa de aumentar potencialmente la velocidad de emulación en menos del 1%.</string>
<string name="settings_sustained_performance_mode">Modo de Rendimiento Sostenido</string>
<string name="settings_summary_sustained_performance_mode">Habilita el Modo de Rendimiento Sostenido por Android. Puede resultar en velocidades de fotogramas más consistentes para sesiones largas en algunos dispositivos.</string>
<string name="title_activity_game_directories">Editar Directorio de juegos</string>
<string name="settings_game_directories">Directorio de juegos</string>
<string name="settings_summary_game_directories">Cambia la lista de directorio que se utiliza para buscar juegos.</string>
<string name="game_directories_scanning_subdirectories">Escaneo de subdirectorios.</string>
<string name="game_directories_not_scanning_subdirectories">No escanear subdirectorios.</string>
<string name="settings_display_all_frames">Optimizar Frame Pacing</string>
<string name="settings_summary_display_all_frames">Habilitar esta opción asegurará que cada fotograma que la consola renderice se muestre en la pantalla, para un ritmo de fotograma óptimo. Si tiene dificultades para mantener la velocidad máxima o problemas de audio, intente desactivar esta opción.</string>
</resources>

View File

@@ -0,0 +1,221 @@
<resources>
<string-array name="settings_console_region_entries">
<item>Auto-Rileva</item>
<item>NTSC-J (Giappone)</item>
<item>NTSC-U (US, Canada)</item>
<item>PAL (Europa, Australia)</item>
</string-array>
<string-array name="settings_cpu_execution_mode_entries">
<item>Interprete (Il più lento)</item>
<item>Cached Interpreter (Più veloce)</item>
<item>Recompiler (Il più veloce)</item>
</string-array>
<string-array name="settings_cpu_fastmem_mode_entries">
<item>Disabilitato (Il più lento)</item>
<item>MMap (Hardware, il più veloce, Solo 64-Bit)</item>
<item>LUT (Più veloce)</item>
</string-array>
<string-array name="gpu_renderer_entries">
<item>Hardware (OpenGL)</item>
<item>Hardware (Vulkan)</item>
<item>Software</item>
</string-array>
<string-array name="settings_gpu_resolution_scale_entries">
<item>1x</item>
<item>2x</item>
<item>3x (per 720p)</item>
<item>4x</item>
<item>5x (per 1080p)</item>
<item>6x (per 1440p)</item>
<item>7x</item>
<item>8x</item>
<item>9x (per 4K)</item>
<item>10x</item>
<item>11x</item>
<item>12x</item>
<item>13x</item>
<item>14x</item>
<item>15x</item>
<item>16x</item>
</string-array>
<string-array name="settings_display_crop_mode_entries">
<item>None</item>
<item>Solo area di Overscan</item>
<item>Tutti i bordi</item>
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Game Native)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>
<item>19:9</item>
<item>20:9</item>
<item>21:9</item>
<item>32:9</item>
<item>8:7</item>
<item>5:4</item>
<item>3:2</item>
<item>2:1 (VRAM 1:1)</item>
<item>1:1</item>
<item>PAR 1:1</item>
</string-array>
<string-array name="settings_gpu_texture_filter_names">
<item>Nearest-Neighbor</item>
<item>Bilineare</item>
<item>Bilineare (No Blending Bordi)</item>
<item>JINC2</item>
<item>JINC2 (No Blending Bordi)</item>
<item>xBR</item>
<item>xBR (No Blending Bordi)</item>
</string-array>
<string-array name="settings_controller_type_entries">
<item>Controller Digitale (Gamepad)</item>
<item>Controller Analogico (DualShock)</item>
</string-array>
<string-array name="settings_memory_card_mode_entries">
<item>No Memory Card</item>
<item>Condivisa fra tutti i giochi</item>
<item>MC separata per ogni gioco (Codice Gioco)</item>
<item>MC separata per ogni gioco (Titolo Gioco)</item>
</string-array>
<string-array name="emulation_menu">
<item>Carica Stato</item>
<item>Salva Stato</item>
<item>Abilita/Disabilita Avanti Veloce</item>
<item>Altre Opzioni</item>
<item>Esci</item>
</string-array>
<string-array name="emulation_more_menu">
<item>Reset</item>
<item>Codici Patch</item>
<item>Cambia Disco</item>
<item>Impostazioni</item>
<item>Cambia Controller Touchscreen</item>
<item>Edit Touchscreen Controller Layout</item>
</string-array>
<string-array name="settings_cdrom_read_speedup_entries">
<item>Nessuna Velocità Doppia)</item>
<item>2x (Velocità Quadrupla</item>
<item>3x (Velocità 6x)</item>
<item>4x (Velocità 8x)</item>
<item>5x (Velocità 10x)</item>
<item>6x (Velocità 12x)</item>
<item>7x (Velocità 14x)</item>
<item>8x (Velocità 16x)</item>
<item>9x (Velocità 18x)</item>
<item>10x (Velocità 20x)</item>
</string-array>
<string-array name="settings_touchscreen_controller_view_entries">
<item>Nessuno</item>
<item>Pad Digitale</item>
<item>Pad Analogico Singolo</item>
<item>Pad Analogico Doppio</item>
</string-array>
<string-array name="settings_audio_backend_entries">
<item>Null (No Output)</item>
<item>Cubeb</item>
<item>OpenSL ES (Raccomandato)</item>
</string-array>
<string-array name="settings_audio_buffer_size_entries">
<item>1024 Fotogrammi (23.22ms)</item>
<item>2048 Fotogrammi (46.44ms, Raccomandato)</item>
<item>3072 Fotogrammi (69.66ms)</item>
<item>4096 Fotogrammi (92.88ms)</item>
</string-array>
<string-array name="settings_log_level_entries">
<item>None</item>
<item>Error</item>
<item>Warning</item>
<item>Performance Warnings</item>
<item>Information</item>
<item>Verbose</item>
<item>Developer</item>
<item>Profile</item>
<item>Debug</item>
<item>Trace</item>
</string-array>
<string-array name="settings_tabs">
<item>Generali</item>
<item>Display</item>
<item>Audio</item>
<item>Miglioramenti</item>
<item>Controller</item>
<item>Avanzate</item>
</string-array>
<string-array name="settings_gpu_msaa_entries">
<item>Disabilitato</item>
<item>2x MSAA</item>
<item>4x MSAA</item>
<item>8x MSAA</item>
<item>2x SSAA</item>
<item>4x SSAA</item>
<item>8x SSAA</item>
</string-array>
<string-array name="settings_advanced_display_fps_limit_entries">
<item>Senza Limite (Mostra tutti i fotogrammi)</item>
<item>10 FPS</item>
<item>15 FPS</item>
<item>30 FPS</item>
<item>45 FPS</item>
<item>60 FPS</item>
<item>75 FPS</item>
<item>90 FPS</item>
</string-array>
<string-array name="settings_emulation_speed_entries">
<item>Senza Limite</item>
<item>10% [6 FPS (NTSC) / 5 FPS (PAL)]</item>
<item>20% [12 FPS (NTSC) / 10 FPS (PAL)]</item>
<item>30% [18 FPS (NTSC) / 15 FPS (PAL)]</item>
<item>40% [24 FPS (NTSC) / 20 FPS (PAL)]</item>
<item>50% [30 FPS (NTSC) / 25 FPS (PAL)]</item>
<item>60% [36 FPS (NTSC) / 30 FPS (PAL)]</item>
<item>70% [42 FPS (NTSC) / 35 FPS (PAL)]</item>
<item>80% [48 FPS (NTSC) / 40 FPS (PAL)]</item>
<item>90% [54 FPS (NTSC) / 45 FPS (PAL)]</item>
<item>100% [60 FPS (NTSC) / 50 FPS (PAL), Default]</item>
<item>125% [75 FPS (NTSC) / 62 FPS (PAL)]</item>
<item>150% [90 FPS (NTSC) / 75 FPS (PAL)]</item>
<item>175% [105 FPS (NTSC) / 87 FPS (PAL)]</item>
<item>200% [120 FPS (NTSC) / 100 FPS (PAL)]</item>
<item>250% [150 FPS (NTSC) / 125 FPS (PAL)]</item>
<item>300% [180 FPS (NTSC) / 150 FPS (PAL)]</item>
<item>350% [210 FPS (NTSC) / 175 FPS (PAL)]</item>
<item>400% [240 FPS (NTSC) / 200 FPS (PAL)]</item>
<item>450% [270 FPS (NTSC) / 225 FPS (PAL)]</item>
<item>500% [300 FPS (NTSC) / 250 FPS (PAL)]</item>
<item>600% [360 FPS (NTSC) / 300 FPS (PAL)]</item>
<item>700% [420 FPS (NTSC) / 350 FPS (PAL)]</item>
<item>800% [480 FPS (NTSC) / 400 FPS (PAL)]</item>
<item>900% [540 FPS (NTSC) / 450 FPS (PAL)]</item>
<item>1000% [600 FPS (NTSC) / 500 FPS (PAL)]</item>
</string-array>
<string-array name="settings_advanced_cpu_overclock_entries">
<item>25% (8MHz)</item>
<item>50% (16MHz)</item>
<item>75% (24MHz)</item>
<item>100% (33MHz, Default)</item>
<item>125% (41MHz)</item>
<item>150% (49MHz)</item>
<item>175% (57MHz)</item>
<item>200% (66MHz)</item>
<item>225% (74MHz)</item>
<item>250% (82MHz)</item>
<item>275% (90MHz)</item>
<item>300% (99MHz)</item>
<item>350% (115MHz)</item>
<item>400% (132MHz)</item>
<item>450% (148MHz)</item>
<item>500% (165MHz)</item>
<item>500% (165MHz)</item>
<item>600% (198MHz)</item>
<item>700% (231MHz)</item>
<item>800% (264MHz)</item>
<item>900% (297MHz)</item>
<item>1000% (330MHz)</item>
</string-array>
<string-array name="settings_emulation_screen_orientation_entries">
<item>Usa Impostazione Dispositivo</item>
<item>Verticale</item>
<item>Orizzontale</item>
</string-array>
</resources>

View File

@@ -0,0 +1,16 @@
<resources>
<string name="app_name">DuckStation</string>
<string name="action_settings">Impostazioni</string>
<string name="title_activity_settings">Impostazioni</string>
<string name="settings_console_region">Regione Console</string>
<string name="settings_console_tty_output">Abilita TTY Output</string>
<string name="settings_console_fast_boot">Avvio Rapido</string>
<string name="settings_osd_show_messages">Mostra Messaggi</string>
<string name="settings_osd_show_speed">Mostra Velocità Emulazione</string>
<string name="settings_osd_show_show_fps">Mostra FPS</string>
<string name="settings_osd_show_show_vps">Mostra VPS</string>
<string name="settings_cpu_execution_mode">Modalità di Esecuzione CPU</string>
<string name="settings_gpu_renderer">GPU Renderer</string>
<string name="settings_gpu_resolution_scale">Scala di Risoluzione</string>
<string name="title_activity_emulation">EmulationActivity</string>
</resources>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#000000</color>
<color name="colorPrimaryDark">#000000</color>
<color name="colorAccent">#03A9F4</color>
<color name="colorNavigation">#000000</color>
<color name="black_overlay">#66000000</color>
<color name="fab_background">#222222</color>
</resources>

View File

@@ -0,0 +1,221 @@
<resources>
<string-array name="settings_console_region_entries">
<item>Automatisch Detecteren</item>
<item>NTSC-J (Japan)</item>
<item>NTSC-U (VS)</item>
<item>PAL (Europa, Australië)</item>
</string-array>
<string-array name="settings_cpu_execution_mode_entries">
<item>Interpreter (Langzaamst)</item>
<item>Cached Interpreter (Sneller)</item>
<item>Recompiler (Snelst)</item>
</string-array>
<string-array name="settings_cpu_fastmem_mode_entries">
<item>Uitgeschakeld (Langzaamst)</item>
<item>MMap (Hardware, Snelst, Alleen 64-Bit)</item>
<item>LUT (Sneller)</item>
</string-array>
<string-array name="gpu_renderer_entries">
<item>Hardware (OpenGL)</item>
<item>Hardware (Vulkan)</item>
<item>Software</item>
</string-array>
<string-array name="settings_gpu_resolution_scale_entries">
<item>1x</item>
<item>2x</item>
<item>3x (voor 720p)</item>
<item>4x</item>
<item>5x (voor 1080p)</item>
<item>6x (voor 1440p)</item>
<item>7x</item>
<item>8x</item>
<item>9x (voor 4K)</item>
<item>10x</item>
<item>11x</item>
<item>12x</item>
<item>13x</item>
<item>14x</item>
<item>15x</item>
<item>16x</item>
</string-array>
<string-array name="settings_display_crop_mode_entries">
<item>Geen</item>
<item>Alleen Overscangebied</item>
<item>Alle Randen</item>
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Game Native)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>
<item>19:9</item>
<item>20:9</item>
<item>21:9</item>
<item>32:9</item>
<item>8:7</item>
<item>5:4</item>
<item>3:2</item>
<item>2:1 (VRAM 1:1)</item>
<item>1:1</item>
<item>PAR 1:1</item>
</string-array>
<string-array name="settings_gpu_texture_filter_names">
<item>Dichtstbijzijde</item>
<item>Bilineair</item>
<item>Bilineair (Geen Edge Blending)</item>
<item>JINC2</item>
<item>JINC2 (Geen Edge Blending)</item>
<item>xBR</item>
<item>xBR (Geen Edge Blending)</item>
</string-array>
<string-array name="settings_controller_type_entries">
<item>Digitale Controller (Gamepad)</item>
<item>Analoge Controller (DualShock)</item>
</string-array>
<string-array name="settings_memory_card_mode_entries">
<item>Geen Geheugenkaart</item>
<item>Gedeeld Tussen Alle Spellen</item>
<item>Aparte Kaart Per Spel (Spelcode)</item>
<item>Aparte Kaart Per Spel (Speltitel)</item>
</string-array>
<string-array name="emulation_menu">
<item>Staat Laden</item>
<item>Staat Opslaan</item>
<item>Doorspoelen aan/uitzetten</item>
<item>Meer Opties</item>
<item>Afsluiten</item>
</string-array>
<string-array name="emulation_more_menu">
<item>Resetten</item>
<item>Patch Codes</item>
<item>Disc Veranderen</item>
<item>Instellingen</item>
<item>Touchscreen Controller Aanpassen</item>
<item>Edit Touchscreen Controller Layout</item>
</string-array>
<string-array name="settings_cdrom_read_speedup_entries">
<item>Geen (Dubbele Snelheid)</item>
<item>2x (Vierdubbele Snelheid)</item>
<item>3x (6x Snelheid)</item>
<item>4x (8x Snelheid)</item>
<item>5x (10x Snelheid)</item>
<item>6x (12x Snelheid)</item>
<item>7x (14x Snelheid)</item>
<item>8x (16x Snelheid)</item>
<item>9x (18x Snelheid)</item>
<item>10x (20x Snelheid)</item>
</string-array>
<string-array name="settings_touchscreen_controller_view_entries">
<item>Geen</item>
<item>Digitale Pad</item>
<item>Enekele Analoge Pad</item>
<item>Dubbele Analoge Pad</item>
</string-array>
<string-array name="settings_audio_backend_entries">
<item>Null (Geen Output)</item>
<item>Cubeb</item>
<item>OpenSL ES (Aanbevolen)</item>
</string-array>
<string-array name="settings_audio_buffer_size_entries">
<item>1024 Frames (23.22ms)</item>
<item>2048 Frames (46.44ms, Recommended)</item>
<item>3072 Frames (69.66ms)</item>
<item>4096 Frames (92.88ms)</item>
</string-array>
<string-array name="settings_log_level_entries">
<item>Geen</item>
<item>Fout</item>
<item>Waarschuwing</item>
<item>Uitgebreid</item>
<item>Prestatie Waarschuwingen</item>
<item>Informatie</item>
<item>Ontwikkelaar</item>
<item>Profiel</item>
<item>Debug</item>
<item>Trace</item>
</string-array>
<string-array name="settings_tabs">
<item>Algemeen</item>
<item>Weergave</item>
<item>Audio</item>
<item>Verbeteringen</item>
<item>Controllers</item>
<item>Geavanceerd</item>
</string-array>
<string-array name="settings_gpu_msaa_entries">
<item>Uitgeschakeld</item>
<item>2x MSAA</item>
<item>4x MSAA</item>
<item>8x MSAA</item>
<item>2x SSAA</item>
<item>4x SSAA</item>
<item>8x SSAA</item>
</string-array>
<string-array name="settings_advanced_display_fps_limit_entries">
<item>Onbegrensd (Alle Frames Weergeven)</item>
<item>10 FPS</item>
<item>15 FPS</item>
<item>30 FPS</item>
<item>45 FPS</item>
<item>60 FPS</item>
<item>75 FPS</item>
<item>90 FPS</item>
</string-array>
<string-array name="settings_emulation_speed_entries">
<item>Onbegrensd</item>
<item>10% [6 FPS (NTSC) / 5 FPS (PAL)]</item>
<item>20% [12 FPS (NTSC) / 10 FPS (PAL)]</item>
<item>30% [18 FPS (NTSC) / 15 FPS (PAL)]</item>
<item>40% [24 FPS (NTSC) / 20 FPS (PAL)]</item>
<item>50% [30 FPS (NTSC) / 25 FPS (PAL)]</item>
<item>60% [36 FPS (NTSC) / 30 FPS (PAL)]</item>
<item>70% [42 FPS (NTSC) / 35 FPS (PAL)]</item>
<item>80% [48 FPS (NTSC) / 40 FPS (PAL)]</item>
<item>90% [54 FPS (NTSC) / 45 FPS (PAL)]</item>
<item>100% [60 FPS (NTSC) / 50 FPS (PAL), Default]</item>
<item>125% [75 FPS (NTSC) / 62 FPS (PAL)]</item>
<item>150% [90 FPS (NTSC) / 75 FPS (PAL)]</item>
<item>175% [105 FPS (NTSC) / 87 FPS (PAL)]</item>
<item>200% [120 FPS (NTSC) / 100 FPS (PAL)]</item>
<item>250% [150 FPS (NTSC) / 125 FPS (PAL)]</item>
<item>300% [180 FPS (NTSC) / 150 FPS (PAL)]</item>
<item>350% [210 FPS (NTSC) / 175 FPS (PAL)]</item>
<item>400% [240 FPS (NTSC) / 200 FPS (PAL)]</item>
<item>450% [270 FPS (NTSC) / 225 FPS (PAL)]</item>
<item>500% [300 FPS (NTSC) / 250 FPS (PAL)]</item>
<item>600% [360 FPS (NTSC) / 300 FPS (PAL)]</item>
<item>700% [420 FPS (NTSC) / 350 FPS (PAL)]</item>
<item>800% [480 FPS (NTSC) / 400 FPS (PAL)]</item>
<item>900% [540 FPS (NTSC) / 450 FPS (PAL)]</item>
<item>1000% [600 FPS (NTSC) / 500 FPS (PAL)]</item>
</string-array>
<string-array name="settings_advanced_cpu_overclock_entries">
<item>25% (8MHz)</item>
<item>50% (16MHz)</item>
<item>75% (24MHz)</item>
<item>100% (33MHz, Default)</item>
<item>125% (41MHz)</item>
<item>150% (49MHz)</item>
<item>175% (57MHz)</item>
<item>200% (66MHz)</item>
<item>225% (74MHz)</item>
<item>250% (82MHz)</item>
<item>275% (90MHz)</item>
<item>300% (99MHz)</item>
<item>350% (115MHz)</item>
<item>400% (132MHz)</item>
<item>450% (148MHz)</item>
<item>500% (165MHz)</item>
<item>500% (165MHz)</item>
<item>600% (198MHz)</item>
<item>700% (231MHz)</item>
<item>800% (264MHz)</item>
<item>900% (297MHz)</item>
<item>1000% (330MHz)</item>
</string-array>
<string-array name="settings_emulation_screen_orientation_entries">
<item>Apparaatinstellingen Gebruiken</item>
<item>Portret</item>
<item>Landschap</item>
</string-array>
</resources>

View File

@@ -0,0 +1,154 @@
<resources>
<string name="app_name">DuckStation</string>
<string name="action_settings">Instellingen</string>
<string name="title_activity_settings">Instellingen</string>
<string name="settings_console_region">Console Gebied</string>
<string name="settings_console_tty_output">TTY Output Aanzetten</string>
<string name="settings_console_fast_boot">Snel Starten</string>
<string name="settings_osd_show_messages">Toon Berichten</string>
<string name="settings_osd_show_speed">Toon Emulatiesnelheid</string>
<string name="settings_osd_show_show_fps">Toon FPS</string>
<string name="settings_osd_show_show_vps">Toon VPS</string>
<string name="settings_cpu_execution_mode">CPU Executie Modus</string>
<string name="settings_gpu_renderer">GPU Renderer</string>
<string name="settings_gpu_resolution_scale">Resolutie Schaal</string>
<string name="title_activity_emulation">Emulatie Activiteit</string>
<string name="settings_emulation_speed">Emulatie Snelheid</string>
<string name="settings_fast_forward_speed">Doorspoelsnelheid</string>
<string name="settings_save_state_on_exit">Staat Opslaan Bij Afsluiten</string>
<string name="settings_pause_when_menu_opened">Pauze In Menus</string>
<string name="settings_emulation_screen_orientation">Emulatie Schermorientatie</string>
<string name="settings_load_patch_codes">Laad Patch Codes</string>
<string name="settings_summary_save_state_on_exit">Slaat automatisch de emulator staat op bij afsluiten. Je kan dan de volgende keer verder vanaf waar je gebleven was.</string>
<string name="settings_summary_pause_when_menu_opened">Pauzeert de emulatie wanneer je in een spel bent en het menu geopend is.</string>
<string name="settings_summary_load_patch_codes"><![CDATA[Laad patch codes van cheats/<game name>.cht in PCSXR formaat. Codes kunnen aan- en uitgeschakeld worden in-game.]]></string>
<string name="settings_apply_compatibility_settings">Pas Compatibiliteitsinstellingen Toe</string>
<string name="settings_summary_apply_compatibility_settings">Schakelt automatisch verbeteringen uit wanneer ze niet door spellen ondersteund worden.</string>
<string name="settings_summary_video_sync">Schakel deze optie in om DuckStation\'s verversingssnelheid te synchroniseren met je scherm. VSync is automatisch uitegeschakeld wanneer dit niet mogelijk is (bijvoorbeeld wanneer er niet op 100% snelheid gespeeld wordt).</string>
<string name="settings_video_sync">Video Sync</string>
<string name="settings_cpu_overclocking">CPU Overclocken</string>
<string name="settings_cdrom_region_check">CD-ROM Regio Check</string>
<string name="settings_summary_cdrom_region_check">Voorkomt dat discs uit incorrecte regio\'s geladen worden door de emulator. Over het algemeen veilig om uit te schakelen.</string>
<string name="settings_cdrom_preload_image_to_ram">CD-ROM Image Voorladen naar RAM</string>
<string name="settings_summary_preload_image_to_ram">Laadt de image van het spel in RAM. Handig voor netwerkpaden die instabiel kunnen worden tijdens het spelen van het spelen. Kan soms ook haperingen voorkomen wanneer spellen audio instellen.</string>
<string name="settings_pgxp_vertex_cache">PGXP Vertex Cache</string>
<string name="settings_summary_pgxp_vertex_cache">Gebruikt schermcoordinaten als terugval wanneer vertices niet door het geheugen getraceerd kunnen worden. Kan PGXP compatibiliteit verbeteren.</string>
<string name="settings_pgxp_cpu_mode">PGXP CPU Modus</string>
<string name="settings_summary_pgxp_cpu_mode">Probeert vertex manupulatie te traceren door de CPU. Sommige spellen vereisen deze optie om PGXP te gebruiken. Heel langzaam, en incompatibel met de recompiler.</string>
<string name="settings_cpu_recompiler_icache">CPU Recompiler ICache</string>
<string name="settings_summary_cpu_recompiler_icache">Bepaalt of de CPU\'s instructie cache gesimuleerd wordt in de recompiler. Verbetert precisie, maar kost een klein beetje prestatie. Als games te snel afspelen, probeer dan deze optie aan te zetten.</string>
<string name="settings_cpu_recompiler_fastmem">CPU Recompiler Fast Memory Access</string>
<string name="settings_summary_cpu_recompiler_fastmem">Maakt geheugentoegang van het gesimuleerde systeem meer efficient door page faults en backpatching te gebruiken. Schakel dit uit als het instabiel is op je systeem.</string>
<string name="settings_presented_frame_limit">Getoonde Frame Begrenzing</string>
<string name="settings_logging_level">Logging Niveau</string>
<string name="settings_log_to_file">Log Naar Bestand</string>
<string name="settings_summary_log_to_file">Schrijft de log naar duckstation.log in je gebruikersfolder. Gebruik dit alleen voor debuggen, want het kan vertraagt de emulatie.</string>
<string name="settings_log_to_logcat">Log Naar Logcat</string>
<string name="settings_summary_log_to_logcat">Schrijft logberichten naar de Android berichtenlog. Alleen nuttig wanneer gebruikt in combinatie met een computer met adb.</string>
<string name="settings_volume">Volume</string>
<string name="settings_summary_volume">Bedient het volume van de emulator.</string>
<string name="settings_mute_all_sound">Alles Dempen</string>
<string name="settings_summary_mute_all_sound">Voorkomt dat de emulator geluid produceert.</string>
<string name="settings_mute_cd_audio">CD Audio Dempen</string>
<string name="settings_summary_mute_cd_audio">Dempt zowel CD-DA en XA audio van de CD-ROM. Kan gebruikt worden om achtergrondmuziek uit te schakelen in sommige spellen.</string>
<string name="settings_audio_backend">Audio Backend</string>
<string name="settings_audio_buffer_size">Audio Buffer Grootte</string>
<string name="settings_summary_audio_buffer_size">Bepaald de vertraging tussen de audiogeneratie en de output van de speakers. Kleinere waardes kunnen vertraging verkleinen, maar variaties in emulatiesnelheid kunnen voor haperingen zorgen.</string>
<string name="settings_audio_sync">Audio Sync</string>
<string name="settings_summary_audio_sync">Beperkt de emulatiesnelheid gebaseerd op hoe snel de audio backend samples opvraagt. Dit helpt om ruis en kraken te voorkomen wanneer de emulator te snel gaat. Wordt automatisch uitgeschakeld wanneer er niet op 100% snelheid afgespeeld wordt.</string>
<string name="settings_controller_type">Controller Type</string>
<string name="settings_enable_analog_mode_on_reset">Analoge Modus Bij Reset.</string>
<string name="settings_touchscreen_controller_view">Touchscreen Controller Beeld</string>
<string name="settings_auto_hide_touchscreen_controller">Automatisch Touchscreen Controller Verbergen</string>
<string name="settings_summary_auto_hide_touchscreen_controller">Verbergt de touchscreen controller wanneer een externe controller gedetecteerd wordt.</string>
<string name="settings_vibrate_on_press">Vibreren Bij Indrukking</string>
<string name="settings_summary_vibrate_on_press">Schakelt een kleine trilling in wanneer een touchscreenknop ingedrukt wordt. Vereist dat \"Trillen bij aanraking\" ingeschakeld is op je apparaat.</string>
<string name="settings_enable_vibration">Vibratie Inschakelen</string>
<string name="settings_summary_enable_vibration">Vibreert de telefoon wanneer de spel dit voor een controller doet.</string>
<string name="settings_memory_card_1_type">Geheugenkaart 1 Type</string>
<string name="settings_memory_card_2_type">Geheugenkaart 2 Type</string>
<string name="settings_crop_mode">Knip Modus</string>
<string name="settings_aspect_ratio">Schermverhouding</string>
<string name="settings_linear_upscaling">Lineaire Opschaling</string>
<string name="settings_integer_upscaling">Integer Opschaling</string>
<string name="settings_summary_linear_upscaling">Interpoleert tussen pixels wanneer het beeld opgeschaald wordt naar het apparaat.</string>
<string name="settings_summary_integer_upscaling">Voegt randen toe aan het beeld zodat de verhouding tussen pixels op het apparaat, en pixels van de console een geheel getal is. Kan voor een scherper beeld zorgen in sommige 2D games.</string>
<string name="settings_summary_osd_show_messages">Toont berichten op het scherm wanneer gebeurtenissen als het opslaan/laden van een spelstatus, schermafbeeldingen maken, etc. gebeuren.</string>
<string name="settings_summary_osd_show_speed">Zet een doelsnelheid voor de emulatie. Het is niet gegarandeerd dat deze snelheid behaald wordt. Zo niet, dan gaat de emulator zo snel als hij kan.</string>
<string name="settings_summary_osd_show_fps">Toont de interne framesnelheid van het spel in de rechter bovenhoek van het scherm.</string>
<string name="settings_summary_osd_show_vps">Toont het aantal frames (of v-syncs) van het systeem in de rechter bovenhoek van het scherm.</string>
<string name="settings_cdrom_read_speedup">CD-ROM Leesversnelling</string>
<string name="settings_summary_cdrom_read_speedup">Versnelt de CD-ROM leessnelheid met de gegeven factor. Alleen van toepassing op dubbele-snelheids leesoperaties, en genegeerd wanneer audio afspeelt. Kan laadsnelheden vergroten bij sommige spellen, maar kan andere spellen niet goed laten werken.</string>
<string name="settings_summary_console_fast_boot">Slaat de BIOS intro over, en start direct het spel. Over het algemeen veilig om in te schakelen, maar sommige spellen werken niet goed meer.</string>
<string name="settings_msaa">Multisample Antialiasing</string>
<string name="settings_true_color">True Color Rendering (24-bit, schakelt dithering uit)</string>
<string name="settings_summary_true_color">Dit produceert mooiere gradienten, maar kan sommige kleuren een klein beetje verkleuren. Uitschakelen schakelt ook dithering uit. De meeste spellen zijn compatibel met deze optie.</string>
<string name="settings_scaled_dithering">Geschaalde Dithering (schaal dither patrron naar resolutie)</string>
<string name="settings_summary_scaled_dithering">Schaalt het dither patroon naar de resolutieschaal van de geëmuleerde GPU. Dit maakt het ditherpatroon minder duidelijk bij hogere resoluties. Over het algemeen veilig in te schakelen. Werkt alleen bij hardware renderers.</string>
<string name="settings_disable_interlacing">Interlacing Uitschakelen(forceer progressieve render/scan)</string>
<string name="settings_summary_disable_interlacing">Forceert het renderen en weergeven van frames naar de progressieve modus. Dit verwijdert het \"kam\" effect gezien in 480i spellen door ze in 480p te rendreren. Meestal veilig om in te schakelen.</string>
<string name="settings_texture_filtering">Texture Filtering</string>
<string name="settings_force_ntsc_timings">Forceer NTSC Timings (60hz-on-PAL)</string>
<string name="settings_summary_force_ntsc_timings">Gebruikt NTSC frame timings wanneer de console in PAL modus is. Dwingt PAL spellen om in 60hz af te spelen.</string>
<string name="settings_widescreen_hack">Widescreen Hack</string>
<string name="settings_summary_widescreen_hack">Schaalt vertex posities in schermruimte op naar een breedbeeldverhouding, wat in essentie het gezichtsveld van 4:3 naar 16:9 verhoogt in 3D spellen. Niet compatibel met alle spellen.</string>
<string name="settings_force_4_3_for_24bit">Forceer 4:3 Voor 24-Bit Schermen</string>
<string name="settings_summary_force_4_3_for_24bit">Gaat terug naar een 4:3 schermverhouding wanneer 24-bit inhoud weergeven wordt, meestal FMVs.</string>
<string name="settings_chroma_smoothing_24bit">Chroma Smoothing Voor 24-Bit Schermen</string>
<string name="settings_summary_chrome_smoothing_24bit">Vermindert de blokkerigheid bij kleurtransities van 24-bit inhoud, meestal FMVs. Alleen van toepassing bij hardware renderers.</string>
<string name="settings_pgxp_geometry_correction">PGXP Geometry Correction</string>
<string name="settings_summary_pgxp_geometry_correction"><![CDATA[Vermindert \"wiebelige\" polygons en \"vervormde\" textures die vaak in PS1 spellen voorkomen. >Werkt alleen met hardware renderers. Mogelijk niet compatibel met alle spellen.]]></string>
<string name="settings_pgxp_culling_correction">PGXP Culling Correction</string>
<string name="settings_summary_pgxp_culling_correction">Verhoogt de precisie van polygon culling, vermindert het aantal gaten in objecten. Vereist dat \"geometry correction\" ingeschakeld is.</string>
<string name="settings_pgxp_texture_correction">PGXP Texture Correction</string>
<string name="settings_summary_pgxp_texture_correction">Gebruikt perspectief-correcte interpolatie voor texture coordinaten en kleuren, maakt vervormde textures weer glad. Vereist dat \"geometry correction\" ingeschakeld is.</string>
<string name="settings_pgxp_preserve_projection_precision">PGXP Behoud Projectie Precisie</string>
<string name="settings_summary_pgxp_preserve_projection_precision">Schakelt extra precisie in voor PGXP. Kan beeld verbeteren in sommige spellen, maar kan andere minder goed laten werken.</string>
<string name="menu_main_resume_last_session">Hervat Vorige Sessie</string>
<string name="menu_main_start_file">Start Bestand</string>
<string name="menu_main_start_bios">Start BIOS</string>
<string name="menu_main_edit_game_directories">Bewerk Gamemappen</string>
<string name="menu_main_scan_for_new_games">Scan Naar Nieuwe Spellen</string>
<string name="menu_main_rescan_all_games">Alle Spellen Opnieuw Scannen</string>
<string name="menu_main_import_bios">Importeer BIOS</string>
<string name="menu_main_show_version">Toon Versie</string>
<string name="menu_main_github_repository">GitHub Repository</string>
<string name="menu_main_discord_server">Discord Server</string>
<string name="menu_game_list_entry_start_game">Start Spel</string>
<string name="menu_game_list_entry_resume_game">Hervat Spel</string>
<string name="android_progress_callback_please_wait">Wachten alstublieft...</string>
<string name="android_progress_callback_ok">Oké</string>
<string name="android_progress_callback_information">Informatie</string>
<string name="android_progress_callback_confirmation">Bevestiging</string>
<string name="android_progress_callback_yes">Ja</string>
<string name="android_progress_callback_no">Nee</string>
<string name="emulation_activity_error">Fout</string>
<string name="emulation_activity_ok">Oké</string>
<string name="emulation_activity_import_patch_codes">Importeer Patch Codes...</string>
<string name="emulation_activity_patch_on">(AAN)</string>
<string name="emulation_activity_patch_off">(UIT)</string>
<string name="emulation_activity_choose_patch_code_file">Kies Een Patch Code Bestand</string>
<string name="emulation_activity_failed_to_import_patch_codes">Patch codes importeren mislukt. Selecteer een PCSXR of Libretro formaat bestand.</string>
<string name="main_activity_choose_directory">Kies folder</string>
<string name="main_activity_error">Fout</string>
<string name="main_activity_get_path_from_file_error">Mislukt om het bestand op te halen. Zorg ervoor dat het bestand in de interne/externe opslag is.\n\nTik op de overflow knop in de folderselectie.\nSelecteer "Toon Interne Opslag".\nTik op de menuknop en selecteer uw apparaat of SD kaart.</string>
<string name="main_activity_ok">Oké</string>
<string name="main_activity_get_path_from_directory_error">Pad van folder ophalen mislukt.Zorg ervoor dat de folder in de interne/externe opslag is.\n\nTik op de overflow knop in de folderselectie.\nSelecteer "Toon Interne Opslag".\nTik op de menuknop en selecteer uw apparaat of SD kaart.</string>
<string name="main_activity_external_storage_permissions_error">Toegang tot externe opslag nodig om DuckStation te gebruiken.</string>
<string name="main_activity_choose_disc_image">Kies Disc Image</string>
<string name="main_activity_missing_bios_image_prompt">Er was geen BIOS image was gevonden in DuckStation\'s bios folder. Wilt u nu een BIOS image importeren?</string>
<string name="main_activity_missing_bios_image">Ontbrekende BIOS Image</string>
<string name="main_activity_yes">Ja</string>
<string name="main_activity_no">Nee</string>
<string name="main_activity_choose_bios_image">Kies BIOS Image</string>
<string name="main_activity_failed_to_open_bios_image">BIOS image openen mislukt.</string>
<string name="main_activity_failed_to_read_bios_image_prefix">\"BIOS image lezen mislukt: \"</string>
<string name="main_activity_bios_image_too_large">BIOS image is te groot.</string>
<string name="main_activity_invalid_error">Deze BIOS image is ongeldig, of is al geimporteerd.</string>
<string name="main_activity_show_version_title">Versie</string>
<string name="main_activity_copy">Kopieer</string>
<string name="settings_fast_forward_volume">Doorspoel Volume</string>
<string name="settings_summary_fast_forward_volume">Bedient het volume van de emulator wanneer het spel sneller afgespeeld wordt.</string>
<string name="settings_gpu_thread">Threaded GPU Rendering</string>
<string name="settings_summary_gpu_thread">Gebruikt een tweede thread voor het renderen van graphics. Op het moment alleen beschikbaar voor software renderers, maar kan een significante snelheidsverbetering opleveren, en is veilig te gebruiken.</string>
</resources>

View File

@@ -0,0 +1,235 @@
<resources>
<string-array name="settings_console_region_entries">
<item>Auto-Detectar</item>
<item>NTSC-J (Japão)</item>
<item>NTSC-U (US)</item>
<item>PAL (Europa, Austrália)</item>
</string-array>
<string-array name="settings_cpu_execution_mode_entries">
<item>Interpretador (Mais Lento)</item>
<item>Interpretador Armazenado (Rápido)</item>
<item>Recompilador (Mais Rápido)</item>
</string-array>
<string-array name="settings_cpu_fastmem_mode_entries">
<item>Desabilitado (Lento)</item>
<item>MMap (Hardware, Mais Rápido, (Dispositivos 64-Bits)</item>
<item>LUT (Rápido)</item>
</string-array>
<string-array name="gpu_renderer_entries">
<item>Dedicado (OpenGL)</item>
<item>Dedicado (Vulkan)</item>
<item>Software</item>
</string-array>
<string-array name="settings_gpu_resolution_scale_entries">
<item>1x</item>
<item>2x</item>
<item>3x (para 720p)</item>
<item>4x</item>
<item>5x (para 1080p)</item>
<item>6x (para 1440p)</item>
<item>7x</item>
<item>8x</item>
<item>9x (para 4K)</item>
<item>10x</item>
<item>11x</item>
<item>12x</item>
<item>13x</item>
<item>14x</item>
<item>15x</item>
<item>16x</item>
</string-array>
<string-array name="settings_display_crop_mode_entries">
<item>None</item>
<item>Área Renderizada</item>
<item>Todas as Bordas</item>
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Auto (Nativo)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>
<item>19:9</item>
<item>20:9</item>
<item>21:9</item>
<item>32:9</item>
<item>8:7</item>
<item>5:4</item>
<item>3:2</item>
<item>2:1 (VRAM 1:1)</item>
<item>1:1</item>
<item>PAR 1:1</item>
</string-array>
<string-array name="settings_gpu_texture_filter_names">
<item>Nearest-Neighbor</item>
<item>Bilinear</item>
<item>Bilinear (Sem ajustes laterais)</item>
<item>JINC2</item>
<item>JINC2 (Sem ajustes laterais)</item>
<item>xBR</item>
<item>xBR (Sem ajustes laterais)</item>
</string-array>
<string-array name="settings_controller_type_entries">
<item>Controle Digital (Gamepad)</item>
<item>Controle Analógico (DualShock)</item>
</string-array>
<string-array name="settings_memory_card_mode_entries">
<item>Sem Cartão de Memória</item>
<item>Compartilhada entre Jogos</item>
<item>Separado Por Jogo (Cód. Jogo)</item>
<item>Separado Por Jogo (Título Jogo)</item>
</string-array>
<string-array name="emulation_menu">
<item>Carregar Estado</item>
<item>Salvar Estado</item>
<item>Avanço (Fixo)</item>
<item>Mais Opções</item>
<item>Sair</item>
</string-array>
<string-array name="emulation_more_menu">
<item>Reiniciar</item>
<item>Trapaças</item>
<item>Mudar Disco</item>
<item>Configurações</item>
<item>Mudar controle em Tela</item>
<item>Editar Posição dos Controles (Tela)</item>
</string-array>
<string-array name="settings_cdrom_read_speedup_entries">
<item>Nenhum</item>
<item>2x (4x Veloz)</item>
<item>3x (6x Veloz)</item>
<item>4x (8x Veloz)</item>
<item>5x (10x Veloz)</item>
<item>6x (12x Veloz)</item>
<item>7x (14x Veloz)</item>
<item>8x (16x Veloz)</item>
<item>9x (18x Veloz)</item>
<item>10x (20x Veloz)</item>
</string-array>
<string-array name="settings_touchscreen_controller_view_entries">
<item>Nenhum</item>
<item>Digital D-Pad</item>
<item>1 Analógico</item>
<item>2 Analógicos</item>
</string-array>
<string-array name="settings_audio_backend_entries">
<item>Mudo</item>
<item>Cubeb</item>
<item>SLES (Recomendado)</item>
</string-array>
<string-array name="settings_audio_buffer_size_entries">
<item>1024 Quadros (23.22ms)</item>
<item>2048 Quadros (46.44ms, Recomendado)</item>
<item>3072 Quadros (69.66ms)</item>
<item>4096 Quadros (92.88ms)</item>
</string-array>
<string-array name="settings_log_level_entries">
<item>Nenhum</item>
<item>Erro</item>
<item>Alerta</item>
<item>Alertas de Performance</item>
<item>Informação</item>
<item>Detalhado</item>
<item>Desenvolvedor</item>
<item>Perfil</item>
<item>Depuração</item>
<item>Rota</item>
</string-array>
<string-array name="settings_tabs">
<item>Geral</item>
<item>Vídeo</item>
<item>Áudio</item>
<item>Melhorias</item>
<item>Controles</item>
<item>Avançado</item>
</string-array>
<string-array name="settings_gpu_msaa_entries">
<item>Desativado</item>
<item>2x MSAA</item>
<item>4x MSAA</item>
<item>8x MSAA</item>
<item>2x SSAA</item>
<item>4x SSAA</item>
<item>8x SSAA</item>
</string-array>
<string-array name="settings_advanced_display_fps_limit_entries">
<item>ilimitado (Mostrar Quadros)</item>
<item>10 FPS</item>
<item>15 FPS</item>
<item>30 FPS</item>
<item>45 FPS</item>
<item>60 FPS</item>
<item>75 FPS</item>
<item>90 FPS</item>
</string-array>
<string-array name="settings_emulation_speed_entries">
<item>ilimitado</item>
<item>10% [6 FPS (NTSC) / 5 FPS (PAL)]</item>
<item>20% [12 FPS (NTSC) / 10 FPS (PAL)]</item>
<item>30% [18 FPS (NTSC) / 15 FPS (PAL)]</item>
<item>40% [24 FPS (NTSC) / 20 FPS (PAL)]</item>
<item>50% [30 FPS (NTSC) / 25 FPS (PAL)]</item>
<item>60% [36 FPS (NTSC) / 30 FPS (PAL)]</item>
<item>70% [42 FPS (NTSC) / 35 FPS (PAL)]</item>
<item>80% [48 FPS (NTSC) / 40 FPS (PAL)]</item>
<item>90% [54 FPS (NTSC) / 45 FPS (PAL)]</item>
<item>100% [60 FPS (NTSC) / 50 FPS (PAL), Padrão]</item>
<item>125% [75 FPS (NTSC) / 62 FPS (PAL)]</item>
<item>150% [90 FPS (NTSC) / 75 FPS (PAL)]</item>
<item>175% [105 FPS (NTSC) / 87 FPS (PAL)]</item>
<item>200% [120 FPS (NTSC) / 100 FPS (PAL)]</item>
<item>250% [150 FPS (NTSC) / 125 FPS (PAL)]</item>
<item>300% [180 FPS (NTSC) / 150 FPS (PAL)]</item>
<item>350% [210 FPS (NTSC) / 175 FPS (PAL)]</item>
<item>400% [240 FPS (NTSC) / 200 FPS (PAL)]</item>
<item>450% [270 FPS (NTSC) / 225 FPS (PAL)]</item>
<item>500% [300 FPS (NTSC) / 250 FPS (PAL)]</item>
<item>600% [360 FPS (NTSC) / 300 FPS (PAL)]</item>
<item>700% [420 FPS (NTSC) / 350 FPS (PAL)]</item>
<item>800% [480 FPS (NTSC) / 400 FPS (PAL)]</item>
<item>900% [540 FPS (NTSC) / 450 FPS (PAL)]</item>
<item>1000% [600 FPS (NTSC) / 500 FPS (PAL)]</item>
</string-array>
<string-array name="settings_advanced_cpu_overclock_entries">
<item>25% (8MHz)</item>
<item>50% (16MHz)</item>
<item>75% (24MHz)</item>
<item>100% (33MHz, Padrão)</item>
<item>125% (41MHz)</item>
<item>150% (49MHz)</item>
<item>175% (57MHz)</item>
<item>200% (66MHz)</item>
<item>225% (74MHz)</item>
<item>250% (82MHz)</item>
<item>275% (90MHz)</item>
<item>300% (99MHz)</item>
<item>350% (115MHz)</item>
<item>400% (132MHz)</item>
<item>450% (148MHz)</item>
<item>500% (165MHz)</item>
<item>500% (165MHz)</item>
<item>600% (198MHz)</item>
<item>700% (231MHz)</item>
<item>800% (264MHz)</item>
<item>900% (297MHz)</item>
<item>1000% (330MHz)</item>
</string-array>
<string-array name="settings_emulation_screen_orientation_entries">
<item>Padrão do Dispositivo</item>
<item>Retrato</item>
<item>Paisagem</item>
</string-array>
<string-array name="settings_theme_entries">
<item>Padrão do Sistema</item>
<item>Claro</item>
<item>Escuro</item>
</string-array>
<string-array name="settings_downsample_mode_entries">
<item>Desabilitado</item>
<item>Misto (Reduz 3D / Suaviza Tudo)</item>
<item>Adaptativo (Preserva o 3D / Suaviza 2D)</item>
</string-array>
<string-array name="settings_boolean_entries">
<item>Disabled</item>
<item>Enabled</item>
</string-array>
</resources>

View File

@@ -0,0 +1,213 @@
<resources>
<string name="app_name">DuckStation</string>
<string name="action_settings">Configurações</string>
<string name="action_controller_mapping">Mapear Controles</string>
<string name="title_activity_settings">Configurações</string>
<string name="settings_console_region">Região do Console</string>
<string name="settings_console_tty_output">EAtivar saída TTY</string>
<string name="settings_console_fast_boot">Inicio Rápido</string>
<string name="settings_osd_show_messages">Mostrar Mensagens</string>
<string name="settings_osd_show_speed">Mostrar Velocidade da Emulação</string>
<string name="settings_osd_show_show_fps">Mostrar FPS</string>
<string name="settings_osd_show_show_vps">Mostrar VPS</string>
<string name="settings_cpu_execution_mode">Modo de execução CPU</string>
<string name="settings_gpu_renderer">Renderizado por GPU</string>
<string name="settings_gpu_resolution_scale">Escala de Resolução</string>
<string name="title_activity_emulation">Atividade da Emulação</string>
<string name="settings_emulation_speed">Velocidade da Emulação</string>
<string name="settings_fast_forward_speed">Velocidade de Avanço Rápido</string>
<string name="settings_save_state_on_exit">Salvar ao Sair</string>
<string name="settings_pause_when_menu_opened">Pausar ao abrir Menu</string>
<string name="settings_emulation_screen_orientation">Orientação de Tela</string>
<string name="settings_load_patch_codes">Carregar Trapaças</string>
<string name="settings_summary_save_state_on_exit">Salvar automaticamente o estado da emulação ao desligar.</string>
<string name="settings_summary_pause_when_menu_opened">Pausa a emulação assim que o menu é aberto.</string>
<string name="settings_summary_load_patch_codes"><![CDATA[Carregar códigos de trapaça formato .cht e ou PCSXR. Códigos podem ser alternados durante o jogo.]]></string>
<string name="settings_apply_compatibility_settings">Aplicar Configurações de Compatibilidade</string>
<string name="settings_summary_apply_compatibility_settings">Desativar automaticamente melhorias quando não são suportadas.</string>
<string name="settings_summary_video_sync">Ative essa opção para que o emulador sincronize a taxa de FPS de acordo com a taxa do seu aparelho.</string>
<string name="settings_video_sync">Sincronização Vertical</string>
<string name="settings_cpu_overclocking">Aumento de Velocidade CPU (Overclock)</string>
<string name="settings_cdrom_region_check">Checagem de Região do CD-ROM</string>
<string name="settings_summary_cdrom_region_check">Previne que discos de regiões incorretas sejam lidos pelo emulador. Pode ser Desligado.</string>
<string name="settings_cdrom_preload_image_to_ram">Carregar CD-ROM para memória RAM</string>
<string name="settings_summary_preload_image_to_ram">LCarrega o jogo todo na RAM. Útil para prevenir instabilidades durante o jogo. Em alguns casos também elimina travamentos durante os carregamentos.</string>
<string name="settings_pgxp_vertex_cache">PGXP - Vértice Armazenado</string>
<string name="settings_summary_pgxp_vertex_cache">Reduz as oscilações nos poligonos tentando preservar os mesmos na hora da transferência para a RAM.</string>
<string name="settings_pgxp_cpu_mode">PGXP - Modo CPU</string>
<string name="settings_summary_pgxp_cpu_mode">Tenta reduzir oscilações nos poligonos preservando-os na hora da transferência para o CPU. Alguns jogos se beneficiam com esta opção junto com o PGXP para que funcione corretamente. Muito lento, e imcompativel com o modo recompilador.</string>
<string name="settings_cpu_recompiler_icache">Recompilador CPU Modo ICache</string>
<string name="settings_summary_cpu_recompiler_icache">Determina se a instrução enviada ao CPU emulado fica armazenada no recompilador. Melhor a precisão ao pequeno custo de performance. Se os jogos estão rodando muito rápido, tente ativar esta opção.</string>
<string name="settings_cpu_recompiler_fastmem">Recompilador CPU Modo FASTMEM</string>
<string name="settings_summary_cpu_recompiler_fastmem">Torna o acesso à memória mais eficiente. Desative se estiver instável em seu aparelho.</string>
<string name="settings_presented_frame_limit">Limite do Quadro atual</string>
<string name="settings_logging_level">Nível de Registro</string>
<string name="settings_log_to_file">Registro para Arquivo</string>
<string name="settings_summary_log_to_file">Escreve mensagens em um arquivo duckstation.log em seu diretório raiz. Use só para depuração isto deixará o emulador lento.</string>
<string name="settings_log_to_logcat">Registro em Linha de Comando</string>
<string name="settings_summary_log_to_logcat">Escreve um arquivo de registro para arquivo no Android. Só útil quando atrelado ao PC com adb.</string>
<string name="settings_volume">Volume</string>
<string name="settings_summary_volume">Controla o volume do emulador.</string>
<string name="settings_fast_forward_volume">Volume do Avanço Rápido</string>
<string name="settings_summary_fast_forward_volume">Controla o volume do áudio quando o avanço rápido é usado.</string>
<string name="settings_mute_all_sound">Silenciar Tudo</string>
<string name="settings_summary_mute_all_sound">Silencia totalmente o emulador.</string>
<string name="settings_mute_cd_audio">Silenciar CD\'s de Áudio</string>
<string name="settings_summary_mute_cd_audio">Silencia de forma forçada tanto para CD\'s de música quanto em jogos.</string>
<string name="settings_audio_backend">Opções de Áudio</string>
<string name="settings_audio_buffer_size">Latência do Volume:</string>
<string name="settings_summary_audio_buffer_size">Determina a latência entre o áudio. Valores menores reduzem a latência (atraso), pode causar engasgos quando jogos são acelerados.</string>
<string name="settings_audio_sync">Sincronia de Áudio</string>
<string name="settings_summary_audio_sync">Limita a velocidade de emulação com base na opção escolhida. Isso ajuda a remover ruídos ou estalos se a emulação for muito rápida. A sincronização será automaticamente desativada se não funcionar a 100%.</string>
<string name="settings_controller_type">Tipo de Controle</string>
<string name="settings_enable_analog_mode_on_reset">Ativa modo analógico ao reiniciar</string>
<string name="settings_touchscreen_controller_view">Visualização do controle em tela</string>
<string name="settings_auto_hide_touchscreen_controller">Auto ocultar controles em tela</string>
<string name="settings_summary_auto_hide_touchscreen_controller">Esconde controles em tela quando um controle externo é detectado.</string>
<string name="settings_vibrate_on_press">Vibrar ao Pressionar</string>
<string name="settings_summary_vibrate_on_press">Ativa vibração quando um botão da tela de toque é pressionado. Requer \"Vibrar ao Tocar\" ativado nas opções do seu dispositivo para funcionar.</string>
<string name="settings_enable_vibration">Ativa Vibração</string>
<string name="settings_summary_enable_vibration">Encaminha vibração do jogo para o motor do aparelho</string>
<string name="settings_memory_card_1_type">Tipo de Cartão de Memória 1</string>
<string name="settings_memory_card_2_type">Tipo de Cartão de Memória 2</string>
<string name="settings_crop_mode">Modo de Corte</string>
<string name="settings_aspect_ratio">Aspect Ratio</string>
<string name="settings_linear_upscaling">Escalonamento Linear</string>
<string name="settings_integer_upscaling">Escalonamento Integro</string>
<string name="settings_summary_linear_upscaling">Suaviza a imagem ao aumentar a resolução da emulação.</string>
<string name="settings_summary_integer_upscaling">Adiciona preenchimento a área exibida para garantir a proporção entre os pixels. Pode resultar em uma imagem mais nítida em jogos 2D.</string>
<string name="settings_summary_osd_show_messages">Mostra mensagens em tela ao salvar, carregar, carregar trapaças quando eventos ou alertas ocorrerem.</string>
<string name="settings_summary_osd_show_speed">Define a velocidade de emulação. Não é garantido que essa velocidade será atingida.</string>
<string name="settings_summary_osd_show_fps">Mostra a taxa de quadros (FPS) interna do jogo no canto superior direito da tela.</string>
<string name="settings_summary_osd_show_vps">Mostra o número de quadros (VPS) exibidos por segundo pelo sistema no canto superior direito da tela.</string>
<string name="settings_cdrom_read_speedup">Velocidade de leitura CD-ROM</string>
<string name="settings_summary_cdrom_read_speedup">Acelera a leitura de CD-ROM. Aplica-se apenas a leituras de velocidade 2x é ignorado quando o áudio está sendo reproduzido. Pode melhorar a velocidade de carregamento em alguns jogos, ao custo de quebrar outros.</string>
<string name="settings_summary_console_fast_boot">Pula a tela de abertura clássica da Sony seguro ativar porém alguns raros jogos podem quebrar.</string>
<string name="settings_msaa">Filtro Anti-serrilhado (MSAA)</string>
<string name="settings_true_color">Renderização em (24 Cores, desativa dithering)</string>
<string name="settings_summary_true_color">Produz gradientes de aparência mais agradável ao custo de fazer algumas cores ficarem ligeiramente diferentes. A maioria dos jogos são compatíveis com esta opção.</string>
<string name="settings_scaled_dithering">Efeito Dithering Escalado (escala pontilhados para resolução). </string>
<string name="settings_summary_scaled_dithering">Escala o dithering para a resolução da GPU emulada. Torna o padrão do pontilhado muito menos óbvio em resoluções mais altas.</string>
<string name="settings_disable_interlacing">Desativar Entrelaçamento (força redenrização progressiva).</string>
<string name="settings_summary_disable_interlacing">Força a renderização e exibição de quadros para o modo progressivo. Remove o efeito de \'alisamento\' visto em jogos 480i renderizando sempre em 480, seguro deixar ativo.</string>
<string name="settings_texture_filtering">Filtragem de textura</string>
<string name="settings_force_ntsc_timings">Força renderização em NTSC (60hz-em-PAL)</string>
<string name="settings_summary_force_ntsc_timings">Usa temporizadores de quadro NTSC forçando os jogos PAL a rodarem a 60 Hz.</string>
<string name="settings_widescreen_hack">Hack de tela panorâmica</string>
<string name="settings_summary_widescreen_hack">Dimensiona as posições dos vértices da tela para a proporção mais larga (Panoramicas), basicamente aumenta o campo de visão de 4:3 para 16:09 em jogos 3D. Não é compatível com todos os jogos.</string>
<string name="settings_force_4_3_for_24bit">Forçar 4:3 para telas 24-bits.</string>
<string name="settings_summary_force_4_3_for_24bit">Volta a tela para 4:3 (Desativa efeito Esticado em FMVs).</string>
<string name="settings_chroma_smoothing_24bit">Suavização de Croma</string>
<string name="settings_summary_chrome_smoothing_24bit">Suavização de Croma (reduz artefatos em cenas FMV).</string>
<string name="settings_pgxp_geometry_correction">Correção Geométrica PGXP</string>
<string name="settings_summary_pgxp_geometry_correction"><![CDATA[Reduz as "oscilações" nos polígonos tentando preservar os mesmos na hora da transferência para a memória. Funciona apenas se rederizado por hardware e pode não ser compatível com todos os jogos Não compativel com todos os jogos.]]></string>
<string name="settings_pgxp_culling_correction">Correção de Curvas PGXP</string>
<string name="settings_summary_pgxp_culling_correction">Aumenta a precisão das curvas nos polígonos, reduzindo o número de buracos na geometria do mesmo. Requer a Correção Geometrica ativada. Requer que a correção geométrica esteja ativada.</string>
<string name="settings_pgxp_texture_correction">Correção de Textura PGXP</string>
<string name="settings_summary_pgxp_texture_correction">Utiliza interpolação corretiva em perspetiva para coordenadas e das cores na textura, endireitando as que estiverem distorcidas. Requer que a correção geométrica esteja ativada.</string>
<string name="settings_pgxp_preserve_projection_precision">Preserva Precisão de Projeção PGXP</string>
<string name="settings_summary_pgxp_preserve_projection_precision">Permite precisão adicional para PGXP; Pode melhorar o visual em alguns jogos e prejudicar outros.</string>
<string name="settings_pgxp_depth_buffer">PGXP Modo Polimento (Z)</string>
<string name="settings_summary_pgxp_depth_buffer">Tenta reduzir os poligonos no eixo Z (parte inferior ou cantos em alguns casos) ajustando os limites dos valores para que não haja conflitos na renderização de poligonos 3D. Gerando um efeito de buracos ou quadrados piscando. Tem pouca compatibilidade no geral, mas pode funcionar bem em alguns jogos. Outros precisam ser ajustados via limitador.</string>
<string name="menu_main_resume_last_session">Resumir Jogo</string>
<string name="menu_main_start_file">Iniciar Arquivo</string>
<string name="menu_main_start_bios">Iniciar BIOS</string>
<string name="menu_main_edit_game_directories">Editar Diretórios de Jogos</string>
<string name="menu_main_scan_for_new_games">Escanear Jogos Novos</string>
<string name="menu_main_rescan_all_games">Rescanear Tudo</string>
<string name="menu_main_import_bios">Importar BIOS</string>
<string name="menu_main_show_version">Mostrar Versão</string>
<string name="menu_main_github_repository">Repositório no Github</string>
<string name="menu_main_discord_server">Servidor no Discord</string>
<string name="menu_game_list_entry_start_game">Iniciar Jogo</string>
<string name="menu_game_list_entry_resume_game">Resumir Jogo</string>
<string name="android_progress_callback_please_wait">Aguarde...</string>
<string name="android_progress_callback_ok">OK</string>
<string name="android_progress_callback_information">Informação</string>
<string name="android_progress_callback_confirmation">Confirmação</string>
<string name="android_progress_callback_yes">Sim</string>
<string name="android_progress_callback_no">Não</string>
<string name="emulation_activity_error">Erro</string>
<string name="emulation_activity_ok">Ok</string>
<string name="emulation_activity_import_patch_codes">Importar Trapaças...</string>
<string name="emulation_activity_patch_on">(Ligar)</string>
<string name="emulation_activity_patch_off">(Desligar)</string>
<string name="emulation_activity_choose_patch_code_file">Escolher Arquivo de Trapaça</string>
<string name="emulation_activity_failed_to_import_patch_codes">Falha ao importar trapaça. Assegure-se de ter escolhido o formato PCSXR ou Libretro CHT.</string>
<string name="main_activity_choose_directory">Escolher Diretório</string>
<string name="main_activity_error">Erro</string>
<string name="main_activity_get_path_from_file_error">Falha ao obter o caminho para o arquivo selecionado. Certifique-se de que o arquivo esteja no armazenamento interno / externo.\n\nTap.\nSelect "Mostrar armazenamento interno".\nTap selecione o nome do seu dispositivo ou cartão SD.</string>
<string name="main_activity_ok">OK</string>
<string name="main_activity_get_path_from_directory_error">Falha ao obter o caminho para o arquivo selecionado. Certifique-se de que o arquivo esteja no armazenamento interno / externo. \n\nTap the overflow button in the directory selector.\nSelect \"Mostrar armazenamento interno\".\nTap selecione o nome do seu dispositivo ou cartão SD.</string>
<string name="main_activity_external_storage_permissions_error">Permissões de armazenamento externo são necessárias para usar o DuckStation.</string>
<string name="main_activity_choose_disc_image">Escolha Arquivo de Jogo</string>
<string name="main_activity_missing_bios_image_prompt">Nenhum BIOS foi encontrada no diretório de BIOS do DuckStation. Deseja localizar e importar o BIOS agora?</string>
<string name="main_activity_missing_bios_image">BIOS ausente.</string>
<string name="main_activity_yes">Sim</string>
<string name="main_activity_no">Não</string>
<string name="main_activity_choose_bios_image">Escolher BIOS</string>
<string name="main_activity_failed_to_open_bios_image">Falha ao Abrir BIOS.</string>
<string name="main_activity_failed_to_read_bios_image_prefix">\"Falha ao ler BIOS: \"</string>
<string name="main_activity_bios_image_too_large">Aqruivo BIOS muito grande.</string>
<string name="main_activity_invalid_error">Esse BIOS não é válido, ou já foi importado.</string>
<string name="main_activity_show_version_title">Versão</string>
<string name="main_activity_copy">Copiar</string>
<string name="settings_gpu_thread">Renderização Sequencial</string>
<string name="settings_summary_gpu_thread">Usa um segundo processo para desenhar gráficos em tela. Atualmente só disponível para renderizadores por software, pode fornecer uma melhoria significativa na velocidade, pode ser usado a vontade.</string>
<string name="settings_gpu_threaded_presentation">Renderização Sequencial</string>
<string name="settings_summary_gpu_threaded_presentation">Apresenta quadros sequêncialmente em segundo plano quando o avanço rápido ou sincronizador vertical (Vsync) está desativado Isso pode melhorar o desempenho no renderizador Vulkan.</string>
<string name="settings_language">Linguagem (Necessário Reiniciar)</string>
<string name="touchscreen_controller_stop_editing">Terminado</string>
<string name="touchscreen_controller_reset_layout">Redefinir</string>
<string name="emulation_activity_touchscreen_controller_not_active">Controle em Tela não Ativado.</string>
<string name="settings_theme">Tema</string>
<string name="settings_controller_mapping_summary">Permite configurar e atribuir os botões de seu controle externo no emulador.</string>
<string name="settings_controller_mapping">Mapear Controles</string>
<string name="controller_binding_dialog_message">Pressione os botões para atribuí-los ao controle.\n\nAtribuição Atual: %s</string>
<string name="controller_binding_dialog_no_binding"><![CDATA[<Nenhuma>]]></string>
<string name="controller_binding_dialog_cancel">Cancelar</string>
<string name="controller_binding_dialog_clear">Limpar</string>
<string name="controller_mapping_activity_title">Mapear Controle</string>
<string name="controller_mapping_activity_no_profiles_found">Perfil não encontrado.</string>
<string name="controller_mapping_activity_select_input_profile">Escolha o Perfil de Entrada</string>
<string name="controller_mapping_activity_failed_to_load_profile">Falha ao carregar o perfil \'%s\'</string>
<string name="controller_mapping_activity_input_profile_name">Nome do Perfil:</string>
<string name="controller_mapping_activity_save">Salvar</string>
<string name="controller_mapping_activity_name_must_be_provided">Um nome deve ser escolhido.</string>
<string name="controller_mapping_activity_failed_to_save_input_profile">Falha ao salvar perfil.</string>
<string name="controller_mapping_activity_input_profile_saved">Perfil \'%s\' salvo.</string>
<string name="controller_mapping_activity_cancel">Cancelar</string>
<string name="settings_use_analog_sticks_for_dpad">Usar Analógicos como D-Pad no Modo Digital</string>
<string name="settings_summary_enable_analog_mode_on_reset">Força os controles ao modo analógico quando emulador é reiniciado.</string>
<string name="settings_summary_use_analog_sticks_for_dpad">Permite usar os analógicos como um direcional (D-Pad) no modo digital, assim como os botões.</string>
<string name="settings_disable_all_enhancements">Desativar todas as Melhorias</string>
<string name="settings_summary_disable_all_enhancements">Desliga temporariamente todas as melhorias, útil para achar problemas de performance.</string>
<string name="settings_downsample_mode">Suavização da Imagem</string>
<string name="activity_game_properties">Propriedades do Jogo</string>
<string name="game_properties_preference_use_global_setting">Usar configuração global</string>
<string name="settings_input_profile">Perfil de controle</string>
<string name="game_properties_tab_summary">Sumário</string>
<string name="game_properties_tab_game_settings">Configuração de Jogo</string>
<string name="game_properties_tab_controller_settings">Configurações de Controle</string>
<string name="settings_audio_resampling">Ajuste de Áudio</string>
<string name="settings_summary_audio_resampling">Quando estiver rodando fora dos 100% da velocidade, o áudio será ajustado para que não haja queda de quadros. Produz uma melhor qualidade do avanço rápido no áudio ao custo pequeno de perda de performance.</string>
<string name="settings_general_sync_to_host_refresh_rate">Sincronizar taxa de atualização</string>
<string name="settings_summary_general_sync_to_host_refresh_rate">Ajusta a velocidade da emulação de acordo com a mesma taxa de atualização do dispositivo.</string>
<string name="settings_sustained_performance_mode">Desempenho Contínuo</string>
<string name="settings_summary_sustained_performance_mode">Ativa o modo contínuo de perfomance do Android. Resulta em um melhor desempenho de quadros e perfomance por longos periodos em alguns dispositivos.</string>
<string name="title_activity_game_directories">Editar Diretórios de Jogos</string>
<string name="settings_game_directories">Diretório de Jogos</string>
<string name="settings_summary_game_directories">Altera a lista de diretórios usados para pesquisar jogos.</string>
<string name="game_directories_scanning_subdirectories">Ler subdiretórios.</string>
<string name="game_directories_not_scanning_subdirectories">Não ver subdiretórios.</string>
<string name="settings_display_all_frames">Otimização de Quadros</string>
<string name="settings_summary_display_all_frames">Garante que cada quadro renderizado será mostrado em tela, no seu rtimo adequado. Se estiver tendo dificuldades ao manter uma boa velocidade, ou estiver enfrentando algumas falhas de áudio tente desativar esta opção.</string>
<string name="menu_edit_game_directories_add_directory">Adicionar Diretório</string>
<string name="menu_edit_game_directories_add_path">Adicionar Caminho</string>
<string name="edit_game_directories_add_path">Editar Caminho</string>
<string name="edit_game_directories_add_path_summary">Insira o caminho completo dos seus jogos.\n\nUse um gerenciador de arquivos para ver o caminho.\n\nExemplo: /storage/emulated/0/games</string>
<string name="save_state_info_slot_is_empty">Espaço Vazio</string>
<string name="save_state_info_game_save_n">Id do Jogo %d</string>
<string name="save_state_info_global_save_n">Espaço Global %d</string>
<string name="save_state_info_quick_save">Salvar Rápido</string>
</resources>

View File

@@ -0,0 +1,235 @@
<resources>
<string-array name="settings_console_region_entries">
<item>Автоопределение</item>
<item>NTSC-J (Япония)</item>
<item>NTSC-U (США)</item>
<item>PAL (Европа, Австралия)</item>
</string-array>
<string-array name="settings_cpu_execution_mode_entries">
<item>Интерпретатор (самый медленный)</item>
<item>Кэшированный интерпретатор (быстрее)</item>
<item>Рекомпилятор (самый быстрый)</item>
</string-array>
<string-array name="settings_cpu_fastmem_mode_entries">
<item>Выключен (самый медленный)</item>
<item>MMap (аппаратный, самый быстрый, только для 64-бит)</item>
<item>LUT (быстрее)</item>
</string-array>
<string-array name="gpu_renderer_entries">
<item>Аппаратный (OpenGL)</item>
<item>Аппаратный (Vulkan)</item>
<item>Программный</item>
</string-array>
<string-array name="settings_gpu_resolution_scale_entries">
<item>1x</item>
<item>2x</item>
<item>3x (для 720p)</item>
<item>4x</item>
<item>5x (для 1080p)</item>
<item>6x (для 1440p)</item>
<item>7x</item>
<item>8x</item>
<item>9x (для 4K)</item>
<item>10x</item>
<item>11x</item>
<item>12x</item>
<item>13x</item>
<item>14x</item>
<item>15x</item>
<item>16x</item>
</string-array>
<string-array name="settings_display_crop_mode_entries">
<item>Нет</item>
<item>Только вылеты развёртки</item>
<item>Все границы</item>
</string-array>
<string-array name="settings_display_aspect_ratio_names">
<item>Автонастройка (нативное игре)</item>
<item>4:3</item>
<item>16:9</item>
<item>16:10</item>
<item>19:9</item>
<item>20:9</item>
<item>21:9</item>
<item>32:9</item>
<item>8:7</item>
<item>5:4</item>
<item>3:2</item>
<item>2:1 (VRAM 1:1)</item>
<item>1:1</item>
<item>PAR 1:1</item>
</string-array>
<string-array name="settings_gpu_texture_filter_names">
<item>Метод ближайшего соседа</item>
<item>Билинейная</item>
<item>Билинейная (без сглаживания краёв)</item>
<item>JINC2</item>
<item>JINC2 (без сглаживания краёв)</item>
<item>xBR</item>
<item>xBR (без сглаживания краёв)</item>
</string-array>
<string-array name="settings_controller_type_entries">
<item>Цифровой</item>
<item>Аналоговый (DualShock)</item>
</string-array>
<string-array name="settings_memory_card_mode_entries">
<item>Без карты памяти</item>
<item>Общая для всех игр</item>
<item>Своя карта для каждой игры (по коду)</item>
<item>Своя карта для каждой игры (по названию)</item>
</string-array>
<string-array name="emulation_menu">
<item>Загрузить состояние</item>
<item>Сохранить состояние</item>
<item>Включить ускорение</item>
<item>Другие опции</item>
<item>Выход</item>
</string-array>
<string-array name="emulation_more_menu">
<item>Сброс</item>
<item>Чит-коды</item>
<item>Сменить диск</item>
<item>Настройки</item>
<item>Сменить экранный контроллер</item>
<item>Настроить экранный контроллер</item>
</string-array>
<string-array name="settings_cdrom_read_speedup_entries">
<item>Нет (двойная скорость)</item>
<item>2x (скорость 4x)</item>
<item>3x (скорость 6x)</item>
<item>4x (скорость 8x)</item>
<item>5x (скорость 10x)</item>
<item>6x (скорость 12x)</item>
<item>7x (скорость 14x)</item>
<item>8x (скорость 16x)</item>
<item>9x (скорость 18x)</item>
<item>10x (скорость 20x)</item>
</string-array>
<string-array name="settings_touchscreen_controller_view_entries">
<item>Нет</item>
<item>Цифровой</item>
<item>Аналоговый с одним стиком</item>
<item>Аналоговый с двумя стиками</item>
</string-array>
<string-array name="settings_audio_backend_entries">
<item>Нет (без звука)</item>
<item>Cubeb</item>
<item>OpenSL ES (рекомендовано)</item>
</string-array>
<string-array name="settings_audio_buffer_size_entries">
<item>1024 блока (23.22 мс)</item>
<item>2048 блоков (46.44 мс, рекомендовано)</item>
<item>3072 блока (69.66 мс)</item>
<item>4096 блоков (92.88 мс)</item>
</string-array>
<string-array name="settings_log_level_entries">
<item>Нет</item>
<item>Error</item>
<item>Warning</item>
<item>Performance Warnings</item>
<item>Information</item>
<item>Verbose</item>
<item>Developer</item>
<item>Profile</item>
<item>Debug</item>
<item>Trace</item>
</string-array>
<string-array name="settings_tabs">
<item>Основные</item>
<item>Экран</item>
<item>Звук</item>
<item>Улучшения</item>
<item>Контроллеры</item>
<item>Расширенные</item>
</string-array>
<string-array name="settings_gpu_msaa_entries">
<item>Выключен</item>
<item>2x MSAA</item>
<item>4x MSAA</item>
<item>8x MSAA</item>
<item>2x SSAA</item>
<item>4x SSAA</item>
<item>8x SSAA</item>
</string-array>
<string-array name="settings_advanced_display_fps_limit_entries">
<item>Без ограничений (выводить все кадры)</item>
<item>10 FPS</item>
<item>15 FPS</item>
<item>30 FPS</item>
<item>45 FPS</item>
<item>60 FPS</item>
<item>75 FPS</item>
<item>90 FPS</item>
</string-array>
<string-array name="settings_emulation_speed_entries">
<item>Без ограничений</item>
<item>10% [6 FPS (NTSC) / 5 FPS (PAL)]</item>
<item>20% [12 FPS (NTSC) / 10 FPS (PAL)]</item>
<item>30% [18 FPS (NTSC) / 15 FPS (PAL)]</item>
<item>40% [24 FPS (NTSC) / 20 FPS (PAL)]</item>
<item>50% [30 FPS (NTSC) / 25 FPS (PAL)]</item>
<item>60% [36 FPS (NTSC) / 30 FPS (PAL)]</item>
<item>70% [42 FPS (NTSC) / 35 FPS (PAL)]</item>
<item>80% [48 FPS (NTSC) / 40 FPS (PAL)]</item>
<item>90% [54 FPS (NTSC) / 45 FPS (PAL)]</item>
<item>100% [60 FPS (NTSC) / 50 FPS (PAL), по умолчанию]</item>
<item>125% [75 FPS (NTSC) / 62 FPS (PAL)]</item>
<item>150% [90 FPS (NTSC) / 75 FPS (PAL)]</item>
<item>175% [105 FPS (NTSC) / 87 FPS (PAL)]</item>
<item>200% [120 FPS (NTSC) / 100 FPS (PAL)]</item>
<item>250% [150 FPS (NTSC) / 125 FPS (PAL)]</item>
<item>300% [180 FPS (NTSC) / 150 FPS (PAL)]</item>
<item>350% [210 FPS (NTSC) / 175 FPS (PAL)]</item>
<item>400% [240 FPS (NTSC) / 200 FPS (PAL)]</item>
<item>450% [270 FPS (NTSC) / 225 FPS (PAL)]</item>
<item>500% [300 FPS (NTSC) / 250 FPS (PAL)]</item>
<item>600% [360 FPS (NTSC) / 300 FPS (PAL)]</item>
<item>700% [420 FPS (NTSC) / 350 FPS (PAL)]</item>
<item>800% [480 FPS (NTSC) / 400 FPS (PAL)]</item>
<item>900% [540 FPS (NTSC) / 450 FPS (PAL)]</item>
<item>1000% [600 FPS (NTSC) / 500 FPS (PAL)]</item>
</string-array>
<string-array name="settings_advanced_cpu_overclock_entries">
<item>25% (8 МГц)</item>
<item>50% (16 МГц)</item>
<item>75% (24 МГц)</item>
<item>100% (33 МГц, по умолчанию)</item>
<item>125% (41 МГц)</item>
<item>150% (49 МГц)</item>
<item>175% (57 МГц)</item>
<item>200% (66 МГц)</item>
<item>225% (74 МГц)</item>
<item>250% (82 МГц)</item>
<item>275% (90 МГц)</item>
<item>300% (99 МГц)</item>
<item>350% (115 МГц)</item>
<item>400% (132 МГц)</item>
<item>450% (148 МГц)</item>
<item>500% (165 МГц)</item>
<item>500% (165 МГц)</item>
<item>600% (198 МГц)</item>
<item>700% (231 МГц)</item>
<item>800% (264 МГц)</item>
<item>900% (297 МГц)</item>
<item>1000% (330 МГц)</item>
</string-array>
<string-array name="settings_emulation_screen_orientation_entries">
<item>По выбору системы</item>
<item>Портретная</item>
<item>Ландшафтная</item>
</string-array>
<string-array name="settings_theme_entries">
<item>По выбору системы</item>
<item>Светлая</item>
<item>Тёмная</item>
</string-array>
<string-array name="settings_downsample_mode_entries">
<item>Выключен</item>
<item>Прямоугольный (понижать 3D/сглаживать всё)</item>
<item>Адаптивный (не понижать 3D/сглаживать 2D)</item>
</string-array>
<string-array name="settings_boolean_entries">
<item>Выключен</item>
<item>Включен</item>
</string-array>
</resources>

View File

@@ -0,0 +1,207 @@
<resources>
<string name="app_name">DuckStation</string>
<string name="action_settings">Настройки</string>
<string name="action_controller_mapping">Привязки геймпада</string>
<string name="title_activity_settings">Настройки</string>
<string name="settings_console_region">Регион консоли</string>
<string name="settings_console_tty_output">Включить вывод в TTY</string>
<string name="settings_console_fast_boot">Быстрый запуск</string>
<string name="settings_osd_show_messages">Показывать сообщения</string>
<string name="settings_osd_show_speed">Показывать скорость эмуляции</string>
<string name="settings_osd_show_show_fps">Показывать FPS</string>
<string name="settings_osd_show_show_vps">Показывать VPS</string>
<string name="settings_cpu_execution_mode">Режим работы CPU</string>
<string name="settings_gpu_renderer">Графический движок</string>
<string name="settings_gpu_resolution_scale">Множитель разрешения</string>
<string name="title_activity_emulation">EmulationActivity</string>
<string name="settings_emulation_speed">Скорость эмуляции</string>
<string name="settings_fast_forward_speed">Скорость перемотки</string>
<string name="settings_save_state_on_exit">Сохранять при выходе</string>
<string name="settings_pause_when_menu_opened">Пауза при вызове меню</string>
<string name="settings_emulation_screen_orientation">Ориентация экрана эмуляции</string>
<string name="settings_load_patch_codes">Загружать чит-коды</string>
<string name="settings_summary_save_state_on_exit">Автоматически сохранять состояние эмулятора при выходе. Позволяет продолжить игру с места остановки.</string>
<string name="settings_summary_pause_when_menu_opened">Останавливать эмуляцию при вызове меню во время игры.</string>
<string name="settings_summary_load_patch_codes">Загружать чит-коды из cheats/&lt;название игры&gt;.cht в формате PCSXR или Libretro. Коды можно активировать внутри игры.</string>
<string name="settings_apply_compatibility_settings">Применять настройки совместимости</string>
<string name="settings_summary_apply_compatibility_settings">Автоматически отключать улучшения, которые не поддерживаются играми.</string>
<string name="settings_summary_video_sync">Включите эту настройку для синхронизации частоты обновления DuckStation с частотой экрана устройства. Синхронизация будет автоматически выключена, если скорость эмуляции не равна 100%.</string>
<string name="settings_video_sync">Видеосинхронизация</string>
<string name="settings_cpu_overclocking">Разгон CPU</string>
<string name="settings_cdrom_region_check">Проверка региона CD-ROM</string>
<string name="settings_summary_cdrom_region_check">Снижает вероятность некорректного считывания региона диска эмулятором. Как правило, не влияет на стабильность.</string>
<string name="settings_cdrom_preload_image_to_ram">Предзагрузка образа CD-ROM в ОЗУ</string>
<string name="settings_summary_preload_image_to_ram">Загружать образ диска в оперативную память. Полезно при запуске игр с ненадёжных сетевых ресурсов. В некоторых случаях помогает устранить заикания при запуске игрой аудиодорожек.</string>
<string name="settings_pgxp_vertex_cache">Вершинный кэш PGXP</string>
<string name="settings_summary_pgxp_vertex_cache">Использовать координаты экрана в качестве резерва при отслеживании вершин с помощью отказов памяти. Может улучшать совместимость PGXP.</string>
<string name="settings_pgxp_cpu_mode">Режим CPU PGXP</string>
<string name="settings_summary_pgxp_cpu_mode">Пытаться отслеживать изменения вершин с помощью CPU. Требуется для правильной работы PGXP в некоторых играх. Очень медленный режим, несовместимый с рекомпилятором.</string>
<string name="settings_cpu_recompiler_icache">Рекомпиляция кэша команд CPU</string>
<string name="settings_summary_cpu_recompiler_icache">Включает симуляцию кэша команд CPU в рекомпиляторе. Повышает точность, незначительно снижая производительность. Попробуйте включить данную опцию, если игры идут слишком быстро.</string>
<string name="settings_cpu_recompiler_fastmem">Быстрый доступ к памяти в рекомпиляторе CPU</string>
<string name="settings_summary_cpu_recompiler_fastmem">Повышает эффективность доступа к гостевой памяти с помощью бэкпатчей и ошибок страниц. Отключите при нестабильной работе на устройстве.</string>
<string name="settings_presented_frame_limit">Ограничение частоты кадров</string>
<string name="settings_logging_level">Уровень логирования</string>
<string name="settings_log_to_file">Лог в файл</string>
<string name="settings_summary_log_to_file">Записывать сообщения лога в duckstation.log в папке эмулятора. Используйте только для отладки из-за замедления эмуляции.</string>
<string name="settings_log_to_logcat">Лог в Logcat</string>
<string name="settings_summary_log_to_logcat">Записывать сообщения лога в журнал отладки Android. Полезно только при подключении к ПК с adb.</string>
<string name="settings_volume">Громкость</string>
<string name="settings_summary_volume">Управление громкостью звука эмулятора.</string>
<string name="settings_fast_forward_volume">Громкость при ускорении</string>
<string name="settings_summary_fast_forward_volume">Управление громкостью звука эмулятора при ускоренной перемотке.</string>
<string name="settings_mute_all_sound">Отключить звук</string>
<string name="settings_summary_mute_all_sound">Отключает вывод звука в эмуляторе.</string>
<string name="settings_mute_cd_audio">Отключить CD аудио</string>
<string name="settings_summary_mute_cd_audio">Принудительное отключение CD-DA и XA дорожек диска. Может быть использовано для отключения фоновой музыки в играх.</string>
<string name="settings_audio_backend">Аудио бэкенд</string>
<string name="settings_audio_buffer_size">Размер аудио буфера</string>
<string name="settings_summary_audio_buffer_size">Определяет задержку звука между обработкой и выводом. Меньшие значения снижают задержку, но вызывают треск при нестабильной скорости эмуляции.</string>
<string name="settings_audio_sync">Аудиосинхронизация</string>
<string name="settings_summary_audio_sync">Ускоряет эмуляцию в зависимости от скорости вывода блоков бэкендом. Помогает устранить искажения звука, если эмуляция идёт слишком быстро. Синхронизация автоматически выключается, если скорость эмуляции не равна 100%.</string>
<string name="settings_controller_type">Тип контроллера</string>
<string name="settings_enable_analog_mode_on_reset">Включить аналоговый режим при сбросе</string>
<string name="settings_touchscreen_controller_view">Вид экранного контроллера</string>
<string name="settings_auto_hide_touchscreen_controller">Автоотключение экранного контроллера</string>
<string name="settings_summary_auto_hide_touchscreen_controller">Скрывать экранный контроллер при подключении внешнего геймпада.</string>
<string name="settings_vibrate_on_press">Вибрация при нажатии</string>
<string name="settings_summary_vibrate_on_press">Включает короткую вибрацию при нажатии экранных кнопок. Виброотклик должен быть включен в настройках системы.</string>
<string name="settings_enable_vibration">Включить вибрацию</string>
<string name="settings_summary_enable_vibration">Перенаправлять отдачу в игре на вибромотор смартфона.</string>
<string name="settings_memory_card_1_type">Тип карты памяти 1</string>
<string name="settings_memory_card_2_type">Тип карты памяти 2</string>
<string name="settings_crop_mode">Режим обрезки</string>
<string name="settings_aspect_ratio">Соотношение сторон</string>
<string name="settings_linear_upscaling">Линейное масштабирование</string>
<string name="settings_integer_upscaling">Целочисленное масштабирование</string>
<string name="settings_summary_linear_upscaling">Сглаживать картинку при масштабировании изображения с консоли под экран.</string>
<string name="settings_summary_integer_upscaling">Добавлять пустое пространство к изображению, чтобы пиксельное соотношение устройства и консоли равнялось целому числу. Позволяет получить более чёткую картинку в некоторых 2D-играх.</string>
<string name="settings_summary_osd_show_messages">Выводить на экран сообщения о системных событиях, таких как сохранение/загрузка, снимок экрана и т.д.</string>
<string name="settings_summary_osd_show_speed">Установка скорости эмуляции. Достижение заданной скорости не гарантируется и в этом случае эмулятор будет работать на максимально возможной скорости</string>
<string name="settings_summary_osd_show_fps">Показывать внутреннюю частоту кадров игры в правом верхнем углу экрана.</string>
<string name="settings_summary_osd_show_vps">Показывать количество кадров (или синхронизаций) в секунду в правом верхнем углу экрана.</string>
<string name="settings_cdrom_read_speedup">Ускорение считывания CD-ROM</string>
<string name="settings_summary_cdrom_read_speedup">Повышает скорость чтения диска на заданный множитель. Применяется только при считывании с двойной скоростью и не учитывается при воспроизведении аудио. Ускоряет загрузки в некоторых играх, но приводит к ошибкам в других.</string>
<string name="settings_summary_console_fast_boot">Пропускать BIOS/заставку, загружаясь прямо в игру. Как правило, не влияет на стабильность, но некоторые игры могут перестать запускаться.</string>
<string name="settings_msaa">Мультисэмплинг</string>
<string name="settings_true_color">Рендеринг в True Color (24-бита, без дизеринга)</string>
<string name="settings_summary_true_color">Позволяет получить более качественные градиенты, но меняет отображение некоторых цветов. Отключение опции также включает дизеринг. Большинство игр совместимо с этой настройкой.</string>
<string name="settings_scaled_dithering">Масштабируемый дизеринг (изменять паттерн дизеринга под разрешение)</string>
<string name="settings_summary_scaled_dithering">Масштабировать паттерн дизеринга согласно разрешению эмулируемого GPU. Маскирует эффект зашумления на высоких разрешениях. Поддерживается только аппаратными рендерами и, как правило, не влияет на стабильность.</string>
<string name="settings_disable_interlacing">Отключить чересстрочность (рендеринг в построчной развёртке)</string>
<string name="settings_summary_disable_interlacing">Принудительная отрисовка и вывод кадров в прогрессивной развёртке. Убирает эффект \"гребёнки\" для игр в 480i. Как правило, не влияет на стабильность.</string>
<string name="settings_texture_filtering">Фильтрация текстур</string>
<string name="settings_force_ntsc_timings">Принудительный NTSC-тайминг (PAL в 60 Гц)</string>
<string name="settings_summary_force_ntsc_timings">Использовать NTSC-тайминги кадра, если консоль в режиме PAL, тем самым принудительно запуская игры PAL в 60 Гц.</string>
<string name="settings_widescreen_hack">Широкоформатный хак</string>
<string name="settings_summary_widescreen_hack">Масштабировать позиции вершин в пространстве экрана до широкоформатных соотношений сторон, расширяя область обзора в 3D-играх с 4:3 до 16:9. Совместимо не со всеми играми.</string>
<string name="settings_force_4_3_for_24bit">Включать 4:3 для 24-бит</string>
<string name="settings_summary_force_4_3_for_24bit">Переключаться обратно на соотношение 4:3 при отображении 24-битного контента, например видеороликов.</string>
<string name="settings_chroma_smoothing_24bit">Сглаживание цвета для 24-бит</string>
<string name="settings_summary_chrome_smoothing_24bit">Сглаживает блочность цветовых переходов в 24-битном контенте, например видеороликах. Работает только с аппаратным рендерингом.</string>
<string name="settings_pgxp_geometry_correction">Коррекция геометрии PGXP</string>
<string name="settings_summary_pgxp_geometry_correction">Уменьшает дрожание и искривление текстур, присущее играм PS1. Работает только с аппаратными рендерами. Совместимо не со всеми играми.</string>
<string name="settings_pgxp_culling_correction">Коррекция выборки PGXP</string>
<string name="settings_summary_pgxp_culling_correction">Повышает точность отбраковки полигонов, снижая количество провалов в геометрии. Требуется включение коррекции геометрии.</string>
<string name="settings_pgxp_texture_correction">Коррекция текстур PGXP</string>
<string name="settings_summary_pgxp_texture_correction">Использовать перспективно-корректную интерполяцию для координат текстур и цветов, выпрямляя искривлённые текстуры. Должна быть включена коррекция геометрии.</string>
<string name="settings_pgxp_preserve_projection_precision">Точность проекции PGXP</string>
<string name="settings_summary_pgxp_preserve_projection_precision">Включает повышенную точность PGXP. Может улучшать графику в некоторых играх, но приводить к ошибкам в других.</string>
<string name="settings_pgxp_depth_buffer">Буфер глубины PGXP</string>
<string name="settings_summary_pgxp_depth_buffer">Пытаться устранять наложения полигонов проверкой пикселей по значениям глубины PGXP. Обладает низкой совместимостью, но в ряде игр даёт хороший эффект.</string>
<string name="menu_main_resume_last_session">Продолжить сеанс</string>
<string name="menu_main_start_file">Запустить файл</string>
<string name="menu_main_start_bios">Запустить BIOS</string>
<string name="menu_main_edit_game_directories">Настроить каталоги игр</string>
<string name="menu_main_scan_for_new_games">Обновить список игр</string>
<string name="menu_main_rescan_all_games">Проверить игры в списке</string>
<string name="menu_main_import_bios">Импорт BIOS</string>
<string name="menu_main_show_version">Показать версию</string>
<string name="menu_main_github_repository">Репозиторий GitHub</string>
<string name="menu_main_discord_server">Сервер Discord</string>
<string name="menu_game_list_entry_start_game">Запустить игру</string>
<string name="menu_game_list_entry_resume_game">Продолжить игру</string>
<string name="android_progress_callback_please_wait">Пожалуйста, подождите...</string>
<string name="android_progress_callback_ok">OK</string>
<string name="android_progress_callback_information">Информация</string>
<string name="android_progress_callback_confirmation">Подтверждение</string>
<string name="android_progress_callback_yes">Да</string>
<string name="android_progress_callback_no">Нет</string>
<string name="emulation_activity_error">Ошибка</string>
<string name="emulation_activity_ok">OK</string>
<string name="emulation_activity_import_patch_codes">Импорт чит-кодов...</string>
<string name="emulation_activity_patch_on">(ВКЛ)</string>
<string name="emulation_activity_patch_off">(ВЫКЛ)</string>
<string name="emulation_activity_choose_patch_code_file">Выберите файл с чит-кодами</string>
<string name="emulation_activity_failed_to_import_patch_codes">Не удалось импортировать чит-коды. Убедитесь, что выбранный файл в формате PCSXR или Libretro.</string>
<string name="main_activity_choose_directory">Выберите каталог</string>
<string name="main_activity_error">Ошибка</string>
<string name="main_activity_get_path_from_file_error">Не удалось получить путь к указанному файлу. Пожалуйста, убедитесь, что файл присутствует во внутреннем/внешнем хранилище. Нажмите значок настроек в окне выбора каталога. Включите отображение внутренней памяти. Нажмите кнопку меню и выберите устройство или SD-карту.</string>
<string name="main_activity_ok">OK</string>
<string name="main_activity_get_path_from_directory_error">Не удалось получить путь к указанному каталогу. Пожалуйста, убедитесь, что каталог присутствует во внутреннем/внешнем хранилище. Нажмите значок настроек в окне выбора каталога. Включите отображение внутренней памяти. Нажмите кнопку меню и выберите устройство или SD-карту.</string>
<string name="main_activity_external_storage_permissions_error">DuckStation требуются разрешения для доступа к внешнему хранилищу.</string>
<string name="main_activity_choose_disc_image">Выберите образ диска</string>
<string name="main_activity_missing_bios_image_prompt">Не найдены образы BIOS в папке bios эмулятора. Указать путь и импортировать образ BIOS сейчас?</string>
<string name="main_activity_missing_bios_image">Отсутствует образ BIOS</string>
<string name="main_activity_yes">Да</string>
<string name="main_activity_no">Нет</string>
<string name="main_activity_choose_bios_image">Выберите образ BIOS</string>
<string name="main_activity_failed_to_open_bios_image">Не удалось открыть образ BIOS.</string>
<string name="main_activity_failed_to_read_bios_image_prefix">\"Не удалось прочитать образ BIOS: \"</string>
<string name="main_activity_bios_image_too_large">Образ BIOS слишком большой.</string>
<string name="main_activity_invalid_error">Образ BIOS неверный или уже был импортирован.</string>
<string name="main_activity_show_version_title">Версия</string>
<string name="main_activity_copy">Копировать</string>
<string name="settings_gpu_thread">Рендеринг GPU в отдельном потоке</string>
<string name="settings_summary_gpu_thread">Использовать второй поток для отрисовки графики. В настоящее время доступно только для программного рендера, существенно повышая производительность и не влияя на стабильность.</string>
<string name="settings_gpu_threaded_presentation">Вывод с GPU в отдельном потоке</string>
<string name="settings_summary_gpu_threaded_presentation">Выводить кадры в фоновом потоке, если отключена перемотка или видеосинхронизация. Может значительно улучшать производительность при рендеринге на Vulkan.</string>
<string name="settings_language">Язык (требуется перезапуск)</string>
<string name="touchscreen_controller_stop_editing">Закрыть редактор</string>
<string name="touchscreen_controller_reset_layout">Сбросить макет</string>
<string name="emulation_activity_touchscreen_controller_not_active">Экранный контроллер неактивен.</string>
<string name="settings_theme">Тема</string>
<string name="settings_controller_mapping_summary">Позволяет настроить привязки внешнего геймпада к кнопкам и осям эмулируемого контроллера.</string>
<string name="settings_controller_mapping">Настройка контроллера</string>
<string name="controller_binding_dialog_message">Нажмите кнопку геймпада для установки новой привязки.\n\nТекущая привязка: %s</string>
<string name="controller_binding_dialog_no_binding">&lt;Нет привязки&gt;</string>
<string name="controller_binding_dialog_cancel">Отмена</string>
<string name="controller_binding_dialog_clear">Удалить</string>
<string name="controller_mapping_activity_title">Настройка контроллера</string>
<string name="controller_mapping_activity_no_profiles_found">Профили не найдены.</string>
<string name="controller_mapping_activity_select_input_profile">Выбор профиля ввода</string>
<string name="controller_mapping_activity_failed_to_load_profile">Не удалось загрузить профиль \'%s\'</string>
<string name="controller_mapping_activity_input_profile_name">Имя профиля ввода:</string>
<string name="controller_mapping_activity_save">Сохранить</string>
<string name="controller_mapping_activity_name_must_be_provided">Требуется ввести имя.</string>
<string name="controller_mapping_activity_failed_to_save_input_profile">Не удалось сохранить профиль ввода.</string>
<string name="controller_mapping_activity_input_profile_saved">Профиль ввода \'%s\' сохранён.</string>
<string name="controller_mapping_activity_cancel">Отмена</string>
<string name="settings_use_analog_sticks_for_dpad">Аналог в качестве d-pad в цифровом режиме</string>
<string name="settings_summary_enable_analog_mode_on_reset">Переключает контроллер в аналоговый режим при выключении/перезагрузке консоли.</string>
<string name="settings_summary_use_analog_sticks_for_dpad">Позволяет использовать аналоговый джойстик как d-pad вместе с кнопками в цифровом режиме.</string>
<string name="settings_disable_all_enhancements">Отключить улучшения</string>
<string name="settings_summary_disable_all_enhancements">Временно отключить все улучшения. Полезно для отладки.</string>
<string name="settings_downsample_mode">Даунсэмплинг</string>
<string name="activity_game_properties">Свойства</string>
<string name="game_properties_preference_use_global_setting">Глобальная настройка</string>
<string name="settings_input_profile">Профиль ввода</string>
<string name="game_properties_tab_summary">Сведения</string>
<string name="game_properties_tab_game_settings">Настройки игры</string>
<string name="game_properties_tab_controller_settings">Настройки контроллера</string>
<string name="settings_audio_resampling">Аудио ресэмплинг</string>
<string name="settings_summary_audio_resampling">Изменять частоту звука вместо пропуска блоков, если скорость эмуляции выходит за 100%. Улучшает звук при ускорении/замедлении, незначительно влияя на производительность.</string>
<string name="settings_general_sync_to_host_refresh_rate">Синхронизировать с частотой хоста</string>
<string name="settings_summary_general_sync_to_host_refresh_rate">Подстраивать скорость эмуляции для совпадения частоты обновления консоли с частотой хоста, если включены Видеосинхронизация и Аудио ресэмплинг. Обеспечивает наиболее плавную анимацию за счёт возможного завышения скорости менее чем на 1%.</string>
<string name="settings_sustained_performance_mode">Режим устойчивой производительности</string>
<string name="settings_summary_sustained_performance_mode">Включает режим устойчивой производительности Андроид. Может обеспечивать более стабильный фреймрейт при продолжительных сеансах игры на некоторых устройствах.</string>
<string name="title_activity_game_directories">Настройка каталогов игр</string>
<string name="settings_game_directories">Каталоги игр</string>
<string name="settings_summary_game_directories">Настроить список каталогов, используемых при поиске игр.</string>
<string name="game_directories_scanning_subdirectories">Сканировать подкаталоги.</string>
<string name="game_directories_not_scanning_subdirectories">Не сканировать подкаталоги.</string>
<string name="settings_display_all_frames">Оптимальное распределение кадров</string>
<string name="settings_summary_display_all_frames">Включение настройки гарантирует, что все кадры с консоли будут выведены на экран для оптимального распределения. Попробуйте отключить опцию, если не получается достичь полной скорости или есть проблемы со звуком.</string>
<string name="settings_osd_show_show_resolution">Показывать разрешение</string>
<string name="settings_summary_osd_show_resolution">Показывать разрешение рендеринга игры в правом верхнем углу экрана.</string>
</resources>

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