Compare commits

...

490 Commits

Author SHA1 Message Date
AniLeo fbe6900b28 rpcs3_version: Bump to 0.0.9 2020-03-01 00:17:15 +03:00
kd-11 7fe9802f87 vk: Properly use declared pitch when loading simple images 2020-03-01 00:16:52 +03:00
kd-11 14aebeac58 video-out: Allow applications to successfully change display resolution
- Avoids a situation where a game configures output correctly but gets back bogus information later when querying.
- Should fix games being broken at some resolutions but not others.
2020-03-01 00:16:52 +03:00
kd-11 76bbbe27f1 vk: Fix dma resource leak
- Fix broken check; a relic of the past where flush method would reset the fence
2020-03-01 00:16:02 +03:00
kd-11 9af52d12a8 vk: Improve events
- Make events properly managed objects.
- Add a workaround for AMD's broken event status query
2020-03-01 00:16:02 +03:00
kd-11 5eb314fbbb vk: Add execution barriers.
- Useful for debugging
2020-03-01 00:16:02 +03:00
Eladash 655f7ce8a2 cellSaveData: Add null funcStat check
it's ordered specially for some functions
2020-03-01 00:14:45 +03:00
Eladash c11074a128 RawSPU: fix race condition in RunCntl stop request 2020-02-29 21:54:54 +03:00
InvoxiPlayGames ef6854ca46 sys_usbd: Guitar Hero Live controller emulation (#7336)
* Initial GHLtar emulation

* Add GHLtar to CMakeLists and VS project, zero the buffer and remove unused header values

* Fix coding style issues and include headers

* Remove redundant if, improve code formatting

* Remove needless includes

Co-authored-by: Ivan <Nekotekina@users.noreply.github.com>
2020-02-29 21:40:44 +03:00
clienthax 7e590eaa2f Change key_vault to use version ranges. 2020-02-29 21:24:15 +03:00
MSuih 94478ad4a0 Add error for missing firmware 2020-02-29 21:19:01 +03:00
Nekotekina e28e51463b Compilation fix
Should fix #7642
2020-02-29 21:16:28 +03:00
Nekotekina cb252b1ce2 Partial revert of 5871c4e93f 2020-02-29 18:39:15 +03:00
Nekotekina d37e770497 Shut up all channels on exit at some point
Some object are getting destroyed.
Makes valgrind more quiet.
2020-02-29 18:29:32 +03:00
Eladash 5871c4e93f Segfault/exceptions reports: Get rid of unhandled exeption handler, log memory bases
* Getting rid of handled exception handler fixes 2 things:
- Visual Studio debugger won't force it's own handler on unhandled exception.
- SPU segfaults in recompiler can now be reported.

* Log vm memory bases.
2020-02-29 17:16:36 +03:00
Eladash 50f51be06a Improve sys_timer_get_information (#7638)
* Improve sys_timer_get_information

* sys_timer_disconnect_event_queue sets STATE_STOP regardless of port connection status.
* sys_timer_get_information sets 0 for period and next_expire if the timer is stopped.

* Fix two minor races in lv2_timer thread

* If the timer thread is about to fire an event of queue x, then another thread disconnects the queue, then restarts the timer and connects the event queue, then the timer thread sends an event - event data combination (source, data1, data2, next) may be inaccurate.

* If the timer thread is about to send an event (periodically), then another thread stops the timer and starts it again with sys_timer_start_periodic_absolute, timer.expire in info->timer_state in sys_timer_get_information may be inaccurate.
2020-02-29 17:15:25 +03:00
Nekotekina 8e5a03f171 Use named_thread_group in rsx_cache.h 2020-02-29 16:55:25 +03:00
Nekotekina f72971f19f Implement named_thread_group 2020-02-29 16:55:25 +03:00
kd-11 eb140c52a4 rsx: Reset ZCULL statistics at the end of a frame
- Workaround for games that leak zpass/zstats.
  The information is useless anyway without a clear op so it should be fine.
2020-02-29 14:23:52 +03:00
kd-11 198c84cabf rsx: Fix zcull clear command; do not clear ZPASS when ZSTATS is cleared. 2020-02-29 14:23:52 +03:00
Eladash 5a73943be6 Fix sys_timer_destroy
Also some cleanup.
2020-02-29 13:06:14 +03:00
Eladash 34a0c3f488 cellSaveData: Add error param 72, 73 checks for file write ops 2020-02-29 13:06:14 +03:00
Eladash 8762f2a588 Use more starts_with 2020-02-29 13:06:14 +03:00
Eladash d7dd4897f8 Allow 0x30000000 > addr >= 0x2000000 ppu loader exec allocations (workaround) 2020-02-29 13:06:14 +03:00
Nekotekina a84077f174 sys_ss: use BCryptGenRandom on Win32 2020-02-29 12:15:42 +03:00
kd-11 08f3460365 vk: Fixup for RCB/RDB in special cases
- Images must be in TRANSFER_DST_OPTIMAL or GENERAL layouts to call the image upload routines.
2020-02-29 12:13:11 +03:00
Nekotekina be0e4e9879 Move Progress Dialog Server to named_thread
Make it a global variable, but that can be actually destructed at exit.
2020-02-28 21:59:56 +03:00
Nekotekina 799c3f9708 Remove global thread counter (again)
Seems fine without it now.
2020-02-28 21:50:19 +03:00
Nekotekina 490f58ff3c Try to purge thread_state::detached
It's rarely necessary, but can cause unexpected problems.
2020-02-28 21:11:13 +03:00
kd-11 cb047fcc75 rsx: Disable zstat checks to avoid unnecessary stream splitting (#7624) 2020-02-28 20:27:31 +03:00
Nekotekina ac2581659a RSXOffload: fix dma_manager::sync() freeze on exit
Its logic was completely broken.
2020-02-28 19:55:43 +03:00
Nekotekina f335d034fc Fix RSX Offloader thread exit (MTRSX fix)
Hangs on exit if MTRSX is enabled.
2020-02-28 19:43:42 +03:00
Eladash 05bb6e1545 Improve sceNpDrmVerifyUpgradeLicense(2), sceNpDrmIsAvailable(2)
* sceNpDrmVerifyUpgradeLicense(2): copied string from content_id is 47 chars in length at max, is no null term was found it forces string termiation.
* sceNpDrmIsAvailable(2): Same with drm path just that it's 256 chars at max.
2020-02-28 19:10:39 +03:00
Nekotekina 65eeee0f4c Remove cancerous lf_value<>
Replace thread names (generic, PPU, SPU) with new shared pointers.
Devirtualize cpu_thread::get_name (used in single case).
2020-02-28 18:54:46 +03:00
Nekotekina bf4bdf73b7 Remove unused lf_hashmap
There are better ways to implement this.
2020-02-28 18:54:46 +03:00
Eladash 30f7c81cc5 cellSaveData: Implement/Fix param error 22 for funcFile, funcDone, funcFixed and funcList 2020-02-28 16:47:51 +01:00
Nekotekina 08ab9c4b04 fixed_typemap.hpp: reset creation index to avoid confusion 2020-02-28 00:16:04 +03:00
Nekotekina 4474757162 fixed_typemap.hpp: remove <algorithm> dep in header
Create fixed_typemap.cpp
2020-02-28 00:04:37 +03:00
Nekotekina bacd1698fc fixed_typemap.hpp: minor cleanup 2020-02-27 23:04:23 +03:00
Ivan e133c7a7dc Merge pull request #7506 from elad335/patch-1
PPU exec/ovlm ldr: restrict allocations
2020-02-27 22:55:30 +03:00
Eladash 0eabfdcadd cellSavedata: reset padding of g_savedata_context 2020-02-27 22:31:31 +03:00
Eladash d86241bbcd cellSaveData: reset fileSet and fileGet->reserved everytime 2020-02-27 22:31:31 +03:00
Eladash 42a0512c66 cellSaveData: Avoid passing vm pointer to native API 2020-02-27 22:31:31 +03:00
Eladash 556aba46b5 cellSaveData: do not fail on empty directory 2020-02-27 22:31:31 +03:00
Stephen McKinney 2b853cc8bc Don't improperly resolve symlinks when booting games. 2020-02-27 22:30:11 +03:00
JohnHolmesII 00b74fb951 Update BUILDING.md and CMakeLists.txt
Several parts of the guide had fallen out of sync, notably the Ubuntu section. I've tried to clean it up a bit.
In addition, I matched some of the version numbers to what is found in the CI system here: https://github.com/hcorion/rpcs3-docker/blob/master/xenial/Dockerfile
2020-02-27 21:31:43 +03:00
Nekotekina ecd68dfc70 overlays: add "thread bits" to wait on and avoid lockup
Add TLS variable to store its own bit.
2020-02-27 19:14:08 +03:00
Nekotekina d0b2eecc9a fixed_typemap.hpp: polish move constructor a bit
GitHub, plz.
2020-02-27 19:14:08 +03:00
Nekotekina d5c85f308a fixed_typemap.hpp: forgot destructor 2020-02-27 13:04:12 +03:00
Nekotekina f71cdb4eb8 g_fxo: implement logging for object creation/destruction.
Only logged at automated phase for initial/final processing.
2020-02-27 13:04:12 +03:00
Megamouse ee46ad1ca9 move overlays code to headers 2020-02-26 23:43:18 +01:00
gamerforEA 762c106e19 sys_prx_.cpp: Fix RAII locks usage (without local variables they destroyed immediately after construction) 2020-02-27 00:38:55 +03:00
gamerforEA 93552a5958 Apply some Clang-Tidy fixes 2020-02-27 00:38:55 +03:00
gamerforEA c0fbf3091e Remove unnamed namespaces from headers 2020-02-27 00:38:55 +03:00
gamerforEA 49294a3dd2 Add missing include guards 2020-02-27 00:38:55 +03:00
RipleyTom abfa303e07 Auto-updater minifix 2020-02-26 22:06:58 +03:00
Nekotekina 5094ab8283 Fix RSX Offloader thread name 2020-02-26 21:57:01 +03:00
Nekotekina a0d2bc9769 named_thread: allow default constructor only with thread_name
In C++20, lambdas may be default-constructible allowing nasty stuff.
2020-02-26 21:23:30 +03:00
Nekotekina e102dc2a94 Add message on exit if some thread are still waiting 2020-02-26 21:23:30 +03:00
Nekotekina 5e59f18720 fixed_typemap: implement need<> method
It may be used in constructors of other objects to assert a dependency.
It also helps to ensure reverse destruction order of that dependency.
2020-02-26 21:23:30 +03:00
Nekotekina b35a5982e8 Fix one bug with MsgDialog thread (freeze on exit)
Forgot to check thread state
2020-02-26 21:23:30 +03:00
Eladash 4d3cdca7f6 Stub sys_spu_thread_group_set_cooperative_victims and syscall_253 2020-02-26 18:17:13 +00:00
Eladash 0d4f8ca234 fs: Make fs::get_dir_size able to report an error 2020-02-26 18:17:13 +00:00
kd-11 569e1c2df6 rsx: Fix typo. Noted by github user @gamerforEA 2020-02-26 19:40:35 +03:00
kd-11 6e9392fb45 rsx: Restructure ZCULL query triggers
- Both ZCULL stats and ZPASS stats require hardware queries, but
  ZCULL stats should not contribute to ZPASS stats and vice versa!

- Disables hardware queries for ZCULL stats by themselves, we cannot
  generate them correctly anyway and no game so far has been found to
  actually use them. Should lessen the load on the backend for games
  that do not actually require it.
2020-02-26 19:40:35 +03:00
Nekotekina df1813b4e2 overlays: hotfix for waiting on thread_count 2020-02-25 23:43:05 +03:00
Nekotekina ff16e678a5 Add thread_count instead of former thread pool 2020-02-25 23:16:55 +03:00
Nekotekina 982856e70d overlays: remove unused threadpool 2020-02-25 22:56:50 +03:00
Nekotekina 144c20649f Try to fix msg dialog breakage 2020-02-25 22:50:44 +03:00
Megamouse e719bcf338 overlays: add layer modes to osk 2020-02-25 21:57:49 +03:00
Megamouse 3f4226b70e overlays: Fix find and replace regression 2020-02-25 21:57:49 +03:00
Megamouse 620cfd5063 overlays: move code to overlay_utils.cpp 2020-02-25 21:57:49 +03:00
Megamouse 69b2e746fa overlays: fix overlay_utils.h filter 2020-02-25 21:57:49 +03:00
Megamouse 2341749485 overlays: add overlay_osk.h 2020-02-25 21:57:49 +03:00
MSuih 33abcf74f2 Add information about boot process 2020-02-25 19:42:20 +03:00
Nekotekina 4e33ae319b fixed_typemap.hpp: minor fixup 2020-02-25 18:27:05 +03:00
Nekotekina b083edccd3 Threads: remove some unused code (remnants from thread spawn) 2020-02-25 15:57:57 +03:00
Nekotekina b59bb16fad Threads: removed outdated on_abort detection deemed unnecessary
May cause regressions.
2020-02-25 15:48:25 +03:00
Nekotekina 3f943945a7 Threads: Remove unused on_wait() detection to simplify code 2020-02-25 15:36:08 +03:00
Nekotekina 136d769895 Fix g_fxo->init internal logic for CTAD (use () not {})
Also improve comments to the functions.
2020-02-25 14:34:06 +03:00
Nekotekina 9c9c2eb2c9 Fix wrong g_fxo->init_crtp name, use just init<> 2020-02-25 14:07:50 +03:00
Nekotekina 318a364d09 Try to fix OSK 2020-02-25 14:03:13 +03:00
Nekotekina fa02a04baa Add g_fxo->init_crtp to simplify thread construction 2020-02-25 11:51:41 +03:00
Nekotekina 7eebe06931 Restore thread counter (world may be not ready yet)
Remove dumb 1300ms timeout.
2020-02-25 11:51:19 +03:00
kd-11 cd40bc8c61 overlays: Avoid race condition between rendering and layout operations for system widgets
- System widgets are callable from outside RSX code.
- Responding to draw requests while setup is in progress can cause malformed cached output
- Fixes glitched layouts for system message dialogs
2020-02-24 23:33:47 +03:00
kd-11 f6ebd88687 overlays: Ditch wstring for u32string
- Turns out wstring is not the same as u32string on windows.
2020-02-24 23:33:47 +03:00
MSuih 13ef0cc8c4 Fix native UI tooltip 2020-02-24 19:45:16 +01:00
MSuih df5059b142 Change logging level for invalid disc path 2020-02-24 19:45:16 +01:00
Megamouse f7666f44da Untangle GUI and input includes 2020-02-24 16:31:01 +01:00
Megamouse 7b49249f5f Input: Add config lerp factor for buttons and triggers
Adds new lerp factors to the keyboard pad handler In order to simulate triggers and analog buttons.
See "Analog Button Lerp Factor" and "Trigger Lerp Factor" in the yml in InputConfigs/Keyboard/.
Values Range from 0-100 as before, where 100 is instant press and 0 is never.

Currently I'm not planning any GUI element for this.
2020-02-24 08:56:57 +01:00
Megamouse 64ed2f1151 Input: use std::lerp instead of lerp template 2020-02-24 08:56:57 +01:00
Megamouse 17f335648c Input: misc updates to some functions in PadHandler 2020-02-24 08:56:57 +01:00
Nekotekina 1dc2eb1cc8 Avoid deprecated av_register_all with version check. 2020-02-23 20:58:02 +03:00
Emmanuel Gil Peyrot 1a702de9e4 cellVdec: replace deprecated ffmpeg function
avcodec_decode_video2() is deprecated, now replaced with
avcodec_send_packet() and avcodec_receive_frame().
2020-02-23 20:21:59 +03:00
Nekotekina f1241c572c Fix some deprecation warnings (plunder cellAdec btw) 2020-02-23 20:21:59 +03:00
Eladash 522daf5eac rsx: Fix NULL renderer 2020-02-23 19:57:55 +03:00
Nekotekina e772dde3cc Add more thread information (context switch, page faults).
Only implemented on Linux, possibly works on some BSD.
2020-02-23 16:21:26 +03:00
Nekotekina 8b4b859091 Remove "thread_ctrl::spawn" 2020-02-23 15:03:38 +03:00
Nekotekina 18db020b93 Fix warning in RSXOffload.cpp (rewrite thread) 2020-02-23 14:19:23 +03:00
Nekotekina 7069e7265f RSX: move g_dma_manager to g_fxo 2020-02-23 13:12:50 +03:00
Nekotekina fa0bf6a92c Fix "unknown pragma" on zlib clang workarounds 2020-02-23 10:42:35 +03:00
JohnHolmesII 758902382d AudioBackend.cpp: Implicit enum to float conversions are deprecated 2020-02-23 09:38:04 +03:00
JohnHolmesII cc71d2c4bf memory_string_searcher: Change to std strings
- Compiler warnings indicated that the call to toStdString() did not
   create an object that lived long enough be used. Simply use std
   string ahead of time.
2020-02-23 09:38:04 +03:00
JohnHolmesII 9b7d28b5dd cellSaveData.cpp: Use ref instead of copy 2020-02-23 09:38:04 +03:00
JohnHolmesII b9ee53d82a game_list_frame.cpp: Fix progress dialog constructor arguments 2020-02-23 09:38:04 +03:00
JohnHolmesII 479a64c4e8 Remove some inline compiler pragmas 2020-02-23 09:38:04 +03:00
JohnHolmesII 7b54d386f2 Set required Clang to 9
- 10 is not yet required and is not very available
2020-02-23 09:38:04 +03:00
JohnHolmesII 7eccbecb2f File.cpp: Make var ref instead of copy 2020-02-23 01:22:38 +01:00
Nekotekina 2bab3afae0 Fix deprecation warning in System.cpp 2020-02-22 19:41:03 +03:00
AniLeo fa3fde7a29 hle: Fix cellAvconfExt function registrations
Co-authored-by: Clienthax <clienthax@gmail.com>
2020-02-22 17:27:58 +03:00
AniLeo 3aa293a7a3 hle: cellAuthDialog
Basic RE of cellAuthDialog, stubs functions
2020-02-22 16:03:14 +03:00
RipleyTom 4befa36365 Use official libusb repo 2020-02-22 16:02:40 +03:00
Nekotekina 96be40bf30 Implement cellMsgDialog closing thread
Fixing deprecation warning.
2020-02-22 15:17:02 +03:00
Nekotekina 3001701059 Test: disable warning for "macro redefined" spam 2020-02-22 15:17:02 +03:00
kd-11 fa41297b27 overlays/trophy: Migrate to multibyte strings 2020-02-22 15:07:14 +03:00
kd-11 b8f51398b7 overlays/save_dialog: Migrate to multibyte strings 2020-02-22 15:07:14 +03:00
kd-11 cb2129c7e4 overlays/osk: Migrate to multibyte encoding 2020-02-22 15:07:14 +03:00
kd-11 703ec9f896 overlays: More unicode utilities 2020-02-22 15:07:14 +03:00
kd-11 19350d024b overlays: Font system improvements
- Add support for Hangul blocks (korean)
- Restructure font fallback system to allow the user to 'install' fonts if missing.
  Should allow fonts to work with no firmware on open systems like linux
2020-02-22 15:07:14 +03:00
kd-11 8e68427daf overlays: Add basic font substitution system and separate JPN from Latin-1 set
- Gets JP glyphs to render correctly, but the generalization may negatively affect other CJK glyph sets.
  PS3 doesn't seem to use other glyph sets much however.
2020-02-22 15:07:14 +03:00
kd-11 6220206cbc vk: Implement 2D array textures required for new font subsystem 2020-02-22 15:07:14 +03:00
kd-11 1df1ceb4ea gl: Support new glyph format with array textures 2020-02-22 15:07:14 +03:00
kd-11 6178a0ab25 overlays: Migrate to wide-char strings 2020-02-22 15:07:14 +03:00
Eladash 6bb083a77c Add more information for segfault reports (#7538) 2020-02-22 10:58:42 +00:00
Megamouse 171e6c6e54 Qt: remove duplicate paths in game list 2020-02-21 21:00:46 +01:00
Megamouse 313b967217 Qt: simplify blockingMap occurances 2020-02-21 21:00:46 +01:00
Megamouse b47a8b9995 Skip some logging in add_only Load 2020-02-21 21:00:46 +01:00
Megamouse c4a1c6f845 Do not reset PS3_GAME when booting disc patches 2020-02-21 21:00:46 +01:00
Eladash 24d3e2b2b8 cellGameDataCheckCreate(2): More improvements
* IsNewData is false only if PARAM.SFO exists.
* Don't create directory on error (setParam == nullptr && isNewData).
* Return CELL_GAMEDATA_ERROR_BROKEN if PARAM.SFO exists on target directory yet is not from GD category.
2020-02-21 21:15:55 +03:00
Nekotekina 145b80d262 Re-enable warning "macro redefined" (clang) 2020-02-21 19:36:05 +03:00
Nekotekina 5e75a0c497 Disable cotire on travis
Make some workarounds for clang because it poorly supports -Wold-style-cast
2020-02-21 17:03:54 +03:00
Nekotekina 972e0ab31d Remove -Wno-reorder and make it an error 2020-02-21 15:20:34 +03:00
Eladash 54f2c27ba0 cellGameDataCheckCreate(2): Set nullptr in setParam
* setParam is nullptr by default.
* if setParam is null and it's new data, return error code.
2020-02-21 14:49:45 +03:00
Eladash 0ba1f8f4ef Fix cellDiscGameGetBootDiscInfo on error
* Always set first dword to 0, other bytes are untouched,
2020-02-21 14:49:45 +03:00
Eladash 4d7e53d7a0 cellGameDataCheckCreate(2): Check dirName 2020-02-21 14:49:45 +03:00
Eladash 0c757222cb Minor improvements to sys_ss_random_number_generator
* Replace CELL_EABORT with exception.
* Improve error codes a bit.
* pkg_id == 1 should not return an error if root permission is present.
* Avoid passing vm pointers to native API, use temp buffer instead.
2020-02-21 14:49:45 +03:00
Megamouse 0ed87be47a Qt: add apply button to settings dialog 2020-02-21 10:08:22 +01:00
Silent e005581dda Gracefully fall back to a null renderer if XAudio2 fails to Init
This can happen as a non-error condition if user has no output
audio devices enabled.
2020-02-20 23:33:09 +03:00
Silent 312fc94daa Replace XAudio2 implementation with an unified Xaudio2Redist
This removes dual implementation for 2.7 and 2.8/2.9 interfaces
and also removes reliance on DirectX End User Runtimes for Windows 7.
2020-02-20 23:33:09 +03:00
Megamouse 0dd417e5f2 Add more game window title options 2020-02-20 20:07:25 +01:00
Eladash dd85e733d3 Fixup for #7304 2020-02-20 20:31:56 +03:00
Nekotekina 9e9ddf42c9 Change stdafx.h to trigger pch regeneration 2020-02-20 17:42:28 +03:00
Nekotekina 4d1f818162 umax: restore "natural" operation order 2020-02-20 17:13:41 +03:00
Nekotekina 3e0e1f668c Another attempt to fix OSX 2020-02-20 16:54:56 +03:00
scribam 4662ee0255 cmake: Update glslang build options 2020-02-20 16:23:25 +03:00
Nekotekina 2f255a528e Another attempt on umax 2020-02-20 15:18:31 +03:00
Nekotekina 987223da3f Minor fixup for /dev_flash creation 2020-02-20 14:38:09 +03:00
Nekotekina 78cc36cdd8 Allow empty /dev_flash cfg (fixup) 2020-02-20 14:07:26 +03:00
Nekotekina 580b5cda0e Revert "Maintenance: disable cotire on travis (Linux)"
This reverts commit 48c47eede4.
2020-02-20 13:45:44 +03:00
Nekotekina 81f974125c Travis: allow failure for osx 2020-02-20 13:13:48 +03:00
Nekotekina 48c47eede4 Maintenance: disable cotire on travis (Linux) 2020-02-20 13:02:57 +03:00
Nekotekina da036de3e4 Restore some /dev_flash logic 2020-02-20 12:43:53 +03:00
Nekotekina 92e3eaf3ff Fix signed-unsigned comparisons and mark warning as error (part 2). 2020-02-19 22:54:58 +03:00
Nekotekina 771eff273b First part of fixing sign-compare warning (inside be_t). 2020-02-19 22:54:58 +03:00
Nekotekina 0cf35e3b22 Implement umax global variable (max unsigned value)
Implements operators == and != comparisons.
2020-02-19 22:54:58 +03:00
Nekotekina 70bcb1cd52 Add "-Wno-macro-redefined" for clang spam 2020-02-19 21:17:23 +03:00
Nekotekina 762c8d5430 Remove -Wno-sign-compare 2020-02-19 21:17:23 +03:00
Zion Nimchuk aa9055f4c3 Switch the AppImage building over to gcc from clang
Turns out the current version of clang doesn't support the [[likely]] and [[unlikely]] attributes, so to ensure good performance, we'll be switching to gcc, at least for now.
2020-02-19 21:16:32 +03:00
Zion Nimchuk 9d1833c5a8 Bump FAudio depedency, set FAudio to build statically, enable FAudio in the build script 2020-02-19 21:16:32 +03:00
AniLeo 583220b95a .gitignore: maintenance, add missing files 2020-02-19 21:15:52 +03:00
AniLeo 85bde0f43f themes/YoRHa: Workaround broken Trophy Manager bg 2020-02-19 21:15:52 +03:00
AniLeo b96f064868 OpenAL: Update to 1.20.1 2020-02-19 21:15:12 +03:00
Eladash 6de91a1691 HLE cellGcmSys: Make IOTable accurate
Affects cellGcmAddressToOffset when using addresses above 0xC0000000
2020-02-19 18:11:30 +00:00
Eladash 1aa11440e0 HLE cellGcmSys: Make cellGcmUnmapEaIoAddress accurate 2020-02-19 18:11:30 +00:00
Eladash df8d0cde4a RSX/SPU: Accurate reservation access 2020-02-19 18:11:30 +00:00
Zion Nimchuk 57a9844279 Re-eanble gcc matrix in Travis CI, thanks to Neko for the hint 2020-02-19 10:08:58 +03:00
Eladash f02b4801b2 Fix max SPURS threads regression 2020-02-18 19:20:40 +00:00
Eladash 727d783959 RawSPU: protect NPC from writes/reads in running state 2020-02-18 18:09:10 +00:00
Eladash fad8b38b28 sys_spu: protect sys_spu_image members in kernel mode
Save relevant info in idm, set sys_spu_image segs and nsegs members to 0.
2020-02-18 18:09:10 +00:00
Nekotekina 8a176de6a1 Restore -Wenum-compare and fix some [=] warnings 2020-02-18 17:37:30 +03:00
Nekotekina 0ee2f761ae Fix warning in lf_fifo<>::push_begin() 2020-02-18 14:59:11 +03:00
Nekotekina c48ceafc15 sys_sync.h: fix warning (signed prio) 2020-02-18 14:53:23 +03:00
Nekotekina ee6494c14b Use strcpy_trync in cellAvConfExt.cpp (silence warnings) 2020-02-18 14:53:23 +03:00
Nekotekina a1456da24e Silence C++17 std::iterator deprecation warning 2020-02-18 14:53:23 +03:00
Nekotekina f08c778d2c Use more starts_with/ends_with.
Remove ends_with global func.
2020-02-18 14:53:23 +03:00
Megamouse 90f4023cb8 appv 2020-02-18 09:14:14 +00:00
Silent ea9abe7701 Qt: Update Game List Icon on changing Game List Mode 2020-02-18 00:25:21 +01:00
Nekotekina 5c42d29c98 Try to fix MSVC warning (std::iterator deprecation) 2020-02-17 22:01:11 +03:00
Nekotekina 950940febe cheat_manager: minor fix for T to be_t transition 2020-02-17 22:00:32 +03:00
Nekotekina 6e7fbc5c5c endian.hpp: fix zero array warning 2020-02-17 22:00:00 +03:00
Nekotekina 6a1a0bf48d Use std::endian for endianness test
Remove legacy IS_LE_MACHINE IS_BE_MACHINE macro.
2020-02-17 21:33:24 +03:00
Nekotekina 244e74ebe2 Try to ignore some annoying warning (seems CIB) 2020-02-17 20:56:03 +03:00
Silent aa14432846 Disable vertex cache checkbox with MTRSX 2020-02-17 20:34:07 +03:00
Ani afb594c233 gitmodules: Fix LLVM branch
gitmodules contained some old unused branch
2020-02-17 20:29:44 +03:00
Megamouse 7a7ac625cd move enum formatters from system to config files 2020-02-17 15:08:17 +03:00
Megamouse fe75311be2 move config structs to own files and clean up some headers 2020-02-17 15:08:17 +03:00
Eladash 812d03894b PPU exec/ovlm ldr: restrict allocations 2020-02-16 22:48:23 +02:00
kd-11 5e6b1003ec vk: Only declare explicit subpass dependencies for RADV 2020-02-16 18:00:06 +03:00
clienthax a08ed0d22e Fix #7445 2020-02-16 17:09:32 +03:00
Megamouse b5ed73ebe0 Qt: add reset button to game window title and center the label 2020-02-16 13:56:49 +01:00
Eladash c1bdaccd8c sceNpTrophyRegisterContext: Fix off by one progress callbacks count 2020-02-15 23:32:29 +01:00
Eladash 4421831c8b sceNpTrophyRegisterContext: Fix values passed to first callback 2020-02-15 23:32:29 +01:00
Eladash d03804b523 Fix sceNpTrophyGetTrophyInfo
* Only writeback data on success.
* Fix a typo on error code of invalid trophy ID.
2020-02-15 23:32:29 +01:00
Nekotekina 634c4355fe Fix startup failure on invalid games.yml
Add some exception checking/ignoring.
2020-02-15 22:34:10 +03:00
Megamouse ee54ba970a GUI: add custom title format to settings dialog 2020-02-15 20:33:02 +01:00
kd-11 23f1515448 vk: Explicitly declare null subpass dependencies
- We do not want any actual dependencies, but it turns out removing them
  entirely makes the driver add even worse dependencies.
2020-02-15 21:45:25 +03:00
Nekotekina 4018b833ad game_list: fix duplicate removal from games.yml
Also add some warnings.
2020-02-15 14:08:08 +03:00
Eladash ddf87864de atomic_t: Fix regression from #7489 2020-02-15 14:07:52 +03:00
Eladash 299af768e8 HLE cellGcmSys: Make cellGcmAddressToOffset accurate 2020-02-15 14:07:52 +03:00
Megamouse e645627b78 Qt: Allow for duplications in game list
This fixes app versions when multiple game data directories were found.
We only removed duplications because we didn't wanna see multiple disc games from different locations
2020-02-15 11:36:01 +01:00
Megamouse 1cb1d14d0c Qt: only add version update hint to bootable applications 2020-02-15 11:36:01 +01:00
Megamouse 1c2df15755 Qt: simplify category localization in gamelist refresh 2020-02-15 11:36:01 +01:00
Megamouse 687bb1697b Qt: fix gamelist version check regression after localization changes 2020-02-15 11:36:01 +01:00
Eladash 04e0bf2eff Whitespace fix after #7087
Was this close to enter programmers' hell.
2020-02-15 11:37:13 +03:00
Eladash eb8710d3c1 atomic.hpp: C-style casts cleanup 2020-02-15 11:37:13 +03:00
Eladash e98fcfdf77 rsx debugger: Fix a crash on opening before rsx was intialized 2020-02-15 10:41:42 +03:00
Eladash cdda19c79f Fix recursive locking in sceNpTrophyUnlockTrophy 2020-02-15 10:41:15 +03:00
Eladash fa9330d0e0 Log returned reqspace in sceNpTrophyGetRequiredDiskSpace 2020-02-15 10:41:15 +03:00
Eladash 1d4595a349 Idm: Minor assert fix 2020-02-15 10:41:15 +03:00
Eladash 9344b21484 rsx: Unify FIFO recovery methods
TODO: Maybe consider fifo stack content when recovering.
2020-02-14 17:11:26 +03:00
Eladash 07f300a14e rsx: ZCULL typo fix 2020-02-14 17:11:26 +03:00
Eladash ddeb39d8de HLE cellGcmSys: Fix unmapping 2020-02-14 17:11:26 +03:00
Nekotekina 0d7aa5e310 GUI: implement custom title format
New option "Window Title Format" in Misc.
Backward compatible with FPS disabler.
Make rpcs3:::get_branch() return string_view.
2020-02-13 21:24:52 +03:00
Eladash 606693a9f7 Avoid closing the emulator after access violation 2020-02-13 14:14:28 +03:00
Eladash 78c49e7331 cellSearch: another memory access fix 2020-02-12 20:02:18 +03:00
Eladash 9760053c8c cellSearch: Fix id memory access (#7476) 2020-02-12 18:17:45 +03:00
Nekotekina e8988faed5 geometry.h: remove MSVC workaround 2020-02-12 12:50:42 +03:00
Nekotekina 7137142351 geometry.h: more cleanup
Remove wrong constructors.
2020-02-12 12:50:42 +03:00
Zion Nimchuk bacd234258 Add a check for GLIBCXX_3.4.26 support in the AppImage checker binary 2020-02-12 12:49:46 +03:00
Silent 3006b003c4 Implement links as a cellSearch specific concept
Linking in VFS is done only from cellSearchPrepareFile and works
by mounting virtual files to host FS files
2020-02-12 12:49:02 +03:00
Silent e30637351e Move SearchState to a fxo object so it resets with emulation 2020-02-12 12:49:02 +03:00
Silent d2b83c69bb cellSearch updates from Brolijah
Co-authored-by: Brolijah <brolijahrh@gmail.com>
2020-02-12 12:49:02 +03:00
Nekotekina bcbe324534 geometry.h: make conversion operators explicit
It requires static_cast<> to call them.
2020-02-11 13:21:45 +03:00
Eladash dcb30df7c8 rsx capture: Fix capture recovery after a crash 2020-02-10 21:39:39 +00:00
Eladash bdab26ec09 rsx: rewrite io mappings
Along with some with fixes to cellGcmSys HLE.
2020-02-10 21:39:39 +00:00
kd-11 f47333997f rsx: Validate memory blocks before checking for overlap 2020-02-10 21:48:35 +03:00
kd-11 3787108ee7 rsx: Typo fix in audit condition 2020-02-10 21:48:35 +03:00
Megamouse 30d176ac5e Qt/linux: set DISPLAY variable if undefined 2020-02-10 21:48:13 +03:00
RipleyTom 98f91457bf Small sys_usbd changes 2020-02-10 21:47:48 +03:00
Megamouse 6847e52364 Fix visual studio filters after someone tinkered with the files 2020-02-10 21:47:13 +03:00
Zion Nimchuk 896d16ec7b Bump minimum Qt5 version to 5.14.0 in CMake 2020-02-10 21:46:35 +03:00
Megamouse 6862790cf7 Qt: icon overhaul 2020-02-10 17:38:19 +01:00
Eladash 639245c071 Make handle_access_violation noexcept 2020-02-10 17:27:34 +03:00
Nekotekina 034267adb2 Compilation fix 2020-02-10 16:57:56 +03:00
Nekotekina 6e47a6fb76 Update LLVM for C++2a workaround 2020-02-10 14:47:12 +03:00
Nekotekina 9569ae24e0 Bump minimal compiler versions: gcc-9 and clang-10. 2020-02-10 14:47:12 +03:00
Nekotekina 491526b421 Add option USE_COTIRE=ON (by default)
Precompiled headers cause rebuild problems with ninja, for example.
2020-02-10 14:47:12 +03:00
Nekotekina 5a41d75eb8 Silence unused parameter warning 2020-02-10 14:47:12 +03:00
Nekotekina 4bc431ec31 Silence deprecation warning (implicit capture of this on [=]) 2020-02-10 14:47:12 +03:00
Nekotekina 1bc9fd2863 Set cmake min version and CXX_STANDARD to 20 2020-02-10 14:08:51 +03:00
Megamouse 5d82b0f4c4 Qt: set min version to 5.14 2020-02-10 14:05:36 +03:00
Zion Nimchuk d3abff5486 Disable FAudio due to upstream packaging issues 2020-02-10 13:31:29 +03:00
Zion Nimchuk 77aa1fbeea Bump glslang to fix issues with LLVM 10 2020-02-10 13:31:29 +03:00
Zion Nimchuk af9bc631cc Bump Docker version, update clang10+gcc9, CMake 3.16, adds SDL2, LLD
The vulkan library and SDL2 libraries are now self-built, due to distro packages being too low version
2020-02-10 13:31:29 +03:00
RipleyTom 762718002e make decrypt default to All Binaries 2020-02-10 09:45:06 +01:00
Maxim Kulyk 16bbd93885 [props] Move stdcpplatest and FH4 to common_default.props
This way stdcpplatest  and FH4 disabling propagates to all projects except llvm and glslang.
2020-02-09 17:32:02 +03:00
Eladash 80eff58950 cellAudio: Implement cellAudioSet/RemoveNotifyEventQueueEx 2020-02-09 12:31:55 +00:00
Nekotekina 7ea4eb0095 Atomic fix
Fix possible pointer arithmetic ops.
Fix fat atomics (currently unused).
2020-02-09 14:09:29 +03:00
kd-11 efc8c3f4a9 vk: Fixup for VK_ERROR_SUBOPTIMAL_KHR
- break from a switch does not break out of the external scope!
2020-02-09 13:45:30 +03:00
kd-11 792c481f6d rsx/overlays: Fix clipped rendering of UI elements
- Take viewport offset into account when applying window transforms.
  This is necessary because gl_FragCoord is based on the framebuffer and not the viewport.
2020-02-09 12:55:56 +03:00
13xforever 7973b01b1c update issue templates 2020-02-09 08:29:33 +00:00
Eladash 11675d7645 Compilation fix for VSH pr 2020-02-09 06:48:16 +00:00
Eladash 1915fe75a4 VSH: Stubs 2020-02-08 23:07:03 +03:00
Eladash 9d1bb60ad7 cellGcm HLE: fix cellGcmMapMainMemory
Fix arguments order, softcode RsxReports::report offset.
2020-02-08 22:18:56 +03:00
Eladash b7043ce000 Make rsx::get_address report caller location 2020-02-08 22:18:56 +03:00
kd-11 c64935f9dd rsx: Clean up graphics state notifications and add notification for change in point size
- Adds a backend notification when point size changes.
- Refactors all those separate notifiers into one reusable template.
2020-02-08 18:13:05 +03:00
Eladash 629eddfb9f sceNpTrophy: Implement SCE_NP_TROPHY_ERROR_CONTEXT_NOT_REGISTERED 2020-02-08 11:11:59 +00:00
Eladash 1f94c8f272 sceNpTrophyGetGameProgress Fix 2020-02-08 11:11:59 +00:00
Megamouse 0c8611bd49 Qt: fix game category localization 2020-02-08 11:04:13 +01:00
Megamouse 5dcb91b671 Restart games with the same config instead of global 2020-02-08 11:04:13 +01:00
Megamouse 7abda27b46 Fix Boot inconsistencies for Reloads 2020-02-08 11:04:13 +01:00
Megamouse 901fc87bca Only start the playtime clock if it makes sense 2020-02-08 07:13:29 +01:00
kd-11 54da9ac7e5 overlays: Fixup
- Avoid calling join on self thread.
- Avoid use-after-free.
2020-02-07 19:28:41 +03:00
kd-11 e45360de2b overlays: Fix use after free
- Overlay can be closed when secondary thread is asleep!
  Wait for it to wake before proceeding with deletion.
2020-02-07 16:15:02 +03:00
kd-11 d59c449ff6 vk: Remove an overzealous assert 2020-02-07 16:15:02 +03:00
MSuih 17df6c8878 Enable C++20 for MSVC in CMakeLists.txt 2020-02-06 22:15:58 +00:00
eladash f901846acb RawSPU: execute MFC proxy cmd after reading CMDStatus
Implement MFC proxy argument sequence checking.
2020-02-06 20:43:38 +00:00
Megamouse edcd2fc14a Qt: fix game grid regression 2020-02-06 19:58:19 +01:00
Megamouse 382bdcdcb7 Qt: set Tooltips.h to UTF-8 in order to fix translation with special characters 2020-02-06 17:41:50 +01:00
Megamouse 1bbc60c3e7 Qt: do not use localized filenames for default current config and default stylesheet 2020-02-06 17:41:50 +01:00
Megamouse c13d345604 Qt: add language menu 2020-02-06 17:41:50 +01:00
Megamouse efe907ffae Qt: use config to load translation file on startup 2020-02-06 17:41:50 +01:00
kd-11 0bba04ef8d vk: Fix a bug in RCB/RDB when MSAA is set to disabled.
- Initially MSAA option was hardcoded to be always enabled, this bug is a remnant of that time.
2020-02-06 17:54:05 +03:00
kd-11 43dae6c14d gl: Implement RCB/RDB 2020-02-06 17:54:05 +03:00
kd-11 2b5c24b304 gl: Fix memory barrier implementation and stub for RCB/RDB
- It's a miracle it even compiled
2020-02-06 17:54:05 +03:00
kd-11 50b1e26b17 gl: Fix a long-standing regression with typeless transfer caused by a typo.
- The parameters for the final upload should be 'unpack_info' not 'pack_info'!
2020-02-06 12:44:46 +03:00
kd-11 18e0559438 gl: Fix per-level sub-image sizes to comply with OpenGL guidelines for compressed textures 2020-02-06 12:44:46 +03:00
Eladash 37513b1898 SPU reservations: Do not access violate under vm::writer_lock
TODO: Throw exception when encountering page faults notification enabled memory
2020-02-06 00:27:17 +00:00
Silent fbbad7c851 Include trailing separators in section split
This fixes the case on Windows where one of the paths ends up consisting
only of a drive letter and no trailing slash - in which case Windows
treats it as "current directory on drive X" and not "root of drive X"
and GetFileAttributes throws an invalid param error
2020-02-05 23:21:32 +00:00
Eladash f8b3c48af7 sys_spu: Implement proper SPU group flags (#7320)
* sys_spu: Implement proper SPU group flags
2020-02-05 20:46:05 +00:00
kd-11 3cc42c1bf8 gl: Fix broken image transfer operations 2020-02-05 18:18:09 +03:00
kd-11 b6422c9a33 rsx: Fixup
- Destination Y coordinate must be 'rebased' onto the current slice by subtracting its offset.
  Only the local path was affected this time
2020-02-05 18:18:09 +03:00
Eladash 049e392a97 Make preferred spu threads dynamically adjustable 2020-02-05 10:06:07 +00:00
Eladash 9a64d08c9f Make sleep timers accuracy dynamically adjustable 2020-02-05 10:06:07 +00:00
Nekotekina c0f80cfe7a Use attributes for LIKELY/UNLIKELY
Remove LIKELY/UNLIKELY macro.
2020-02-05 10:42:34 +03:00
Eladash 49e11b7cfd cellVdecQueryAttrEx: Add some error checks for MPEG2 2020-02-05 05:01:07 +00:00
Eladash 6a32ceaab5 cellVdecQueryAttrEx: Add workaround for codec specific info 2020-02-05 05:01:07 +00:00
Eladash acc7320cae Fix cellVdecGetPicItem
Fix potential overflow, race condition and correctness fixes for picInfo_addr
2020-02-05 05:01:07 +00:00
Nekotekina 1a78e0e80c Make RPCS3 compile in C++2a mode 2020-02-04 23:43:55 +03:00
Eladash e9e8f0c5b7 cellGame: report not found sfo params 2020-02-04 18:29:52 +03:00
Eladash cb52ee0a4d cellGame: report fs::remove_all failure 2020-02-04 18:29:52 +03:00
Eladash 4488312e81 Avoid out of memory with cellGameGetParamString 2020-02-04 18:29:52 +03:00
kd-11 9d9b5c4d66 rsx: Rewrite coverage test to take sum of areas into account.
- TODO: A proper sweep algorithm to calculate sum of overlapping rectangles
2020-02-04 16:20:52 +03:00
kd-11 b9ec012922 rsx: Allow for proper data checks when WCB/WDB is enabled 2020-02-04 16:20:52 +03:00
Megamouse d47a8b49a4 Qt: use current locale for last played in gamelist
This also sets the basic groundwork for Qt translations
2020-02-04 09:18:05 +01:00
Megamouse 1759d6d90a Qt: fix gamelist sorting for playtimes 2020-02-03 21:22:11 +01:00
Nekotekina c4a01875d0 Space fix commit 2020-02-03 11:16:26 +03:00
Nekotekina f9a8efe406 SPU LLVM: gisable NewGVN pass
It goes into an endless loop with memory leak for some reason.
2020-02-03 11:16:03 +03:00
Silent 7f4e546f19 Protect m_storage.find(key) to fix a race 2020-02-02 22:28:14 +03:00
Nekotekina 0a2874405d logs: allow disabling RPCS3.log.gz
Disabled by creating a directory with the same name.
2020-02-02 14:32:29 +03:00
Nekotekina 87a5dd66ab Move logs::channel registration out of the constructor
Allow constinit initialization of logs::channel.
2020-02-02 14:12:54 +03:00
Eladash e57c01907e cellVdec: Improve cellVdecQuery and cellVdecOpen 2020-02-02 09:01:32 +03:00
Nekotekina 32df809626 Update llvm (fixup) 2020-02-01 19:05:36 +03:00
kd-11 7d2ed9200d rsx: Remove sections that are wholly inherited by new blocks
- Allows sections reclaimed by the surface store due to overlap/inheritance to be identified and removed.
- Additionally, potentially lowers the number of flushes required per block with multiple overlaps improving efficiency and theoretically performance.
2020-02-01 15:14:29 +03:00
Nekotekina f6e90b4c72 Fix FAudio logging 2020-02-01 13:34:36 +03:00
InvoxiPlayGames c1180d76dd sys_usbd: Fix bug preventing multiple USB devices 2020-02-01 12:34:42 +03:00
Nekotekina 6dfd97f0b6 Modernize SPU logging (spu_log variable) and remove log legacy
Remove legacy macro (LOG_ERROR, etc)
2020-02-01 11:52:52 +03:00
Nekotekina 327bb2d8f0 Modernize PPU logging (ppu_log variable) 2020-02-01 11:52:24 +03:00
Nekotekina 21f7b0ff0f Remove HLE log channel 2020-02-01 11:52:24 +03:00
Nekotekina 15391f45d0 Modernize RSX logging (rsx_log variable) 2020-02-01 11:52:22 +03:00
Nekotekina 3c0bd821c8 Give log channels fancier names
Improve LOG_CHANNEL macro to accept custom name.
2020-02-01 10:43:43 +03:00
Nekotekina ec80932c21 logs: use relaxed atomics
May help with optimizations.
2020-02-01 10:30:03 +03:00
Nekotekina 3eca2d5d6c Remove legacy LOADER log channel 2020-02-01 07:49:38 +03:00
Nekotekina d9a0619ddd Remove legacy GENERAL log channel
Add some more log channels instead.
2020-02-01 07:49:38 +03:00
Nekotekina efafda2650 Add config to silence all logs 2020-02-01 07:49:38 +03:00
Eladash 943368912b Hotfix after #7351 2020-02-01 05:50:58 +03:00
Nekotekina 1d0f359406 logs: add more log channels instead of GENERAL 2020-01-31 16:44:48 +03:00
Nekotekina d5f019c3d3 Implement logs::silence
Disables all log channels.
Also disables unsupported "default" log level for log channels.
2020-01-31 16:44:48 +03:00
Nekotekina 67075dfc6c logs: cleanup for audio backends
In process of removing GENERAL log channel.
2020-01-31 16:44:48 +03:00
Nekotekina a867522b16 logs: implement logs::get_channels() 2020-01-31 16:44:48 +03:00
Nekotekina 26cccead6e logs: remove legacy MEMORY channel
Add channels vm_log, sig_log.
2020-01-31 16:44:48 +03:00
Asinine e6f7467f67 Update missing rap file error 2020-01-31 14:13:55 +01:00
kd-11 36d5db7f30 rsx: Plug texture data leak in the 'exact match' path.
- Followup to previous texture data leak fix for the replaced section path.
2020-01-31 14:56:53 +03:00
Nekotekina e7b24461ec Implement logs::get_level 2020-01-31 12:09:52 +03:00
Nekotekina 007a7a5859 Fixup for LOG system.
Register all channels at program initialization and allow duplicates.
2020-01-31 12:09:52 +03:00
Nekotekina 59a0f810b9 Implement fat atomics
Atomics with embedded mutex bit.
2020-01-31 12:09:52 +03:00
Silent 9f678cc47a Fix code relying on initialization order
Allows Debug - LLVM to boot
2020-01-31 11:23:55 +03:00
Silent aeebcfe141 Fix Debug - LLVM in VS project files 2020-01-31 11:23:55 +03:00
Eladash 48a847d1b6 Qt: Bugfixes regarding usage of ShowConfirmationBox 2020-01-30 21:49:08 +01:00
Eladash 232c6c3aaf Qt: Display "Reboot With Custom/Global config" on running game 2020-01-30 21:49:08 +01:00
kd-11 c9e35926f5 rsx: Preserve pixel data when splitting sections
- Ironically rhis data leak is caused by trying to fix another type of data leak
2020-01-30 21:07:36 +03:00
Megamouse 8ef69429d8 Add early out to pkg_install 2020-01-30 18:21:18 +01:00
Megamouse 336cd6e33a Qt: Prevent Qt from blocking the explorer during installations 2020-01-30 18:21:18 +01:00
Silent 360e484b08 Fix ellipsis
… is an UTF-8 character and those don't really belong in messages like this anyway
2020-01-30 16:06:00 +03:00
Eladash 92466165f6 Increase Maximum Vblank Rate and Clocks Scale
Allow x30 times the speed of vblank rate + clocks scale of original PS3.
In theory a 60 fps limit game which scales frame limit perfectly with vblank rate can be played at up to 1800 fps with this change.

And:
* Fixed lv2 sleep with Clocks Scaling
* Make these settings dynamicaly adjustable.
* Avoid code duplication
2020-01-29 21:42:41 +01:00
kd-11 1206a5d4b7 rsx: Tweak blit engine heurestics a bit
- Reject writes to RTT if the source data is of unknown origin.
  non-RTT data and only 1 line in length is suspicious and often GPU data like programs or other rendering inputs.
2020-01-29 12:54:06 +03:00
TotalCaesar659 c1d7b46235 Qt: change labels in package installer (#7325) 2020-01-29 00:39:05 +01:00
RipleyTom 795bc5d52b Add mutex guard for s_unfire 2020-01-28 19:16:16 +03:00
Malcolm Jestadt ad8988afd3 Embedded SPU elf patching
- PS3 games include both PPU and SPU code in their PPU executables, so to make patching games that make use of the same SPU libraries easier, we add a system to find and patch them.
- Patches for this system still use SPU LS (Local Storage) addresses despite the fact that we aren't loading anything into SPU LS at this time. The patches are checked against each segment and patched in place.
2020-01-28 02:13:37 +03:00
Ivan 7f07b79c04 Partial revert of #7180
PC is PS
2020-01-27 07:05:18 +03:00
RipleyTom 610a6a1404 Increases number of buffers when buffering 2020-01-27 02:13:30 +00:00
Eladash a7aef22754 ppu: Log SELF header information and CIA of caller HLE functions 2020-01-27 01:21:40 +00:00
Eladash 4e0070f16d Log sys_spu thread group and thread names
Also safely read thread name after relevant error checks passed.
2020-01-26 20:32:10 +00:00
Eladash 7ae679adbe Fix logging of ppu name in sys_ppu_thread_create/rename 2020-01-26 20:32:10 +00:00
Eladash d481c3c7fd cellGameGet/SetParamString: Implement CELL_GAME_ERROR_NOTSUPPORTED 2020-01-26 20:32:10 +00:00
Eladash a9162a3f57 SPU LLVM: Improve approximate FCMGT 2020-01-26 18:37:07 +00:00
Megamouse b341113ad8 Qt: Change some labels 2020-01-26 18:46:04 +01:00
Nick Renieris 1e69de1205 overlays/perf: Graph label tune-up
Place graph text on top, split in 2 lines, center it horizontally.
Also if it's wider than the graph, match up graph's width to it.
2020-01-26 17:55:11 +01:00
kd-11 79216917b3 rsx: Workaround for broken rtt resampling
- Avoids WCB requirement for now to keep res scaling working correctly.
- TODO: Fix this properly
2020-01-26 13:58:48 +03:00
kd-11 698702cd4a vk: Fix DMA data leak
- There still does not exist a ranged flush implementation which is required.
- TODO: Implement this properly
2020-01-26 13:58:48 +03:00
kd-11 1166ae19bb vk: Use appropriate layouts depending on use case when creating new textures to avoid needless barriers 2020-01-26 13:58:48 +03:00
kd-11 44f2cacf7b rsx: Blit engine tuning
- Attempt to identify blit operations that will be flushed immediately
after and just do them on CPU instead if the transformation is trivial.
- If only a single blit section is contributing to an atlas merge op, the
threshold should be 100%. The only acceptable result here is a
truncation.
2020-01-26 13:58:48 +03:00
kd-11 7a275eaa3a rsx: Fix incomplete blit operations getting used as texture inputs
- Raise passing 'score' from 50% to 90% to filter out very incomplete
merge operations.
- Catch unfit sections passing the match test; possible for blit_dst
data but will likely be always harmless. Disabled in release builds by default.
2020-01-26 13:58:48 +03:00
Silent 331c1a394a Qt: Present game removal failure to the user
All the required information was already there,
but UI always reported success
2020-01-25 19:28:52 +01:00
Eladash e4ba096190 VSH: sys_mmapper
* Implement syscalls sys_mmapper_allocate_shared_memory_ext, sys_mmapper_allocate_shared_memory_from_container_ext.
* Implement multi-process shared memory allocations.
2020-01-24 20:08:30 +00:00
Eladash 46df58b662 sys_usbd: Add error_code 2020-01-24 19:25:52 +00:00
Eladash 95ed2ef62e cellGcm HLE: Add error_code 2020-01-24 19:25:52 +00:00
Megamouse 3f076d63e3 HLE: add error checks to cellAudioInGetDeviceInfo 2020-01-23 10:50:55 +01:00
Megamouse 3e8a5c6395 HLE: add some more constants 2020-01-23 10:50:55 +01:00
Megamouse 18f167ddd0 HLE: Fix error checks in cellAudioInRegisterDevice 2020-01-23 10:50:55 +01:00
Maksim Derbasov 1abdee242a small improvement (#7288)
* small improvement

* comments addressed

Co-authored-by: kd-11 <15904127+kd-11@users.noreply.github.com>
2020-01-22 12:28:48 +00:00
kd-11 adcc3e9c4b rsx: Optionally sync on texture read semaphore
- Some games use texture semaphore for zcull sync which is rather bizzare.
  However, it works on realhw as the depth test happens before fragment shader completion
- Due to the high performance penalty incurred by this act, this
behavior is only enabled by the "strict rendering mode" option.
2020-01-21 22:21:51 +03:00
Eladash 949cfa7fdb Fix cellVdecSetFrameRate error check 2020-01-21 16:45:41 +03:00
Eladash fe381b8581 SPU: Add SPU LS to debugger 2020-01-21 16:45:41 +03:00
Eladash 160ddcf86b SPU: Minor FREST bugfix 2020-01-21 16:45:41 +03:00
Eladash f05a3da964 Fix lv2_file::op_write regression 2020-01-21 16:45:41 +03:00
Nekotekina ddda09607d SPU: fixup for STOP 0w0 2020-01-21 16:32:00 +03:00
Eladash 9993df9b8b RawSPU: fix race between spu start and stop
This race could lead to spu status bits indicate RUNNING status, but cpu state being stopped.
Fix it by making sure cpu state is set before spu status.
2020-01-21 14:08:39 +03:00
Nekotekina 98a8eeaac2 SPU: properly support STOP 0x0 instruction 2020-01-20 23:40:10 +03:00
Nekotekina 0f87c6c7c3 Make system config thread-safe (almost) 2020-01-20 21:51:28 +03:00
Nekotekina 0147bc2c72 Fixup shared_cptr, atomic_cptr 2020-01-20 21:51:28 +03:00
Nekotekina 1e7a02badb Implement shared_cptr and atomic_cptr
Limited shared_ptr with atomic support.
Atomic version is only partially implemented.
2020-01-20 16:53:42 +03:00
Nekotekina 3617f12a1e sys_fs: avoid possible out of memory on file reads/writes
Use fixed-sized intermediate buffer.
2020-01-20 16:00:20 +03:00
Nekotekina 63f67c88cc sys_fs: better stub sys_fs_fcntl(0xc0000006)
This syscall does something to classify filesystems by mountpoint.
2020-01-20 16:00:20 +03:00
Nekotekina 1b1b804d7e sys_fs: add /dev_flash mountpoint 2020-01-20 16:00:20 +03:00
Nekotekina 55cb96ab3b sys_fs: fix CELL_EIO condition in cellFsReadWithOffset 2020-01-20 16:00:20 +03:00
Megamouse 5ef3465f65 cellVdec: (experimental) allow AV_PIX_FMT_YUVJ420P 2020-01-20 00:33:25 +01:00
Megamouse 9a27cc9442 cellVdec: improve error checks 2020-01-20 00:33:25 +01:00
Megamouse 858ce014fd VS: fix filter facepalm 2020-01-19 16:38:17 +01:00
Megamouse 4dbad6cce6 fix some random warnings 2020-01-19 16:38:17 +01:00
Megamouse 485b22d664 Qt: fix deprecation warnings 2020-01-19 16:38:17 +01:00
Megamouse 30d5a849e3 Qt: enlarge some tooltip hover areas in settings 2020-01-19 12:40:43 +01:00
MSuih 9ef96e8274 Add pagesteps for some controls
With the snap changes the default pagestep of 1 is ignored because of rounding.
2020-01-19 09:09:36 +01:00
MSuih cbaa8f3329 Add snapping and limit range for wakeup delay 2020-01-19 09:09:36 +01:00
MSuih 807d6cfea4 Add slider snapping 2020-01-19 09:09:36 +01:00
kd-11 22ca2827de rsx: Improve window border detection and clearing
- Improves logic to detect if the frame requires letterboxing and
properly clears the background appropriately.
2020-01-18 19:52:52 +03:00
kd-11 5e0ca4c0c4 rsx: Fixup for missing visuals when framebuffer is larger than requested
display dimensions.
2020-01-18 19:52:52 +03:00
kd-11 48407752a6 formatting: Unify indentation type in the newly added files to tabs 2020-01-18 19:52:52 +03:00
kd-11 bad4d1ff05 rsx: Improve present image scanning
- Adds support for partial (letterboxed) source images by taking insets
into account.
- Bugfix for potential access violation when capturing screenshot on
vulkan
2020-01-18 19:52:52 +03:00
kd-11 7453e46a7c rsx: Refactor out complex present code into separate files
- Also restructures present code to have image lookup in a separate
re-usable function.
2020-01-18 19:52:52 +03:00
Eladash b07b5c9005 Fix sys_spu_thread_initialize for attr->name_len is 0 and attr->name is not null
If name_len is 0 name is empty, in any other case name is not empty (attr->name == nullptr isn't allowed in this case).
Check name_len and option for invalid values as fw.
2020-01-18 18:46:13 +03:00
Eladash 9d15083c61 Fix sys_ppu_thread_create/rename thread name range 2020-01-18 18:46:13 +03:00
Eladash 14b99d9e8b Write nread/nwrite in cellFsWrite/Read regardless of error checks 2020-01-18 15:56:05 +03:00
kd-11 b36b9e4822 vk: Fixup for total number of combined samplers using the dynamic binding structure 2020-01-18 11:17:19 +03:00
kd-11 0a2b6a290d vk: Fixup
- Scaling is not needed for a direct typeless transfer!
2020-01-17 14:31:14 +03:00
Emmanuel Gil Peyrot ca5bc512ae Optimise the SVG logo with svgcleaner
It still contained Inkscape leftovers, which are of no use for anything.
There are no functional changes.

See https://github.com/razrfalcon/svgcleaner
2020-01-17 08:31:00 +01:00
Megamouse 449cbb7281 Qt: use persistent_settings for playtimes 2020-01-17 07:43:10 +01:00
Nekotekina e2512e78b6 sys_fs: always close locked file in sys_fs_close
Syscall returns EBUSY but succeeds nevertheless.
2020-01-17 00:24:07 +03:00
Nekotekina a005090d3d sys_fs: use constant in sys_fs_disk_free 2020-01-17 00:24:07 +03:00
Nekotekina 7fcc49004d lf_fifo: fix UB and fix size()
Simplify internal counter to atomic<u64>.
Make size() return correct difference between push and pop pointers.
2020-01-17 00:24:07 +03:00
MSuih 833fbe015e Use floating point pixel ratio 2020-01-16 23:54:47 +03:00
Eladash c9b0f0e734 SPU: Fix FREST 2020-01-16 23:42:50 +03:00
kd-11 9b34f00241 vk: Optimize image transfers
- Adds the same optimization/simplification steps to complex image
transfer routines. Whenever possible, multi-step transfers are collapsed
into a single operation.
2020-01-16 22:29:26 +03:00
kd-11 82af17beb1 gl: Optimize image operations
- Avoid double transfers where a transfer to a temp image is done
without scaling and then a secondary transfer follows. Combines the two
steps into one whenever possible which can significantly alleviate
bandwidth problems at higher resolutions. Significant speedup, upto 90%
in some cases (PDF, PDF2)
2020-01-16 22:29:26 +03:00
kd-11 47b196e9d0 rsx: Fix uninitialized variable 2020-01-16 17:57:31 +03:00
kd-11 db014d8a58 rsx: Fix section length calculations when generating new blit targets. 2020-01-16 17:57:31 +03:00
kd-11 621fab2ad9 vk: Fix D32S8 interpolation by using integer interpolation instead of floating point
- Interpolating floats is not the same as interpolating their bits!
  Use integer format to interpolate linearly for D32F formats instead of using R32F as intermediary
2020-01-16 11:12:08 +03:00
kd-11 086ecf4ba6 vk: Add some missing image memory barriers causing artifacting on AMD cards
- There needs to be a memory barrier after each step.
- TODO: Optimize scale_typeless_safe function
2020-01-16 11:12:08 +03:00
kd-11 309251ce7a rsx: Touch locked dst memory after blit transfer operations in case it is locked by WCB/WDB 2020-01-16 11:12:08 +03:00
Eladash 9084209cfc Update cellVdecSetFrameRate error checking 2020-01-15 23:29:32 +01:00
kd-11 74ad525566 vk: Fixup for cs_scatter job
- Access to the stencil output has to be atomic as each 'word' is shared among 4 adjacent texels
- TODO: Can be optimized using mirrored buffer views
2020-01-15 21:12:51 +03:00
Eladash 05e5e6058f Add description for rsx wake-up delay 2020-01-15 19:54:23 +03:00
MSuih 556ac1cf22 Add wake-up delay to settings 2020-01-15 19:54:23 +03:00
Eladash 85695c8bac rsx: FIFO wake-up pause control 2020-01-15 19:54:23 +03:00
kd-11 2984300385 vk: Fix invocation alignment to support non-power-of-2 alignment 2020-01-15 15:42:36 +03:00
kd-11 ac4cadf538 vk: Fix word index counting for shuffle tasks 2020-01-15 15:42:36 +03:00
kd-11 175f78f5b3 vk: Lower default compute heap size to 64M
- There is no need to guess and use a large memory footprint as the heap is
now dynamic.
2020-01-15 15:42:36 +03:00
kd-11 3d96fe79cc vk: Implement dynamic sized compute heap
- Implements a dynamically sized compute heap to allow growing up the
size if it is too small.
2020-01-15 15:42:36 +03:00
Eladash 1ccb3c4492 rsx: Verify local memory offset 2020-01-15 13:23:56 +03:00
Eladash 01035d35bd sys_process: Fix sys_process_get_id, add error_code (#7246) 2020-01-14 21:32:41 +03:00
kd-11 8bbda3dedb vk: Restructure command queue flushing behavior to avoid deadlock
- Queueing commands on the offloader is a good idea but unfortunately
page faults can still happen causing a cyclic dependency and eventual
deadlock. Characterized by a vk::wait_for_event timed out error
accompanied by severe hitching.

- Drain the fault-able commands before pushing a submit operation to the
queue. If a fault is in progress, bypass the queue system and submit
raw. Technically this is incorrect but there isn't much that can be
done about it right now.
2020-01-14 14:32:40 +03:00
Megamouse a24514651c Update Appveyor to Qt 5.14 2020-01-14 10:15:35 +01:00
Megamouse 542d2ef8da Qt: smoother batch package installation 2020-01-14 09:27:09 +01:00
Megamouse be2d225d96 sceNpTrophy: deny unlocking of platinum trophies 2020-01-13 22:50:05 +01:00
Eladash 765bd6b6c6 SPU: Optimize gpr reset for MSVC 2020-01-11 22:56:46 +03:00
Nekotekina aeed349a99 sys_fs: adjust permissions for /dev_bdvd
Remove write permissions returned by stat, fstat, etc.
Also make sys_fs_open return CELL_EPERM on write attempt.
2020-01-11 04:48:42 +03:00
Nekotekina 8447d75dda sys_fs: improve sys_fs_lsn_lock
It appears it does nothing only on /dev_hdd0 or /host_root (HOSTFS).
2020-01-11 03:44:52 +03:00
Nekotekina fc6356a74c sys_fs: adjust /dev_bdvd block size
From test.
2020-01-11 03:05:26 +03:00
Nekotekina 41f2ee7b6c VFS: minor change in handling /host_root path 2020-01-11 01:55:36 +03:00
Nekotekina 87cd653c6e sys_fs: improve sys_fs_disk_free
Fix error codes and arg checks.
2020-01-11 01:10:50 +03:00
Nekotekina 7e35fd54a8 sys_fs: improve sys_fs_fcntl(0xc0000002)
Always obtain free space on /dev_hdd0.
2020-01-11 01:09:30 +03:00
Nekotekina 582ee80552 sys_fs: correct block size for /dev_hdd1 2020-01-10 05:24:43 +03:00
Nekotekina 0b4b87f069 sys_fs: fix sys_fs_get_block_size
Don't check file existence on /dev_hdd0.
Relax check on some mountpoints.
Fix CELL_EISDIR error condition.
2020-01-10 05:19:18 +03:00
Nekotekina a8e1afa0af sys_net: fix sys_net_bnet_select arg check (nfds) 2020-01-10 03:21:27 +03:00
Eladash 71df5044fc sys_vm_get_statistics: Write timestamp 2020-01-09 20:43:03 +00:00
kd-11 db5d03c340 vk: Generate dynamic binding table based on the capability of the drivers
- This alleviates constraints imposed on shaders to allow running on some not-so-great platforms.
2020-01-09 15:38:23 +03:00
RipleyTom 4a5559ee65 Add buzz controllers to usb whitelist 2020-01-09 07:51:16 +00:00
Nekotekina 7523416a12 sys_fs: return CELL_ENOTSUP in sys_fs_fcntl(0xc0000006) 2020-01-09 04:15:20 +03:00
Nekotekina 9075208c80 sys_fs: fix logging in sys_fs_get_block_size 2020-01-09 04:15:20 +03:00
Nekotekina d477889763 sys_fs: fix mountpoint detection 2020-01-09 04:15:20 +03:00
kd-11 ef3b0db7d8 vk: Workaround for NVIDIA occlusion query failure
- When using partial results on NVIDIA, a non-zero result is returned even when the draw is fully occluded.
  This, I believe, violates spec which says the partial result shall be between 0 and the final result.
2020-01-08 19:02:45 +03:00
Nekotekina f5cb147f8d sys_fs: improve sys_fs_get_block_size values
Affected other syscalls:
sys_fs_fget_block_size
sys_fs_stat
sys_fs_fstat
sys_fs_fcntl (cellFsGetDirectoryEntries, cellFsGetFreeSize)

For default values:
Return sector_size = 512.
Return 4th arg = 512.
Fod /dev_bdvd:
Sector size = 2048.
Block size = 2048.
2020-01-07 23:16:17 +03:00
Nekotekina 63e669c0cf sys_fs: fix sys_fs_fget_block_size
Return flags via last argument.
2020-01-07 21:55:19 +03:00
Nekotekina 9c54305e10 sys_fs: disable sys_fs_lsn_lock/unlock
According to test, nothing seems to happen.
Disable CELL_EBUSY errors associated with Stream Support API.
2020-01-07 21:55:19 +03:00
Nekotekina f3d52de429 sys_fs: Adjust flags of /app_home mountpoint 2020-01-07 21:55:19 +03:00
kd-11 3f34a0196c overlays/osk: Add linear fade-in/out effect to OSK 2020-01-07 21:31:19 +03:00
kd-11 ecf00be155 rsx: Add color interpolation animation
- Adds color interpolation and modulation pass and refactors the code a
bit. Elements with this pass applied have their color modulated by the
animated color from the pass. Modulation transform is multiplicative.
2020-01-07 21:31:19 +03:00
kd-11 071e73a68e geometry: Allow basic color arithmetic 2020-01-07 21:31:19 +03:00
kd-11 ad845861be video: Remove pointless aspect ratio option
- The auto option is used when requesting the system is works like a
"dont care" specifier to tell the system to use what settings have been
passed in by HDMI EDID or the user TV type setting. Since this option
simulates the "TV type setting", auto makes no sense and is also not
something you can select on a PS3.
- Also adds a few missing checks.
2020-01-07 15:56:54 +03:00
Nekotekina c51779d4d3 Fix format string in log_frame.cpp 2020-01-06 23:44:48 +03:00
Nekotekina 55f9a56e45 Fix sys_tty_write (UTF-8 encoding of literals) 2020-01-06 23:23:04 +03:00
Nick Renieris 5bace118a7 overlays: Redesign animation system (add easing functions, fix bugs)
Instead of speed, direction and distance, the user now specifies
start/end offsets and how much time the transition should take.

Fixes:
- Stuttering caused from framerate estimation.
- An edge case where animations would go over their supposed limit.

Adds:
- The ability to specify arbitrary easing functions for the animations
  - Implemented quadratic ease in and ease out and cubic ease in/out.
- Usage of cubic ease in/out in the trophy notification
2020-01-06 22:42:07 +03:00
Nick Renieris 28770c1580 overlays: Move vertex & vector utility classes to new file 2020-01-06 22:42:07 +03:00
Nick Renieris 192912131e rsx: Update vblank count in LLE mode 2020-01-06 22:42:07 +03:00
Dravonic 94d2f97f27 Multithreaded shader compliation follow-up (#7190)
* Multithreaded load pipeline entries shader compliation stage

Co-authored-by: kd-11 <15904127+kd-11@users.noreply.github.com>
2020-01-06 21:59:59 +03:00
Megamouse 632cc79c54 cellGame: add more checks 2020-01-06 10:47:13 +01:00
Megamouse e7845357e2 sceNpTrophy: unlock platinum trophies 2020-01-05 19:47:31 +01:00
Nekotekina 4450ae0c7a sys_fs: fix CELL_FS_O_APPEND emulation
Don't use fs::append (not capable of).
Fix sys_fs_ftruncate (remove wrong workaround).
2020-01-05 18:15:55 +03:00
Nekotekina 9fc0aec066 sys_fs_stat: fix split file handling
Allow single-file case (consistently with sys_fs_open)
2020-01-05 18:15:55 +03:00
Nekotekina bed2d558a6 sys_fs: implement CELL_EROFS error
Implement lv2_mp_flag::read_only.
Currently only /dev_bdvd is affected.
2020-01-05 18:15:55 +03:00
Nekotekina d5f0957558 Implement lv2_fs_mount_point with mount point flags
Implement some actual mount points
Implement lv2_mp_flag::no_uid_gid
2020-01-05 18:15:43 +03:00
kd-11 7f09def94e rsx/vp: Properly initialize output registers.
- All registers tested on hw show contents to be 0, 0, 0, 1.
  Make default output registers match this pattern.
2020-01-05 18:06:08 +03:00
Silent b88fb43acc Minor cleanup in InstallPkg and InstallPup 2020-01-05 11:01:26 +01:00
Silent e7ddc5187a Add a dialog to Batch PKG Install
Dialog allows users to preview the order in which PKG's will be installed
and allows users to move items around if needed.

Because clicking "Install" on this new dialog acts as a confirmation
and user has a second chance to eyeball what is to be installed,
"Install package X?" dialogs have been removed and instead user
is only notified of success. In case of failure, batch installation
aborts with a descriptive error.
2020-01-05 11:01:26 +01:00
Eladash 872be25ed1 cellFs: Fix cellFsLseek with negative whence 2020-01-04 22:38:53 +03:00
Eladash 9d2c9e5d62 cellFs: Improve cellFsGetDirectoryEntries 2020-01-04 22:38:53 +03:00
Nekotekina 28fb0d1741 Fix lv2_fs_object::name
Recreate path from actual decoded components.
2020-01-04 21:44:03 +03:00
MSuih 5534c9e27c Disable AA for renderers which do not support it 2020-01-04 18:58:33 +01:00
MSuih 049f852a9c Slight cleanup of mousewheel pr
Fixes theoretical uninitialized variable and micro-optimizes scrollwheel stop code
2020-01-04 18:58:33 +01:00
MSuih 69f11d82d1 Change Null microphone to Disabled 2020-01-04 18:58:33 +01:00
Silent f92794360d Qt: Add tooltips to Virtual File System buttons 2020-01-04 17:10:28 +01:00
kd-11 bdb5115c7f rsx/overlays: Improve space usage on trophy dialog
- Slightly increases the size of the trophy dialog and the font size.
  The old dimensions did not work with some libre fonts causing
alignment errors and other problems.
2020-01-04 16:36:49 +03:00
kd-11 3ada97d2d3 rsx/overlays: Implement trophy notification queue
- Allows to display more than one trophy at a time. Trophy notifications
will simply get queued up and displayed at appropriate time.
2020-01-04 16:36:49 +03:00
Nekotekina 49d5ce3ba4 Update glslang.7z 2020-01-04 01:50:28 +03:00
Nekotekina 691a57a4da Add BOM to sys_tty.cpp 2020-01-04 01:32:21 +03:00
Nekotekina 671ae20876 Inject rpcs3_glslang.props to glslang build
Disable new exception format to remove vcruntime140_1.dll dependency.
2020-01-04 01:30:52 +03:00
Nekotekina 7af7e3cec1 Update ffmpeg fork URL 2020-01-03 21:54:37 +03:00
MSuih ca52c1e2d1 Link Bcrypt with ffmpeg 2020-01-03 21:45:09 +03:00
kd-11 31b07fece5 rsx/overlays: Add support for animations
- Adds animation support. This commit adds the base framework and
implements a translate animation used to slide elements around the
screen. This is then used to implement the sliding animation for the
trophy notification.
2020-01-03 20:33:32 +03:00
Megamouse b3ad89cc8b cellSaveData: remove duplicate yield 2020-01-03 14:22:40 +01:00
Megamouse 5e7d25ad35 overlays: refactor shader loading dialogs 2020-01-03 14:22:40 +01:00
Megamouse d94d094a7e overlays: fix non-interactive dialog loops 2020-01-03 14:22:40 +01:00
Megamouse c9aee27d48 VK: remove unused init function declaration 2020-01-03 14:22:40 +01:00
kd-11 d12762414a vk: Change default vertex output value
- Prefer w!=0 to avoid a situation where xyz/w = nan. More of a
theoretical problem, but some calculations break down in such a
situation.
2020-01-03 10:35:53 +03:00
kd-11 7786681954 rsx: Improve MTRSX synchronization
- Properly synchronize DMA transfers when handling RSX pipeline
barriers. Texture read barrier is used to signify completion of DMA
routines and is often used to signal that Cell can overwrite vertex
data!
2020-01-03 10:35:53 +03:00
Megamouse 02ca8f0002 Qt: repaint all related icons for custom configs 2020-01-02 11:35:51 +01:00
Megamouse 7af2ebb6f4 cellSaveData: use errDialog to skip error dialogs 2020-01-02 05:49:03 +01:00
Nekotekina 2c4ecc55af Update ffmpeg 2020-01-02 00:53:22 +03:00
kd-11 c4e59b5115 vk: Clamp depth export in FS
- PS3 matches OGL behavior where writing to the depth export
register results in clamping.
2020-01-01 22:39:20 +03:00
Eladash 4c20881f8f Fixup after #6933 (#7166)
* fixup

* Get rid of obsolute arg in lv2_obj::awake

* nvm ill do this later

* Typo fix of the decade
2020-01-01 17:38:05 +00:00
564 changed files with 21698 additions and 14894 deletions
-24
View File
@@ -1,24 +0,0 @@
<!---
THIS IS NOT A SUPPORT FORUM, FOR SUPPORT GO TO:
https://forums.rpcs3.net
or our discord:
https://discord.me/RPCS3
PLEASE READ THE GUIDELINES BEFORE OPENING AN ISSUE:
https://github.com/RPCS3/rpcs3/blob/master/.github/CONTRIBUTING.md
====================================================
When submitting an issue, please check the following:
- You have read the above.
- You have provided the version (commit hash) of RPCS3 you are using.
- You have provided sufficient detail for the issue to be reproduced.
- You have provided system specs.
- Please also provide:
- For crashes, a backtrace.
- For graphical issues, comparison screenshots with real hardware.
Remember that the GitHub Issue Tracker is not the place to ask for support or to submit Game Compatibility reports. You must use our forums for that.
--->
@@ -0,0 +1,28 @@
---
name: Regression report
about: If something worked before, but now it doesn't
title: ''
labels: ''
assignees: ''
---
<!---
Please do not ask for help or report compatibility regressions here, use RPCS3 Discord server or forums instead.
Please read Contributing guide under Helpful resources on the right. →
--->
## Quick summary
Please describe what exactly has stopped working correctly
## Details
Please provide _exact_ build (or commit) information that introduced the regression you're reporting.
Please see How to find the build that caused a regression in wiki: https://wiki.rpcs3.net/index.php?title=Help:Using_different_versions_of_RPCS3#How_to_find_the_build_that_caused_a_regression.3F
You can find old builds here: https://rpcs3.net/compatibility?b
Please remember to attach TWO logs: one for the build that exhibits regression, and one for the previous build that works as expected.
If the regression caused a graphical issue, please provide RSX capture and a Renderdoc capture that demonstrate the issue.
To create an RSX capture, enable Debugger view (View → Show Debugger) and use the RSX Capture button. Captues will be stored in RPCS3 folder → captures.
To create Renderdoc capture, please refer to Renderdoc documentation https://renderdoc.org/docs/how/how_capture_frame.html
+26
View File
@@ -0,0 +1,26 @@
---
name: Bug report
about: If something doesn't work correctly in RPCS3
title: ''
labels: ''
assignees: ''
---
<!---
Please do not ask for help or general inquiry here, use RPCS3 Discord server instead.
Please read Contributing guide under Helpful resources on the right. →
--->
## Quick summary
Please summarize the issue here
## Details
Please provide as much detail as you can here, including
- expected (real hw) and observed (emulator) behavior
- full logs (not from UI)
- back traces (for hard crashes)
- screenshots, Renderdoc, and RSX captures (for visual issues)
- your system configuration (OS, CPU, GPU, driver versions, etc)
- anything else you deem to be important
+11
View File
@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Quickstart guide
url: https://rpcs3.net/quickstart
about: Everything you need to know to install and configure emulator, and add games
- name: Ask for help
url: https://discord.me/RPCS3
about: If you have some questions or need help, please use our Discord server instead of GitHub
- name: Report game compatibility
url: https://forums.rpcs3.net/thread-196671.html
about: Please use RPCS3 forums to submit or update game compatibility status
+9
View File
@@ -37,6 +37,7 @@
/rpcs3/Debug
/rpcs3/Release
/llvm_build
/3rdparty/llvm_build
/Vulkan/Vulkan-build
/Vulkan/glslang-build
@@ -71,10 +72,15 @@ Makefile
*CMakeFiles*
CMakeCache.txt
*cmake_install.cmake*
CPackConfig.cmake
CPackSourceConfig.cmake
compile_commands.json
# cotire
rpcs3/cotire/*
rpcs3/rpcs3_*_cotire.cmake
rpcs3/Emu/rpcs3_emu_CXX_Release_cotire.cmake
rpcs3/Emu/rpcs3_emu_CXX_cotire.cmake
# kdevelop
*.kdev4
@@ -99,3 +105,6 @@ CMakeLists.txt.user
# 7zlib
/3rdparty/7z/**/*.lib
# yaml-cpp
yaml-cpp.pc
+3 -3
View File
@@ -1,6 +1,6 @@
[submodule "rpcs3-ffmpeg"]
path = 3rdparty/ffmpeg
url = https://github.com/hrydgard/ppsspp-ffmpeg
url = https://github.com/RPCS3/ffmpeg-core
ignore = dirty
[submodule "asmjit"]
path = asmjit
@@ -9,7 +9,6 @@
[submodule "llvm"]
path = llvm
url = https://github.com/RPCS3/llvm
branch = release_60
ignore = dirty
[submodule "Vulkan/glslang"]
path = Vulkan/glslang
@@ -46,7 +45,7 @@
ignore = dirty
[submodule "3rdparty/libusb"]
path = 3rdparty/libusb
url = https://github.com/RPCS3/libusb.git
url = https://github.com/libusb/libusb.git
ignore = dirty
[submodule "3rdparty/FAudio"]
path = 3rdparty/FAudio
@@ -55,3 +54,4 @@
[submodule "3rdparty/span"]
path = 3rdparty/span
url = https://github.com/tcbrindle/span
ignore = dirty
+18 -18
View File
@@ -1,31 +1,29 @@
language: cpp
matrix:
jobs:
include:
# - os: linux
# env:
# - NAME="Linux build"
# - COMPILER="gcc"
# services: docker
# cache: ccache
# install: "docker pull rpcs3/rpcs3-travis-xenial:1.0"
# script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .travis/travis.env rpcs3/rpcs3-travis-xenial:1.0 /bin/bash -ex /rpcs3/.travis/build-linux.bash'
- os: linux
dist: xenial
env:
- NAME="Linux build"
- COMPILER="gcc"
- DEPLOY_APPIMAGE="true"
services: docker
cache: ccache
compiler: gcc
install: "docker pull rpcs3/rpcs3-travis-xenial:1.2"
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .travis/travis.env rpcs3/rpcs3-travis-xenial:1.2 /bin/bash -ex /rpcs3/.travis/build-linux.bash'
- os: linux
dist: xenial
env:
- NAME="Linux build"
- COMPILER="clang"
- DEPLOY_APPIMAGE="true"
services: docker
cache: ccache
install: "docker pull rpcs3/rpcs3-travis-xenial:1.0"
addons:
apt:
packages:
- libsdl2-2.0
- libsdl2-dev
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .travis/travis.env rpcs3/rpcs3-travis-xenial:1.0 /bin/bash -ex /rpcs3/.travis/build-linux.bash'
compiler: clang
install: "docker pull rpcs3/rpcs3-travis-xenial:1.2"
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .travis/travis.env rpcs3/rpcs3-travis-xenial:1.2 /bin/bash -ex /rpcs3/.travis/build-linux.bash'
- os: osx
osx_image: xcode10.2
osx_image: xcode11.3
addons:
homebrew:
packages:
@@ -35,6 +33,8 @@ matrix:
- qt
script: "/bin/bash -ex .travis/build-mac.bash"
cache: ccache
allow_failures:
- os: osx
git:
depth: false # Unshallow clone to obtain proper GIT_VERSION
+1 -1
View File
@@ -26,7 +26,7 @@ else
export CXX=${CLANGXX_BINARY}
fi
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_LLVM_SUBMODULE=OFF -DLLVM_DIR=llvmlibs/lib/cmake/llvm/ -DUSE_NATIVE_INSTRUCTIONS=OFF -G Ninja
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_LLVM_SUBMODULE=OFF -DUSE_COTIRE=OFF -DLLVM_DIR=llvmlibs/lib/cmake/llvm/ -DUSE_NATIVE_INSTRUCTIONS=OFF -G Ninja
ninja; build_status=$?;
+2 -1
View File
@@ -26,7 +26,8 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
# This may need updating if you update the compiler or rpcs3 uses newer c++ features
# See https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/config/abi/pre/gnu.ver
# for which definitions correlate to which CXXABI version.
printf "#include <memory>\nint main(){std::make_exception_ptr(0);}" | $CXX -x c++ -o ./appdir/usr/optional/checker -
# Currently we target a minimum of GLIBCXX_3.4.26 and CXXABI_1.3.11
printf "#include <bits/stdc++.h>\nint main(){std::make_exception_ptr(0);std::pmr::get_default_resource();}" | $CXX -x c++ -std=c++2a -o ./appdir/usr/optional/checker -
# Package it up and send it off
./squashfs-root/usr/bin/appimagetool /rpcs3/build/appdir
-1
View File
@@ -204,7 +204,6 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
+20 -19
View File
@@ -1,14 +1,6 @@
find_package(PkgConfig)
include(ExternalProject)
if(APPLE)
set(PLATFORM_ARCH "macosx/x86_64")
elseif(WIN32)
set(PLATFORM_ARCH "Windows/x86_64")
else()
set(PLATFORM_ARCH "linux/x86_64")
endif()
# Dummy target to use when lib isn't available
add_library(3rdparty_dummy_lib INTERFACE)
@@ -146,9 +138,9 @@ if(CMAKE_SYSTEM MATCHES "DragonFly|FreeBSD")
elseif(MSVC)
# Windows time.h defines timespec but doesn't add any flag for it, which makes libusb attempt to define it again
add_definitions(-DHAVE_STRUCT_TIMESPEC=1)
add_subdirectory(libusb EXCLUDE_FROM_ALL)
add_subdirectory(libusb_cmake EXCLUDE_FROM_ALL)
else()
add_subdirectory(libusb EXCLUDE_FROM_ALL)
add_subdirectory(libusb_cmake EXCLUDE_FROM_ALL)
endif()
@@ -345,6 +337,7 @@ if(USE_FAUDIO)
if (NOT SDL2_FOUND OR SDL2_VERSION VERSION_LESS 2.0.9)
message("-- RPCS3: FAudio requires SDL 2.0.9 or newer.")
else()
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared library")
add_subdirectory(FAudio EXCLUDE_FROM_ALL)
target_compile_definitions(FAudio INTERFACE -DHAVE_FAUDIO)
set(FAUDIO_TARGET FAudio)
@@ -362,8 +355,6 @@ if(USE_SYSTEM_FFMPEG)
target_include_directories(3rdparty_ffmpeg INTERFACE ${FFMPEG_INCLUDE_DIR})
target_link_libraries(3rdparty_ffmpeg INTERFACE ${FFMPEG_LIBRARIES})
else()
set(FFMPEG_PLATFORM_DIR "ffmpeg/${PLATFORM_ARCH}")
if (NOT MSVC AND WIN32)
message("-- RPCS3: building ffmpeg submodule")
@@ -371,26 +362,36 @@ else()
DOWNLOAD_COMMAND ""
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/ffmpeg
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg/configure --prefix=./Windows/x86_64 --arch=x86_64 --disable-avdevice --disable-programs --disable-avfilter --disable-postproc --disable-doc --disable-pthreads --enable-w32threads --disable-network --disable-everything --disable-encoders --disable-muxers --disable-hwaccels --disable-parsers --disable-protocols --enable-dxva2 --enable-static --disable-shared --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=atrac3 --enable-decoder=atrac3p --enable-decoder=mp3 --enable-decoder=pcm_s16le --enable-decoder=pcm_s8 --enable-decoder=h264 --enable-decoder=mpeg4 --enable-decoder=mpeg2video --enable-decoder=mjpeg --enable-decoder=mjpegb --enable-encoder=pcm_s16le --enable-encoder=ffv1 --enable-encoder=mpeg4 --enable-parser=h264 --enable-parser=mpeg4video --enable-parser=mpegaudio --enable-parser=mpegvideo --enable-parser=mjpeg --enable-parser=aac --enable-parser=aac_latm --enable-muxer=avi --enable-demuxer=h264 --enable-demuxer=m4v --enable-demuxer=mp3 --enable-demuxer=mpegvideo --enable-demuxer=mpegps --enable-demuxer=mjpeg --enable-demuxer=avi --enable-demuxer=aac --enable-demuxer=pmp --enable-demuxer=oma --enable-demuxer=pcm_s16le --enable-demuxer=pcm_s8 --enable-demuxer=wav --enable-hwaccel=h264_dxva2 --enable-indev=dshow --enable-protocol=file
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg/configure --prefix=./windows/x86_64 --arch=x86_64 --disable-avdevice --disable-programs --disable-avfilter --disable-postproc --disable-doc --disable-pthreads --enable-w32threads --disable-network --disable-everything --disable-encoders --disable-muxers --disable-hwaccels --disable-parsers --disable-protocols --enable-dxva2 --enable-static --disable-shared --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=atrac3 --enable-decoder=atrac3p --enable-decoder=mp3 --enable-decoder=pcm_s16le --enable-decoder=pcm_s8 --enable-decoder=h264 --enable-decoder=mpeg4 --enable-decoder=mpeg2video --enable-decoder=mjpeg --enable-decoder=mjpegb --enable-encoder=pcm_s16le --enable-encoder=ffv1 --enable-encoder=mpeg4 --enable-parser=h264 --enable-parser=mpeg4video --enable-parser=mpegaudio --enable-parser=mpegvideo --enable-parser=mjpeg --enable-parser=aac --enable-parser=aac_latm --enable-muxer=avi --enable-demuxer=h264 --enable-demuxer=m4v --enable-demuxer=mp3 --enable-demuxer=mpegvideo --enable-demuxer=mpegps --enable-demuxer=mjpeg --enable-demuxer=avi --enable-demuxer=aac --enable-demuxer=pmp --enable-demuxer=oma --enable-demuxer=pcm_s16le --enable-demuxer=pcm_s8 --enable-demuxer=wav --enable-hwaccel=h264_dxva2 --enable-indev=dshow --enable-protocol=file
BUILD_COMMAND make -j 4
INSTALL_COMMAND make install
)
set(FFMPEG_LIB_AVFORMAT "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/${PLATFORM_ARCH}/lib/libavformat.a")
set(FFMPEG_LIB_AVCODEC "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/${PLATFORM_ARCH}/lib/libavcodec.a")
set(FFMPEG_LIB_AVUTIL "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/${PLATFORM_ARCH}/lib/libavutil.a")
set(FFMPEG_LIB_SWSCALE "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/${PLATFORM_ARCH}/lib/libswscale.a")
set(FFMPEG_LIB_AVFORMAT "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/windows/x86_64/lib/libavformat.a")
set(FFMPEG_LIB_AVCODEC "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/windows/x86_64/lib/libavcodec.a")
set(FFMPEG_LIB_AVUTIL "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/windows/x86_64/lib/libavutil.a")
set(FFMPEG_LIB_SWSCALE "${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/windows/x86_64/lib/libswscale.a")
else()
message("-- RPCS3: using builtin ffmpeg")
set(FFMPEG_LIB_DIR "${FFMPEG_PLATFORM_DIR}/lib")
if (WIN32)
set(FFMPEG_LIB_DIR "ffmpeg/windows/x86_64")
target_link_libraries(3rdparty_ffmpeg INTERFACE "Bcrypt.lib")
elseif(CMAKE_SYSTEM MATCHES "Linux")
set(FFMPEG_LIB_DIR "ffmpeg/linux/x86_64")
elseif(APPLE)
set(FFMPEG_LIB_DIR "ffmpeg/macos/x86_64")
else()
message(FATAL_ERROR "Prebuilt ffmpeg is not available on this platform! Try USE_SYSTEM_FFMPEG=ON.")
endif()
find_library(FFMPEG_LIB_AVFORMAT avformat PATHS ${FFMPEG_LIB_DIR} NO_DEFAULT_PATH)
find_library(FFMPEG_LIB_AVCODEC avcodec PATHS ${FFMPEG_LIB_DIR} NO_DEFAULT_PATH)
find_library(FFMPEG_LIB_AVUTIL avutil PATHS ${FFMPEG_LIB_DIR} NO_DEFAULT_PATH)
find_library(FFMPEG_LIB_SWSCALE swscale PATHS ${FFMPEG_LIB_DIR} NO_DEFAULT_PATH)
endif()
target_include_directories(3rdparty_ffmpeg INTERFACE "${FFMPEG_PLATFORM_DIR}/include")
target_include_directories(3rdparty_ffmpeg INTERFACE "ffmpeg/include")
target_link_libraries(3rdparty_ffmpeg
INTERFACE
+2 -2
View File
@@ -31,9 +31,9 @@ extern "C" {
#define ALC_VERSION_0_1 1
/** Opaque device handle */
typedef struct ALCdevice_struct ALCdevice;
typedef struct ALCdevice ALCdevice;
/** Opaque context handle */
typedef struct ALCcontext_struct ALCcontext;
typedef struct ALCcontext ALCcontext;
/** 8-bit boolean */
typedef char ALCboolean;
+21
View File
@@ -509,6 +509,27 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
#endif
#endif
#ifndef AL_SOFT_direct_channels_remix
#define AL_SOFT_direct_channels_remix 1
#define AL_DROP_UNMATCHED_SOFT 0x0001
#define AL_REMIX_UNMATCHED_SOFT 0x0002
#endif
#ifndef AL_SOFT_bformat_ex
#define AL_SOFT_bformat_ex 1
#define AL_AMBISONIC_LAYOUT_SOFT 0x1997
#define AL_AMBISONIC_SCALING_SOFT 0x1998
/* Ambisonic layouts */
#define AL_FUMA_SOFT 0x0000
#define AL_ACN_SOFT 0x0001
/* Ambisonic scalings (normalization) */
/*#define AL_FUMA_SOFT*/
#define AL_SN3D_SOFT 0x0001
#define AL_N3D_SOFT 0x0002
#endif
#ifdef __cplusplus
}
#endif
+1
View File
@@ -1,6 +1,7 @@
#ifndef AL_EFX_H
#define AL_EFX_H
#include <float.h>
#include "alc.h"
#include "al.h"
Binary file not shown.
@@ -7,11 +7,31 @@
*
**************************************************************************/
#ifdef _MSC_VER
#pragma once
#endif
#ifndef __XAUDIO2_INCLUDED__
#define __XAUDIO2_INCLUDED__
#include <sdkddkver.h>
// Current name of the DLL shipped in the same SDK as this header.
// The name reflects the current version
#define XAUDIO2_DLL_A "xaudio2redist.dll"
#define XAUDIO2_DLL_W L"xaudio2redist.dll"
#define XAUDIO2D_DLL_A "xaudio2redist.dll"
#define XAUDIO2D_DLL_W L"xaudio2redist.dll"
#ifdef UNICODE
#define XAUDIO2_DLL XAUDIO2_DLL_W
#define XAUDIO2D_DLL XAUDIO2D_DLL_W
#else
#define XAUDIO2_DLL XAUDIO2_DLL_A
#define XAUDIO2D_DLL XAUDIO2D_DLL_A
#endif
/**************************************************************************
*
* XAudio2 COM object class and interface IDs.
@@ -20,8 +40,19 @@
#include <basetyps.h>
// XAudio 2.8
interface __declspec(uuid("60d8dac8-5aa1-4e8e-b597-2f5e2883d484")) IXAudio2;
#ifdef __cplusplus
// XAudio 2.9
interface __declspec(uuid("2B02E3CF-2E0B-4ec3-BE45-1B2A3FE7210D")) IXAudio2;
interface __declspec(uuid("84ac29bb-d619-44d2-b197-e4acf7df3ed6")) IXAudio2Extension;
EXTERN_C const GUID DECLSPEC_SELECTANY IID_IXAudio2Extension = __uuidof(IXAudio2Extension);
EXTERN_C const GUID DECLSPEC_SELECTANY IID_IXAudio2 = __uuidof(IXAudio2);
#else // #ifdef __cplusplus
// Compiling with C for Windows 10 and later
DEFINE_GUID(IID_IXAudio2, 0x2B02E3CF, 0x2E0B, 0x4ec3, 0xBE, 0x45, 0x1B, 0x2A, 0x3F, 0xE7, 0x21, 0x0D);
DEFINE_GUID(IID_IXAudio2Extension, 0x84ac29bb, 0xd619, 0x44d2, 0xb1, 0x97, 0xe4, 0xac, 0xf7, 0xdf, 0x3e, 0xd6);
#endif // #ifdef __cplusplus
// Ignore the rest of this header if only the GUID definitions were requested
#ifndef GUID_DEFS_ONLY
@@ -31,6 +62,31 @@ interface __declspec(uuid("60d8dac8-5aa1-4e8e-b597-2f5e2883d484")) IXAudio2;
#include <mmreg.h> // Basic data types and constants for audio work
#include <audiosessiontypes.h> // For AUDIO_STREAM_CATEGORY
// The Windows 7 version of audiosessiontypes.h does not define AUDIO_STREAM_CATEGORY, so if we are targeting
// Windows 7 we might have to define it here, depending on which SDK is used.
#if _WIN32_WINNT < _WIN32_WINNT_WIN8
// If we are compiling for Windows 7, we might be using the Windows 7 Platform SDK, which does not have AUDIO_STREAM_CATEGORY.
// But we might be using a newer SDK (such as the Win8 Platform SDK), which has AUDIO_STREAM_CATEGORY.
// Determine if we are using the Windows 7 Platform SDK by checking if WAVE_FORMAT_WM9_SPECTRUM_ANALYZER is defined.
#ifndef WAVE_FORMAT_WM9_SPECTRUM_ANALYZER
typedef enum _AUDIO_STREAM_CATEGORY
{
AudioCategory_Other = 0,
AudioCategory_ForegroundOnlyMedia = 1,
AudioCategory_Communications = 3,
AudioCategory_Alerts = 4,
AudioCategory_SoundEffects = 5,
AudioCategory_GameEffects = 6,
AudioCategory_GameMedia = 7,
AudioCategory_GameChat = 8,
AudioCategory_Speech = 9,
AudioCategory_Movie = 10,
AudioCategory_Media = 11,
} AUDIO_STREAM_CATEGORY;
#endif /* WAVE_FORMAT_WM9_SPECTRUM_ANALYZER */
#endif /* NTDDI_VERSION < NTDDI_WIN8 */
// All structures defined in this file use tight field packing
#pragma pack(push, 1)
@@ -83,7 +139,7 @@ interface __declspec(uuid("60d8dac8-5aa1-4e8e-b597-2f5e2883d484")) IXAudio2;
#define XAUDIO2_VOICE_NOSAMPLESPLAYED 0x0100 // Used in IXAudio2SourceVoice::GetState
#define XAUDIO2_STOP_ENGINE_WHEN_IDLE 0x2000 // Used in XAudio2Create to force the engine to Stop when no source voices are Started, and Start when a voice is Started
#define XAUDIO2_1024_QUANTUM 0x8000 // Used in XAudio2Create to specify nondefault processing quantum of 21.33 ms (1024 samples at 48KHz)
#define XAUDIO2_NO_VIRTUAL_AUDIO_CLIENT 0x10000 // Used in CreateMasteringVoice to create a virtual audio client
#define XAUDIO2_NO_VIRTUAL_AUDIO_CLIENT 0x10000 // Used in CreateMasteringVoice to create a virtual audio client
// Default parameters for the built-in filter
#define XAUDIO2_DEFAULT_FILTER_TYPE LowPassFilter
@@ -99,10 +155,10 @@ interface __declspec(uuid("60d8dac8-5aa1-4e8e-b597-2f5e2883d484")) IXAudio2;
// XAudio2 error codes
#define FACILITY_XAUDIO2 0x896
#define XAUDIO2_E_INVALID_CALL 0x88960001 // An API call or one of its arguments was illegal
#define XAUDIO2_E_XMA_DECODER_ERROR 0x88960002 // The XMA hardware suffered an unrecoverable error
#define XAUDIO2_E_XAPO_CREATION_FAILED 0x88960003 // XAudio2 failed to initialize an XAPO effect
#define XAUDIO2_E_DEVICE_INVALIDATED 0x88960004 // An audio device became unusable (unplugged, etc)
#define XAUDIO2_E_INVALID_CALL ((HRESULT)0x88960001) // An API call or one of its arguments was illegal
#define XAUDIO2_E_XMA_DECODER_ERROR ((HRESULT)0x88960002) // The XMA hardware suffered an unrecoverable error
#define XAUDIO2_E_XAPO_CREATION_FAILED ((HRESULT)0x88960003) // XAudio2 failed to initialize an XAPO effect
#define XAUDIO2_E_DEVICE_INVALIDATED ((HRESULT)0x88960004) // An audio device became unusable (unplugged, etc)
/**************************************************************************
*
@@ -166,6 +222,13 @@ typedef UINT32 XAUDIO2_PROCESSOR;
#define Processor31 0x40000000
#define Processor32 0x80000000
#define XAUDIO2_ANY_PROCESSOR 0xffffffff
// This value indicates that XAudio2 will choose the default processor by itself. The actual value chosen
// may vary depending on the hardware platform.
#define XAUDIO2_USE_DEFAULT_PROCESSOR 0x00000000
// This definition is included for backwards compatibilty. New implementations should use
// XAUDIO2_USE_DEFAULT_PROCESSOR instead to let XAudio2 select the appropriate default processor for the hardware platform.
#define XAUDIO2_DEFAULT_PROCESSOR Processor1
// Returned by IXAudio2Voice::GetVoiceDetails
@@ -359,13 +422,13 @@ DECLARE_INTERFACE_(IXAudio2, IUnknown)
{
// NAME: IXAudio2::QueryInterface
// DESCRIPTION: Queries for a given COM interface on the XAudio2 object.
// Only IID_IUnknown and IID_IXAudio2 are supported.
// Only IID_IUnknown, IID_IXAudio2 and IID_IXaudio2Extension are supported.
//
// ARGUMENTS:
// riid - IID of the interface to be obtained.
// ppvInterface - Returns a pointer to the requested interface.
//
STDMETHOD(QueryInterface) (THIS_ REFIID riid, _Outptr_ void** ppvInterface) PURE;
STDMETHOD(QueryInterface) (THIS_ REFIID riid, _COM_Outptr_ void** ppvInterface) PURE;
// NAME: IXAudio2::AddRef
// DESCRIPTION: Adds a reference to the XAudio2 object.
@@ -489,6 +552,50 @@ DECLARE_INTERFACE_(IXAudio2, IUnknown)
_Reserved_ void* pReserved X2DEFAULT(NULL)) PURE;
};
// This interface extends IXAudio2 with additional functionality.
// Use IXAudio2::QueryInterface to obtain a pointer to this interface.
#undef INTERFACE
#define INTERFACE IXAudio2Extension
DECLARE_INTERFACE_(IXAudio2Extension, IUnknown)
{
// NAME: IXAudio2Extension::QueryInterface
// DESCRIPTION: Queries for a given COM interface on the XAudio2 object.
// Only IID_IUnknown, IID_IXAudio2 and IID_IXaudio2Extension are supported.
//
// ARGUMENTS:
// riid - IID of the interface to be obtained.
// ppvInterface - Returns a pointer to the requested interface.
//
STDMETHOD(QueryInterface) (THIS_ REFIID riid, _COM_Outptr_ void** ppvInterface) PURE;
// NAME: IXAudio2Extension::AddRef
// DESCRIPTION: Adds a reference to the XAudio2 object.
//
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
// NAME: IXAudio2Extension::Release
// DESCRIPTION: Releases a reference to the XAudio2 object.
//
STDMETHOD_(ULONG, Release) (THIS) PURE;
// NAME: IXAudio2Extension::GetProcessingQuantum
// DESCRIPTION: Returns the processing quantum
// quantumMilliseconds = (1000.0f * quantumNumerator / quantumDenominator)
//
// ARGUMENTS:
// quantumNumerator - Quantum numerator
// quantumDenominator - Quantum denominator
//
STDMETHOD_(void, GetProcessingQuantum)(THIS_ _Out_ UINT32* quantumNumerator, _Out_range_(!= , 0) UINT32* quantumDenominator);
// NAME: IXAudio2Extension::GetProcessor
// DESCRIPTION: Returns the number of the processor used by XAudio2
//
// ARGUMENTS:
// processor - Non-zero Processor number
//
STDMETHOD_(void, GetProcessor)(THIS_ _Out_range_(!= , 0) XAUDIO2_PROCESSOR* processor);
};
/**************************************************************************
*
@@ -949,6 +1056,10 @@ DECLARE_INTERFACE(IXAudio2VoiceCallback)
#define IXAudio2_GetPerformanceData(This,pPerfData) ((This)->lpVtbl->GetPerformanceData(This,pPerfData))
#define IXAudio2_SetDebugConfiguration(This,pDebugConfiguration,pReserved) ((This)->lpVtbl->SetDebugConfiguration(This,pDebugConfiguration,pReserved))
// IXAudio2Extension
#define IXAudio2Extension_GetProcessingQuantum(This,quantumNumerator,quantumDenominator) ((This)->lpVtbl->GetProcessingQuantum(This,quantumNumerator,quantumDenominator))
#define IXAudio2Extension_GetProcessor(This,processor) ((This)->lpVtbl->GetProcessor(This,processor))
// IXAudio2Voice
#define IXAudio2Voice_GetVoiceDetails(This,pVoiceDetails) ((This)->lpVtbl->GetVoiceDetails(This,pVoiceDetails))
#define IXAudio2Voice_SetOutputVoices(This,pSendList) ((This)->lpVtbl->SetOutputVoices(This,pSendList))
@@ -1143,12 +1254,16 @@ __inline float XAudio2CutoffFrequencyToOnePoleCoefficient(float CutoffFrequency,
* will use. Note that XAudio2 supports concurrent processing on
* multiple threads, using any combination of XAUDIO2_PROCESSOR
* flags. The values are platform-specific; platform-independent
* code can use XAUDIO2_DEFAULT_PROCESSOR to use the default on
* code can use XAUDIO2_USE_DEFAULT_PROCESSOR to use the default on
* each platform.
*
**************************************************************************/
typedef HRESULT(*XAudio2Create)(_Outptr_ IXAudio2** ppXAudio2, UINT32 Flags, XAUDIO2_PROCESSOR XAudio2Processor);
// We're an xaudio2 client
#define XAUDIO2_STDAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE
XAUDIO2_STDAPI XAudio2Create(_Outptr_ IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0),
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_USE_DEFAULT_PROCESSOR));
// Undo the #pragma pack(push, 1) directive at the top of this file
#pragma pack(pop)
@@ -1156,3 +1271,4 @@ typedef HRESULT(*XAudio2Create)(_Outptr_ IXAudio2** ppXAudio2, UINT32 Flags, XAU
#endif // #ifndef GUID_DEFS_ONLY
#endif // #ifndef __XAUDIO2_INCLUDED__
Binary file not shown.
-1295
View File
File diff suppressed because it is too large Load Diff
-263
View File
@@ -1,263 +0,0 @@
/***************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* File: audiodefs.h
* Content: Basic constants and data types for audio work.
*
* Remarks: This header file defines all of the audio format constants and
* structures required for XAudio2 and XACT work. Providing these
* in a single location avoids certain dependency problems in the
* legacy audio headers (mmreg.h, mmsystem.h, ksmedia.h).
*
* NOTE: Including the legacy headers after this one may cause a
* compilation error, because they define some of the same types
* defined here without preprocessor guards to avoid multiple
* definitions. If a source file needs one of the old headers,
* it must include it before including audiodefs.h.
*
***************************************************************************/
#ifndef __AUDIODEFS_INCLUDED__
#define __AUDIODEFS_INCLUDED__
#include <windef.h> // For WORD, DWORD, etc.
#pragma pack(push, 1) // Pack structures to 1-byte boundaries
/**************************************************************************
*
* WAVEFORMATEX: Base structure for many audio formats. Format-specific
* extensions can be defined for particular formats by using a non-zero
* cbSize value and adding extra fields to the end of this structure.
*
***************************************************************************/
#ifndef _WAVEFORMATEX_
#define _WAVEFORMATEX_
typedef struct tWAVEFORMATEX
{
WORD wFormatTag; // Integer identifier of the format
WORD nChannels; // Number of audio channels
DWORD nSamplesPerSec; // Audio sample rate
DWORD nAvgBytesPerSec; // Bytes per second (possibly approximate)
WORD nBlockAlign; // Size in bytes of a sample block (all channels)
WORD wBitsPerSample; // Size in bits of a single per-channel sample
WORD cbSize; // Bytes of extra data appended to this struct
} WAVEFORMATEX;
#endif
// Defining pointer types outside of the #if block to make sure they are
// defined even if mmreg.h or mmsystem.h is #included before this file
typedef WAVEFORMATEX *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX;
typedef const WAVEFORMATEX *PCWAVEFORMATEX, *LPCWAVEFORMATEX;
/**************************************************************************
*
* WAVEFORMATEXTENSIBLE: Extended version of WAVEFORMATEX that should be
* used as a basis for all new audio formats. The format tag is replaced
* with a GUID, allowing new formats to be defined without registering a
* format tag with Microsoft. There are also new fields that can be used
* to specify the spatial positions for each channel and the bit packing
* used for wide samples (e.g. 24-bit PCM samples in 32-bit containers).
*
***************************************************************************/
#ifndef _WAVEFORMATEXTENSIBLE_
#define _WAVEFORMATEXTENSIBLE_
typedef struct
{
WAVEFORMATEX Format; // Base WAVEFORMATEX data
union
{
WORD wValidBitsPerSample; // Valid bits in each sample container
WORD wSamplesPerBlock; // Samples per block of audio data; valid
// if wBitsPerSample=0 (but rarely used).
WORD wReserved; // Zero if neither case above applies.
} Samples;
DWORD dwChannelMask; // Positions of the audio channels
GUID SubFormat; // Format identifier GUID
} WAVEFORMATEXTENSIBLE;
#endif
typedef WAVEFORMATEXTENSIBLE *PWAVEFORMATEXTENSIBLE, *LPWAVEFORMATEXTENSIBLE;
typedef const WAVEFORMATEXTENSIBLE *PCWAVEFORMATEXTENSIBLE, *LPCWAVEFORMATEXTENSIBLE;
/**************************************************************************
*
* Define the most common wave format tags used in WAVEFORMATEX formats.
*
***************************************************************************/
#ifndef WAVE_FORMAT_PCM // Pulse Code Modulation
// If WAVE_FORMAT_PCM is not defined, we need to define some legacy types
// for compatibility with the Windows mmreg.h / mmsystem.h header files.
// Old general format structure (information common to all formats)
typedef struct waveformat_tag
{
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
} WAVEFORMAT, *PWAVEFORMAT, NEAR *NPWAVEFORMAT, FAR *LPWAVEFORMAT;
// Specific format structure for PCM data
typedef struct pcmwaveformat_tag
{
WAVEFORMAT wf;
WORD wBitsPerSample;
} PCMWAVEFORMAT, *PPCMWAVEFORMAT, NEAR *NPPCMWAVEFORMAT, FAR *LPPCMWAVEFORMAT;
#define WAVE_FORMAT_PCM 0x0001
#endif
#ifndef WAVE_FORMAT_ADPCM // Microsoft Adaptive Differental PCM
// Replicate the Microsoft ADPCM type definitions from mmreg.h.
typedef struct adpcmcoef_tag
{
short iCoef1;
short iCoef2;
} ADPCMCOEFSET;
#pragma warning(push)
#pragma warning(disable:4200) // Disable zero-sized array warnings
typedef struct adpcmwaveformat_tag {
WAVEFORMATEX wfx;
WORD wSamplesPerBlock;
WORD wNumCoef;
ADPCMCOEFSET aCoef[]; // Always 7 coefficient pairs for MS ADPCM
} ADPCMWAVEFORMAT;
#pragma warning(pop)
#define WAVE_FORMAT_ADPCM 0x0002
#endif
// Other frequently used format tags
#ifndef WAVE_FORMAT_UNKNOWN
#define WAVE_FORMAT_UNKNOWN 0x0000 // Unknown or invalid format tag
#endif
#ifndef WAVE_FORMAT_IEEE_FLOAT
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 // 32-bit floating-point
#endif
#ifndef WAVE_FORMAT_MPEGLAYER3
#define WAVE_FORMAT_MPEGLAYER3 0x0055 // ISO/MPEG Layer3
#endif
#ifndef WAVE_FORMAT_DOLBY_AC3_SPDIF
#define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 // Dolby Audio Codec 3 over S/PDIF
#endif
#ifndef WAVE_FORMAT_WMAUDIO2
#define WAVE_FORMAT_WMAUDIO2 0x0161 // Windows Media Audio
#endif
#ifndef WAVE_FORMAT_WMAUDIO3
#define WAVE_FORMAT_WMAUDIO3 0x0162 // Windows Media Audio Pro
#endif
#ifndef WAVE_FORMAT_WMASPDIF
#define WAVE_FORMAT_WMASPDIF 0x0164 // Windows Media Audio over S/PDIF
#endif
#ifndef WAVE_FORMAT_EXTENSIBLE
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE // All WAVEFORMATEXTENSIBLE formats
#endif
/**************************************************************************
*
* Define the most common wave format GUIDs used in WAVEFORMATEXTENSIBLE
* formats. Note that including the Windows ksmedia.h header after this
* one will cause build problems; this cannot be avoided, since ksmedia.h
* defines these macros without preprocessor guards.
*
***************************************************************************/
#ifdef __cplusplus // uuid() and __uuidof() are only available in C++
#ifndef KSDATAFORMAT_SUBTYPE_PCM
struct __declspec(uuid("00000001-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_PCM_STRUCT;
#define KSDATAFORMAT_SUBTYPE_PCM __uuidof(KSDATAFORMAT_SUBTYPE_PCM_STRUCT)
#endif
#ifndef KSDATAFORMAT_SUBTYPE_ADPCM
struct __declspec(uuid("00000002-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_ADPCM_STRUCT;
#define KSDATAFORMAT_SUBTYPE_ADPCM __uuidof(KSDATAFORMAT_SUBTYPE_ADPCM_STRUCT)
#endif
#ifndef KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
struct __declspec(uuid("00000003-0000-0010-8000-00aa00389b71")) KSDATAFORMAT_SUBTYPE_IEEE_FLOAT_STRUCT;
#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT __uuidof(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT_STRUCT)
#endif
#endif
/**************************************************************************
*
* Speaker positions used in the WAVEFORMATEXTENSIBLE dwChannelMask field.
*
***************************************************************************/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x00000001
#define SPEAKER_FRONT_RIGHT 0x00000002
#define SPEAKER_FRONT_CENTER 0x00000004
#define SPEAKER_LOW_FREQUENCY 0x00000008
#define SPEAKER_BACK_LEFT 0x00000010
#define SPEAKER_BACK_RIGHT 0x00000020
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080
#define SPEAKER_BACK_CENTER 0x00000100
#define SPEAKER_SIDE_LEFT 0x00000200
#define SPEAKER_SIDE_RIGHT 0x00000400
#define SPEAKER_TOP_CENTER 0x00000800
#define SPEAKER_TOP_FRONT_LEFT 0x00001000
#define SPEAKER_TOP_FRONT_CENTER 0x00002000
#define SPEAKER_TOP_FRONT_RIGHT 0x00004000
#define SPEAKER_TOP_BACK_LEFT 0x00008000
#define SPEAKER_TOP_BACK_CENTER 0x00010000
#define SPEAKER_TOP_BACK_RIGHT 0x00020000
#define SPEAKER_RESERVED 0x7FFC0000
#define SPEAKER_ALL 0x80000000
#define _SPEAKER_POSITIONS_
#endif
#ifndef SPEAKER_STEREO
#define SPEAKER_MONO (SPEAKER_FRONT_CENTER)
#define SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT)
#define SPEAKER_2POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY)
#define SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER)
#define SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
#define SPEAKER_4POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
#define SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
#define SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER)
#define SPEAKER_5POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT)
#define SPEAKER_7POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT)
#endif
#pragma pack(pop)
#endif // #ifndef __AUDIODEFS_INCLUDED__
-65
View File
@@ -1,65 +0,0 @@
// comdecl.h: Macros to facilitate COM interface and GUID declarations.
// Copyright (c) Microsoft Corporation. All rights reserved.
#ifndef _COMDECL_H_
#define _COMDECL_H_
#ifndef _XBOX
#include <basetyps.h> // For standard COM interface macros
#else
#pragma warning(push)
#pragma warning(disable:4061)
#include <xtl.h> // Required by xobjbase.h
#include <xobjbase.h> // Special definitions for Xbox build
#pragma warning(pop)
#endif
// The DEFINE_CLSID() and DEFINE_IID() macros defined below allow COM GUIDs to
// be declared and defined in such a way that clients can obtain the GUIDs using
// either the __uuidof() extension or the old-style CLSID_Foo / IID_IFoo names.
// If using the latter approach, the client can also choose whether to get the
// GUID definitions by defining the INITGUID preprocessor constant or by linking
// to a GUID library. This works in either C or C++.
#ifndef _MSC_VER
#define DEFINE_UUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) __CRT_UUID_DECL(name, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
#define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) class className; DEFINE_UUID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
#define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) struct interfaceName; DEFINE_UUID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
#elif __cplusplus
#define DECLSPEC_UUID_WRAPPER(x) __declspec(uuid(#x))
#ifdef INITGUID
#define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
class DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) className; \
EXTERN_C const GUID DECLSPEC_SELECTANY CLSID_##className = __uuidof(className)
#define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
interface DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) interfaceName; \
EXTERN_C const GUID DECLSPEC_SELECTANY IID_##interfaceName = __uuidof(interfaceName)
#else // INITGUID
#define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
class DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) className; \
EXTERN_C const GUID CLSID_##className
#define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
interface DECLSPEC_UUID_WRAPPER(l##-##w1##-##w2##-##b1##b2##-##b3##b4##b5##b6##b7##b8) interfaceName; \
EXTERN_C const GUID IID_##interfaceName
#endif // INITGUID
#else // __cplusplus
#define DEFINE_CLSID(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
DEFINE_GUID(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
#define DEFINE_IID(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
DEFINE_GUID(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
#endif // __cplusplus
#endif // #ifndef _COMDECL_H_
-18
View File
@@ -1,18 +0,0 @@
/*==========================================================================;
*
*
* File: dxsdkver.h
* Content: DirectX SDK Version Include File
*
****************************************************************************/
#ifndef _DXSDKVER_H_
#define _DXSDKVER_H_
#define _DXSDK_PRODUCT_MAJOR 9
#define _DXSDK_PRODUCT_MINOR 29
#define _DXSDK_BUILD_MAJOR 1962
#define _DXSDK_BUILD_MINOR 0
#endif // _DXSDKVER_H_
-718
View File
@@ -1,718 +0,0 @@
/***************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* File: xma2defs.h
* Content: Constants, data types and functions for XMA2 compressed audio.
*
***************************************************************************/
#ifndef __XMA2DEFS_INCLUDED__
#define __XMA2DEFS_INCLUDED__
#include <sal.h> // Markers for documenting API semantics
#include <winerror.h> // For S_OK, E_FAIL
#include <audiodefs.h> // Basic data types and constants for audio work
/***************************************************************************
* Overview
***************************************************************************/
// A typical XMA2 file contains these RIFF chunks:
//
// 'fmt' or 'XMA2' chunk (or both): A description of the XMA data's structure
// and characteristics (length, channels, sample rate, loops, block size, etc).
//
// 'seek' chunk: A seek table to help navigate the XMA data.
//
// 'data' chunk: The encoded XMA2 data.
//
// The encoded XMA2 data is structured as a set of BLOCKS, which contain PACKETS,
// which contain FRAMES, which contain SUBFRAMES (roughly speaking). The frames
// in a file may also be divided into several subsets, called STREAMS.
//
// FRAME: A variable-sized segment of XMA data that decodes to exactly 512 mono
// or stereo PCM samples. This is the smallest unit of XMA data that can
// be decoded in isolation. Frames are an arbitrary number of bits in
// length, and need not be byte-aligned. See "XMA frame structure" below.
//
// SUBFRAME: A region of bits in an XMA frame that decodes to 128 mono or stereo
// samples. The XMA decoder cannot decode a subframe in isolation; it needs
// a whole frame to work with. However, it can begin emitting the frame's
// decoded samples at any one of the four subframe boundaries. Subframes
// can be addressed for seeking and looping purposes.
//
// PACKET: A 2Kb region containing a 32-bit header and some XMA frames. Frames
// can (and usually do) span packets. A packet's header includes the offset
// in bits of the first frame that begins within that packet. All of the
// frames that begin in a given packet belong to the same "stream" (see the
// Multichannel Audio section below).
//
// STREAM: A set of packets within an XMA file that all contain data for the
// same mono or stereo component of a PCM file with more than two channels.
// The packets comprising a given stream may be interleaved with each other
// more or less arbitrarily; see Multichannel Audio.
//
// BLOCK: An array of XMA packets; or, to break it down differently, a series of
// consecutive XMA frames, padded at the end with reserved data. A block
// must contain at least one 2Kb packet per stream, and it can hold up to
// 4095 packets (8190Kb), but its size is typically in the 32Kb-128Kb range.
// (The size chosen involves a trade-off between memory use and efficiency
// of reading from permanent storage.)
//
// XMA frames do not span blocks, so a block is guaranteed to begin with a
// set of complete frames, one per stream. Also, a block in a multi-stream
// XMA2 file always contains the same number of samples for each stream;
// see Multichannel Audio.
//
// The 'data' chunk in an XMA2 file is an array of XMA2WAVEFORMAT.BlockCount XMA
// blocks, all the same size (as specified in XMA2WAVEFORMAT.BlockSizeInBytes)
// except for the last one, which may be shorter.
// MULTICHANNEL AUDIO: the XMA decoder can only decode raw XMA data into either
// mono or stereo PCM data. In order to encode a 6-channel file (say), the file
// must be deinterleaved into 3 stereo streams that are encoded independently,
// producing 3 encoded XMA data streams. Then the packets in these 3 streams
// are interleaved to produce a single XMA2 file, and some information is added
// to the file so that the original 6-channel audio can be reconstructed at
// decode time. This works using the concept of an XMA stream (see above).
//
// The frames for all the streams in an XMA file are interleaved in an arbitrary
// order. To locate a frame that belongs to a given stream in a given XMA block,
// you must examine the first few packets in the block. Here (and only here) the
// packets are guaranteed to be presented in stream order, so that all frames
// beginning in packet 0 belong to stream 0 (the first stereo pair), etc.
//
// (This means that when decoding multi-stream XMA files, only entire XMA blocks
// should be submitted to the decoder; otherwise it cannot know which frames
// belong to which stream.)
//
// Once you have one frame that belongs to a given stream, you can find the next
// one by looking at the frame's 'NextFrameOffsetBits' value (which is stored in
// its first 15 bits; see XMAFRAME below). The GetXmaFrameBitPosition function
// uses this technique.
// SEEKING IN XMA2 FILES: Here is some pseudocode to find the byte position and
// subframe in an XMA2 file which will contain sample S when decoded.
//
// 1. Traverse the seek table to find the XMA2 block containing sample S. The
// seek table is an array of big-endian DWORDs, one per block in the file.
// The Nth DWORD is the total number of PCM samples that would be obtained
// by decoding the entire XMA file up to the end of block N. Hence, the
// block we want is the first one whose seek table entry is greater than S.
// (See the GetXmaBlockContainingSample helper function.)
//
// 2. Calculate which frame F within the block found above contains sample S.
// Since each frame decodes to 512 samples, this is straightforward. The
// first frame in the block produces samples X to X + 512, where X is the
// seek table entry for the prior block. So F is (S - X) / 512.
//
// 3. Find the bit offset within the block where frame F starts. Since frames
// are variable-sized, this can only be done by traversing all the frames in
// the block until we reach frame F. (See GetXmaFrameBitPosition.)
//
// 4. Frame F has four 128-sample subframes. To find the subframe containing S,
// we can use the formula (S % 512) / 128.
//
// In the case of multi-stream XMA files, sample S is a multichannel sample with
// parts coming from several frames, one per stream. To find all these frames,
// steps 2-4 need to be repeated for each stream N, using the knowledge that the
// first packets in a block are presented in stream order. The frame traversal
// in step 3 must be started at the first frame in the Nth packet of the block,
// which will be the first frame for stream N. (And the packet header will tell
// you the first frame's start position within the packet.)
//
// Step 1 can be performed using the GetXmaBlockContainingSample function below,
// and steps 2-4 by calling GetXmaDecodePositionForSample once for each stream.
/***************************************************************************
* XMA constants
***************************************************************************/
// Size of the PCM samples produced by the XMA decoder
#define XMA_OUTPUT_SAMPLE_BYTES 2u
#define XMA_OUTPUT_SAMPLE_BITS (XMA_OUTPUT_SAMPLE_BYTES * 8u)
// Size of an XMA packet
#define XMA_BYTES_PER_PACKET 2048u
#define XMA_BITS_PER_PACKET (XMA_BYTES_PER_PACKET * 8u)
// Size of an XMA packet header
#define XMA_PACKET_HEADER_BYTES 4u
#define XMA_PACKET_HEADER_BITS (XMA_PACKET_HEADER_BYTES * 8u)
// Sample blocks in a decoded XMA frame
#define XMA_SAMPLES_PER_FRAME 512u
// Sample blocks in a decoded XMA subframe
#define XMA_SAMPLES_PER_SUBFRAME 128u
// Maximum encoded data that can be submitted to the XMA decoder at a time
#define XMA_READBUFFER_MAX_PACKETS 4095u
#define XMA_READBUFFER_MAX_BYTES (XMA_READBUFFER_MAX_PACKETS * XMA_BYTES_PER_PACKET)
// Maximum size allowed for the XMA decoder's output buffers
#define XMA_WRITEBUFFER_MAX_BYTES (31u * 256u)
// Required byte alignment of the XMA decoder's output buffers
#define XMA_WRITEBUFFER_BYTE_ALIGNMENT 256u
// Decode chunk sizes for the XMA_PLAYBACK_INIT.subframesToDecode field
#define XMA_MIN_SUBFRAMES_TO_DECODE 1u
#define XMA_MAX_SUBFRAMES_TO_DECODE 8u
#define XMA_OPTIMAL_SUBFRAMES_TO_DECODE 4u
// LoopCount<255 means finite repetitions; LoopCount=255 means infinite looping
#define XMA_MAX_LOOPCOUNT 254u
#define XMA_INFINITE_LOOP 255u
/***************************************************************************
* XMA format structures
***************************************************************************/
// The currently recommended way to express format information for XMA2 files
// is the XMA2WAVEFORMATEX structure. This structure is fully compliant with
// the WAVEFORMATEX standard and contains all the information needed to parse
// and manage XMA2 files in a compact way.
#define WAVE_FORMAT_XMA2 0x166
typedef struct XMA2WAVEFORMATEX
{
WAVEFORMATEX wfx;
// Meaning of the WAVEFORMATEX fields here:
// wFormatTag; // Audio format type; always WAVE_FORMAT_XMA2
// nChannels; // Channel count of the decoded audio
// nSamplesPerSec; // Sample rate of the decoded audio
// nAvgBytesPerSec; // Used internally by the XMA encoder
// nBlockAlign; // Decoded sample size; channels * wBitsPerSample / 8
// wBitsPerSample; // Bits per decoded mono sample; always 16 for XMA
// cbSize; // Size in bytes of the rest of this structure (34)
WORD NumStreams; // Number of audio streams (1 or 2 channels each)
DWORD ChannelMask; // Spatial positions of the channels in this file,
// stored as SPEAKER_xxx values (see audiodefs.h)
DWORD SamplesEncoded; // Total number of PCM samples the file decodes to
DWORD BytesPerBlock; // XMA block size (but the last one may be shorter)
DWORD PlayBegin; // First valid sample in the decoded audio
DWORD PlayLength; // Length of the valid part of the decoded audio
DWORD LoopBegin; // Beginning of the loop region in decoded sample terms
DWORD LoopLength; // Length of the loop region in decoded sample terms
BYTE LoopCount; // Number of loop repetitions; 255 = infinite
BYTE EncoderVersion; // Version of XMA encoder that generated the file
WORD BlockCount; // XMA blocks in file (and entries in its seek table)
} XMA2WAVEFORMATEX, *PXMA2WAVEFORMATEX;
// The legacy XMA format structures are described here for reference, but they
// should not be used in new content. XMAWAVEFORMAT was the structure used in
// XMA version 1 files. XMA2WAVEFORMAT was used in early XMA2 files; it is not
// placed in the usual 'fmt' RIFF chunk but in its own 'XMA2' chunk.
#ifndef WAVE_FORMAT_XMA
#define WAVE_FORMAT_XMA 0x0165
// Values used in the ChannelMask fields below. Similar to the SPEAKER_xxx
// values defined in audiodefs.h, but modified to fit in a single byte.
#ifndef XMA_SPEAKER_LEFT
#define XMA_SPEAKER_LEFT 0x01
#define XMA_SPEAKER_RIGHT 0x02
#define XMA_SPEAKER_CENTER 0x04
#define XMA_SPEAKER_LFE 0x08
#define XMA_SPEAKER_LEFT_SURROUND 0x10
#define XMA_SPEAKER_RIGHT_SURROUND 0x20
#define XMA_SPEAKER_LEFT_BACK 0x40
#define XMA_SPEAKER_RIGHT_BACK 0x80
#endif
// Used in XMAWAVEFORMAT for per-stream data
typedef struct XMASTREAMFORMAT
{
DWORD PsuedoBytesPerSec; // Used by the XMA encoder (typo preserved for legacy reasons)
DWORD SampleRate; // The stream's decoded sample rate (in XMA2 files,
// this is the same for all streams in the file).
DWORD LoopStart; // Bit offset of the frame containing the loop start
// point, relative to the beginning of the stream.
DWORD LoopEnd; // Bit offset of the frame containing the loop end.
BYTE SubframeData; // Two 4-bit numbers specifying the exact location of
// the loop points within the frames that contain them.
// SubframeEnd: Subframe of the loop end frame where
// the loop ends. Ranges from 0 to 3.
// SubframeSkip: Subframes to skip in the start frame to
// reach the loop. Ranges from 0 to 4.
BYTE Channels; // Number of channels in the stream (1 or 2)
WORD ChannelMask; // Spatial positions of the channels in the stream
} XMASTREAMFORMAT;
// Legacy XMA1 format structure
typedef struct XMAWAVEFORMAT
{
WORD FormatTag; // Audio format type (always WAVE_FORMAT_XMA)
WORD BitsPerSample; // Bit depth (currently required to be 16)
WORD EncodeOptions; // Options for XMA encoder/decoder
WORD LargestSkip; // Largest skip used in interleaving streams
WORD NumStreams; // Number of interleaved audio streams
BYTE LoopCount; // Number of loop repetitions; 255 = infinite
BYTE Version; // XMA encoder version that generated the file.
// Always 3 or higher for XMA2 files.
XMASTREAMFORMAT XmaStreams[1]; // Per-stream format information; the actual
// array length is in the NumStreams field.
} XMAWAVEFORMAT;
// Used in XMA2WAVEFORMAT for per-stream data
typedef struct XMA2STREAMFORMAT
{
BYTE Channels; // Number of channels in the stream (1 or 2)
BYTE RESERVED; // Reserved for future use
WORD ChannelMask; // Spatial positions of the channels in the stream
} XMA2STREAMFORMAT;
// Legacy XMA2 format structure (big-endian byte ordering)
typedef struct XMA2WAVEFORMAT
{
BYTE Version; // XMA encoder version that generated the file.
// Always 3 or higher for XMA2 files.
BYTE NumStreams; // Number of interleaved audio streams
BYTE RESERVED; // Reserved for future use
BYTE LoopCount; // Number of loop repetitions; 255 = infinite
DWORD LoopBegin; // Loop begin point, in samples
DWORD LoopEnd; // Loop end point, in samples
DWORD SampleRate; // The file's decoded sample rate
DWORD EncodeOptions; // Options for the XMA encoder/decoder
DWORD PsuedoBytesPerSec; // Used internally by the XMA encoder
DWORD BlockSizeInBytes; // Size in bytes of this file's XMA blocks (except
// possibly the last one). Always a multiple of
// 2Kb, since XMA blocks are arrays of 2Kb packets.
DWORD SamplesEncoded; // Total number of PCM samples encoded in this file
DWORD SamplesInSource; // Actual number of PCM samples in the source
// material used to generate this file
DWORD BlockCount; // Number of XMA blocks in this file (and hence
// also the number of entries in its seek table)
XMA2STREAMFORMAT Streams[1]; // Per-stream format information; the actual
// array length is in the NumStreams field.
} XMA2WAVEFORMAT;
#endif // #ifndef WAVE_FORMAT_XMA
/***************************************************************************
* XMA packet structure (in big-endian form)
***************************************************************************/
typedef struct XMA2PACKET
{
int FrameCount : 6; // Number of XMA frames that begin in this packet
int FrameOffsetInBits : 15; // Bit of XmaData where the first complete frame begins
int PacketMetaData : 3; // Metadata stored in the packet (always 1 for XMA2)
int PacketSkipCount : 8; // How many packets belonging to other streams must be
// skipped to find the next packet belonging to this one
BYTE XmaData[XMA_BYTES_PER_PACKET - sizeof(DWORD)]; // XMA encoded data
} XMA2PACKET;
// E.g. if the first DWORD of a packet is 0x30107902:
//
// 001100 000001000001111 001 00000010
// | | | |____ Skip 2 packets to find the next one for this stream
// | | |___________ XMA2 signature (always 001)
// | |_____________________ First frame starts 527 bits into packet
// |________________________________ Packet contains 12 frames
// Helper functions to extract the fields above from an XMA packet. (Note that
// the bitfields cannot be read directly on little-endian architectures such as
// the Intel x86, as they are laid out in big-endian form.)
__inline DWORD GetXmaPacketFrameCount(__in_bcount(1) const BYTE* pPacket)
{
return (DWORD)(pPacket[0] >> 2);
}
__inline DWORD GetXmaPacketFirstFrameOffsetInBits(__in_bcount(3) const BYTE* pPacket)
{
return ((DWORD)(pPacket[0] & 0x3) << 13) |
((DWORD)(pPacket[1]) << 5) |
((DWORD)(pPacket[2]) >> 3);
}
__inline DWORD GetXmaPacketMetadata(__in_bcount(3) const BYTE* pPacket)
{
return (DWORD)(pPacket[2] & 0x7);
}
__inline DWORD GetXmaPacketSkipCount(__in_bcount(4) const BYTE* pPacket)
{
return (DWORD)(pPacket[3]);
}
/***************************************************************************
* XMA frame structure
***************************************************************************/
// There is no way to represent the XMA frame as a C struct, since it is a
// variable-sized string of bits that need not be stored at a byte-aligned
// position in memory. This is the layout:
//
// XMAFRAME
// {
// LengthInBits: A 15-bit number representing the length of this frame.
// XmaData: Encoded XMA data; its size in bits is (LengthInBits - 15).
// }
// Size in bits of the frame's initial LengthInBits field
#define XMA_BITS_IN_FRAME_LENGTH_FIELD 15
// Special LengthInBits value that marks an invalid final frame
#define XMA_FINAL_FRAME_MARKER 0x7FFF
/***************************************************************************
* XMA helper functions
***************************************************************************/
// We define a local ASSERT macro to equal the global one if it exists.
// You can define XMA2DEFS_ASSERT in advance to override this default.
#ifndef XMA2DEFS_ASSERT
#ifdef ASSERT
#define XMA2DEFS_ASSERT ASSERT
#else
#define XMA2DEFS_ASSERT(a) /* No-op by default */
#endif
#endif
// GetXmaBlockContainingSample: Use a given seek table to find the XMA block
// containing a given decoded sample. Note that the seek table entries in an
// XMA file are stored in big-endian form and may need to be converted prior
// to calling this function.
__inline HRESULT GetXmaBlockContainingSample
(
DWORD nBlockCount, // Blocks in the file (= seek table entries)
__in_ecount(nBlockCount) const DWORD* pSeekTable, // Pointer to the seek table data
DWORD nDesiredSample, // Decoded sample to locate
__out DWORD* pnBlockContainingSample, // Index of the block containing the sample
__out DWORD* pnSampleOffsetWithinBlock // Position of the sample in this block
)
{
DWORD nPreviousTotalSamples = 0;
DWORD nBlock;
DWORD nTotalSamplesSoFar;
XMA2DEFS_ASSERT(pSeekTable);
XMA2DEFS_ASSERT(pnBlockContainingSample);
XMA2DEFS_ASSERT(pnSampleOffsetWithinBlock);
for (nBlock = 0; nBlock < nBlockCount; ++nBlock)
{
nTotalSamplesSoFar = pSeekTable[nBlock];
if (nTotalSamplesSoFar > nDesiredSample)
{
*pnBlockContainingSample = nBlock;
*pnSampleOffsetWithinBlock = nDesiredSample - nPreviousTotalSamples;
return S_OK;
}
nPreviousTotalSamples = nTotalSamplesSoFar;
}
return E_FAIL;
}
// GetXmaFrameLengthInBits: Reads a given frame's LengthInBits field.
__inline DWORD GetXmaFrameLengthInBits
(
__in_bcount(nBitPosition / 8 + 3)
__in const BYTE* pPacket, // Pointer to XMA packet[s] containing the frame
DWORD nBitPosition // Bit offset of the frame within this packet
)
{
DWORD nRegion;
DWORD nBytePosition = nBitPosition / 8;
DWORD nBitOffset = nBitPosition % 8;
if (nBitOffset < 2) // Only need to read 2 bytes (and might not be safe to read more)
{
nRegion = (DWORD)(pPacket[nBytePosition+0]) << 8 |
(DWORD)(pPacket[nBytePosition+1]);
return (nRegion >> (1 - nBitOffset)) & 0x7FFF; // Last 15 bits
}
else // Need to read 3 bytes
{
nRegion = (DWORD)(pPacket[nBytePosition+0]) << 16 |
(DWORD)(pPacket[nBytePosition+1]) << 8 |
(DWORD)(pPacket[nBytePosition+2]);
return (nRegion >> (9 - nBitOffset)) & 0x7FFF; // Last 15 bits
}
}
// GetXmaFrameBitPosition: Calculates the bit offset of a given frame within
// an XMA block or set of blocks. Returns 0 on failure.
__inline DWORD GetXmaFrameBitPosition
(
__in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s]
DWORD nXmaDataBytes, // Size of pXmaData in bytes
DWORD nStreamIndex, // Stream within which to seek
DWORD nDesiredFrame // Frame sought
)
{
const BYTE* pCurrentPacket;
DWORD nPacketsExamined = 0;
DWORD nFrameCountSoFar = 0;
DWORD nFramesToSkip;
DWORD nFrameBitOffset;
XMA2DEFS_ASSERT(pXmaData);
XMA2DEFS_ASSERT(nXmaDataBytes % XMA_BYTES_PER_PACKET == 0);
// Get the first XMA packet belonging to the desired stream, relying on the
// fact that the first packets for each stream are in consecutive order at
// the beginning of an XMA block.
pCurrentPacket = pXmaData + nStreamIndex * XMA_BYTES_PER_PACKET;
for (;;)
{
// If we have exceeded the size of the XMA data, return failure
if (pCurrentPacket + XMA_BYTES_PER_PACKET > pXmaData + nXmaDataBytes)
{
return 0;
}
// If the current packet contains the frame we are looking for...
if (nFrameCountSoFar + GetXmaPacketFrameCount(pCurrentPacket) > nDesiredFrame)
{
// See how many frames in this packet we need to skip to get to it
XMA2DEFS_ASSERT(nDesiredFrame >= nFrameCountSoFar);
nFramesToSkip = nDesiredFrame - nFrameCountSoFar;
// Get the bit offset of the first frame in this packet
nFrameBitOffset = XMA_PACKET_HEADER_BITS + GetXmaPacketFirstFrameOffsetInBits(pCurrentPacket);
// Advance nFrameBitOffset to the frame of interest
while (nFramesToSkip--)
{
nFrameBitOffset += GetXmaFrameLengthInBits(pCurrentPacket, nFrameBitOffset);
}
// The bit offset to return is the number of bits from pXmaData to
// pCurrentPacket plus the bit offset of the frame of interest
return (DWORD)(pCurrentPacket - pXmaData) * 8 + nFrameBitOffset;
}
// If we haven't found the right packet yet, advance our counters
++nPacketsExamined;
nFrameCountSoFar += GetXmaPacketFrameCount(pCurrentPacket);
// And skip to the next packet belonging to the same stream
pCurrentPacket += XMA_BYTES_PER_PACKET * (GetXmaPacketSkipCount(pCurrentPacket) + 1);
}
}
// GetLastXmaFrameBitPosition: Calculates the bit offset of the last complete
// frame in an XMA block or set of blocks.
__inline DWORD GetLastXmaFrameBitPosition
(
__in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s]
DWORD nXmaDataBytes, // Size of pXmaData in bytes
DWORD nStreamIndex // Stream within which to seek
)
{
const BYTE* pLastPacket;
DWORD nBytesToNextPacket;
DWORD nFrameBitOffset;
DWORD nFramesInLastPacket;
XMA2DEFS_ASSERT(pXmaData);
XMA2DEFS_ASSERT(nXmaDataBytes % XMA_BYTES_PER_PACKET == 0);
XMA2DEFS_ASSERT(nXmaDataBytes >= XMA_BYTES_PER_PACKET * (nStreamIndex + 1));
// Get the first XMA packet belonging to the desired stream, relying on the
// fact that the first packets for each stream are in consecutive order at
// the beginning of an XMA block.
pLastPacket = pXmaData + nStreamIndex * XMA_BYTES_PER_PACKET;
// Search for the last packet belonging to the desired stream
for (;;)
{
nBytesToNextPacket = XMA_BYTES_PER_PACKET * (GetXmaPacketSkipCount(pLastPacket) + 1);
XMA2DEFS_ASSERT(nBytesToNextPacket);
if (pLastPacket + nBytesToNextPacket + XMA_BYTES_PER_PACKET > pXmaData + nXmaDataBytes)
{
break; // The next packet would extend beyond the end of pXmaData
}
pLastPacket += nBytesToNextPacket;
}
// The last packet can sometimes have no seekable frames, in which case we
// have to use the previous one
if (GetXmaPacketFrameCount(pLastPacket) == 0)
{
pLastPacket -= nBytesToNextPacket;
}
// Found the last packet. Get the bit offset of its first frame.
nFrameBitOffset = XMA_PACKET_HEADER_BITS + GetXmaPacketFirstFrameOffsetInBits(pLastPacket);
// Traverse frames until we reach the last one
nFramesInLastPacket = GetXmaPacketFrameCount(pLastPacket);
while (--nFramesInLastPacket)
{
nFrameBitOffset += GetXmaFrameLengthInBits(pLastPacket, nFrameBitOffset);
}
// The bit offset to return is the number of bits from pXmaData to
// pLastPacket plus the offset of the last frame in this packet.
return (DWORD)(pLastPacket - pXmaData) * 8 + nFrameBitOffset;
}
// GetXmaDecodePositionForSample: Obtains the information needed to make the
// decoder generate audio starting at a given sample position relative to the
// beginning of the given XMA block: the bit offset of the appropriate frame,
// and the right subframe within that frame. This data can be passed directly
// to the XMAPlaybackSetDecodePosition function.
__inline HRESULT GetXmaDecodePositionForSample
(
__in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s]
DWORD nXmaDataBytes, // Size of pXmaData in bytes
DWORD nStreamIndex, // Stream within which to seek
DWORD nDesiredSample, // Sample sought
__out DWORD* pnBitOffset, // Returns the bit offset within pXmaData of
// the frame containing the sample sought
__out DWORD* pnSubFrame // Returns the subframe containing the sample
)
{
DWORD nDesiredFrame = nDesiredSample / XMA_SAMPLES_PER_FRAME;
DWORD nSubFrame = (nDesiredSample % XMA_SAMPLES_PER_FRAME) / XMA_SAMPLES_PER_SUBFRAME;
DWORD nBitOffset = GetXmaFrameBitPosition(pXmaData, nXmaDataBytes, nStreamIndex, nDesiredFrame);
XMA2DEFS_ASSERT(pnBitOffset);
XMA2DEFS_ASSERT(pnSubFrame);
if (nBitOffset)
{
*pnBitOffset = nBitOffset;
*pnSubFrame = nSubFrame;
return S_OK;
}
else
{
return E_FAIL;
}
}
// GetXmaSampleRate: Obtains the legal XMA sample rate (24, 32, 44.1 or 48Khz)
// corresponding to a generic sample rate.
__inline DWORD GetXmaSampleRate(DWORD dwGeneralRate)
{
DWORD dwXmaRate = 48000; // Default XMA rate for all rates above 44100Hz
if (dwGeneralRate <= 24000) dwXmaRate = 24000;
else if (dwGeneralRate <= 32000) dwXmaRate = 32000;
else if (dwGeneralRate <= 44100) dwXmaRate = 44100;
return dwXmaRate;
}
// Functions to convert between WAVEFORMATEXTENSIBLE channel masks (combinations
// of the SPEAKER_xxx flags defined in audiodefs.h) and XMA channel masks (which
// are limited to eight possible speaker positions: left, right, center, low
// frequency, side left, side right, back left and back right).
__inline DWORD GetStandardChannelMaskFromXmaMask(BYTE bXmaMask)
{
DWORD dwStandardMask = 0;
if (bXmaMask & XMA_SPEAKER_LEFT) dwStandardMask |= SPEAKER_FRONT_LEFT;
if (bXmaMask & XMA_SPEAKER_RIGHT) dwStandardMask |= SPEAKER_FRONT_RIGHT;
if (bXmaMask & XMA_SPEAKER_CENTER) dwStandardMask |= SPEAKER_FRONT_CENTER;
if (bXmaMask & XMA_SPEAKER_LFE) dwStandardMask |= SPEAKER_LOW_FREQUENCY;
if (bXmaMask & XMA_SPEAKER_LEFT_SURROUND) dwStandardMask |= SPEAKER_SIDE_LEFT;
if (bXmaMask & XMA_SPEAKER_RIGHT_SURROUND) dwStandardMask |= SPEAKER_SIDE_RIGHT;
if (bXmaMask & XMA_SPEAKER_LEFT_BACK) dwStandardMask |= SPEAKER_BACK_LEFT;
if (bXmaMask & XMA_SPEAKER_RIGHT_BACK) dwStandardMask |= SPEAKER_BACK_RIGHT;
return dwStandardMask;
}
__inline BYTE GetXmaChannelMaskFromStandardMask(DWORD dwStandardMask)
{
BYTE bXmaMask = 0;
if (dwStandardMask & SPEAKER_FRONT_LEFT) bXmaMask |= XMA_SPEAKER_LEFT;
if (dwStandardMask & SPEAKER_FRONT_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT;
if (dwStandardMask & SPEAKER_FRONT_CENTER) bXmaMask |= XMA_SPEAKER_CENTER;
if (dwStandardMask & SPEAKER_LOW_FREQUENCY) bXmaMask |= XMA_SPEAKER_LFE;
if (dwStandardMask & SPEAKER_SIDE_LEFT) bXmaMask |= XMA_SPEAKER_LEFT_SURROUND;
if (dwStandardMask & SPEAKER_SIDE_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT_SURROUND;
if (dwStandardMask & SPEAKER_BACK_LEFT) bXmaMask |= XMA_SPEAKER_LEFT_BACK;
if (dwStandardMask & SPEAKER_BACK_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT_BACK;
return bXmaMask;
}
// LocalizeXma2Format: Modifies a XMA2WAVEFORMATEX structure in place to comply
// with the current platform's byte-ordering rules (little- or big-endian).
__inline HRESULT LocalizeXma2Format(__inout XMA2WAVEFORMATEX* pXma2Format)
{
#define XMASWAP2BYTES(n) ((WORD)(((n) >> 8) | (((n) & 0xff) << 8)))
#define XMASWAP4BYTES(n) ((DWORD)((n) >> 24 | (n) << 24 | ((n) & 0xff00) << 8 | ((n) & 0xff0000) >> 8))
if (pXma2Format->wfx.wFormatTag == WAVE_FORMAT_XMA2)
{
return S_OK;
}
else if (XMASWAP2BYTES(pXma2Format->wfx.wFormatTag) == WAVE_FORMAT_XMA2)
{
pXma2Format->wfx.wFormatTag = XMASWAP2BYTES(pXma2Format->wfx.wFormatTag);
pXma2Format->wfx.nChannels = XMASWAP2BYTES(pXma2Format->wfx.nChannels);
pXma2Format->wfx.nSamplesPerSec = XMASWAP4BYTES(pXma2Format->wfx.nSamplesPerSec);
pXma2Format->wfx.nAvgBytesPerSec = XMASWAP4BYTES(pXma2Format->wfx.nAvgBytesPerSec);
pXma2Format->wfx.nBlockAlign = XMASWAP2BYTES(pXma2Format->wfx.nBlockAlign);
pXma2Format->wfx.wBitsPerSample = XMASWAP2BYTES(pXma2Format->wfx.wBitsPerSample);
pXma2Format->wfx.cbSize = XMASWAP2BYTES(pXma2Format->wfx.cbSize);
pXma2Format->NumStreams = XMASWAP2BYTES(pXma2Format->NumStreams);
pXma2Format->ChannelMask = XMASWAP4BYTES(pXma2Format->ChannelMask);
pXma2Format->SamplesEncoded = XMASWAP4BYTES(pXma2Format->SamplesEncoded);
pXma2Format->BytesPerBlock = XMASWAP4BYTES(pXma2Format->BytesPerBlock);
pXma2Format->PlayBegin = XMASWAP4BYTES(pXma2Format->PlayBegin);
pXma2Format->PlayLength = XMASWAP4BYTES(pXma2Format->PlayLength);
pXma2Format->LoopBegin = XMASWAP4BYTES(pXma2Format->LoopBegin);
pXma2Format->LoopLength = XMASWAP4BYTES(pXma2Format->LoopLength);
pXma2Format->BlockCount = XMASWAP2BYTES(pXma2Format->BlockCount);
return S_OK;
}
else
{
return E_FAIL; // Not a recognizable XMA2 format
}
#undef XMASWAP2BYTES
#undef XMASWAP4BYTES
}
#endif // #ifndef __XMA2DEFS_INCLUDED__
+25
View File
@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 2.8.4)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/cmake/modules")
set(LIBUSB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../libusb/)
project(libusb)
option(WITH_DEBUG_LOG "enable debug logging" OFF)
# if debug logging is enabled, by default enable logging
option(WITH_LOGGING "if false, disable all logging" ON)
option(WITHOUT_PTHREADS "force pthreads to not be used. if on, then they are used based on detection logic" OFF)
set(LIBUSB_MAJOR 1)
set(LIBUSB_MINOR 0)
set(LIBUSB_MICRO 23)
macro(append_compiler_flags)
foreach(FLAG IN ITEMS ${ARGN})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAG}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")
endforeach()
endmacro()
include(libusb.cmake)
@@ -0,0 +1,17 @@
# CoreFoundation_INCLUDE_DIR
# CoreFoundation_LIBRARIES
# CoreFoundation_FOUND
include(LibFindMacros)
find_path(CoreFoundation_INCLUDE_DIR
CoreFoundation.h
PATH_SUFFIXES CoreFoundation
)
find_library(CoreFoundation_LIBRARY
NAMES CoreFoundation
)
set(CoreFoundation_PROCESS_INCLUDES CoreFoundation_INCLUDE_DIR)
set(CoreFoundation_PROCESS_LIBS CoreFoundation_LIBRARY)
libfind_process(CoreFoundation)
+20
View File
@@ -0,0 +1,20 @@
# IOKit_INCLUDE_DIR
# IOKit_LIBRARIES
# IOKit_FOUND
include(LibFindMacros)
# IOKit depends on CoreFoundation
find_package(CoreFoundation REQUIRED)
find_path(IOKit_INCLUDE_DIR
IOKitLib.h
PATH_SUFFIXES IOKit
)
find_library(IOKit_LIBRARY
NAMES IOKit
)
set(IOKit_PROCESS_INCLUDES IOKit_INCLUDE_DIR CoreFoundation_INCLUDE_DIR)
set(IOKit_PROCESS_LIBS IOKit_LIBRARY CoreFoundation_LIBRARIES)
libfind_process(IOKit)
+99
View File
@@ -0,0 +1,99 @@
# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments
# used for the current package. For this to work, the first parameter must be the
# prefix of the current package, then the prefix of the new package etc, which are
# passed to find_package.
macro (libfind_package PREFIX)
set (LIBFIND_PACKAGE_ARGS ${ARGN})
if (${PREFIX}_FIND_QUIETLY)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
endif (${PREFIX}_FIND_QUIETLY)
if (${PREFIX}_FIND_REQUIRED)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
endif (${PREFIX}_FIND_REQUIRED)
find_package(${LIBFIND_PACKAGE_ARGS})
endmacro (libfind_package)
# CMake developers made the UsePkgConfig system deprecated in the same release (2.6)
# where they added pkg_check_modules. Consequently I need to support both in my scripts
# to avoid those deprecated warnings. Here's a helper that does just that.
# Works identically to pkg_check_modules, except that no checks are needed prior to use.
macro (libfind_pkg_check_modules PREFIX PKGNAME)
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
include(UsePkgConfig)
pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(${PREFIX} ${PKGNAME})
endif (PKG_CONFIG_FOUND)
endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
endmacro (libfind_pkg_check_modules)
# Do the final processing once the paths have been detected.
# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
# all the variables, each of which contain one include directory.
# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
# Also handles errors in case library detection was required, etc.
macro (libfind_process PREFIX)
# Skip processing if already processed during this run
if (NOT ${PREFIX}_FOUND)
# Start with the assumption that the library was found
set (${PREFIX}_FOUND TRUE)
# Process all includes and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_INCLUDES})
if (${i})
set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)
# Process all libraries and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_LIBS})
if (${i})
set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)
# Print message and/or exit on fatal error
if (${PREFIX}_FOUND)
if (NOT ${PREFIX}_FIND_QUIETLY)
message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
endif (NOT ${PREFIX}_FIND_QUIETLY)
else (${PREFIX}_FOUND)
if (${PREFIX}_FIND_REQUIRED)
foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
message("${i}=${${i}}")
endforeach (i)
message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.")
endif (${PREFIX}_FIND_REQUIRED)
endif (${PREFIX}_FOUND)
endif (NOT ${PREFIX}_FOUND)
endmacro (libfind_process)
macro(libfind_library PREFIX basename)
set(TMP "")
if(MSVC80)
set(TMP -vc80)
endif(MSVC80)
if(MSVC90)
set(TMP -vc90)
endif(MSVC90)
set(${PREFIX}_LIBNAMES ${basename}${TMP})
if(${ARGC} GREATER 2)
set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
endif(${ARGC} GREATER 2)
find_library(${PREFIX}_LIBRARY
NAMES ${${PREFIX}_LIBNAMES}
PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
)
endmacro(libfind_library)
+96
View File
@@ -0,0 +1,96 @@
include(CheckCXXCompilerFlag)
include(CheckIncludeFiles)
include(CheckTypeSize)
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
if (NOT OS_WINDOWS)
# mingw appears to print a bunch of warnings about this
check_cxx_compiler_flag("-fvisibility=hidden" HAVE_VISIBILITY)
endif()
check_cxx_compiler_flag("-Wno-pointer-sign" HAVE_WARN_NO_POINTER_SIGN)
set(_GNU_SOURCE 1 CACHE INTERNAL "" FORCE)
unset(ADDITIONAL_CC_FLAGS)
if (HAVE_VISIBILITY)
list(APPEND ADDITIONAL_CC_FLAGS -fvisibility=hidden)
endif()
if (HAVE_WARN_NO_POINTER_SIGN)
list(APPEND ADDITIONAL_CC_FLAGS -Wno-pointer-sign)
endif()
append_compiler_flags(
-std=gnu99
-Wall
-Wundef
-Wunused
-Wstrict-prototypes
-Werror-implicit-function-declaration
-Wshadow
${ADDITIONAL_CC_FLAGS}
)
elseif(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
check_include_files(sys/timerfd.h USBI_TIMERFD_AVAILABLE)
#check_type_size(struct timespec STRUCT_TIMESPEC)
if (HAVE_VISIBILITY)
set(DEFAULT_VISIBILITY "__attribute__((visibility(\"default\")))" CACHE INTERNAL "visibility attribute to function decl" FORCE)
else()
set(DEFAULT_VISIBILITY "" CACHE INTERNAL "visibility attribute to function decl" FORCE)
endif()
if (NOT WITHOUT_POLL_H)
check_include_files(poll.h HAVE_POLL_H)
else()
set(HAVE_POLL_H FALSE CACHE INTERNAL "poll.h explicitely disabled" FORCE)
endif()
if (HAVE_POLL_H)
list(APPEND CMAKE_EXTRA_INCLUDE_FILES "poll.h")
check_type_size(nfds_t NFDS_T)
unset(CMAKE_EXTRA_INCLUDE_FILES)
else()
set(HAVE_NFDS_T FALSE CACHE INTERNAL "poll.h not found - assuming no nfds_t (windows)" FORCE)
set(NFDS_T "" CACHE INTERNAL "" FORCE)
endif()
if (HAVE_NFDS_T)
set(POLL_NFDS_TYPE nfds_t CACHE INTERNAL "the poll nfds types for this platform" FORCE)
else()
set(POLL_NFDS_TYPE "unsigned int" CACHE INTERNAL "the poll nfds for this platform" FORCE)
endif()
if (OS_WINDOWS)
macro(copy_header_if_missing HEADER VARIABLE ALTERNATIVE_DIR)
check_include_files(${HEADER} ${VARIABLE})
if (NOT ${VARIABLE})
message(STATUS "Missing ${HEADER} - grabbing from ${ALTERNATIVE_DIR}")
file(COPY "${ALTERNATIVE_DIR}/${HEADER}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
endif()
endmacro()
# Only VS 2010 has stdint.h
copy_header_if_missing(stdint.h HAVE_STDINT_H ../msvc)
copy_header_if_missing(inttypes.h HAVE_INTTYPES_H ../msvc)
endif()
set(ENABLE_DEBUG_LOGGING ${WITH_DEBUG_LOG} CACHE INTERNAL "enable debug logging (WITH_DEBUG_LOGGING)" FORCE)
set(ENABLE_LOGGING ${WITH_LOGGING} CACHE INTERNAL "enable logging (WITH_LOGGING)" FORCE)
set(PACKAGE "libusb" CACHE INTERNAL "The package name" FORCE)
set(PACKAGE_BUGREPORT "libusb-devel@lists.sourceforge.net" CACHE INTERNAL "Where to send bug reports" FORCE)
set(PACKAGE_VERSION "${LIBUSB_MAJOR}.${LIBUSB_MINOR}.${LIBUSB_MICRO}" CACHE INTERNAL "package version" FORCE)
set(PACKAGE_STRING "${PACKAGE} ${PACKAGE_VERSION}" CACHE INTERNAL "package string" FORCE)
set(PACKAGE_URL "http://www.libusb.org" CACHE INTERNAL "package url" FORCE)
set(PACKAGE_TARNAME "libusb" CACHE INTERNAL "tarball name" FORCE)
set(VERSION "${PACKAGE_VERSION}" CACHE INTERNAL "version" FORCE)
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY)
message(STATUS "Generated configuration file in ${CMAKE_CURRENT_BINARY_DIR}/config.h")
# for generated config.h
include_directories(${CMAKE_CURRENT_BINARY_DIR})
+37
View File
@@ -0,0 +1,37 @@
#ifndef LIBUSB_CONFIG_H
#define LIBUSB_CONFIG_H
#define DEFAULT_VISIBILITY @DEFAULT_VISIBILITY@
#cmakedefine ENABLE_DEBUG_LOGGING
#cmakedefine ENABLE_LOGGING
#define LIBUSB_MAJOR @LIBUSB_MAJOR@
#define LIBUSB_MINOR @LIBUSB_MINOR@
#define LIBUSB_MICRO @LIBUSB_MINOR@
#define _GNU_SOURCE 1
#define PACKAGE @PACKAGE@
#define PACKAGE_BUGREPORT @PACKAGE_BUGREPORT@
#define PACKAGE_STRING @PACKAGE_STRING@
#define PACKAGE_URL @PACKAGE_URL@
#define PACKAGE_VERSION @PACKAGE_VERSION@
#define PACKAGE_TARNAME @PACKAGE_TARNAME@
#define VERSION @VERSION@
#cmakedefine OS_LINUX
#cmakedefine OS_DARWIN
#cmakedefine OS_WINDOWS
#cmakedefine THREADS_POSIX
#cmakedefine USBI_TIMERFD_AVAILABLE
#cmakedefine HAVE_STRUCT_TIMESPEC
#cmakedefine HAVE_POLL_H
#cmakedefine HAVE_SYS_TIME_H
#define POLL_NFDS_TYPE @POLL_NFDS_TYPE@
#endif /* LIBUSB_CONFIG_H */
+11
View File
@@ -0,0 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_PREFIX@/lib@
includedir=@CMAKE_INSTALL_PREFIX@/include@
Name: libusb-1.0
Description: C API for USB device access from Linux, Mac OS X and Windows userspace
Version: @VERSION@
Libs: -L${libdir} -lusb-1.0
Libs.private: @LIBUSB_LIB_DEPENDS@
Cflags: -I${includedir}/libusb-1.0
+76
View File
@@ -0,0 +1,76 @@
include(os.cmake)
include(config.cmake)
include(FindThreads)
set (LIBUSB_COMMON
core.c
descriptor.c
io.c
sync.c
hotplug.c
strerror.c
libusb-1.0.rc
libusb-1.0.def
)
foreach(SRC IN LISTS LIBUSB_COMMON)
list(APPEND LIBUSB_COMMON_FINAL ${LIBUSB_SOURCE_DIR}/libusb/${SRC})
endforeach()
include_directories(${LIBUSB_SOURCE_DIR}/libusb)
include_directories(${LIBUSB_SOURCE_DIR}/libusb/os)
if (CMAKE_THREAD_LIBS_INIT)
list(APPEND LIBUSB_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif()
add_library(usb-1.0-static
STATIC
${LIBUSB_COMMON_FINAL}
${LIBUSB_PLATFORM}
)
target_include_directories(usb-1.0-static PUBLIC $<BUILD_INTERFACE:${LIBUSB_SOURCE_DIR}/libusb>)
set_target_properties(usb-1.0-static PROPERTIES
PREFIX "lib"
OUTPUT_NAME "usb-1.0"
CLEAN_DIRECT_OUTPUT 1
PUBLIC_HEADER libusb.h
VERSION "${LIBUSB_MAJOR}.${LIBUSB_MINOR}.${LIBUSB_MICRO}"
SOVERSION "${LIBUSB_MAJOR}.${LIBUSB_MINOR}.${LIBUSB_MICRO}"
)
if (DEFINED LIBUSB_LIBRARIES)
target_link_libraries(usb-1.0-static
${LIBUSB_LIBRARIES}
)
endif()
list(APPEND LIBUSB_LIBTARGETS usb-1.0-static)
install(TARGETS ${LIBUSB_LIBTARGETS} EXPORT libusb-1
PUBLIC_HEADER DESTINATION include/libusb-1.0
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION lib
)
install(EXPORT libusb-1 DESTINATION lib/libusb)
foreach(LIB IN LISTS LIBUSB_LIBRARIES)
if (LIB MATCHES .framework$)
get_filename_component(LIB "${LIB}" NAME)
set(LIB "-Wl,-framework,${LIB}")
elseif (LIB MATCHES .dylib$)
get_filename_component(LIBDIR "${LIB}" PATH)
get_filename_component(LIB "${LIB}" NAME)
string(REGEX REPLACE "lib(.*).dylib$" "\\1" LIB "${LIB}")
set(LIB "-L${LIBDIR} -l${LIB}")
endif()
set(LIBUSB_LIB_DEPENDS "${LIBUSB_LIB_DEPENDS} ${LIB}")
endforeach()
configure_file(libusb-1.0.pc.cmake "${CMAKE_CURRENT_BINARY_DIR}/libusb-1.0.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libusb-1.0.pc" DESTINATION lib/pkgconfig)
+107
View File
@@ -0,0 +1,107 @@
include(FindThreads)
set(PTHREADS_ENABLED FALSE)
if (CMAKE_USE_PTHREADS_INIT)
set(PTHREADS_ENABLED TRUE)
endif()
if (WIN32 OR "${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
set(OS_WINDOWS 1 CACHE INTERNAL "controls config.h macro definition" FORCE)
# Enable MingW support for RC language (for CMake pre-2.8)
if (MINGW)
set(CMAKE_RC_COMPILER_INIT windres)
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
endif()
enable_language(RC)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
message(STATUS "Detected cygwin")
set(PTHREADS_ENABLED TRUE)
set(WITHOUT_POLL_H TRUE CACHE INTERNAL "Disable using poll.h even if it's available - use windows poll instead fo cygwin's" FORCE)
endif()
list(APPEND PLATFORM_SRC
poll_windows.c
windows_usbdk.c
windows_nt_common.c
windows_winusb.c
threads_windows.c
)
if (PTHREADS_ENABLED AND NOT WITHOUT_PTHREADS)
list(APPEND PLATFORM_SRC threads_posix)
else()
list(APPEND PLATFORM_SRC threads_windows.c)
endif()
elseif (APPLE)
# Apple != OSX alone
set(OS_DARWIN 1 CACHE INTERNAL "controls config.h macro definition" FORCE)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
set(PLATFORM_SRC
darwin_usb.c
threads_posix.c
poll_posix.c
)
find_package(IOKit REQUIRED)
list(APPEND LIBUSB_LIBRARIES ${IOKit_LIBRARIES})
# Currently only objc_registerThreadWithCollector requires linking against it
# which is only for MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
include(CheckCSourceCompiles)
check_c_source_compiles(
"#include <AvailabilityMacros.h>
int main()
{
#if !(MAC_OS_X_VERSION_MIN_REQUIRED >= 1060)
#error \"Don't need objc\"
#endif
}
" NEED_OBJC_REGISTER_THREAD_WITH_COLLECTOR)
if (NEED_OBJC_REGISTER_THREAD_WITH_COLLECTOR)
find_library(LIBOBJC objc)
if (NOT LIBOBJC)
message(SEND_ERROR "Need objc library but can't find it")
else()
list(APPEND LIBUSB_LIBRARIES ${LIBOBJC})
endif()
endif()
endif()
elseif (UNIX)
# Unix is for all *NIX systems including OSX
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(OS_LINUX 1 CACHE INTERNAL "controls config.h macro definition" FORCE)
set(PLATFORM_SRC
linux_usbfs.c
linux_netlink.c
threads_posix.c
poll_posix.c
)
list(APPEND LIBUSB_LIBRARIES rt)
endif()
endif()
if (NOT PLATFORM_SRC)
message(FATAL_ERROR "Unsupported platform ${CMAKE_SYSTEM_NAME}. Currently only support Windows, OSX, & Linux.")
endif()
# the paths are relative to this directory but used in the parent directory,
# so we have to adjust the paths
foreach(SRC IN LISTS PLATFORM_SRC)
list(APPEND LIBUSB_PLATFORM ${LIBUSB_SOURCE_DIR}/libusb/os/${SRC})
endforeach()
# export one level up so that the generic
# libusb parts know what the platform bits are supposed to be
set(LIBUSB_PLATFORM ${LIBUSB_PLATFORM} PARENT_SCOPE)
set(LIBUSB_LIBRARIES ${LIBUSB_LIBRARIES} PARENT_SCOPE)
if (WITHOUT_PTHREADS)
set(PTHREADS_ENABLED FALSE)
endif()
set(THREADS_POSIX ${PTHREADS_ENABLED} CACHE INTERNAL "use pthreads" FORCE)
+9 -9
View File
@@ -1,11 +1,11 @@
add_library(3rdparty_qt5 INTERFACE)
find_package(Qt5 5.11 CONFIG COMPONENTS Widgets Network Qml Concurrent)
find_package(Qt5 5.14 CONFIG COMPONENTS Widgets Network Qml Concurrent)
if(WIN32)
find_package(Qt5 5.11 COMPONENTS WinExtras REQUIRED)
find_package(Qt5 5.14 COMPONENTS WinExtras REQUIRED)
target_link_libraries(3rdparty_qt5 INTERFACE Qt5::Widgets Qt5::WinExtras Qt5::Network Qt5::Qml Qt5::Concurrent)
else()
find_package(Qt5 5.11 COMPONENTS DBus Gui)
find_package(Qt5 5.14 COMPONENTS DBus Gui)
if(Qt5DBus_FOUND)
target_link_libraries(3rdparty_qt5 INTERFACE Qt5::Widgets Qt5::DBus Qt5::Network Qt5::Qml Qt5::Concurrent)
target_compile_definitions(3rdparty_qt5 INTERFACE -DHAVE_QTDBUS)
@@ -16,15 +16,15 @@ else()
endif()
if(NOT Qt5Widgets_FOUND)
if(Qt5Widgets_VERSION VERSION_LESS 5.11.0)
message("Minimum supported Qt5 version is 5.11.0! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
if(Qt5Widgets_VERSION VERSION_LESS 5.14.0)
message("Minimum supported Qt5 version is 5.14.0! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
if(CMAKE_SYSTEM MATCHES "Linux")
message(FATAL_ERROR "Most distros do not provide an up-to-date version of Qt.
If you're on Ubuntu or Linux Mint, there are PPAs you can use to install one of the latest qt5 versions.
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt-5.11.0-bionic
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt-5.11.0-xenial
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt-5.14.1-bionic
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt-5.14.1-xenial
just make sure to run
source /opt/qt511/bin/qt511-env.sh
source /opt/qt514/bin/qt514-env.sh
before re-running cmake")
elseif(WIN32)
message(FATAL_ERROR "You can download the latest version of Qt5 here: https://www.qt.io/download-open-source/")
@@ -35,7 +35,7 @@ before re-running cmake")
message("CMake was unable to find Qt5!")
if(WIN32)
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.11.1\\msvc2017_64\\)
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.14.1\\msvc2017_64\\)
You can also try setting the Qt5_DIR preprocessor definiton.")
elseif(CMAKE_SYSTEM MATCHES "Linux")
message(FATAL_ERROR "Make sure to install your distro's qt5 package!")
+36 -25
View File
@@ -9,20 +9,20 @@ Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Bu
* [CMake 3.14.1+](https://www.cmake.org/download/) (add to PATH)
* [Python 3.3+](https://www.python.org/downloads/) (add to PATH)
* [Qt 5.11+](https://www.qt.io/download-qt-installer) (Avoid 5.11.1, due to a bug)
* [Qt 5.14+](https://www.qt.io/download-qt-installer)
* [Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community)
* [Vulkan SDK 1.1.97.0+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
* [Vulkan SDK 1.1.126+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
**Either add the** `QTDIR` **environment variable, e.g.** `<QtInstallFolder>\5.11.0\msvc2017_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools-19123)**
**Either add the** `QTDIR` **environment variable, e.g.** `<QtInstallFolder>\5.14.1\msvc2017_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools-19123)**
### Linux
These are the essentials tools to build RPCS3 on Linux. Some of them can be installed through your favorite package manager.
* Clang 5.0+ or GCC 8.1+
* [CMake 3.8.2+](https://www.cmake.org/download/)
* [Qt 5.11+](https://www.qt.io/download-qt-installer) (Avoid 5.11.1, due to a bug)
* [Vulkan SDK 1.1.97.0+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
* Clang 9+ or GCC 9+
* [CMake 3.14.1+](https://www.cmake.org/download/)
* [Qt 5.14+](https://www.qt.io/download-qt-installer)
* [Vulkan SDK 1.1.126+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
* [SDL2](https://www.libsdl.org/download-2.0.php) (for the FAudio backend)
**If you have an NVIDIA GPU, you may need to install the libglvnd package.**
@@ -33,40 +33,51 @@ These are the essentials tools to build RPCS3 on Linux. Some of them can be inst
#### Debian & Ubuntu
sudo apt-get install cmake build-essential libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default libevdev-dev qtdeclarative5-dev qtbase5-private-dev libsdl2-2.0 libsdl2-dev
sudo apt-get install build-essential libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git libevdev-dev libsdl2-2.0 libsdl2-dev
##### GCC 8.x installation
Ubuntu is usually horrendously out of date, and some packages need to be downloaded by hand. This part is for Qt, GCC, Vulkan, and CMake
##### Qt PPA
If the `gcc-8` package is not available on your system, use the following command
Ubuntu usually does not have a new enough Qt package to suit rpcs3's needs. There is a PPA available to work around this. Run the following:
```
ucodename=$(lsb_release -sc)
sudo add-apt-repository ppa:beineri/opt-qt-5.14.1-$ucodename
sudo apt-get update
. /opt/qt514/bin/qt514-env.sh >/dev/null 2>&1
sudo apt-get install qt514-meta-minimal qt514svg
```
##### GCC 9.x installation
If the `gcc-9` package is not available on your system, use the following commands
```
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
```
Then
```
sudo apt-get update
sudo apt-get install gcc-8 g++-8
sudo apt-get install gcc-9 g++-9
```
You can either use `update-alternatives` to setup `gcc-8`/`g++-8` as your default compilers or prefix any `cmake` command by `CXX=g++-8 CC=gcc-8 ` to use it.
You can either use `update-alternatives` to setup `gcc-9`/`g++-9` as your default compilers or prefix any `cmake` command by `CXX=g++-9 CC=gcc-9 ` to use it.
##### Vulkan SDK
For Ubuntu systems, it is strongly recommended to use the PPA from [LunarG](https://packages.lunarg.com/) which will provide a compatible Vulkan SDK to compile RPCS3. If your Vulkan SDK is older, it can lead to compilation errors.
Ubuntu 18.04 (Bionic Beaver)
```
ucodename=$(lsb_release -sc)
wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.1.106-bionic.list http://packages.lunarg.com/vulkan/1.1.106/lunarg-vulkan-1.1.106-bionic.list
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.1.126-$ucodename.list http://packages.lunarg.com/vulkan/1.1.126/lunarg-vulkan-1.1.126-$ucodename.list
sudo apt update
sudo apt install vulkan-sdk
```
Ubuntu 16.04 (Xenial Xerus)
##### CMake
```
wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.1.106-xenial.list http://packages.lunarg.com/vulkan/1.1.106/lunarg-vulkan-1.1.106-xenial.list
sudo apt update
sudo apt install vulkan-sdk
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add -
sudo apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -sc) main"
sudo apt-get update
sudo apt-get install kitware-archive-keyring
sudo apt-key --keyring /etc/apt/trusted.gpg del C1F34CDD40CD72DA
sudo apt-get install cmake
```
#### Fedora
@@ -92,7 +103,7 @@ git submodule update --init
#### Configuring the Qt plugin (if used)
1) Go to the Qt5 menu and edit Qt5 options.
2) Add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\5.11.0\msvc2017_64`.
2) Add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\5.14.1\msvc2017_64`.
3) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
#### Building the projects
@@ -110,7 +121,7 @@ If you're not using precompiled libs, build the projects in *__BUILD_BEFORE* fol
While still in the project root:
1) `cd .. && mkdir rpcs3_build && cd rpcs3_build`
2) `cmake ../rpcs3/ && make` or `CXX=g++-8 CC=gcc-8 cmake ../rpcs3/ && make` to force these compilers
2) `cmake ../rpcs3/ && make` or `CXX=g++-9 CC=gcc-9 cmake ../rpcs3/ && make` to force these compilers
3) Run RPCS3 with `./bin/rpcs3`
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
+7 -6
View File
@@ -1,14 +1,14 @@
cmake_minimum_required(VERSION 3.8.2)
cmake_minimum_required(VERSION 3.14.1)
project(rpcs3)
if(CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8)
message(FATAL_ERROR "RPCS3 requires at least gcc-8.")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
message(FATAL_ERROR "RPCS3 requires at least gcc-9.")
endif()
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
message(FATAL_ERROR "RPCS3 requires at least clang-5.0.")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
message(FATAL_ERROR "RPCS3 requires at least clang-9.0.")
endif()
endif()
@@ -22,10 +22,11 @@ option(USE_LIBEVDEV "libevdev-based joystick support" ON)
option(USE_DISCORD_RPC "Discord rich presence integration" ON)
option(USE_SYSTEM_ZLIB "Prefer system ZLIB instead of the builtin one" ON)
option(USE_VULKAN "Vulkan render backend" ON)
option(USE_COTIRE "Use precompiled headers" ON)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/rpcs3/cmake_modules")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
include(CheckCXXCompilerFlag)
if (NOT CMAKE_BUILD_TYPE)
+28 -20
View File
@@ -4,6 +4,12 @@
#include "util/endian.hpp"
#include <cstring>
#if __has_include(<bit>)
#include <bit>
#else
#include <type_traits>
#endif
// 128-bit vector type and also se_storage<> storage type
union alignas(16) v128
{
@@ -26,12 +32,10 @@ union alignas(16) v128
}
};
#if IS_LE_MACHINE == 1
template <typename T, std::size_t N = 16 / sizeof(T)>
using normal_array_t = masked_array_t<T, N, 0>;
using normal_array_t = masked_array_t<T, N, std::endian::little == std::endian::native ? 0 : N - 1>;
template <typename T, std::size_t N = 16 / sizeof(T)>
using reversed_array_t = masked_array_t<T, N, N - 1>;
#endif
using reversed_array_t = masked_array_t<T, N, std::endian::little == std::endian::native ? N - 1 : 0>;
normal_array_t<u64> _u64;
normal_array_t<s64> _s64;
@@ -114,17 +118,27 @@ union alignas(16) v128
// Index 0 returns the MSB and index 127 returns the LSB
bit_element operator[](u32 index)
{
#if IS_LE_MACHINE == 1
return bit_element(m_data[1 - (index >> 6)], 0x8000000000000000ull >> (index & 0x3F));
#endif
if constexpr (std::endian::little == std::endian::native)
{
return bit_element(m_data[1 - (index >> 6)], 0x8000000000000000ull >> (index & 0x3F));
}
else
{
return bit_element(m_data[index >> 6], 0x8000000000000000ull >> (index & 0x3F));
}
}
// Index 0 returns the MSB and index 127 returns the LSB
bool operator[](u32 index) const
{
#if IS_LE_MACHINE == 1
return (m_data[1 - (index >> 6)] & (0x8000000000000000ull >> (index & 0x3F))) != 0;
#endif
if constexpr (std::endian::little == std::endian::native)
{
return (m_data[1 - (index >> 6)] & (0x8000000000000000ull >> (index & 0x3F))) != 0;
}
else
{
return (m_data[index >> 6] & (0x8000000000000000ull >> (index & 0x3F))) != 0;
}
}
} _bit;
@@ -340,12 +354,10 @@ using stx::se_storage;
template <typename T, std::size_t Align = alignof(T)>
using nse_t = se_t<T, false, Align>;
#if IS_LE_MACHINE == 1
template <typename T, std::size_t Align = alignof(T)>
using be_t = se_t<T, true, Align>;
using be_t = se_t<T, std::endian::little == std::endian::native, Align>;
template <typename T, std::size_t Align = alignof(T)>
using le_t = se_t<T, false, Align>;
#endif
using le_t = se_t<T, std::endian::big == std::endian::native, Align>;
// Type converter: converts native endianness arithmetic/enum types to appropriate se_t<> type
template <typename T, bool Se, typename = void>
@@ -414,20 +426,16 @@ struct to_se<T[N], Se>
};
// BE/LE aliases for to_se<>
#if IS_LE_MACHINE == 1
template <typename T>
using to_be_t = typename to_se<T, true>::type;
using to_be_t = typename to_se<T, std::endian::little == std::endian::native>::type;
template <typename T>
using to_le_t = typename to_se<T, false>::type;
#endif
using to_le_t = typename to_se<T, std::endian::big == std::endian::native>::type;
// BE/LE aliases for atomic_t
#if IS_LE_MACHINE == 1
template <typename T>
using atomic_be_t = atomic_t<be_t<T>>;
template <typename T>
using atomic_le_t = atomic_t<le_t<T>>;
#endif
template <typename T, bool Se, std::size_t Align>
struct fmt_unveil<se_t<T, Se, Align>, void>
+2 -2
View File
@@ -11,7 +11,7 @@ struct bf_base
// Datatype bitsize
static constexpr uint bitmax = sizeof(T) * 8; static_assert(N - 1 < bitmax, "bf_base<> error: N out of bounds");
// Field bitsize
static constexpr uint bitsize = N;
@@ -96,7 +96,7 @@ struct bf_t : bf_base<T, N>
// Optimized bool conversion (must be removed if inappropriate)
explicit constexpr operator bool() const
{
return unshifted() != 0;
return unshifted() != 0u;
}
// Store bitfield value
+9 -7
View File
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Config.h"
#include "yaml-cpp/yaml.h"
@@ -6,6 +6,8 @@
#include <typeinfo>
#include <charconv>
LOG_CHANNEL(cfg_log, "CFG");
namespace cfg
{
_base::_base(type _type)
@@ -72,13 +74,13 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
if (ret.ec != std::errc() || ret.ptr != end)
{
if (out) LOG_ERROR(GENERAL, "cfg::try_to_int('%s'): invalid integer", value);
if (out) cfg_log.error("cfg::try_to_int('%s'): invalid integer", value);
return false;
}
if (result < min || result > max)
{
if (out) LOG_ERROR(GENERAL, "cfg::try_to_int('%s'): out of bounds (%lld..%lld)", value, min, max);
if (out) cfg_log.error("cfg::try_to_int('%s'): out of bounds (%lld..%lld)", value, min, max);
return false;
}
@@ -127,13 +129,13 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
if (ret.ec != std::errc() || ret.ptr != end)
{
if (out) LOG_ERROR(GENERAL, "cfg::try_to_enum_value('%s'): invalid enum or integer", value);
if (out) cfg_log.error("cfg::try_to_enum_value('%s'): invalid enum or integer", value);
return false;
}
if (result > max)
{
if (out) LOG_ERROR(GENERAL, "cfg::try_to_enum_value('%s'): out of bounds(0..%u)", value, max);
if (out) cfg_log.error("cfg::try_to_enum_value('%s'): out of bounds(0..%u)", value, max);
return false;
}
@@ -307,7 +309,7 @@ bool cfg::node::from_string(const std::string& value, bool dynamic) try
}
catch (const std::exception& e)
{
LOG_FATAL(GENERAL, "%s thrown: %s", typeid(e).name(), e.what());
cfg_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
return false;
}
@@ -326,7 +328,7 @@ void cfg::_bool::from_default()
void cfg::string::from_default()
{
m_value = def;
m_value = m_value.make(def);
}
void cfg::set_entry::from_default()
+33 -25
View File
@@ -3,6 +3,8 @@
#include "Utilities/types.h"
#include "Utilities/StrFmt.h"
#include "Utilities/Log.h"
#include "util/atomic.hpp"
#include "util/shared_cptr.hpp"
#include <utility>
#include <string>
@@ -121,10 +123,10 @@ namespace cfg
class _bool final : public _base
{
bool m_value;
atomic_t<bool> m_value;
public:
bool def;
const bool def;
_bool(node* owner, const std::string& name, bool def = false, bool dynamic = false)
: _base(type::_bool, owner, name, dynamic)
@@ -138,7 +140,7 @@ namespace cfg
return m_value;
}
const bool& get() const
bool get() const
{
return m_value;
}
@@ -172,7 +174,7 @@ namespace cfg
template <typename T>
class _enum final : public _base
{
T m_value;
atomic_t<T> m_value;
public:
const T def;
@@ -189,7 +191,7 @@ namespace cfg
return m_value;
}
const T& get() const
T get() const
{
return m_value;
}
@@ -202,7 +204,7 @@ namespace cfg
std::string to_string() const override
{
std::string result;
fmt_class_string<T>::format(result, fmt_unveil<T>::get(m_value));
fmt_class_string<T>::format(result, fmt_unveil<T>::get(m_value.load()));
return result; // TODO: ???
}
@@ -235,7 +237,7 @@ namespace cfg
// Prefer 32 bit type if possible
using int_type = std::conditional_t<Min >= INT32_MIN && Max <= INT32_MAX, s32, s64>;
int_type m_value;
atomic_t<int_type> m_value;
public:
int_type def;
@@ -256,7 +258,7 @@ namespace cfg
return m_value;
}
const int_type& get() const
int_type get() const
{
return m_value;
}
@@ -303,50 +305,56 @@ namespace cfg
// Simple string entry with mutex
class string final : public _base
{
std::string m_name;
std::string m_value;
const std::string m_name;
stx::atomic_cptr<std::string> m_value;
public:
std::string def;
string(node* owner, const std::string& name, const std::string& def = {}, bool dynamic = false)
string(node* owner, std::string name, std::string def = {}, bool dynamic = false)
: _base(type::string, owner, name, dynamic)
, m_name(name)
, m_value(def)
, def(def)
, m_name(std::move(name))
, m_value(m_value.make(def))
, def(std::move(def))
{
}
operator std::string() const
{
return m_value;
return *m_value.load().get();
}
const std::string& get() const
std::pair<const std::string&, stx::shared_cptr<std::string>> get() const
{
return m_value;
auto v = m_value.load();
if (auto s = v.get())
{
return {*s, std::move(v)};
}
else
{
static const std::string _empty;
return {_empty, {}};
}
}
std::string get_name() const
const std::string& get_name() const
{
return m_name;
}
std::size_t size() const
{
return m_value.size();
}
void from_default() override;
std::string to_string() const override
{
return m_value;
return *m_value.load().get();
}
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
{
m_value = value;
m_value = m_value.make(value);
return true;
}
};
+19 -5
View File
@@ -304,7 +304,7 @@ std::shared_ptr<fs::device_base> fs::device_manager::set_device(const std::strin
std::shared_ptr<fs::device_base> fs::get_virtual_device(const std::string& path)
{
// Every virtual device path must have "//" at the beginning
if (path.size() > 2 && reinterpret_cast<const u16&>(path.front()) == "//"_u16)
if (path.starts_with("//"))
{
return get_device_manager().get_device(path);
}
@@ -314,7 +314,7 @@ std::shared_ptr<fs::device_base> fs::get_virtual_device(const std::string& path)
std::shared_ptr<fs::device_base> fs::set_virtual_device(const std::string& name, const std::shared_ptr<device_base>& device)
{
verify(HERE), name.size() > 2, name[0] == '/', name[1] == '/', name.find('/', 2) == -1;
verify(HERE), name.starts_with("//"), name[2] != '/';
return get_device_manager().set_device(name, device);
}
@@ -338,7 +338,7 @@ std::string fs::get_parent_dir(const std::string& path)
if (std::exchange(last, pos - 1) != pos)
{
// Return empty string if the path doesn't contain at least 2 elements
return path.substr(0, pos != -1 && path.find_last_not_of(delim, pos, sizeof(delim) - 1) != -1 ? pos : 0);
return path.substr(0, pos != umax && path.find_last_not_of(delim, pos, sizeof(delim) - 1) != umax ? pos : 0);
}
}
}
@@ -1639,7 +1639,14 @@ u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment)
{
u64 result = 0;
for (const auto entry : dir(path))
const auto root_dir = dir(path);
if (!root_dir)
{
return static_cast<u64>(umax);
}
for (const auto& entry : root_dir)
{
if (entry.name == "." || entry.name == "..")
{
@@ -1653,7 +1660,14 @@ u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment)
if (entry.is_directory == true)
{
result += get_dir_size(path_append(path, entry.name), rounding_alignment);
const u64 size = get_dir_size(path_append(path, entry.name), rounding_alignment);
if (size == umax)
{
return size;
}
result += size;
}
}
+38 -24
View File
@@ -14,6 +14,8 @@
#define CAN_OVERCOMMIT
#endif
LOG_CHANNEL(jit_log, "JIT");
static u8* get_jit_memory()
{
// Reserve 2G memory (magic static)
@@ -43,7 +45,7 @@ static u8* add_jit_memory(std::size_t size, uint align)
// Select subrange
u8* pointer = get_jit_memory() + Off;
if (UNLIKELY(!size && !align))
if (!size && !align) [[unlikely]]
{
// Return subrange info
return pointer;
@@ -57,7 +59,7 @@ static u8* add_jit_memory(std::size_t size, uint align)
const u64 _pos = ::align(ctr & 0xffff'ffff, align);
const u64 _new = ::align(_pos + size, align);
if (UNLIKELY(_new > 0x40000000))
if (_new > 0x40000000) [[unlikely]]
{
// Sorry, we failed, and further attempts should fail too.
ctr |= 0x40000000;
@@ -69,7 +71,7 @@ static u8* add_jit_memory(std::size_t size, uint align)
newa = olda;
// Check the necessity to commit more memory
if (UNLIKELY(_new > olda))
if (_new > olda) [[unlikely]]
{
newa = ::align(_new, 0x100000);
}
@@ -78,13 +80,13 @@ static u8* add_jit_memory(std::size_t size, uint align)
return _pos;
});
if (UNLIKELY(pos == -1))
if (pos == umax) [[unlikely]]
{
LOG_WARNING(GENERAL, "JIT: Out of memory (size=0x%x, align=0x%x, off=0x%x)", size, align, Off);
jit_log.warning("JIT: Out of memory (size=0x%x, align=0x%x, off=0x%x)", size, align, Off);
return nullptr;
}
if (UNLIKELY(olda != newa))
if (olda != newa) [[unlikely]]
{
#ifdef CAN_OVERCOMMIT
madvise(pointer + olda, newa - olda, MADV_WILLNEED);
@@ -117,21 +119,21 @@ jit_runtime::~jit_runtime()
asmjit::Error jit_runtime::_add(void** dst, asmjit::CodeHolder* code) noexcept
{
std::size_t codeSize = code->getCodeSize();
if (UNLIKELY(!codeSize))
if (!codeSize) [[unlikely]]
{
*dst = nullptr;
return asmjit::kErrorNoCodeGenerated;
}
void* p = jit_runtime::alloc(codeSize, 16);
if (UNLIKELY(!p))
if (!p) [[unlikely]]
{
*dst = nullptr;
return asmjit::kErrorNoVirtualMemory;
}
std::size_t relocSize = code->relocate(p);
if (UNLIKELY(!relocSize))
if (!relocSize) [[unlikely]]
{
*dst = nullptr;
return asmjit::kErrorInvalidState;
@@ -431,7 +433,7 @@ public:
void reset()
{
if (!m_segs.size())
if (m_segs.empty())
{
if (m_curr.addr != nullptr)
{
@@ -532,7 +534,7 @@ extern void jit_finalize()
{
if (!RtlDeleteFunctionTable(unwind.data()))
{
LOG_FATAL(GENERAL, "RtlDeleteFunctionTable() failed! Error %u", GetLastError());
jit_log.fatal("RtlDeleteFunctionTable() failed! Error %u", GetLastError());
}
}
@@ -579,11 +581,11 @@ struct MemoryManager : llvm::RTDyldMemoryManager
if (addr)
{
LOG_WARNING(GENERAL, "LLVM: Symbol requested: %s -> 0x%016llx", name, addr);
jit_log.warning("LLVM: Symbol requested: %s -> 0x%016llx", name, addr);
}
else
{
LOG_ERROR(GENERAL, "LLVM: Linkage failed: %s", name);
jit_log.error("LLVM: Linkage failed: %s", name);
addr = reinterpret_cast<u64>(null);
}
}
@@ -661,13 +663,13 @@ struct MemoryManager : llvm::RTDyldMemoryManager
if (ptr == nullptr)
{
LOG_FATAL(GENERAL, "LLVM: Out of memory (size=0x%llx, aligned 0x%x)", size, align);
jit_log.fatal("LLVM: Out of memory (size=0x%llx, aligned 0x%x)", size, align);
return nullptr;
}
utils::memory_commit(ptr, size, utils::protection::wx);
m_code_addr = static_cast<u8*>(ptr);
LOG_NOTICE(GENERAL, "LLVM: Code section %u '%s' allocated -> %p (size=0x%llx, aligned 0x%x)", sec_id, sec_name.data(), ptr, size, align);
jit_log.notice("LLVM: Code section %u '%s' allocated -> %p (size=0x%llx, aligned 0x%x)", sec_id, sec_name.data(), ptr, size, align);
return static_cast<u8*>(ptr);
}
@@ -685,7 +687,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
if (ptr == nullptr)
{
LOG_FATAL(GENERAL, "LLVM: Out of memory (size=0x%llx, aligned 0x%x)", size, align);
jit_log.fatal("LLVM: Out of memory (size=0x%llx, aligned 0x%x)", size, align);
return nullptr;
}
@@ -695,7 +697,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
utils::memory_commit(ptr, size);
LOG_NOTICE(GENERAL, "LLVM: Data section %u '%s' allocated -> %p (size=0x%llx, aligned 0x%x, %s)", sec_id, sec_name.data(), ptr, size, align, is_ro ? "ro" : "rw");
jit_log.notice("LLVM: Data section %u '%s' allocated -> %p (size=0x%llx, aligned 0x%x, %s)", sec_id, sec_name.data(), ptr, size, align, is_ro ? "ro" : "rw");
return static_cast<u8*>(ptr);
}
@@ -718,9 +720,9 @@ struct MemoryManager : llvm::RTDyldMemoryManager
void registerEHFrames(u8* addr, u64 load_addr, std::size_t size) override
{
#ifdef _WIN32
// Lock memory manager
std::lock_guard lock(s_mutex);
#ifdef _WIN32
// Fix RUNTIME_FUNCTION records (.pdata section)
decltype(s_unwater)::value_type pdata_entry = std::move(s_unwater.front());
s_unwater.pop_front();
@@ -738,7 +740,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
// Register .xdata UNWIND_INFO structs
if (!RtlAddFunctionTable(pdata.data(), (DWORD)pdata.size(), segment_start))
{
LOG_ERROR(GENERAL, "RtlAddFunctionTable() failed! Error %u", GetLastError());
jit_log.error("RtlAddFunctionTable() failed! Error %u", GetLastError());
}
else
{
@@ -784,7 +786,11 @@ struct MemoryManager2 : llvm::RTDyldMemoryManager
{
#ifndef _WIN32
RTDyldMemoryManager::registerEHFramesInProcess(addr, size);
s_unfire.push_front(std::make_pair(addr, size));
{
// Lock memory manager
std::lock_guard lock(s_mutex);
s_unfire.push_front(std::make_pair(addr, size));
}
#endif
}
@@ -919,10 +925,14 @@ public:
z_stream zs{};
uLong zsz = compressBound(obj.getBufferSize()) + 256;
auto zbuf = std::make_unique<uchar[]>(zsz);
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
deflateInit2(&zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY);
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
zs.avail_in = static_cast<uInt>(obj.getBufferSize());
zs.next_in = reinterpret_cast<uchar*>(const_cast<char*>(obj.getBufferStart()));
zs.avail_out = static_cast<uInt>(zsz);
@@ -938,14 +948,14 @@ public:
}
default:
{
LOG_ERROR(GENERAL, "LLVM: Failed to compress module: %s", module->getName().data());
jit_log.error("LLVM: Failed to compress module: %s", module->getName().data());
deflateEnd(&zs);
return;
}
}
fs::file(name, fs::rewrite).write(zbuf.get(), zsz - zs.avail_out);
LOG_NOTICE(GENERAL, "LLVM: Created module: %s", module->getName().data());
jit_log.notice("LLVM: Created module: %s", module->getName().data());
}
static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path)
@@ -955,10 +965,14 @@ public:
std::vector<uchar> gz = cached.to_vector<uchar>();
std::vector<uchar> out;
z_stream zs{};
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
inflateInit2(&zs, 16 + 15);
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
zs.avail_in = static_cast<uInt>(gz.size());
zs.next_in = gz.data();
out.resize(gz.size() * 6);
@@ -1016,7 +1030,7 @@ public:
if (auto buf = load(path))
{
LOG_NOTICE(GENERAL, "LLVM: Loaded module: %s", module->getName().data());
jit_log.notice("LLVM: Loaded module: %s", module->getName().data());
return buf;
}
@@ -1182,7 +1196,7 @@ void jit_compiler::add(const std::string& path)
}
else
{
LOG_ERROR(GENERAL, "ObjectCache: Adding failed: %s", path);
jit_log.error("ObjectCache: Adding failed: %s", path);
}
}
+104 -72
View File
@@ -49,7 +49,6 @@ void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
case logs::level::warning: return "Warning";
case logs::level::notice: return "Notice";
case logs::level::trace: return "Trace";
case logs::level::_uninit: return unknown;
}
return unknown;
@@ -94,22 +93,6 @@ namespace logs
void log(logs::level sev, const char* text, std::size_t size);
};
struct channel_info
{
channel* pointer = nullptr;
level enabled = level::notice;
void set_level(level value)
{
enabled = value;
if (pointer)
{
pointer->enabled = value;
}
}
};
struct stored_message
{
message m;
@@ -128,7 +111,7 @@ namespace logs
virtual void log(u64 stamp, const message& msg, const std::string& prefix, const std::string& text) override;
// Channel registry
std::unordered_map<std::string, channel_info> channels;
std::unordered_multimap<std::string, channel*> channels;
// Messages for delayed listener initialization
std::vector<stored_message> messages;
@@ -174,19 +157,11 @@ namespace logs
return timebase.get();
}
channel GENERAL("");
channel LOADER("LDR");
channel MEMORY("MEM");
channel RSX("RSX");
channel HLE("HLE");
channel PPU("PPU");
channel SPU("SPU");
// Channel registry mutex
shared_mutex g_mutex;
static shared_mutex g_mutex;
// Must be set to true in main()
atomic_t<bool> g_init{false};
static atomic_t<bool> g_init{false};
void reset()
{
@@ -194,7 +169,17 @@ namespace logs
for (auto&& pair : get_logger()->channels)
{
pair.second.set_level(level::notice);
pair.second->enabled.store(level::notice, std::memory_order_relaxed);
}
}
void silence()
{
std::lock_guard lock(g_mutex);
for (auto&& pair : get_logger()->channels)
{
pair.second->enabled.store(level::always, std::memory_order_relaxed);
}
}
@@ -202,7 +187,47 @@ namespace logs
{
std::lock_guard lock(g_mutex);
get_logger()->channels[ch_name].set_level(value);
auto found = get_logger()->channels.equal_range(ch_name);
while (found.first != found.second)
{
found.first->second->enabled.store(value, std::memory_order_relaxed);
found.first++;
}
}
level get_level(const std::string& ch_name)
{
std::lock_guard lock(g_mutex);
auto found = get_logger()->channels.equal_range(ch_name);
if (found.first != found.second)
{
return found.first->second->enabled.load(std::memory_order_relaxed);
}
else
{
return level::always;
}
}
std::vector<std::string> get_channels()
{
std::vector<std::string> result;
std::lock_guard lock(g_mutex);
for (auto&& p : get_logger()->channels)
{
// Copy names removing duplicates
if (result.empty() || result.back() != p.first)
{
result.push_back(p.first);
}
}
return result;
}
// Must be called in main() to stop accumulating messages in g_messages
@@ -211,6 +236,7 @@ namespace logs
if (!g_init)
{
std::lock_guard lock(g_mutex);
printf("DEBUG: %zu log messages accumulated. %zu channels registered.\n", get_logger()->messages.size(), get_logger()->channels.size());
get_logger()->messages.clear();
g_init = true;
}
@@ -219,6 +245,19 @@ namespace logs
logs::listener::~listener()
{
// Shut up all channels on exit
if (auto logger = get_logger())
{
if (logger == this)
{
return;
}
for (auto&& pair : logger->channels)
{
pair.second->enabled.store(level::always, std::memory_order_relaxed);
}
}
}
void logs::listener::add(logs::listener* _new)
@@ -241,35 +280,18 @@ void logs::listener::add(logs::listener* _new)
}
}
logs::registerer::registerer(channel& _ch)
{
std::lock_guard lock(g_mutex);
get_logger()->channels.emplace(_ch.name, &_ch);
}
void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, ...) const
{
// Get timestamp
const u64 stamp = get_stamp();
// Register channel
if (ch->enabled == level::_uninit)
{
std::lock_guard lock(g_mutex);
auto& info = get_logger()->channels[ch->name];
if (info.pointer && info.pointer != ch)
{
fmt::throw_exception("logs::channel repetition: %s", ch->name);
}
else if (!info.pointer)
{
info.pointer = ch;
ch->enabled = info.enabled;
// Check level again
if (info.enabled < sev)
{
return;
}
}
}
// Get text, extract va_args
thread_local std::string text;
thread_local std::vector<u64> args;
@@ -400,17 +422,28 @@ logs::file_writer::file_writer(const std::string& name)
verify(name.c_str()), m_fptr;
// Rotate backups (TODO)
fs::remove_file(fs::get_cache_dir() + name + "1.log.gz");
fs::create_dir(fs::get_cache_dir() + "old_logs");
fs::rename(fs::get_cache_dir() + m_name + ".log.gz", fs::get_cache_dir() + "old_logs/" + m_name + ".log.gz", true);
if (std::string gz_file_name = fs::get_cache_dir() + m_name + ".log.gz"; fs::is_file(gz_file_name))
{
fs::remove_file(fs::get_cache_dir() + name + "1.log.gz");
fs::create_dir(fs::get_cache_dir() + "old_logs");
fs::rename(gz_file_name, fs::get_cache_dir() + "old_logs/" + m_name + ".log.gz", true);
}
// Actual log file (allowed to fail)
m_fout.open(log_name, fs::rewrite);
// Compressed log, make it inaccessible (foolproof)
if (!m_fout2.open(log_name + ".gz", fs::rewrite + fs::unread) || deflateInit2(&m_zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) != Z_OK)
if (m_fout2.open(log_name + ".gz", fs::rewrite + fs::unread))
{
m_fout2.close();
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
if (deflateInit2(&m_zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) != Z_OK)
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
m_fout2.close();
}
#ifdef _WIN32
@@ -448,7 +481,7 @@ logs::file_writer::file_writer(const std::string& name)
if (!flush(bufv))
{
if (m_out == -1)
if (m_out == umax)
{
break;
}
@@ -573,7 +606,7 @@ void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
const u64 v1 = v >> 24;
const u64 v2 = v & 0xffffff;
if (UNLIKELY(v2 + size > 0xffffff || v1 + v2 + size >= m_out + s_log_size))
if (v2 + size > 0xffffff || v1 + v2 + size >= m_out + s_log_size) [[unlikely]]
{
bufv = v;
return nullptr;
@@ -583,7 +616,7 @@ void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
return m_fptr + (v1 + v2) % s_log_size;
});
if (UNLIKELY(!pos))
if (!pos) [[unlikely]]
{
if ((bufv & 0xffffff) + size > 0xffffff || bufv & 0xffffff)
{
@@ -629,7 +662,7 @@ logs::file_listener::file_listener(const std::string& name)
ver.m.ch = nullptr;
ver.m.sev = level::always;
ver.stamp = 0;
ver.text = fmt::format("RPCS3 v%s | %s%s\n%s", rpcs3::version.to_string(), rpcs3::get_branch(), firmware_string, utils::get_system_info());
ver.text = fmt::format("RPCS3 v%s | %s%s\n%s", rpcs3::get_version().to_string(), rpcs3::get_branch(), firmware_string, utils::get_system_info());
file_writer::log(logs::level::always, ver.text.data(), ver.text.size());
file_writer::log(logs::level::always, "\n", 1);
@@ -654,15 +687,14 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
// Used character: U+00B7 (Middle Dot)
switch (msg.sev)
{
case level::always: text = u8"·A "; break;
case level::fatal: text = u8"·F "; break;
case level::error: text = u8"·E "; break;
case level::todo: text = u8"·U "; break;
case level::success: text = u8"·S "; break;
case level::warning: text = u8"·W "; break;
case level::notice: text = u8"·! "; break;
case level::trace: text = u8"·T "; break;
case level::_uninit: text = u8"· "; break;
case level::always: text = reinterpret_cast<const char*>(u8"·A "); break;
case level::fatal: text = reinterpret_cast<const char*>(u8"·F "); break;
case level::error: text = reinterpret_cast<const char*>(u8"·E "); break;
case level::todo: text = reinterpret_cast<const char*>(u8"·U "); break;
case level::success: text = reinterpret_cast<const char*>(u8"·S "); break;
case level::warning: text = reinterpret_cast<const char*>(u8"·W "); break;
case level::notice: text = reinterpret_cast<const char*>(u8"·! "); break;
case level::trace: text = reinterpret_cast<const char*>(u8"·T "); break;
}
// Print µs timestamp
+58 -28
View File
@@ -1,9 +1,9 @@
#pragma once
#include "types.h"
#include "util/atomic.hpp"
#include "StrFmt.h"
#include <climits>
#include "util/atomic.hpp"
#include <atomic>
namespace logs
{
@@ -17,8 +17,6 @@ namespace logs
warning,
notice,
trace, // Lowest severity (usually disabled)
_uninit = UINT_MAX, // Special value for delayed initialization
};
struct channel;
@@ -61,27 +59,44 @@ namespace logs
const char* const name;
// The lowest logging level enabled for this channel (used for early filtering)
atomic_t<level> enabled;
std::atomic<level> enabled;
// Constant initialization: channel name
constexpr channel(const char* name)
// Initialize channel
constexpr channel(const char* name) noexcept
: name(name)
, enabled(level::_uninit)
, enabled(level::notice)
{
}
private:
#if __cpp_char8_t >= 201811
using char2 = char8_t;
#else
using char2 = uchar;
#endif
#define GEN_LOG_METHOD(_sev)\
const message msg_##_sev{this, level::_sev};\
template <std::size_t N, typename... Args>\
void _sev(const char(&fmt)[N], const Args&... args)\
{\
if (UNLIKELY(level::_sev <= enabled))\
if (level::_sev <= enabled.load(std::memory_order_relaxed)) [[unlikely]]\
{\
static constexpr fmt_type_info type_list[sizeof...(Args) + 1]{fmt_type_info::make<fmt_unveil_t<Args>>()...};\
msg_##_sev.broadcast(fmt, type_list, u64{fmt_unveil<Args>::get(args)}...);\
}\
}
}\
template <std::size_t N, typename... Args>\
void _sev(const char2(&fmt)[N], const Args&... args)\
{\
if (level::_sev <= enabled.load(std::memory_order_relaxed)) [[unlikely]]\
{\
static constexpr fmt_type_info type_list[sizeof...(Args) + 1]{fmt_type_info::make<fmt_unveil_t<Args>>()...};\
msg_##_sev.broadcast(reinterpret_cast<const char*>(+fmt), type_list, u64{fmt_unveil<Args>::get(args)}...);\
}\
}\
public:
GEN_LOG_METHOD(fatal)
GEN_LOG_METHOD(error)
GEN_LOG_METHOD(todo)
@@ -93,31 +108,46 @@ namespace logs
#undef GEN_LOG_METHOD
};
/* Small set of predefined channels */
extern channel GENERAL;
extern channel LOADER;
extern channel MEMORY;
extern channel RSX;
extern channel HLE;
extern channel PPU;
extern channel SPU;
struct registerer
{
registerer(channel& _ch);
};
// Log level control: set all channels to level::notice
void reset();
// Log level control: set all channels to level::always
void silence();
// Log level control: register channel if necessary, set channel level
void set_level(const std::string&, level);
// Log level control: get channel level
level get_level(const std::string&);
// Get all registered log channels
std::vector<std::string> get_channels();
// Helper: no additional name specified
constexpr const char* make_channel_name(const char* name)
{
return name;
}
// Helper: special channel name specified
constexpr const char* make_channel_name(const char*, const char* name, ...)
{
return name;
}
}
#define LOG_CHANNEL(ch, ...) ::logs::channel ch(#ch, ##__VA_ARGS__)
#if __cpp_constinit >= 201907
#define LOG_CONSTINIT constinit
#else
#define LOG_CONSTINIT
#endif
// Legacy:
#define LOG_CHANNEL(ch, ...) LOG_CONSTINIT inline ::logs::channel ch(::logs::make_channel_name(#ch, ##__VA_ARGS__)); \
namespace logs { inline ::logs::registerer reg_##ch{ch}; }
#define LOG_SUCCESS(ch, fmt, ...) logs::ch.success("" fmt, ##__VA_ARGS__)
#define LOG_NOTICE(ch, fmt, ...) logs::ch.notice ("" fmt, ##__VA_ARGS__)
#define LOG_WARNING(ch, fmt, ...) logs::ch.warning("" fmt, ##__VA_ARGS__)
#define LOG_ERROR(ch, fmt, ...) logs::ch.error ("" fmt, ##__VA_ARGS__)
#define LOG_TODO(ch, fmt, ...) logs::ch.todo ("" fmt, ##__VA_ARGS__)
#define LOG_TRACE(ch, fmt, ...) logs::ch.trace ("" fmt, ##__VA_ARGS__)
#define LOG_FATAL(ch, fmt, ...) logs::ch.fatal ("" fmt, ##__VA_ARGS__)
LOG_CHANNEL(rsx_log, "RSX");
+8 -8
View File
@@ -8,8 +8,8 @@
namespace fmt
{
template <typename... Args>
static std::string format(const char*, const Args&...);
template <typename CharT, std::size_t N, typename... Args>
static std::string format(const CharT(&)[N], const Args&...);
}
template <typename T, typename>
@@ -274,19 +274,19 @@ namespace fmt
void raw_append(std::string& out, const char*, const fmt_type_info*, const u64*) noexcept;
// Formatting function
template <typename... Args>
SAFE_BUFFERS FORCE_INLINE void append(std::string& out, const char* fmt, const Args&... args)
template <typename CharT, std::size_t N, typename... Args>
SAFE_BUFFERS FORCE_INLINE void append(std::string& out, const CharT(&fmt)[N], const Args&... args)
{
static constexpr fmt_type_info type_list[sizeof...(Args) + 1]{fmt_type_info::make<fmt_unveil_t<Args>>()...};
raw_append(out, fmt, type_list, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
raw_append(out, reinterpret_cast<const char*>(fmt), type_list, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
}
// Formatting function
template <typename... Args>
SAFE_BUFFERS FORCE_INLINE std::string format(const char* fmt, const Args&... args)
template <typename CharT, std::size_t N, typename... Args>
SAFE_BUFFERS FORCE_INLINE std::string format(const CharT(&fmt)[N], const Args&... args)
{
std::string result;
append<Args...>(result, fmt, args...);
append(result, fmt, args...);
return result;
}
-6
View File
@@ -25,12 +25,6 @@ inline void strcpy_trunc(char (&dst)[N], const char (&src)[N2])
std::memset(dst + count, 0, N - count);
}
template <std::size_t N>
inline bool ends_with(const std::string& src, const char (&end)[N])
{
return src.size() >= N - 1 && src.compare(src.size() - (N - 1), N - 1, end, N - 1) == 0;
}
namespace fmt
{
std::string replace_first(const std::string& src, const std::string& from, const std::string& to);
+217 -99
View File
@@ -1,7 +1,4 @@
#include "stdafx.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/RawSPUThread.h"
@@ -11,6 +8,7 @@
#include "sysinfo.h"
#include <typeinfo>
#include <thread>
#include <sstream>
#ifdef _WIN32
#include <Windows.h>
@@ -45,11 +43,23 @@
#include "sync.h"
#include "Log.h"
LOG_CHANNEL(sig_log);
LOG_CHANNEL(sys_log, "SYS");
LOG_CHANNEL(vm_log, "VM");
thread_local u64 g_tls_fault_all = 0;
thread_local u64 g_tls_fault_rsx = 0;
thread_local u64 g_tls_fault_spu = 0;
extern thread_local std::string(*g_tls_log_prefix)();
template <>
void fmt_class_string<std::thread::id>::format(std::string& out, u64 arg)
{
std::ostringstream ss;
ss << get_object(arg);
out += ss.str();
}
[[noreturn]] void catch_all_exceptions()
{
try
@@ -185,7 +195,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
{
if (lock)
{
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): LOCK prefix found twice", code - out_length);
sig_log.error("decode_x64_reg_op(%016llxh): LOCK prefix found twice", code - out_length);
}
lock = true;
@@ -195,7 +205,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
{
if (repne)
{
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): REPNE/REPNZ prefix found twice", code - out_length);
sig_log.error("decode_x64_reg_op(%016llxh): REPNE/REPNZ prefix found twice", code - out_length);
}
repne = true;
@@ -205,7 +215,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
{
if (repe)
{
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): REP/REPE/REPZ prefix found twice", code - out_length);
sig_log.error("decode_x64_reg_op(%016llxh): REP/REPE/REPZ prefix found twice", code - out_length);
}
repe = true;
@@ -221,7 +231,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
{
if (pg2)
{
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): 0x%02x (group 2 prefix) found after 0x%02x", code - out_length, prefix, pg2);
sig_log.error("decode_x64_reg_op(%016llxh): 0x%02x (group 2 prefix) found after 0x%02x", code - out_length, prefix, pg2);
}
else
{
@@ -234,7 +244,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
{
if (oso)
{
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): operand-size override prefix found twice", code - out_length);
sig_log.error("decode_x64_reg_op(%016llxh): operand-size override prefix found twice", code - out_length);
}
oso = true;
@@ -243,7 +253,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
case 0x67: // group 4
{
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): address-size override prefix found", code - out_length, prefix);
sig_log.error("decode_x64_reg_op(%016llxh): address-size override prefix found", code - out_length, prefix);
out_op = X64OP_NONE;
out_reg = X64_NOT_SET;
out_size = 0;
@@ -257,7 +267,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
{
if (rex)
{
LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): 0x%02x (REX prefix) found after 0x%02x", code - out_length, prefix, rex);
sig_log.error("decode_x64_reg_op(%016llxh): 0x%02x (REX prefix) found after 0x%02x", code - out_length, prefix, rex);
}
else
{
@@ -757,7 +767,7 @@ uint64_t* darwin_x64reg(x64_context *context, int reg)
case 15: return &state->__r15;
case 16: return &state->__rip;
default:
LOG_ERROR(GENERAL, "Invalid register index: %d", reg);
sig_log.error("Invalid register index: %d", reg);
return nullptr;
}
}
@@ -795,7 +805,7 @@ register_t* freebsd_x64reg(x64_context *context, int reg)
case 15: return &state->mc_r15;
case 16: return &state->mc_rip;
default:
LOG_ERROR(GENERAL, "Invalid register index: %d", reg);
sig_log.error("Invalid register index: %d", reg);
return nullptr;
}
}
@@ -829,7 +839,7 @@ long* openbsd_x64reg(x64_context *context, int reg)
case 15: return &state->sc_r15;
case 16: return &state->sc_rip;
default:
LOG_ERROR(GENERAL, "Invalid register index: %d", reg);
sig_log.error("Invalid register index: %d", reg);
return nullptr;
}
}
@@ -964,7 +974,7 @@ bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_
return true;
}
LOG_ERROR(MEMORY, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", +reg, d_size, i_size);
sig_log.error("get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", +reg, d_size, i_size);
return false;
}
@@ -983,7 +993,7 @@ bool put_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, u64 v
}
}
LOG_ERROR(MEMORY, "put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", +reg, d_size, value);
sig_log.error("put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", +reg, d_size, value);
return false;
}
@@ -995,7 +1005,7 @@ bool set_x64_cmp_flags(x64_context* context, size_t d_size, u64 x, u64 y, bool c
case 2: break;
case 4: break;
case 8: break;
default: LOG_ERROR(MEMORY, "set_x64_cmp_flags(): invalid d_size (%lld)", d_size); return false;
default: sig_log.error("set_x64_cmp_flags(): invalid d_size (%lld)", d_size); return false;
}
const u64 sign = 1ull << (d_size * 8 - 1); // sign mask
@@ -1093,7 +1103,7 @@ namespace rsx
extern std::function<bool(u32 addr, bool is_writing)> g_access_violation_handler;
}
bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) noexcept
{
g_tls_fault_all++;
@@ -1114,7 +1124,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
}
catch (const std::exception& e)
{
LOG_FATAL(RSX, "g_access_violation_handler(0x%x, %d): %s", addr, is_writing, e.what());
rsx_log.fatal("g_access_violation_handler(0x%x, %d): %s", addr, is_writing, e.what());
if (cpu)
{
@@ -1159,13 +1169,13 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
{
if (op == X64OP_NONE)
{
LOG_ERROR(MEMORY, "decode_x64_reg_op(%p): unsupported opcode: %s", code, *reinterpret_cast<const be_t<v128, 1>*>(code));
sig_log.error("decode_x64_reg_op(%p): unsupported opcode: %s", code, *reinterpret_cast<const be_t<v128, 1>*>(code));
}
};
if ((d_size | (d_size + addr)) >= 0x100000000ull)
{
LOG_ERROR(MEMORY, "Invalid d_size (0x%llx)", d_size);
sig_log.error("Invalid d_size (0x%llx)", d_size);
report_opcode();
return false;
}
@@ -1175,7 +1185,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
if ((a_size | (a_size + addr)) >= 0x100000000ull)
{
LOG_ERROR(MEMORY, "Invalid a_size (0x%llx)", a_size);
sig_log.error("Invalid a_size (0x%llx)", a_size);
report_opcode();
return false;
}
@@ -1192,7 +1202,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
if (a_size != 4 || !d_size || !i_size)
{
LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", +op, +reg, d_size, a_size, i_size);
sig_log.error("Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", +op, +reg, d_size, a_size, i_size);
report_opcode();
return false;
}
@@ -1265,7 +1275,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
case X64OP_STOS:
default:
{
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, i_size=%lld)", +op, +reg, d_size, i_size);
sig_log.error("Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, i_size=%lld)", +op, +reg, d_size, i_size);
report_opcode();
return false;
}
@@ -1287,6 +1297,32 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
return true;
}
thread_local bool access_violation_recovered = false;
// Hack: allocate memory in case the emulator is stopping
const auto hack_alloc = [&]()
{
// If failed the value remains true and std::terminate should be called
access_violation_recovered = true;
const auto area = vm::reserve_map(vm::any, addr & -0x10000, 0x10000);
if (!area)
{
return false;
}
if (area->flags & 0x100 || (is_writing && vm::check_addr(addr, std::max(1u, ::narrow<u32>(d_size)))))
{
// For 4kb pages or read only memory
utils::memory_protect(vm::base(addr & -0x1000), 0x1000, utils::protection::rw);
return true;
}
area->falloc(addr & -0x10000, 0x10000);
return vm::check_addr(addr, std::max(1u, ::narrow<u32>(d_size)), is_writing ? vm::page_writable : vm::page_readable);
};
if (cpu)
{
u32 pf_port_id = 0;
@@ -1357,13 +1393,13 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
pf_events->events.emplace(static_cast<u32>(data2), addr);
}
LOG_ERROR(MEMORY, "Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
sig_log.error("Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
addr, data3 == SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY ? "writing read-only" : "using unmapped");
error_code sending_error = sys_event_port_send(pf_port_id, data1, data2, data3);
// If we fail due to being busy, wait a bit and try again.
while (sending_error == CELL_EBUSY)
while (static_cast<u32>(sending_error) == CELL_EBUSY)
{
if (cpu->id_type() == 1)
{
@@ -1374,22 +1410,23 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
sending_error = sys_event_port_send(pf_port_id, data1, data2, data3);
}
if (sending_error)
{
fmt::throw_exception("Unknown error %x while trying to pass page fault.", sending_error.value);
}
if (cpu->id_type() == 1)
{
// Deschedule
lv2_obj::sleep(*cpu);
}
if (sending_error)
{
vm_log.fatal("Unknown error %x while trying to pass page fault.", +sending_error);
cpu->state += cpu_flag::dbg_pause;
}
// Wait until the thread is recovered
for (std::shared_lock pf_lock(pf_events->pf_mutex);
pf_events->events.find(static_cast<u32>(data2)) != pf_events->events.end();)
pf_events->events.count(static_cast<u32>(data2)) && !sending_error;)
{
if (Emu.IsStopped())
if (cpu->is_stopped())
{
break;
}
@@ -1398,16 +1435,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
pf_events->cond.wait(pf_lock, 10000);
}
// Reschedule
if (cpu->test_stopped())
// Reschedule, test cpu state and try recovery if stopped
if (cpu->test_stopped() && !hack_alloc())
{
//
}
if (Emu.IsStopped())
{
// Hack: allocate memory in case the emulator is stopping
vm::falloc(addr & -0x10000, 0x10000);
std::terminate();
}
return true;
@@ -1415,36 +1446,29 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
if (cpu->id_type() != 1)
{
LOG_NOTICE(GENERAL, "\n%s", cpu->dump());
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
if (!access_violation_recovered)
{
vm_log.notice("\n%s", cpu->dump());
vm_log.fatal("Access violation %s location 0x%x (%s)", is_writing ? "writing" : "reading", addr, (is_writing && vm::check_addr(addr)) ? "read-only memory" : "unmapped memory");
}
// TODO:
// RawSPU: Send appropriate interrupt
// SPUThread: Send sys_spu exception event
cpu->state += cpu_flag::dbg_pause;
if (cpu->check_state())
if (cpu->check_state() && !hack_alloc())
{
// Hack: allocate memory in case the emulator is stopping
auto area = vm::reserve_map(vm::any, addr & -0x10000, 0x10000);
if (area->flags & 0x100)
{
// For 4kb pages
utils::memory_protect(vm::base(addr & -0x1000), 0x1000, utils::protection::rw);
}
else
{
area->falloc(addr & -0x10000, 0x10000);
}
return true;
std::terminate();
}
return true;
}
else
{
if (auto last_func = static_cast<ppu_thread*>(cpu)->current_function)
{
LOG_FATAL(PPU, "Function aborted: %s", last_func);
ppu_log.fatal("Function aborted: %s", last_func);
}
lv2_obj::sleep(*cpu);
@@ -1453,19 +1477,24 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
Emu.Pause();
if (cpu)
if (cpu && !access_violation_recovered)
{
LOG_NOTICE(GENERAL, "\n%s", cpu->dump());
vm_log.notice("\n%s", cpu->dump());
}
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
// Note: a thread may access violate more than once after hack_alloc recovery
// Do not log any further access violations in this case.
if (!access_violation_recovered)
{
vm_log.fatal("Access violation %s location 0x%x (%s)", is_writing ? "writing" : "reading", addr, (is_writing && vm::check_addr(addr)) ? "read-only memory" : "unmapped memory");
}
while (Emu.IsPaused())
{
thread_ctrl::wait();
}
if (Emu.IsStopped())
if (Emu.IsStopped() && !hack_alloc())
{
std::terminate();
}
@@ -1475,8 +1504,13 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
#ifdef _WIN32
static LONG exception_handler(PEXCEPTION_POINTERS pExp)
static LONG exception_handler(PEXCEPTION_POINTERS pExp) noexcept
{
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && IsDebuggerPresent())
{
return EXCEPTION_CONTINUE_SEARCH;
}
const u64 addr64 = pExp->ExceptionRecord->ExceptionInformation[1] - reinterpret_cast<u64>(vm::g_base_addr);
const u64 exec64 = (pExp->ExceptionRecord->ExceptionInformation[1] - reinterpret_cast<u64>(vm::g_exec_addr)) / 2;
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
@@ -1496,10 +1530,11 @@ static LONG exception_handler(PEXCEPTION_POINTERS pExp)
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
static LONG exception_filter(PEXCEPTION_POINTERS pExp)
static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
{
std::string msg = fmt::format("Unhandled Win32 exception 0x%08X.\n", pExp->ExceptionRecord->ExceptionCode);
@@ -1507,18 +1542,35 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp)
{
const auto cause = pExp->ExceptionRecord->ExceptionInformation[0] != 0 ? "writing" : "reading";
msg += fmt::format("Segfault %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
fmt::append(msg, "Segfault %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
}
else
{
msg += fmt::format("Exception address: %p.\n", pExp->ExceptionRecord->ExceptionAddress);
fmt::append(msg, "Exception address: %p.\n", pExp->ExceptionRecord->ExceptionAddress);
for (DWORD i = 0; i < pExp->ExceptionRecord->NumberParameters; i++)
{
msg += fmt::format("ExceptionInformation[0x%x]: %p.\n", i, pExp->ExceptionRecord->ExceptionInformation[i]);
fmt::append(msg, "ExceptionInformation[0x%x]: %p.\n", i, pExp->ExceptionRecord->ExceptionInformation[i]);
}
}
if (thread_ctrl::get_current())
{
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
if (const auto cpu = get_current_cpu_thread())
{
sys_log.notice("\n%s", cpu->dump());
}
}
// TODO: Report full thread name if not an emu thread
fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
sys_log.notice("Memory bases:\nvm::g_base_addr = %p\nvm::g_sudo_addr = %p\nvm::g_exec_addr = %p\nvm::g_stat_addr = %p\nvm::g_reservations = %p\n",
vm::g_base_addr, vm::g_sudo_addr, vm::g_exec_addr, vm::g_stat_addr, vm::g_reservations);
std::vector<HMODULE> modules;
for (DWORD size = 256; modules.size() != size; size /= sizeof(HMODULE))
{
@@ -1530,14 +1582,14 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp)
}
}
msg += fmt::format("Instruction address: %p.\n", pExp->ContextRecord->Rip);
fmt::append(msg, "Instruction address: %p.\n", pExp->ContextRecord->Rip);
DWORD64 unwind_base;
if (const auto rtf = RtlLookupFunctionEntry(pExp->ContextRecord->Rip, &unwind_base, nullptr))
{
// Get function address
const DWORD64 func_addr = rtf->BeginAddress + unwind_base;
msg += fmt::format("Function address: %p (base+0x%x).\n", func_addr, rtf->BeginAddress);
fmt::append(msg, "Function address: %p (base+0x%x).\n", func_addr, rtf->BeginAddress);
// Access UNWIND_INFO structure
//const auto uw = (u8*)(unwind_base + rtf->UnwindData);
@@ -1564,18 +1616,23 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp)
}
}
msg += fmt::format("Module name: '%s'.\n", module_name);
msg += fmt::format("Module base: %p.\n", info.lpBaseOfDll);
fmt::append(msg, "Module name: '%s'.\n", module_name);
fmt::append(msg, "Module base: %p.\n", info.lpBaseOfDll);
}
}
}
msg += fmt::format("RPCS3 image base: %p.\n", GetModuleHandle(NULL));
fmt::append(msg, "RPCS3 image base: %p.\n", GetModuleHandle(NULL));
// TODO: print registers and the callstack
// Report fatal error
report_fatal_error(msg);
sys_log.fatal("\n%s", msg);
if (!IsDebuggerPresent())
{
report_fatal_error(msg);
}
return EXCEPTION_CONTINUE_SEARCH;
}
@@ -1596,7 +1653,7 @@ const bool s_exception_handler_set = []() -> bool
#else
static void signal_handler(int sig, siginfo_t* info, void* uct)
static void signal_handler(int sig, siginfo_t* info, void* uct) noexcept
{
x64_context* context = static_cast<ucontext_t*>(uct);
@@ -1633,8 +1690,28 @@ static void signal_handler(int sig, siginfo_t* info, void* uct)
}
}
if (const auto cpu = get_current_cpu_thread())
{
sys_log.notice("\n%s", cpu->dump());
}
sys_log.notice("Memory bases:\nvm::g_base_addr = %p\nvm::g_sudo_addr = %p\nvm::g_exec_addr = %p\nvm::g_stat_addr = %p\nvm::g_reservations = %p\n",
vm::g_base_addr, vm::g_sudo_addr, vm::g_exec_addr, vm::g_stat_addr, vm::g_reservations);
std::string msg = fmt::format("Segfault %s location %p at %p.\n", cause, info->si_addr, RIP(context));
if (thread_ctrl::get_current())
{
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
}
// TODO: Report full thread name if not an emu thread
fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
// TODO (debugger interaction)
report_fatal_error(fmt::format("Segfault %s location %p at %p.", cause, info->si_addr, RIP(context)));
sys_log.fatal("\n%s", msg);
report_fatal_error(msg);
}
const bool s_exception_handler_set = []() -> bool
@@ -1679,9 +1756,11 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
g_tls_log_prefix = []
{
return thread_ctrl::g_tls_this_thread->m_name.get();
return thread_ctrl::get_name_cached();
};
std::string name = thread_ctrl::get_name_cached();
#ifdef _MSC_VER
struct THREADNAME_INFO
{
@@ -1692,11 +1771,11 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
};
// Set thread name for VS debugger
if (IsDebuggerPresent())
if (IsDebuggerPresent()) [&]() NEVER_INLINE
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = m_name.get().c_str();
info.szName = name.c_str();
info.dwThreadID = -1;
info.dwFlags = 0;
@@ -1707,24 +1786,26 @@ void thread_base::initialize(bool(*wait_cb)(const void*))
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
}
}();
#endif
#if defined(__APPLE__)
pthread_setname_np(m_name.get().substr(0, 15).c_str());
name.resize(std::min<std::size_t>(15, name.size()));
pthread_setname_np(name.c_str());
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
pthread_set_name_np(pthread_self(), m_name.get().c_str());
pthread_set_name_np(pthread_self(), name.c_str());
#elif defined(__NetBSD__)
pthread_setname_np(pthread_self(), "%s", const_cast<char*>(m_name.get().c_str()));
pthread_setname_np(pthread_self(), "%s", name.data());
#elif !defined(_WIN32)
pthread_setname_np(pthread_self(), m_name.get().substr(0, 15).c_str());
name.resize(std::min<std::size_t>(15, name.size()));
pthread_setname_np(pthread_self(), name.c_str());
#endif
#ifdef __linux__
m_timer = timerfd_create(CLOCK_MONOTONIC, 0);
if (m_timer == -1)
{
LOG_ERROR(GENERAL, "Linux timer allocation failed, use wait_unlock() only");
sig_log.error("Linux timer allocation failed, use wait_unlock() only");
}
#endif
}
@@ -1755,34 +1836,49 @@ bool thread_base::finalize(int) noexcept
FILETIME ctime, etime, ktime, utime;
GetThreadTimes(GetCurrentThread(), &ctime, &etime, &ktime, &utime);
const u64 time = ((ktime.dwLowDateTime | (u64)ktime.dwHighDateTime << 32) + (utime.dwLowDateTime | (u64)utime.dwHighDateTime << 32)) * 100ull;
const u64 fsoft = 0;
const u64 fhard = 0;
const u64 ctxvol = 0;
const u64 ctxinv = 0;
#elif defined(RUSAGE_THREAD)
const u64 cycles = 0; // Not supported
struct ::rusage stats{};
::getrusage(RUSAGE_THREAD, &stats);
const u64 time = (stats.ru_utime.tv_sec + stats.ru_stime.tv_sec) * 1000000000ull + (stats.ru_utime.tv_usec + stats.ru_stime.tv_usec) * 1000ull;
const u64 fsoft = stats.ru_minflt;
const u64 fhard = stats.ru_majflt;
const u64 ctxvol = stats.ru_nvcsw;
const u64 ctxinv = stats.ru_nivcsw;
#else
const u64 cycles = 0;
const u64 time = 0;
const u64 fsoft = 0;
const u64 fhard = 0;
const u64 ctxvol = 0;
const u64 ctxinv = 0;
#endif
g_tls_log_prefix = []
{
return thread_ctrl::g_tls_this_thread->m_name.get();
return thread_ctrl::get_name_cached();
};
LOG_NOTICE(GENERAL, "Thread time: %fs (%fGc); Faults: %u [rsx:%u, spu:%u];",
sig_log.notice("Thread time: %fs (%fGc); Faults: %u [rsx:%u, spu:%u]; [soft:%u hard:%u]; Switches:[vol:%u unvol:%u]",
time / 1000000000.,
cycles / 1000000000.,
g_tls_fault_all,
g_tls_fault_rsx,
g_tls_fault_spu);
g_tls_fault_spu,
fsoft, fhard, ctxvol, ctxinv);
// Return true if need to delete thread object
const bool result = m_state.exchange(thread_state::finished) == thread_state::detached;
const bool ok = m_state.exchange(thread_state::finished) <= thread_state::aborting;
// Signal waiting threads
m_state.notify_all();
return result;
// No detached thread supported atm
return !ok;
}
void thread_base::finalize() noexcept
@@ -1808,7 +1904,7 @@ void thread_ctrl::_wait_for(u64 usec, bool alert /* true */)
timeout.it_interval.tv_nsec = 0;
timerfd_settime(_this->m_timer, 0, &timeout, NULL);
if (read(_this->m_timer, &missed, sizeof(missed)) != sizeof(missed))
LOG_ERROR(GENERAL, "timerfd: read() failed");
sig_log.error("timerfd: read() failed");
return;
}
#endif
@@ -1857,8 +1953,27 @@ void thread_ctrl::_wait_for(u64 usec, bool alert /* true */)
}
}
std::string thread_ctrl::get_name_cached()
{
auto _this = thread_ctrl::g_tls_this_thread;
if (!_this)
{
return {};
}
static thread_local stx::shared_cptr<std::string> name_cache;
if (!_this->m_tname.is_equal(name_cache)) [[unlikely]]
{
name_cache = _this->m_tname.load();
}
return *name_cache;
}
thread_base::thread_base(std::string_view name)
: m_name(name)
: m_tname(stx::shared_cptr<std::string>::make(name))
{
}
@@ -1949,13 +2064,13 @@ void thread_ctrl::detect_cpu_layout()
// If buffer size is set to 0 bytes, it will be overwritten with the required size
if (GetLogicalProcessorInformationEx(relationship, nullptr, &buffer_size))
{
LOG_ERROR(GENERAL, "GetLogicalProcessorInformationEx returned 0 bytes");
sig_log.error("GetLogicalProcessorInformationEx returned 0 bytes");
return;
}
DWORD error_code = GetLastError();
if (error_code != ERROR_INSUFFICIENT_BUFFER)
{
LOG_ERROR(GENERAL, "Unexpected windows error code when detecting CPU layout: %u", error_code);
sig_log.error("Unexpected windows error code when detecting CPU layout: %u", error_code);
return;
}
@@ -1964,7 +2079,7 @@ void thread_ctrl::detect_cpu_layout()
if (!GetLogicalProcessorInformationEx(relationship,
reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *>(buffer.data()), &buffer_size))
{
LOG_ERROR(GENERAL, "GetLogicalProcessorInformationEx failed (size=%u, error=%u)", buffer_size, GetLastError());
sig_log.error("GetLogicalProcessorInformationEx failed (size=%u, error=%u)", buffer_size, GetLastError());
}
else
{
@@ -1984,7 +2099,7 @@ void thread_ctrl::detect_cpu_layout()
}
}
#else
LOG_TODO(GENERAL, "Thread scheduler is not implemented for Intel and this OS");
sig_log.todo("Thread scheduler is not implemented for Intel and this OS");
#endif
}
}
@@ -2160,7 +2275,7 @@ void thread_ctrl::set_native_priority(int priority)
if (!SetThreadPriority(_this_thread, native_priority))
{
LOG_ERROR(GENERAL, "SetThreadPriority() failed: 0x%x", GetLastError());
sig_log.error("SetThreadPriority() failed: 0x%x", GetLastError());
}
#else
int policy;
@@ -2175,7 +2290,7 @@ void thread_ctrl::set_native_priority(int priority)
if (int err = pthread_setschedparam(pthread_self(), policy, &param))
{
LOG_ERROR(GENERAL, "pthraed_setschedparam() failed: %d", err);
sig_log.error("pthraed_setschedparam() failed: %d", err);
}
#endif
}
@@ -2200,7 +2315,10 @@ void thread_ctrl::set_thread_affinity_mask(u64 mask)
if (shifted & 1)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
CPU_SET(core, &cs);
#pragma GCC diagnostic pop
}
if (shifted <= 1)
+104 -94
View File
@@ -2,6 +2,7 @@
#include "types.h"
#include "util/atomic.hpp"
#include "util/shared_cptr.hpp"
#include <string>
#include <memory>
@@ -37,8 +38,7 @@ enum class thread_class : u32
enum class thread_state : u32
{
created, // Initial state
detached, // The thread has been detached to destroy its own named_thread object (can be dangerously misused)
aborting, // The thread has been joined in the destructor or explicitly aborted (mutually exclusive with detached)
aborting, // The thread has been joined in the destructor or explicitly aborted
finished // Final state, always set at the end of thread execution
};
@@ -81,27 +81,6 @@ struct result_storage<void>
template <class Context, typename... Args>
using result_storage_t = result_storage<std::invoke_result_t<Context, Args...>>;
// Detect on_abort() method (should return void)
template <typename T, typename = void>
struct thread_on_abort : std::bool_constant<false> {};
template <typename T>
struct thread_on_abort<T, decltype(std::declval<named_thread<T>&>().on_abort())> : std::bool_constant<true> {};
// Detect on_cleanup() static member function (should return void) (in C++20 can use destroying delete instead)
template <typename T, typename = void>
struct thread_on_cleanup : std::bool_constant<false> {};
template <typename T>
struct thread_on_cleanup<T, decltype(named_thread<T>::on_cleanup(std::declval<named_thread<T>*>()))> : std::bool_constant<true> {};
// Detect on_wait() method (should return bool)
template <typename T, typename = bool>
struct thread_on_wait : std::bool_constant<false> {};
template <typename T>
struct thread_on_wait<T, decltype(std::declval<named_thread<T>&>().on_wait())> : std::bool_constant<true> {};
template <typename T, typename = void>
struct thread_thread_name : std::bool_constant<false> {};
@@ -142,7 +121,7 @@ class thread_base
atomic_t<const void*> m_state_notifier{nullptr};
// Thread name
lf_value<std::string> m_name;
stx::atomic_cptr<std::string> m_tname;
//
atomic_t<u64> m_cycles = 0;
@@ -197,31 +176,34 @@ class thread_ctrl final
friend class thread_base;
// Optimized get_name() for logging
static std::string get_name_cached();
public:
// Get current thread name
static std::string_view get_name()
static std::string get_name()
{
return g_tls_this_thread->m_name.get();
return *g_tls_this_thread->m_tname.load();
}
// Get thread name
template <typename T>
static std::string_view get_name(const named_thread<T>& thread)
static std::string get_name(const named_thread<T>& thread)
{
return static_cast<const thread_base&>(thread).m_name.get();
return *static_cast<const thread_base&>(thread).m_tname.load();
}
// Set current thread name (not recommended)
static void set_name(std::string_view name)
{
g_tls_this_thread->m_name.assign(name);
g_tls_this_thread->m_tname.store(stx::shared_cptr<std::string>::make(name));
}
// Set thread name (not recommended)
template <typename T>
static void set_name(named_thread<T>& thread, std::string_view name)
{
static_cast<thread_base&>(thread).m_name.assign(name);
static_cast<thread_base&>(thread).m_tname.store(stx::shared_cptr<std::string>::make(name));
}
template <typename T>
@@ -286,13 +268,6 @@ public:
// Sets the preferred affinity mask for this thread
static void set_thread_affinity_mask(u64 mask);
// Spawn a detached named thread
template <typename F>
[[deprecated]] static void spawn(std::string_view name, F&& func)
{
new named_thread<F>(thread_state::detached, name, std::forward<F>(func));
}
};
// Derived from the callable object Context, possibly a lambda
@@ -314,15 +289,7 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
// Perform self-cleanup if necessary
if (_this->entry_point())
{
// Call on_cleanup() static member function if it's available
if constexpr (thread_on_cleanup<Context>())
{
Context::on_cleanup(_this);
}
else
{
delete _this;
}
delete _this;
}
thread::finalize();
@@ -344,14 +311,6 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
return false;
}
if constexpr (thread_on_wait<Context>())
{
if (!static_cast<named_thread*>(_this)->on_wait())
{
return false;
}
}
_this->m_state_notifier.release(data);
if (!data)
@@ -365,15 +324,6 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
return false;
}
if constexpr (thread_on_wait<Context>())
{
if (!static_cast<named_thread*>(_this)->on_wait())
{
_this->m_state_notifier.release(nullptr);
return false;
}
}
return true;
});
@@ -391,35 +341,14 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
return thread::finalize(0);
}
static decltype(auto) get_default_thread_name()
{
if constexpr (thread_thread_name<Context>())
{
return Context::thread_name;
}
else
{
return "Unnamed Thread";
}
}
// Detached thread constructor
named_thread(thread_state s, std::string_view name, Context&& f)
: Context(std::forward<Context>(f))
, thread(name)
{
thread::m_state.raw() = s;
thread::start(&named_thread::entry_point);
}
friend class thread_ctrl;
public:
// Default constructor
template <bool Valid = std::is_default_constructible_v<Context>, typename = std::enable_if_t<Valid>>
template <bool Valid = std::is_default_constructible_v<Context> && thread_thread_name<Context>(), typename = std::enable_if_t<Valid>>
named_thread()
: Context()
, thread(get_default_thread_name())
, thread(Context::thread_name)
{
thread::start(&named_thread::entry_point);
}
@@ -473,19 +402,15 @@ public:
return thread::m_state.load();
}
// Try to abort/detach
// Try to abort by assigning thread_state::aborting (UB if assigning different state)
named_thread& operator=(thread_state s)
{
if (s < thread_state::finished && thread::m_state.compare_and_swap_test(thread_state::created, s))
ASSUME(s == thread_state::aborting);
if (s == thread_state::aborting && thread::m_state.compare_and_swap_test(thread_state::created, s))
{
if (s == thread_state::aborting)
{
// Call on_abort() method if it's available
if constexpr (thread_on_abort<Context>())
{
Context::on_abort();
}
thread::notify_abort();
}
}
@@ -496,6 +421,7 @@ public:
// Context type doesn't need virtual destructor
~named_thread()
{
// Assign aborting state forcefully
operator=(thread_state::aborting);
thread::join();
@@ -505,3 +431,87 @@ public:
}
}
};
// Group of named threads, similar to named_thread
template <class Context>
class named_thread_group final
{
using Thread = named_thread<Context>;
const u32 m_count;
Thread* m_threads;
public:
// Lambda constructor, also the implicit deduction guide candidate
named_thread_group(std::string_view name, u32 count, const Context& f)
: m_count(count)
, m_threads(nullptr)
{
if (count == 0)
{
return;
}
m_threads = static_cast<Thread*>(::operator new(sizeof(Thread) * m_count, std::align_val_t{alignof(Thread)}));
// Create all threads
for (u32 i = 0; i < m_count; i++)
{
new (static_cast<void*>(m_threads + i)) Thread(std::string(name) + std::to_string(i + 1), f);
}
}
named_thread_group(const named_thread_group&) = delete;
named_thread_group& operator=(const named_thread_group&) = delete;
// Wait for completion
void join() const
{
for (u32 i = 0; i < m_count; i++)
{
std::as_const(*std::launder(m_threads + i))();
}
}
// Join and access specific thread
auto operator[](u32 index) const
{
return std::as_const(*std::launder(m_threads + index))();
}
// Join and access specific thread
auto operator[](u32 index)
{
return (*std::launder(m_threads + index))();
}
// Dumb iterator
auto begin()
{
return std::launder(m_threads);
}
// Dumb iterator
auto end()
{
return m_threads + m_count;
}
u32 size() const
{
return m_count;
}
~named_thread_group()
{
// Destroy all threads (it should join them)
for (u32 i = 0; i < m_count; i++)
{
std::launder(m_threads + i)->~Thread();
}
::operator delete(static_cast<void*>(m_threads), std::align_val_t{alignof(Thread)});
}
};
+78 -1
View File
@@ -3,6 +3,8 @@
#include "File.h"
#include "Config.h"
LOG_CHANNEL(patch_log);
template <>
void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
{
@@ -40,7 +42,7 @@ void patch_engine::append(const std::string& patch)
}
catch (const std::exception& e)
{
LOG_FATAL(GENERAL, "Failed to load patch file %s\n%s thrown: %s", patch, typeid(e).name(), e.what());
patch_log.fatal("Failed to load patch file %s\n%s thrown: %s", patch, typeid(e).name(), e.what());
return;
}
@@ -173,3 +175,78 @@ std::size_t patch_engine::apply(const std::string& name, u8* dst) const
return found->second.size();
}
std::size_t patch_engine::apply_with_ls_check(const std::string& name, u8* dst, u32 filesz, u32 ls_addr) const
{
u32 rejected = 0;
const auto found = m_map.find(name);
if (found == m_map.cend())
{
return 0;
}
// Apply modifications sequentially
for (const auto& p : found->second)
{
auto ptr = dst + (p.offset - ls_addr);
if(p.offset < ls_addr || p.offset >= (ls_addr + filesz))
{
// This patch is out of range for this segment
rejected++;
continue;
}
switch (p.type)
{
case patch_type::load:
{
// Invalid in this context
break;
}
case patch_type::byte:
{
*ptr = static_cast<u8>(p.value);
break;
}
case patch_type::le16:
{
*reinterpret_cast<le_t<u16, 1>*>(ptr) = static_cast<u16>(p.value);
break;
}
case patch_type::le32:
case patch_type::lef32:
{
*reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
break;
}
case patch_type::le64:
case patch_type::lef64:
{
*reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
break;
}
case patch_type::be16:
{
*reinterpret_cast<be_t<u16, 1>*>(ptr) = static_cast<u16>(p.value);
break;
}
case patch_type::be32:
case patch_type::bef32:
{
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
break;
}
case patch_type::be64:
case patch_type::bef64:
{
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
break;
}
}
}
return (found->second.size() - rejected);
}
+2
View File
@@ -39,4 +39,6 @@ public:
// Apply patch (returns the number of entries applied)
std::size_t apply(const std::string& name, u8* dst) const;
// Apply patch with a check that the address exists in SPU local storage
std::size_t apply_with_ls_check(const std::string&name, u8*dst, u32 filesz, u32 ls_addr) const;
};
+17 -17
View File
@@ -136,7 +136,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case '8':
case '9':
{
if (UNLIKELY(ctx.width))
if (ctx.width) [[unlikely]]
{
drop_sequence();
}
@@ -150,7 +150,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case '*':
{
if (UNLIKELY(ctx.width || !src.test(ctx.args)))
if (ctx.width || !src.test(ctx.args)) [[unlikely]]
{
drop_sequence();
}
@@ -166,7 +166,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case '.':
{
if (UNLIKELY(ctx.dot || ctx.prec))
if (ctx.dot || ctx.prec) [[unlikely]]
{
drop_sequence();
}
@@ -177,7 +177,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
}
else if (*fmt == '*')
{
if (UNLIKELY(!src.test(ctx.args)))
if (!src.test(ctx.args)) [[unlikely]]
{
drop_sequence();
}
@@ -200,7 +200,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'h':
{
if (UNLIKELY(ctx.type))
if (ctx.type) [[unlikely]]
{
drop_sequence();
}
@@ -219,7 +219,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'l':
{
if (UNLIKELY(ctx.type))
if (ctx.type) [[unlikely]]
{
drop_sequence();
}
@@ -238,7 +238,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'z':
{
if (UNLIKELY(ctx.type))
if (ctx.type) [[unlikely]]
{
drop_sequence();
}
@@ -252,7 +252,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'j':
{
if (UNLIKELY(ctx.type))
if (ctx.type) [[unlikely]]
{
drop_sequence();
}
@@ -266,7 +266,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 't':
{
if (UNLIKELY(ctx.type))
if (ctx.type) [[unlikely]]
{
drop_sequence();
}
@@ -280,7 +280,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'c':
{
if (UNLIKELY(ctx.type || !src.test(ctx.args)))
if (ctx.type || !src.test(ctx.args)) [[unlikely]]
{
drop_sequence();
break;
@@ -302,7 +302,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 's':
{
if (UNLIKELY(ctx.type || !src.test(ctx.args)))
if (ctx.type || !src.test(ctx.args)) [[unlikely]]
{
drop_sequence();
break;
@@ -333,7 +333,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'd':
case 'i':
{
if (UNLIKELY(!src.test(ctx.args)))
if (!src.test(ctx.args)) [[unlikely]]
{
drop_sequence();
break;
@@ -395,7 +395,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'o':
{
if (UNLIKELY(!src.test(ctx.args)))
if (!src.test(ctx.args)) [[unlikely]]
{
drop_sequence();
break;
@@ -452,7 +452,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'x':
case 'X':
{
if (UNLIKELY(!src.test(ctx.args)))
if (!src.test(ctx.args)) [[unlikely]]
{
drop_sequence();
break;
@@ -516,7 +516,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'u':
{
if (UNLIKELY(!src.test(ctx.args)))
if (!src.test(ctx.args)) [[unlikely]]
{
drop_sequence();
break;
@@ -563,7 +563,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'p':
{
if (UNLIKELY(!src.test(ctx.args) || ctx.type))
if (!src.test(ctx.args) || ctx.type) [[unlikely]]
{
drop_sequence();
break;
@@ -597,7 +597,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
case 'g':
case 'G':
{
if (UNLIKELY(!src.test(ctx.args) || ctx.type))
if (!src.test(ctx.args) || ctx.type) [[unlikely]]
{
drop_sequence();
break;
+2
View File
@@ -1,3 +1,5 @@
#pragma once
#include <string>
namespace utils
+87 -46
View File
@@ -15,10 +15,6 @@ struct size2_base
{
}
constexpr size2_base(const size2_base& rhs) : width{ rhs.width }, height{ rhs.height }
{
}
constexpr size2_base operator -(const size2_base& rhs) const
{
return{ width - rhs.width, height - rhs.height };
@@ -101,18 +97,21 @@ struct size2_base
return *this;
}
constexpr bool operator == (const size2_base& rhs) const
constexpr bool operator ==(const size2_base& rhs) const
{
return width == rhs.width && height == rhs.height;
}
constexpr bool operator != (const size2_base& rhs) const
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator !=(const size2_base& rhs) const
{
return width != rhs.width || height != rhs.height;
}
#endif
template<typename NT>
constexpr operator size2_base<NT>() const
explicit constexpr operator size2_base<NT>() const
{
return{ static_cast<NT>(width), static_cast<NT>(height) };
}
@@ -212,6 +211,8 @@ struct position1_base
return x == rhs;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
bool operator !=(const position1_base& rhs) const
{
return !(*this == rhs);
@@ -221,9 +222,10 @@ struct position1_base
{
return !(*this == rhs);
}
#endif
template<typename NT>
operator position1_base<NT>() const
explicit operator position1_base<NT>() const
{
return{ static_cast<NT>(x) };
}
@@ -247,10 +249,6 @@ struct position2_base
{
}
constexpr position2_base(const position2_base& rhs) : x{ rhs.x }, y{ rhs.y }
{
}
constexpr bool operator >(const position2_base& rhs) const
{
return x > rhs.x && y > rhs.y;
@@ -385,6 +383,8 @@ struct position2_base
return x == rhs && y == rhs;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator !=(const position2_base& rhs) const
{
return !(*this == rhs);
@@ -394,9 +394,10 @@ struct position2_base
{
return !(*this == rhs);
}
#endif
template<typename NT>
constexpr operator position2_base<NT>() const
explicit constexpr operator position2_base<NT>() const
{
return{ static_cast<NT>(x), static_cast<NT>(y) };
}
@@ -477,6 +478,8 @@ struct position3_base
return x == rhs && y == rhs && z == rhs;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
bool operator !=(const position3_base& rhs) const
{
return !(*this == rhs);
@@ -486,9 +489,10 @@ struct position3_base
{
return !(*this == rhs);
}
#endif
template<typename NT>
operator position3_base<NT>() const
explicit operator position3_base<NT>() const
{
return{ static_cast<NT>(x), static_cast<NT>(y), static_cast<NT>(z) };
}
@@ -567,6 +571,8 @@ struct position4_base
return x == rhs && y == rhs && z == rhs && w == rhs;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator !=(const position4_base& rhs) const
{
return !(*this == rhs);
@@ -576,9 +582,10 @@ struct position4_base
{
return !(*this == rhs);
}
#endif
template<typename NT>
constexpr operator position4_base<NT>() const
explicit constexpr operator position4_base<NT>() const
{
return{ static_cast<NT>(x), static_cast<NT>(y), static_cast<NT>(z), static_cast<NT>(w) };
}
@@ -603,23 +610,11 @@ struct coord_base
};
constexpr coord_base() : position{}, size{}
#ifdef _MSC_VER
//compiler error
, x{}, y{}, width{}, height{}
#endif
{
}
constexpr coord_base(const position_base<T>& position, const size2_base<T>& size)
: position{ position }, size{ size }
#ifdef _MSC_VER
, x{ position.x }, y{ position.y }, width{ size.width }, height{ size.height }
#endif
{
}
constexpr coord_base(const coord_base<T>& other)
: position{ other.position }, size{ other.size }
{
}
@@ -644,13 +639,16 @@ struct coord_base
return position == rhs.position && size == rhs.size;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const coord_base& rhs) const
{
return position != rhs.position || size != rhs.size;
}
#endif
template<typename NT>
constexpr operator coord_base<NT>() const
explicit constexpr operator coord_base<NT>() const
{
return{ static_cast<NT>(x), static_cast<NT>(y), static_cast<NT>(width), static_cast<NT>(height) };
}
@@ -720,10 +718,13 @@ struct area_base
return x1 == rhs.x1 && x2 == rhs.x2 && y1 == rhs.y1 && y2 == rhs.y2;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const area_base& rhs) const
{
return !(*this == rhs);
}
#endif
constexpr area_base operator - (const size2_base<T>& size) const
{
@@ -759,7 +760,7 @@ struct area_base
}
template<typename NT>
constexpr operator area_base<NT>() const
explicit constexpr operator area_base<NT>() const
{
return{ static_cast<NT>(x1), static_cast<NT>(y1), static_cast<NT>(x2), static_cast<NT>(y2) };
}
@@ -769,15 +770,6 @@ template<typename T>
struct size3_base
{
T width, height, depth;
/*
size3_base() : width{}, height{}, depth{}
{
}
size3_base(T width, T height, T depth) : width{ width }, height{ height }, depth{ depth }
{
}
*/
};
template<typename T>
@@ -822,7 +814,7 @@ struct coord3_base
}
template<typename NT>
constexpr operator coord3_base<NT>() const
explicit constexpr operator coord3_base<NT>() const
{
return{ static_cast<NT>(x), static_cast<NT>(y), static_cast<NT>(z), static_cast<NT>(width), static_cast<NT>(height), static_cast<NT>(depth) };
}
@@ -856,7 +848,7 @@ struct color4_base
{
}
constexpr color4_base(T x, T y = {}, T z = {}, T w = {})
constexpr color4_base(T x, T y, T z, T w)
: x(x)
, y(y)
, z(z)
@@ -864,18 +856,59 @@ struct color4_base
{
}
constexpr color4_base(T value)
: x(value)
, y(value)
, z(value)
, w(value)
{
}
constexpr bool operator == (const color4_base& rhs) const
{
return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const color4_base& rhs) const
{
return !(*this == rhs);
}
#endif
void operator *= (const color4_base<T>& rhs)
{
r *= rhs.r;
g *= rhs.g;
b *= rhs.b;
a *= rhs.a;
}
void operator *= (const T& rhs)
{
r *= rhs;
g *= rhs;
b *= rhs;
a *= rhs;
}
constexpr color4_base<T> operator * (const color4_base<T>& rhs) const
{
return { r * rhs.r, g * rhs.g, b * rhs.b, a * rhs.a };
}
constexpr color4_base<T> operator * (const T& rhs) const
{
return { r * rhs, g * rhs, b * rhs, a * rhs };
}
constexpr color4_base<T> operator + (const color4_base<T>& rhs) const
{
return { r + rhs.r, g + rhs.g, b + rhs.b, a + rhs.a };
}
template<typename NT>
constexpr operator color4_base<NT>() const
explicit constexpr operator color4_base<NT>() const
{
return{ static_cast<NT>(x), static_cast<NT>(y), static_cast<NT>(z), static_cast<NT>(w) };
}
@@ -911,14 +944,16 @@ struct color3_base
{
return r == rhs.r && g == rhs.g && b == rhs.b;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const color3_base& rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
constexpr operator color3_base<NT>() const
explicit constexpr operator color3_base<NT>() const
{
return{ static_cast<NT>(x), static_cast<NT>(y), static_cast<NT>(z) };
}
@@ -954,13 +989,16 @@ struct color2_base
return r == rhs.r && g == rhs.g;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const color2_base& rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
constexpr operator color2_base<NT>() const
explicit constexpr operator color2_base<NT>() const
{
return{ static_cast<NT>(x), static_cast<NT>(y) };
}
@@ -985,13 +1023,16 @@ struct color1_base
return r == rhs.r;
}
#if __cpp_impl_three_way_comparison >= 201711
#else
constexpr bool operator != (const color1_base& rhs) const
{
return !(*this == rhs);
}
#endif
template<typename NT>
constexpr operator color1_base<NT>() const
explicit constexpr operator color1_base<NT>() const
{
return{ static_cast<NT>(x) };
}
+16 -140
View File
@@ -22,7 +22,7 @@ public:
~lf_array()
{
for (auto ptr = m_next.raw(); UNLIKELY(ptr);)
for (auto ptr = m_next.raw(); ptr;)
{
delete std::exchange(ptr, std::exchange(ptr->m_next.raw(), nullptr));
}
@@ -30,14 +30,14 @@ public:
T& operator [](std::size_t index)
{
if (LIKELY(index < N))
if (index < N) [[likely]]
{
return m_data[index];
}
else if (UNLIKELY(!m_next))
else if (!m_next) [[unlikely]]
{
// Create new array block. It's not a full-fledged once-synchronization, unlikely needed.
for (auto _new = new lf_array, ptr = this; UNLIKELY(ptr);)
for (auto _new = new lf_array, ptr = this; ptr;)
{
// Install the pointer. If failed, go deeper.
ptr = ptr->m_next.compare_and_swap(nullptr, _new);
@@ -54,98 +54,50 @@ public:
template<typename T, std::size_t N>
class lf_fifo : public lf_array<T, N>
{
struct alignas(8) ctrl_t
{
u32 push;
u32 pop;
};
atomic_t<ctrl_t> m_ctrl{};
// LSB 32-bit: push, MSB 32-bit: pop
atomic_t<u64> m_ctrl{};
public:
constexpr lf_fifo() = default;
// Get current "push" position
// Get number of elements in the queue
u32 size() const
{
return m_ctrl.load().push;
const u64 ctrl = m_ctrl.load();
return static_cast<u32>(ctrl - (ctrl >> 32));
}
// Acquire the place for one or more elements.
u32 push_begin(u32 count = 1)
{
return std::bit_cast<atomic_t<u64>*>(&m_ctrl)->fetch_add(count); // Hack
return static_cast<u32>(m_ctrl.fetch_add(count));
}
// Get current "pop" position
u32 peek() const
{
return m_ctrl.load().pop;
return static_cast<u32>(m_ctrl >> 32);
}
// Acknowledge processed element, return number of the next one.
// Perform clear if possible, zero is returned in this case.
u32 pop_end(u32 count = 1)
{
return m_ctrl.atomic_op([&](ctrl_t& ctrl)
return m_ctrl.atomic_op([&](u64& ctrl)
{
ctrl.pop += count;
ctrl += u64{count} << 32;
if (ctrl.pop == ctrl.push)
if (ctrl >> 32 == static_cast<u32>(ctrl))
{
// Clean if possible
ctrl.push = 0;
ctrl.pop = 0;
ctrl = 0;
}
return ctrl.pop;
return static_cast<u32>(ctrl >> 32);
});
}
};
//! Simple lock-free map. Based on lf_array<>. All elements are accessible, implicitly initialized.
template<typename K, typename T, typename Hash = value_hash<K>, std::size_t Size = 256>
class lf_hashmap
{
struct pair_t
{
// Default-constructed key means "no key"
atomic_t<K> key{};
T value{};
};
//
lf_array<pair_t, Size> m_data{};
// Value for default-constructed key
T m_default_key_data{};
public:
constexpr lf_hashmap() = default;
// Access element (added implicitly)
T& operator [](const K& key)
{
if (UNLIKELY(key == K{}))
{
return m_default_key_data;
}
// Calculate hash and array position
for (std::size_t pos = Hash{}(key) % Size;; pos += Size)
{
// Access the array
auto& pair = m_data[pos];
// Check the key value (optimistic)
if (LIKELY(pair.key == key) || pair.key.compare_and_swap_test(K{}, key))
{
return pair.value;
}
}
}
};
// Helper type, linked list element
template <typename T>
class lf_queue_item final
@@ -536,79 +488,3 @@ public:
return {};
}
};
// Assignable lock-free thread-safe value of any type (memory-inefficient)
template <typename T>
class lf_value final
{
atomic_t<lf_value*> m_head;
T m_data;
public:
template <typename... Args>
explicit constexpr lf_value(Args&&... args)
: m_head(this)
, m_data(std::forward<Args>(args)...)
{
}
~lf_value()
{
// All values are kept in the queue until the end
for (lf_value* ptr = m_head.load(); ptr != this;)
{
delete std::exchange(ptr, std::exchange(ptr->m_head.raw(), ptr));
}
}
// Get current head, allows to inspect old values
[[nodiscard]] const lf_value* head() const
{
return m_head.load();
}
// Inspect the initial (oldest) value
[[nodiscard]] const T& first() const
{
return m_data;
}
[[nodiscard]] const T& get() const
{
return m_head.load()->m_data;
}
[[nodiscard]] operator const T&() const
{
return m_head.load()->m_data;
}
// Construct new value in-place
template <typename... Args>
const T& assign(Args&&... args)
{
lf_value* val = new lf_value(std::forward<Args>(args)...);
lf_value* old = m_head.load();
do
{
val->m_head = old;
}
while (!m_head.compare_exchange(old, val));
return val->m_data;
}
// Copy-assign new value
const T& operator =(const T& value)
{
return assign(value);
}
// Move-assign new value
const T& operator =(T&& value)
{
return assign(std::move(value));
}
};
+15 -15
View File
@@ -45,7 +45,7 @@ public:
{
const u32 value = m_value.load();
if (UNLIKELY(value >= c_one - 1 || !m_value.compare_and_swap_test(value, value + 1)))
if (value >= c_one - 1 || !m_value.compare_and_swap_test(value, value + 1)) [[unlikely]]
{
imp_lock_shared(value);
}
@@ -55,10 +55,10 @@ public:
{
const u32 value = m_value.load();
if (LIKELY(value < c_one - 1))
if (value < c_one - 1) [[likely]]
{
u32 old = value;
if (LIKELY(atomic_storage<u32>::compare_exchange_hle_acq(m_value.raw(), old, value + 1)))
if (atomic_storage<u32>::compare_exchange_hle_acq(m_value.raw(), old, value + 1)) [[likely]]
{
return;
}
@@ -72,7 +72,7 @@ public:
// Unconditional decrement (can result in broken state)
const u32 value = m_value.fetch_sub(1);
if (UNLIKELY(value >= c_one))
if (value >= c_one) [[unlikely]]
{
imp_unlock_shared(value);
}
@@ -82,7 +82,7 @@ public:
{
const u32 value = atomic_storage<u32>::fetch_add_hle_rel(m_value.raw(), -1);
if (UNLIKELY(value >= c_one))
if (value >= c_one) [[unlikely]]
{
imp_unlock_shared(value);
}
@@ -100,7 +100,7 @@ public:
{
const u32 value = m_value.load();
if (UNLIKELY(value >= c_vip - 1 || !m_value.compare_and_swap_test(value, value + 1)))
if (value >= c_vip - 1 || !m_value.compare_and_swap_test(value, value + 1)) [[unlikely]]
{
imp_lock_low(value);
}
@@ -111,7 +111,7 @@ public:
// Unconditional decrement (can result in broken state)
const u32 value = m_value.fetch_sub(1);
if (UNLIKELY(value >= c_one))
if (value >= c_one) [[unlikely]]
{
imp_unlock_low(value);
}
@@ -129,7 +129,7 @@ public:
{
const u32 value = m_value.load();
if (UNLIKELY((value >= c_one - 1 && !(value & (c_one - c_vip))) || (value % c_vip) || !m_value.compare_and_swap_test(value, value + c_vip)))
if ((value >= c_one - 1 && !(value & (c_one - c_vip))) || (value % c_vip) || !m_value.compare_and_swap_test(value, value + c_vip)) [[unlikely]]
{
imp_lock_vip(value);
}
@@ -140,7 +140,7 @@ public:
// Unconditional decrement (can result in broken state)
const u32 value = m_value.fetch_sub(c_vip);
if (UNLIKELY(value >= c_one))
if (value >= c_one) [[unlikely]]
{
imp_unlock_vip(value);
}
@@ -155,7 +155,7 @@ public:
{
const u32 value = m_value.compare_and_swap(0, c_one);
if (UNLIKELY(value))
if (value) [[unlikely]]
{
imp_lock(value);
}
@@ -165,7 +165,7 @@ public:
{
u32 value = 0;
if (UNLIKELY(!atomic_storage<u32>::compare_exchange_hle_acq(m_value.raw(), value, c_one)))
if (!atomic_storage<u32>::compare_exchange_hle_acq(m_value.raw(), value, c_one)) [[unlikely]]
{
imp_lock(value);
}
@@ -176,7 +176,7 @@ public:
// Unconditional decrement (can result in broken state)
const u32 value = m_value.fetch_sub(c_one);
if (UNLIKELY(value != c_one))
if (value != c_one) [[unlikely]]
{
imp_unlock(value);
}
@@ -186,7 +186,7 @@ public:
{
const u32 value = atomic_storage<u32>::fetch_add_hle_rel(m_value.raw(), 0u - c_one);
if (UNLIKELY(value != c_one))
if (value != c_one) [[unlikely]]
{
imp_unlock(value);
}
@@ -202,7 +202,7 @@ public:
void lock_upgrade()
{
if (UNLIKELY(!try_lock_upgrade()))
if (!try_lock_upgrade()) [[unlikely]]
{
imp_lock_upgrade();
}
@@ -223,7 +223,7 @@ public:
// Optimized wait for lockability without locking, relaxed
void lock_unlock()
{
if (UNLIKELY(m_value != 0))
if (m_value != 0) [[unlikely]]
{
imp_lock_unlock();
}
+2 -1
View File
@@ -1,6 +1,7 @@
#pragma once
#pragma once
#include <pugixml.hpp>
#include <memory>
struct rXmlNode
{
+2 -2
View File
@@ -26,7 +26,7 @@ protected:
const s32 value = m_value.load();
// Conditional decrement
if (UNLIKELY(value <= 0 || !m_value.compare_and_swap_test(value, value - 1)))
if (value <= 0 || !m_value.compare_and_swap_test(value, value - 1)) [[unlikely]]
{
imp_wait();
}
@@ -42,7 +42,7 @@ protected:
// Unconditional increment
const s32 value = m_value.fetch_add(1);
if (UNLIKELY(value < 0 || value >= _max))
if (value < 0 || value >= _max) [[unlikely]]
{
imp_post(value);
}
+36 -16
View File
@@ -1,7 +1,7 @@
#include "sysinfo.h"
#include "StrFmt.h"
#include "File.h"
#include "Emu/System.h"
#include "Emu/system_config.h"
#ifdef _WIN32
#include "windows.h"
@@ -75,9 +75,8 @@ bool utils::has_clwb()
return g_value;
}
std::string utils::get_system_info()
std::string utils::get_cpu_brand()
{
std::string result;
std::string brand;
if (get_cpuid(0x80000000, 0)[0] >= 0x80000004)
@@ -101,18 +100,16 @@ std::string utils::get_system_info()
brand.erase(brand.begin() + found);
}
#ifdef _WIN32
::SYSTEM_INFO sysInfo;
::GetNativeSystemInfo(&sysInfo);
::MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(memInfo);
::GlobalMemoryStatusEx(&memInfo);
const u32 num_proc = sysInfo.dwNumberOfProcessors;
const u64 mem_total = memInfo.ullTotalPhys;
#else
const u32 num_proc = ::sysconf(_SC_NPROCESSORS_ONLN);
const u64 mem_total = ::sysconf(_SC_PHYS_PAGES) * ::sysconf(_SC_PAGE_SIZE);
#endif
return brand;
}
std::string utils::get_system_info()
{
std::string result;
const std::string brand = get_cpu_brand();
const u64 mem_total = get_total_memory();
const u32 num_proc = get_thread_count();
fmt::append(result, "%s | %d Threads | %.2f GiB RAM", brand, num_proc, mem_total / (1024.0f * 1024 * 1024));
@@ -189,7 +186,7 @@ std::string utils::get_firmware_version()
std::string utils::get_OS_version()
{
std::string output = "";
std::string output;
#ifdef _WIN32
// GetVersionEx is deprecated, RtlGetVersion is kernel-mode only and AnalyticsInfo is UWP only.
// So we're forced to read PEB instead to get Windows version info. It's ugly but works.
@@ -242,3 +239,26 @@ ullong utils::get_tsc_freq()
return 0;
#endif
}
u64 utils::get_total_memory()
{
#ifdef _WIN32
::MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(memInfo);
::GlobalMemoryStatusEx(&memInfo);
return memInfo.ullTotalPhys;
#else
return ::sysconf(_SC_PHYS_PAGES) * ::sysconf(_SC_PAGE_SIZE);
#endif
}
u32 utils::get_thread_count()
{
#ifdef _WIN32
::SYSTEM_INFO sysInfo;
::GetNativeSystemInfo(&sysInfo);
return sysInfo.dwNumberOfProcessors;
#else
return ::sysconf(_SC_NPROCESSORS_ONLN);
#endif
}
+6
View File
@@ -47,6 +47,8 @@ namespace utils
bool has_clwb();
std::string get_cpu_brand();
std::string get_system_info();
std::string get_firmware_version();
@@ -54,4 +56,8 @@ namespace utils
std::string get_OS_version();
ullong get_tsc_freq();
u64 get_total_memory();
u32 get_thread_count();
}
+12 -12
View File
@@ -658,7 +658,7 @@ namespace utils
static_assert(!std::is_volatile_v<std::remove_reference_t<Type>>);
// Try to acquire the semaphore
if (UNLIKELY(!head->m_sema.try_inc(last + 1)))
if (!head->m_sema.try_inc(last + 1)) [[unlikely]]
{
block = nullptr;
}
@@ -671,7 +671,7 @@ namespace utils
if (block->m_type == 0 && block->m_mutex.try_lock())
{
if (LIKELY(block->m_type == 0))
if (block->m_type == 0) [[likely]]
{
break;
}
@@ -695,7 +695,7 @@ namespace utils
{
block = nullptr;
}
else if (UNLIKELY(block->m_type != 0))
else if (block->m_type != 0) [[unlikely]]
{
block->m_mutex.unlock();
block = nullptr;
@@ -737,13 +737,13 @@ namespace utils
block = reinterpret_cast<typemap_block*>(head->m_ptr + std::size_t{head->m_ssize} * unscaled);
// Check id range and type
if (UNLIKELY(unscaled >= typeinfo_count<Type>::max_count || unbiased % step))
if (unscaled >= typeinfo_count<Type>::max_count || unbiased % step) [[unlikely]]
{
block = nullptr;
}
else
{
if (UNLIKELY(block->m_type == 0))
if (block->m_type == 0) [[unlikely]]
{
block = nullptr;
}
@@ -785,12 +785,12 @@ namespace utils
}
else if constexpr (std::is_invocable_r_v<bool, const Arg&, const Type&>)
{
if (UNLIKELY(!block))
if (!block) [[unlikely]]
{
return;
}
if (LIKELY(block->m_type))
if (block->m_type) [[likely]]
{
if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>())))
{
@@ -800,7 +800,7 @@ namespace utils
}
else if (block)
{
if (LIKELY(block->m_type))
if (block->m_type) [[likely]]
{
return;
}
@@ -848,7 +848,7 @@ namespace utils
}
else if constexpr (is_const || is_volatile)
{
if (LIKELY(block->m_mutex.is_lockable()))
if (block->m_mutex.is_lockable()) [[likely]]
{
return true;
}
@@ -858,7 +858,7 @@ namespace utils
}
else
{
if (LIKELY(block->m_mutex.is_free()))
if (block->m_mutex.is_free()) [[likely]]
{
return true;
}
@@ -878,7 +878,7 @@ namespace utils
if constexpr (I + 1 < N)
{
// Proceed recursively
if (LIKELY(try_lock<I + 1, Types...>(array, locked, std::integer_sequence<bool, Locks...>{})))
if (try_lock<I + 1, Types...>(array, locked, std::integer_sequence<bool, Locks...>{})) [[likely]]
{
return true;
}
@@ -973,7 +973,7 @@ namespace utils
while (true)
{
const uint locked = lock_array<decode_t<Types>...>(result, seq_t{}, locks_t{});
if (LIKELY(try_lock<0, decode_t<Types>...>(result, locked, locks_t{})))
if (try_lock<0, decode_t<Types>...>(result, locked, locks_t{})) [[likely]]
break;
}
+86 -23
View File
@@ -17,9 +17,9 @@
#include <limits>
#include <array>
// Assume little-endian
#define IS_LE_MACHINE 1
#define IS_BE_MACHINE 0
#if __has_include(<bit>)
#include <bit>
#endif
#ifndef __has_builtin
#define __has_builtin(x) 0
@@ -28,8 +28,6 @@
#ifdef _MSC_VER
#define ASSUME(...) __assume(__VA_ARGS__) // MSVC __assume ignores side-effects
#define LIKELY
#define UNLIKELY
#define SAFE_BUFFERS __declspec(safebuffers)
#define NEVER_INLINE __declspec(noinline)
#define FORCE_INLINE __forceinline
@@ -48,8 +46,6 @@
#define ASSUME(...) do { if (!(__VA_ARGS__)) __builtin_unreachable(); } while (0) // note: the compiler will generate code to evaluate "cond" if the expression is opaque
#endif
#define LIKELY(...) __builtin_expect(!!(__VA_ARGS__), 1)
#define UNLIKELY(...) __builtin_expect(!!(__VA_ARGS__), 0)
#define SAFE_BUFFERS
#define NEVER_INLINE __attribute__((noinline))
#define FORCE_INLINE __attribute__((always_inline)) inline
@@ -86,7 +82,7 @@
#define AUDIT(...) ((void)0)
#endif
#if defined(__cpp_lib_bit_cast) && (__cpp_lib_bit_cast >= 201806L)
#if __cpp_lib_bit_cast >= 201806L
#include <bit>
#else
namespace std
@@ -413,6 +409,48 @@ struct alignas(16) s128
CHECK_SIZE_ALIGN(u128, 16, 16);
CHECK_SIZE_ALIGN(s128, 16, 16);
// Return magic value for any unsigned type
constexpr inline struct umax_helper
{
constexpr umax_helper() noexcept = default;
template <typename T, typename S = simple_t<T>, typename = std::enable_if_t<std::is_unsigned_v<S>>>
explicit constexpr operator T() const
{
return std::numeric_limits<S>::max();
}
template <typename T, typename S = simple_t<T>, typename = std::enable_if_t<std::is_unsigned_v<S>>>
constexpr bool operator==(const T& rhs) const
{
return rhs == std::numeric_limits<S>::max();
}
#if __cpp_impl_three_way_comparison >= 201711 && !__INTELLISENSE__
#else
template <typename T>
friend constexpr std::enable_if_t<std::is_unsigned_v<simple_t<T>>, bool> operator==(const T& lhs, const umax_helper& rhs)
{
return lhs == std::numeric_limits<simple_t<T>>::max();
}
#endif
#if __cpp_impl_three_way_comparison >= 201711
#else
template <typename T, typename S = simple_t<T>, typename = std::enable_if_t<std::is_unsigned_v<S>>>
constexpr bool operator!=(const T& rhs) const
{
return rhs != std::numeric_limits<S>::max();
}
template <typename T>
friend constexpr std::enable_if_t<std::is_unsigned_v<simple_t<T>>, bool> operator!=(const T& lhs, const umax_helper& rhs)
{
return lhs != std::numeric_limits<simple_t<T>>::max();
}
#endif
} umax;
using f32 = float;
using f64 = double;
@@ -534,31 +572,56 @@ constexpr u32 to_u8(char c)
return static_cast<u8>(c);
}
// Convert 2-byte string to u16 value like reinterpret_cast does
// Convert 1-2-byte string to u16 value like reinterpret_cast does
constexpr u16 operator""_u16(const char* s, std::size_t /*length*/)
{
return
#if IS_LE_MACHINE == 1
static_cast<u16>(to_u8(s[1]) << 8 | to_u8(s[0]));
#endif
if constexpr (std::endian::little == std::endian::native)
{
return static_cast<u16>(to_u8(s[1]) << 8 | to_u8(s[0]));
}
else
{
return static_cast<u16>(to_u8(s[0]) << 8 | to_u8(s[1]));
}
}
// Convert 4-byte string to u32 value like reinterpret_cast does
// Convert 3-4-byte string to u32 value like reinterpret_cast does
constexpr u32 operator""_u32(const char* s, std::size_t /*length*/)
{
return
#if IS_LE_MACHINE == 1
to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]);
#endif
if constexpr (std::endian::little == std::endian::native)
{
return to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]);
}
else
{
return to_u8(s[0]) << 24 | to_u8(s[1]) << 16 | to_u8(s[2]) << 8 | to_u8(s[3]);
}
}
// Convert 8-byte string to u64 value like reinterpret_cast does
// Convert 5-6-byte string to u64 value like reinterpret_cast does
constexpr u64 operator""_u48(const char* s, std::size_t /*length*/)
{
if constexpr (std::endian::little == std::endian::native)
{
return static_cast<u64>(to_u8(s[5]) << 8 | to_u8(s[4])) << 32 | to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]);
}
else
{
return static_cast<u64>(to_u8(s[0]) << 8 | to_u8(s[1])) << 32 | to_u8(s[2]) << 24 | to_u8(s[3]) << 16 | to_u8(s[4]) << 8 | to_u8(s[5]);
}
}
// Convert 7-8-byte string to u64 value like reinterpret_cast does
constexpr u64 operator""_u64(const char* s, std::size_t /*length*/)
{
return
#if IS_LE_MACHINE == 1
static_cast<u64>(to_u8(s[7]) << 24 | to_u8(s[6]) << 16 | to_u8(s[5]) << 8 | to_u8(s[4])) << 32 | to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]);
#endif
if constexpr (std::endian::little == std::endian::native)
{
return static_cast<u64>(to_u8(s[7]) << 24 | to_u8(s[6]) << 16 | to_u8(s[5]) << 8 | to_u8(s[4])) << 32 | to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]);
}
else
{
return static_cast<u64>(to_u8(s[0]) << 24 | to_u8(s[1]) << 16 | to_u8(s[2]) << 8 | to_u8(s[3])) << 32 | to_u8(s[4]) << 24 | to_u8(s[5]) << 16 | to_u8(s[6]) << 8 | to_u8(s[7]);
}
}
namespace fmt
+3 -3
View File
@@ -1,8 +1,8 @@
set(BUILD_EXTERNAL OFF CACHE BOOL "Build external dependencies in /External" FORCE)
set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "Skip installation" FORCE)
set(ENABLE_SPVREMAPPER OFF CACHE BOOL "Enables building of SPVRemapper" FORCE)
set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "Builds glslangValidator and spirv-remap" FORCE)
set(ENABLE_OPT OFF CACHE BOOL "Enables spirv-opt capability if present" FORCE)
set(ENABLE_HLSL OFF CACHE BOOL "Enables HLSL input support" FORCE)
set(ENABLE_AMD_EXTENSIONS ON CACHE BOOL "Enables support of AMD-specific extensions" FORCE)
set(ENABLE_NV_EXTENSIONS ON CACHE BOOL "Enables support of Nvidia-specific extensions" FORCE)
set(ENABLE_OPT OFF CACHE BOOL "Enables spirv-opt capability if present" FORCE)
set(ENABLE_CTEST OFF CACHE BOOL "Enables testing" FORCE)
add_subdirectory(glslang)
+6 -6
View File
@@ -41,24 +41,24 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)rpcs3_glslang.props /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)rpcs3_glslang.props /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)rpcs3_glslang.props /m</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)rpcs3_glslang.props /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)rpcs3_glslang.props /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)rpcs3_glslang.props /m
</NMakeCleanCommandLine>
</PropertyGroup>
<ItemDefinitionGroup>
+2 -6
View File
@@ -4,10 +4,9 @@ version: '{build}'
image: Visual Studio 2019
environment:
QTDIR: C:\Qt\5.13\msvc2017_64
QT_URL: https://cdn.discordapp.com/attachments/442667232489897997/614126952953020416/msvc2017_64.7z
QTDIR: C:\Qt\5.14\msvc2017_64
LLVMLIBS: https://github.com/RPCS3/llvm/releases/download/continuous-master/llvmlibs.7z
GLSLANG: https://www.dropbox.com/s/ku2qgwmtfptzbvx/glslang.7z?dl=1
GLSLANG: https://www.dropbox.com/s/6e8w6t5dxh3ad4l/glslang.7z?dl=1
COMPATDB: https://rpcs3.net/compatibility?api=v1&export
VULKAN_SDK: "C:\\VulkanSDK\\1.1.126.0"
VULKAN_SDK_URL: https://sdk.lunarg.com/sdk/download/1.1.126.0/windows/VulkanSDK-1.1.126.0-Installer.exe
@@ -17,7 +16,6 @@ cache:
- glslang.7z -> appveyor.yml
- compat_database.dat
- vulkan-sdk.exe -> appveyor.yml
- msvc2017_64.7z -> appveyor.yml
install:
- ps: | # set env vars for versioning
@@ -76,10 +74,8 @@ before_build:
)
if (!(test-path llvmlibs.7z)) { irm $env:LLVMLIBS -outfile llvmlibs.7z }
if (!(test-path glslang.7z)) { irm $env:GLSLANG -outfile glslang.7z }
if (!(test-path msvc2017_64.7z)) { irm $env:QT_URL -outfile msvc2017_64.7z }
7z x llvmlibs.7z -aos -o"." | out-null
7z x glslang.7z -aos -o".\lib\$env:CONFIGURATION-$env:PLATFORM" | out-null
7z x msvc2017_64.7z -aos -o"C:\Qt\5.13" | out-null
if (!(test-path vulkan-sdk.exe))
{
foreach ($url in $VULKAN_SDK_URLS) {
+4 -4
View File
@@ -80,14 +80,14 @@ QToolTip {
}
/* CG Disasm: background-image doesn't work, use static color */
QWidget#cg_disasm {
/* CG Disasm and Trophy Manager: background-image doesn't work, use static color */
QWidget#cg_disasm, QWidget#trophy_manager {
background: #b3ac98;
}
/* Main Window, Dialogs and Trophy Manager which isn't a dialog */
QDialog, QWidget#trophy_manager, QMainWindow#main_window {
/* Main Window and Dialogs */
QDialog, QMainWindow#main_window {
border-image: url("GuiConfigs/YoRHa-background.jpg");
}
Binary file not shown.
+5 -1
View File
@@ -8,8 +8,12 @@
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<LanguageStandard>stdcpp17</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>-d2FH4- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
+1 -1
Submodule llvm updated: 2e038bff10...1394b1ccc8
+6 -4
View File
@@ -110,11 +110,13 @@ else()
target_link_libraries(rpcs3 ${CMAKE_DL_LIBS})
endif()
set_target_properties(rpcs3 PROPERTIES
COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h"
COTIRE_ADD_UNITY_BUILD OFF)
if(USE_COTIRE)
set_target_properties(rpcs3 PROPERTIES
COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h"
COTIRE_ADD_UNITY_BUILD OFF)
cotire(rpcs3)
cotire(rpcs3)
endif()
# Copy icons to executable directory
if(APPLE)
+110 -107
View File
@@ -1,12 +1,15 @@
#include "utils.h"
#include "utils.h"
#include "aes.h"
#include "key_vault.h"
SELF_KEY::SELF_KEY(u64 ver, u16 rev, u32 type, const std::string& e, const std::string& r, const std::string& pb, const std::string& pr, u32 ct)
LOG_CHANNEL(key_vault_log, "KEY_VAULT");
SELF_KEY::SELF_KEY(u64 ver_start, u64 ver_end, u16 rev, u32 type, const std::string& e, const std::string& r, const std::string& pb, const std::string& pr, u32 ct)
{
version = ver;
revision = rev;
self_type = type;
version_start = ver_start;
version_end = ver_end;
revision = rev;
self_type = type;
hex_to_bytes(erk, e.c_str(), 0);
hex_to_bytes(riv, r.c_str(), 0);
hex_to_bytes(pub, pb.c_str(), 0);
@@ -21,7 +24,7 @@ KeyVault::KeyVault()
void KeyVault::LoadSelfLV0Keys()
{
sk_LV0_arr.clear();
sk_LV0_arr.emplace_back(0x0000000000000000, 0x0000, KEY_LV0,
sk_LV0_arr.emplace_back(0x0000000000000000, 0x0000000000000000, 0x0000, KEY_LV0,
"CA7A24EC38BDB45B98CCD7D363EA2AF0C326E65081E0630CB9AB2D215865878A",
"F9205F46F6021697E670F13DFA726212",
"A8FD6DB24532D094EFA08CB41C9A72287D905C6B27B42BE4AB925AAF4AFFF34D41EEB54DD128700D",
@@ -32,7 +35,7 @@ void KeyVault::LoadSelfLV0Keys()
void KeyVault::LoadSelfLDRKeys()
{
sk_LDR_arr.clear();
sk_LDR_arr.emplace_back(0x0000000000000000, 0x0000, KEY_LDR,
sk_LDR_arr.emplace_back(0x0000000000000000, 0x0000000000000000, 0x0000, KEY_LDR,
"C0CEFE84C227F75BD07A7EB846509F93B238E770DACB9FF4A388F812482BE21B",
"47EE7454E4774CC9B8960C7B59F4C14D",
"C2D4AAF319355019AF99D44E2B58CA29252C89123D11D6218F40B138CAB29B7101F3AEB72A975019",
@@ -43,61 +46,61 @@ void KeyVault::LoadSelfLDRKeys()
void KeyVault::LoadSelfLV1Keys()
{
sk_LV1_arr.clear();
sk_LV1_arr.emplace_back(0x0003003000000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0003000000000000, 0x0003003100000000, 0x0000, KEY_LV1,
"B9F3F9E6107CFF2680A91E118C2403CF4A6F18F3C7EFD7D13D1AC4DB760BD222",
"B43661B9A79BAD9D8E2B046469CDA1E7",
"4C870BE86DDD996A92A3F7F404F33604244A1D02AB5B78BC9DAF030B78BE8867CF586171B7D45D20",
"002CC736C7AD06D264E9AB663EB1F35F5DC159248C",
0x33);
sk_LV1_arr.emplace_back(0x0003004200000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0003004000000000, 0x0003004200000000, 0x0000, KEY_LV1,
"B880593856C8C6D2037585626A12977F50DCFCF3F132D2C89AA6E670EAFC1646",
"A79B05D4E37B8117A95E6E7C14FB640E",
"7454C7CCBFC2F66C142D78A730A3A6F973CC0FB75A46FCBB390790138910A0CAC78E5E21F4DA3375",
"00033A699FDD2DA6CDD6CCC03B2C6145F998706F74",
0x34);
sk_LV1_arr.emplace_back(0x0003005000000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0000, KEY_LV1,
"1E8EEEA9E80A729F3FA52CF523B25941EA44B4155D94E5DADC5C5A77847620C7",
"E034D31A80316960024D1B3D3164FDC3",
"7E3A196f4A5879F3A7B091A2263F7C24E1716129B580566D308D9C2254B36AEE53DEF30EC85F8398",
"005815D17125D04C33790321DE29EB6241365100B5",
0x35);
sk_LV1_arr.emplace_back(0x0003005500000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x0000, KEY_LV1,
"53ABDF84BE08B0351B734F2B97D2BE1621BC6C889E4362E5C70F39D6C3ED9F23",
"44E652661AC7584DBE08ECB810FB5FC0",
"733198A7759BC07326755BC9773A8A17C8A7043C7BDAB83D88E230512E2EA3852D7DA4263A7E97F9",
"004312C65347ACBE95CC306442FEFD0AF4C2935EB3",
0x05);
sk_LV1_arr.emplace_back(0x0003005600000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x0000, KEY_LV1,
"48793EBDDA1AF65D737DA2FDA2DD104447A698F8A82CAAEE992831711BA94E83",
"15DCF3C67147A45D09DE7521EECA07A1",
"85A8868C320127F10B6598964C69221C086702021D31803520E21FDE4DBE827766BE41825CB7328C",
"",
0x07);
sk_LV1_arr.emplace_back(0x0003006100000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0003006000000000, 0x0003006100000000, 0x0000, KEY_LV1,
"5FF17D836E2C4AD69476E2614F64BDD05B9115389A9A6D055B5B544B1C34E3D5",
"DF0F50EC3C4743C5B17839D7B49F24A4",
"1CDABE30833823F461CA534104115FFF60010B710631E435A7D915E82AE88EDE667264656CB7062E",
"",
0x05);
sk_LV1_arr.emplace_back(0x0003006600000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0003006500000000, 0x0003006600000000, 0x0000, KEY_LV1,
"BD0621FA19383C3C72ECBC3B008F1CD55FFD7C3BB7510BF11AD0CF0FC2B70951",
"569AF3745E1E02E3E288273CDE244CD8",
"21E26F11C2D69478609DD1BD278CDFC940D90386455BA52FCD1FA7E27AC2AFA826C79A10193B625C",
"",
0x07);
sk_LV1_arr.emplace_back(0x0003007400000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0003007000000000, 0x0003007400000000, 0x0000, KEY_LV1,
"41A6E0039041E9D8AAF4EF2F2A2971248EDBD96A3985611ED7B4CE73EE4804FE",
"C8C98D5A5CE23AF5607A352AECACB0DC",
"4389664390265F96C1A882374C0F856364E33DB09BE124A4666F9A12F0DD9C811EDD55BA21ED0667",
"",
0x12);
sk_LV1_arr.emplace_back(0x0004001100000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0004000000000000, 0x0004001100000000, 0x0000, KEY_LV1,
"557EDF6C063F3272B0D44EEC12F418DA774815B5415597CC5F75C21E048BAD74",
"7144D7574937818517826227EF4AC0B4",
"085D38DBF9B757329EB862107929909D32FA1DAE60641BF4AC25319D7650597EE977F8E810FEEA96",
"",
0x13);
sk_LV1_arr.emplace_back(0x0004005000000000, 0x0000, KEY_LV1,
sk_LV1_arr.emplace_back(0x0004002000000000, 0xFFFFFFFFFFFFFFFF, 0x0000, KEY_LV1,
"10CEA04973FCCC12EC19924510822D8D4C41F657FD3D7E73F415A8D687421BCD",
"ED8699562C6AC65204FA166257E7FCF4",
"9AF86FC869C159FBB62F7D9674EE257ABF12E5A96D5875B4AA73C13C2BC13E2A4079F98B9B935EE2",
@@ -108,61 +111,61 @@ void KeyVault::LoadSelfLV1Keys()
void KeyVault::LoadSelfLV2Keys()
{
sk_LV2_arr.clear();
sk_LV2_arr.emplace_back(0x0003003000000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0000000300000000, 0x0003003100000000, 0x0000, KEY_LV2,
"94303F69513572AB5AE17C8C2A1839D2C24C28F65389D3BBB11894CE23E0798F",
"9769BFD187B90990AE5FEA4E110B9CF5",
"AFAF5E96AF396CBB69071082C46A8F34A030E8EDB799E0A7BE00AA264DFF3AEBF7923920D559404D",
"0070ABF9361B02291829D479F56AB248203CD3EB46",
0x20);
sk_LV2_arr.emplace_back(0x0003004200000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0003004000000000, 0x0003004200000000, 0x0000, KEY_LV2,
"575B0A6C4B4F2760A03FE4189EBAF4D947279FD982B14070349098B08FF92C10",
"411CB18F460CE50CAF2C426D8F0D93C8",
"3FEE313954CB3039C321A7E33B97FFDEC8988A8B55759161B04DBF4731284E4A8191E3F17D32B0EA",
"0073076441A08CD179E5FACE349B86DA58B5B7BA78",
0x21);
sk_LV2_arr.emplace_back(0x0003005000000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0000, KEY_LV2,
"6DBD48D787C58803A8D724DA5ACF04FF8FCE91D7545D2322F2B7ABF57014AF68",
"603A36213708520ED5D745DEC1325BA5",
"5888CB83AC3CCA9610BC173C53141C0CA58B93719E744660CA8823D5EAEE8F9BF736997054E4B7E3",
"0009EBC3DE442FA5FBF6C4F3D4F9EAB07778A142BD",
0x22);
sk_LV2_arr.emplace_back(0x0003005500000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x0000, KEY_LV2,
"84015E90FA23139628A3C75CC09714E6427B527A82D18ABC3E91CD8D7DDAFF17",
"5B240444D645F2038118F97FD5A145D5",
"B266318245266B2D33641CD8A864066D077FAC60B7E27399099A70A683454B70F9888E7CC0C2BF72",
"009D4CBA2BFB1A8330D3E20E59D281D476D231C73A",
0x32);
sk_LV2_arr.emplace_back(0x0003005600000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x0000, KEY_LV2,
"EAE15444048EFDE7A831BFA9F5D96F047C9FCFF50723E292CF50F5417D81E359",
"9CA9282DC7FA9F315EF3156D970B7CD4",
"0D58938CB47598A6A672874F1768068F8B80D8D17014D2ABEBAC85E5B0993D9FB6F307DDC3DDA699",
"",
0x33);
sk_LV2_arr.emplace_back(0x0003006100000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0003006000000000, 0x0003006100000000, 0x0000, KEY_LV2,
"88AD367EDEC2FEED3E2F99B1C685075C41BDEC90C84F526CAF588F89BBD1CBCC",
"8D18E8E525230E63DE10291C9DD615BF",
"86EED1D65E58890ABDA9ACA486A2BDDB9C0A529C2053FAE301F0F698EAF443DA0F60595A597A7027",
"",
0x32);
sk_LV2_arr.emplace_back(0x0003006600000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0003006500000000, 0x0003006600000000, 0x0000, KEY_LV2,
"688D5FCAC6F4EA35AC6AC79B10506007286131EE038116DB8AA2C0B0340D9FB0",
"75E0239D18B0B669EAE650972F99726B",
"008E1C820AC567D1BFB8FE3CC6AD2E1845A1D1B19ED2E18B18CA34A8D28A83EC60C63859CDB3DACA",
"",
0x33);
sk_LV2_arr.emplace_back(0x0003007400000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0003007000000000, 0x0003007400000000, 0x0000, KEY_LV2,
"E81C5B04C29FB079A4A2687A39D4EA97BFB49D80EF546CEB292979A5F77A6254",
"15058FA7F2CAD7C528B5F605F6444EB0",
"438D0E5C1E7AFB18234DB6867472FF5F52B750F30C379C7DD1EE0FD23E417B3EA819CC01BAC480ED",
"",
0x11);
sk_LV2_arr.emplace_back(0x0004001100000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0004001000000000, 0x0004001100000000, 0x0000, KEY_LV2,
"A1E4B86ED02BF7F1372A2C73FE02BC738907EB37CE3BA605FE783C999FAFDB97",
"BBE7799B9A37CB272E386618FDFD4AEC",
"5B31A8E2A663EBD673196E2E1022E0D64988C4E1BBFE5E474415883A3BA0D9C562A2BE9C30E9B4A8",
"",
0x07);
sk_LV2_arr.emplace_back(0x0004005000000000, 0x0000, KEY_LV2,
sk_LV2_arr.emplace_back(0x0004002000000000, 0xFFFFFFFFFFFFFFFF, 0x0000, KEY_LV2,
"0CAF212B6FA53C0DA7E2C575ADF61DBE68F34A33433B1B891ABF5C4251406A03",
"9B79374722AD888EB6A35A2DF25A8B3E",
"1034A6F98AF6625CC3E3604B59B971CA617DF337538D2179EBB22F3BDC9D0C6DA56BA7DDFD205A50",
@@ -173,79 +176,79 @@ void KeyVault::LoadSelfLV2Keys()
void KeyVault::LoadSelfISOKeys()
{
sk_ISO_arr.clear();
sk_ISO_arr.emplace_back(0x0003003000000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0000006000000000, 0x0003003000000000, 0x0001, KEY_ISO,
"8860D0CFF4D0DC688D3223321B96B59A777E6914961488E07048DAECB020ECA4",
"C82D015D46CF152F1DD0C16F18B5B1E5",
"733918D7C888130509346E6B4A8B6CAA357AB557E814E8122BF102C14A314BF9475B9D70EAF9EC29",
"009BE892E122A5C943C1BB7403A67318AA9E1B286F",
0x36);
sk_ISO_arr.emplace_back(0x0003004200000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0003004000000000, 0x0003004200000000, 0x0001, KEY_ISO,
"101E27F3FA2FB53ACA924F783AD553162D56B975D05B81351A1111799F20254D",
"8D2E9C6297B8AD252998458296AC773C",
"138446EE0BDDA5638F97328C8956E6489CBBFE57C5961D40DD5C43BB4138F1C400A8B27204A5D625",
"00849DBC57D3B92F01864E6E82EB4EF0EF6311E122",
0x32);
sk_ISO_arr.emplace_back(0x0003005000000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0001, KEY_ISO,
"3F2604FA27AEADFBE1AC69EB00BB16EF196C2193CBD62900FFD8C25041680843",
"A414AC1DB7987E43777651B330B899E1",
"1F4633AFDE18614D6CEF38A2FD6C4CCAC7B6EB8109D72CD066ECEBA0193EA3F43C37AE83179A4E5F",
"0085B4B05DEBA7E6AD831653C974D95149803BB272",
0x33);
sk_ISO_arr.emplace_back(0x0003005500000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x0001, KEY_ISO,
"BDB74AA6E3BA2DC10B1BD7F17198399A158DBE1FA0BEA68C90FCACBE4D04BE37",
"0207A479B1574F8E7F697528F05D5435",
"917E1F1DC48A54EB5F10B38E7569BB5383628A7C906F0DCA62FDA33805C15FAB270016940A09DB58",
"00294411363290975BA551336D3965D88AF029A17B",
0x03);
sk_ISO_arr.emplace_back(0x0003005600000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x0001, KEY_ISO,
"311C015F169F2A1E0757F7064B14C7C9F3A3FFEE015BD4E3A22401A2667857CE",
"7BB8B3F5AC8E0890E3148AE5688C7350",
"3F040EFA2335FED5670BA4D5C3AB2D9D0B4BA69D154A0062EA995A7D21DBAF0DC5A0DAD333D1C1DD",
"",
0x08);
sk_ISO_arr.emplace_back(0x0003006100000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0003006000000000, 0x0003006100000000, 0x0001, KEY_ISO,
"8474ADCA3B3244931EECEB9357841442442A1C4A4BCF4E498E6738950F4E4093",
"FFF9CACCC4129125CAFB240F419E5F39",
"098E1A53E59A95316B00D5A29C05FFEBAE41D1A8A386F9DA96F98858FD25E07BB7A3BC96A5D5B556",
"",
0x03);
sk_ISO_arr.emplace_back(0x0003006600000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0003006500000000, 0x0003006600000000, 0x0001, KEY_ISO,
"E6A21C599B75696C169EC02582BDA74A776134A6E05108EA701EC0CA2AC03592",
"D292A7BD57C0BB2EABBCA1252FA9EDEF",
"2ED078A13DC4617EB550AD06E228C83C142A2D588EB5E729402D18038A14842FD65B277DCAD225A5",
"",
0x08);
sk_ISO_arr.emplace_back(0x0003007400000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0003007000000000, 0x0003007400000000, 0x0001, KEY_ISO,
"072D3A5C3BDB0D674DE209381432B20414BC9BDA0F583ECB94BD9A134176DD51",
"8516A81F02CF938740498A406C880871",
"5A778DEB5C4F12E8D48E06A2BBBBE3C90FA8C6C47DF9BDB5697FD4A8EB7941CE3F59A557E81C787D",
"",
0x21);
sk_ISO_arr.emplace_back(0x0003007400000000, 0x0100, KEY_ISO,
sk_ISO_arr.emplace_back(0x0003007000000000, 0x0003007400000000, 0x0100, KEY_ISO,
"786FAB8A0B89474A2CB80B3EA104CCCB9E13F66B45EC499BB31865D07C661EA8",
"94662F13D99A9F5D211C979FFDF65FE3",
"912C94C252B7799CEB45DFBB73EF7CAD9BCC0793A3331BBB79E3C47C0F5C782F698065A8D4DB0D8B",
"",
0x0E);
sk_ISO_arr.emplace_back(0x0004001100000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0004001000000000, 0x0004001100000000, 0x0001, KEY_ISO,
"4262657A3185D9480F82C8BD2F81766FCC2C8FD7DD5EBE8657B00B939E0C75BD",
"4F1E3EF07D893A4714B1B3D5A4E50479",
"4DBFCFA68B52F1D66E09AFA6C18EC65479EDBD027B6B8C6A5D85FE5C84D43EA40CEF1672078A0702",
"",
0x11);
sk_ISO_arr.emplace_back(0x0004001100000000, 0x0100, KEY_ISO,
sk_ISO_arr.emplace_back(0x0004001000000000, 0x0004001100000000, 0x0100, KEY_ISO,
"16AA7D7C35399E2B1BFAF68CD19D7512A7855029C08BECC4CC3F035DF7F9C70B",
"0E50DB6D937D262CB0499136852FCB80",
"AEE2795BF295662A50DFAFE70D1B0B6F0A2EBB211E1323A275FC6E2D13BE4F2F10CA34784F4CF1EC",
"",
0x0F);
sk_ISO_arr.emplace_back(0x0004005000000000, 0x0001, KEY_ISO,
sk_ISO_arr.emplace_back(0x0004002000000000, 0xFFFFFFFFFFFFFFFF, 0x0001, KEY_ISO,
"63565DBE98C3B1A52AADC907C47130FE57A10734E84F22592670F86ED2B0A086",
"953F6A99891B4739358F5363A00C08B9",
"26BE7B02E7D65C6C21BF4063CDB8C0092FE1679D62FA1A8CCC284A1D21885473A959992537A06612",
"",
0x15);
sk_ISO_arr.emplace_back(0x0004005000000000, 0x0100, KEY_ISO,
sk_ISO_arr.emplace_back(0x0004002000000000, 0xFFFFFFFFFFFFFFFF, 0x0100, KEY_ISO,
"B96EA32CB96EA32DB96EA32CB96EA32CB96EA32CB96EA32DB96EA32CB96EA32C",
"B96EA32CB96EA32DB96EA32DB96EA32C",
"2D7066E68C6AC3373B1346FD76FE7D18A207C811500E65D85DB57BC4A27AD78F59FD53F38F50E151",
@@ -256,169 +259,169 @@ void KeyVault::LoadSelfISOKeys()
void KeyVault::LoadSelfAPPKeys()
{
sk_APP_arr.clear();
sk_APP_arr.emplace_back(0x0000009200000000, 0x0000, KEY_APP,
sk_APP_arr.emplace_back(0x0000009200000000, 0x0000009200000000, 0x0000, KEY_APP,
"95F50019E7A68E341FA72EFDF4D60ED376E25CF46BB48DFDD1F080259DC93F04",
"4A0955D946DB70D691A640BB7FAECC4C",
"6F8DF8EBD0A1D1DB08B30DD3A951E3F1F27E34030B42C729C55555232D61B834B8BDFFB07E54B343",
"006C3E4CCB2C69A5AD7C6F60448E50C7F9184EEAF4",
0x21);
sk_APP_arr.emplace_back(0x0003003000000000, 0x0001, KEY_APP,
sk_APP_arr.emplace_back(0x0003003000000000, 0x0003003000000000, 0x0001, KEY_APP,
"79481839C406A632BDB4AC093D73D99AE1587F24CE7E69192C1CD0010274A8AB",
"6F0F25E1C8C4B7AE70DF968B04521DDA",
"94D1B7378BAFF5DFED269240A7A364ED68446741622E50BC6079B6E606A2F8E0A4C56E5CFF836526",
"003DE80167D2F0E9D30F2145144A558D1174F5410C",
0x11);
sk_APP_arr.emplace_back(0x0003003000000000, 0x0002, KEY_APP,
sk_APP_arr.emplace_back(0x0003003000000000, 0x0003003000000000, 0x0002, KEY_APP,
"4F89BE98DDD43CAD343F5BA6B1A133B0A971566F770484AAC20B5DD1DC9FA06A",
"90C127A9B43BA9D8E89FE6529E25206F",
"8CA6905F46148D7D8D84D2AFCEAE61B41E6750FC22EA435DFA61FCE6F4F860EE4F54D9196CA5290E",
"",
0x13);
sk_APP_arr.emplace_back(0x0003003000000000, 0x0003, KEY_APP,
sk_APP_arr.emplace_back(0x0003003000000000, 0x0003003000000000, 0x0003, KEY_APP,
"C1E6A351FCED6A0636BFCB6801A0942DB7C28BDFC5E0A053A3F52F52FCE9754E",
"E0908163F457576440466ACAA443AE7C",
"50022D5D37C97905F898E78E7AA14A0B5CAAD5CE8190AE5629A10D6F0CF4173597B37A95A7545C92",
"",
0x0B);
sk_APP_arr.emplace_back(0x0003004200000000, 0x0004, KEY_APP,
sk_APP_arr.emplace_back(0x0003004200000000, 0x0003004200000000, 0x0004, KEY_APP,
"838F5860CF97CDAD75B399CA44F4C214CDF951AC795298D71DF3C3B7E93AAEDA",
"7FDBB2E924D182BB0D69844ADC4ECA5B",
"1F140E8EF887DAB52F079A06E6915A6460B75CD256834A43FA7AF90C23067AF412EDAFE2C1778D69",
"0074E922FDEE5DC4CDF22FC8D7986477F813400860",
0x14);
sk_APP_arr.emplace_back(0x0003004200000000, 0x0005, KEY_APP,
sk_APP_arr.emplace_back(0x0003004200000000, 0x0003004200000000, 0x0005, KEY_APP,
"C109AB56593DE5BE8BA190578E7D8109346E86A11088B42C727E2B793FD64BDC",
"15D3F191295C94B09B71EBDE088A187A",
"B6BB0A84C649A90D97EBA55B555366F52381BB38A84C8BB71DA5A5A0949043C6DB249029A43156F7",
"",
0x15);
sk_APP_arr.emplace_back(0x0003004200000000, 0x0006, KEY_APP,
sk_APP_arr.emplace_back(0x0003004200000000, 0x0003004200000000, 0x0006, KEY_APP,
"6DFD7AFB470D2B2C955AB22264B1FF3C67F180983B26C01615DE9F2ECCBE7F41",
"24BD1C19D2A8286B8ACE39E4A37801C2",
"71F46AC33FF89DF589A100A7FB64CEAC244C9A0CBBC1FDCE80FB4BF8A0D2E66293309CB8EE8CFA95",
"",
0x2C);
sk_APP_arr.emplace_back(0x0003005000000000, 0x0007, KEY_APP,
sk_APP_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0007, KEY_APP,
"945B99C0E69CAF0558C588B95FF41B232660ECB017741F3218C12F9DFDEEDE55",
"1D5EFBE7C5D34AD60F9FBC46A5977FCE",
"AB284CA549B2DE9AA5C903B75652F78D192F8F4A8F3CD99209415C0A84C5C9FD6BF3095C1C18FFCD",
"002CF896D35DB871D0E6A252E799876A70D043C23E",
0x15);
sk_APP_arr.emplace_back(0x0003005000000000, 0x0008, KEY_APP,
sk_APP_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0008, KEY_APP,
"2C9E8969EC44DFB6A8771DC7F7FDFBCCAF329EC3EC070900CABB23742A9A6E13",
"5A4CEFD5A9C3C093D0B9352376D19405",
"6E82F6B54A0E9DEBE4A8B3043EE3B24CD9BBB62B4416B0482582E419A2552E29AB4BEA0A4D7FA2D5",
"",
0x16);
sk_APP_arr.emplace_back(0x0003005000000000, 0x0009, KEY_APP,
sk_APP_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0009, KEY_APP,
"F69E4A2934F114D89F386CE766388366CDD210F1D8913E3B973257F1201D632B",
"F4D535069301EE888CC2A852DB654461",
"1D7B974D10E61C2ED087A0981535904677EC07E96260F89565FF7EBDA4EE035C2AA9BCBDD5893F99",
"",
0x2D);
sk_APP_arr.emplace_back(0x0003005500000000, 0x000A, KEY_APP,
sk_APP_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x000A, KEY_APP,
"29805302E7C92F204009161CA93F776A072141A8C46A108E571C46D473A176A3",
"5D1FAB844107676ABCDFC25EAEBCB633",
"09301B6436C85B53CB1585300A3F1AF9FB14DB7C30088C4642AD66D5C148B8995BB1A698A8C71827",
"0010818ED8A666051C6198662C3D6DDE2CA4901DDC",
0x25);
sk_APP_arr.emplace_back(0x0003005500000000, 0x000B, KEY_APP,
sk_APP_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x000B, KEY_APP,
"A4C97402CC8A71BC7748661FE9CE7DF44DCE95D0D58938A59F47B9E9DBA7BFC3",
"E4792F2B9DB30CB8D1596077A13FB3B5",
"2733C889D289550FE00EAA5A47A34CEF0C1AF187610EB07BA35D2C09BB73C80B244EB4147700D1BF",
"",
0x26);
sk_APP_arr.emplace_back(0x0003005500000000, 0x000C, KEY_APP,
sk_APP_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x000C, KEY_APP,
"9814EFFF67B7074D1B263BF85BDC8576CE9DEC914123971B169472A1BC2387FA",
"D43B1FA8BE15714B3078C23908BB2BCA",
"7D1986C6BEE6CE1E0C5893BD2DF203881F40D5056761CC3F1F2E9D9A378617A2DE40BA5F09844CEB",
"",
0x3D);
sk_APP_arr.emplace_back(0x0003005600000000, 0x000D, KEY_APP,
sk_APP_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x000D, KEY_APP,
"03B4C421E0C0DE708C0F0B71C24E3EE04306AE7383D8C5621394CCB99FF7A194",
"5ADB9EAFE897B54CB1060D6885BE22CF",
"71502ADB5783583AB88B2D5F23F419AF01C8B1E72FCA1E694AD49FE3266F1F9C61EFC6F29B351142",
"",
0x12);
sk_APP_arr.emplace_back(0x0003005600000000, 0x000E, KEY_APP,
sk_APP_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x000E, KEY_APP,
"39A870173C226EB8A3EEE9CA6FB675E82039B2D0CCB22653BFCE4DB013BAEA03",
"90266C98CBAA06C1BF145FF760EA1B45",
"84DE5692809848E5ACBE25BE548F6981E3DB14735A5DDE1A0FD1F475866532B862B1AB6A004B7255",
"",
0x27);
sk_APP_arr.emplace_back(0x0003005600000000, 0x000F, KEY_APP,
sk_APP_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x000F, KEY_APP,
"FD52DFA7C6EEF5679628D12E267AA863B9365E6DB95470949CFD235B3FCA0F3B",
"64F50296CF8CF49CD7C643572887DA0B",
"0696D6CCBD7CF585EF5E00D547503C185D7421581BAD196E081723CD0A97FA40B2C0CD2492B0B5A1",
"",
0x3A);
sk_APP_arr.emplace_back(0x0003006100000000, 0x0010, KEY_APP,
sk_APP_arr.emplace_back(0x0003006100000000, 0x0003006100000000, 0x0010, KEY_APP,
"A5E51AD8F32FFBDE808972ACEE46397F2D3FE6BC823C8218EF875EE3A9B0584F",
"7A203D5112F799979DF0E1B8B5B52AA4",
"50597B7F680DD89F6594D9BDC0CBEE03666AB53647D0487F7F452FE2DD02694631EA755548C9E934",
"",
0x25);
sk_APP_arr.emplace_back(0x0003006100000000, 0x0011, KEY_APP,
sk_APP_arr.emplace_back(0x0003006100000000, 0x0003006100000000, 0x0011, KEY_APP,
"0F8EAB8884A51D092D7250597388E3B8B75444AC138B9D36E5C7C5B8C3DF18FD",
"97AF39C383E7EF1C98FA447C597EA8FE",
"2FDA7A56AAEA65921C0284FF1942C6DE137370093D106034B59191951A5201B422D462F8726F852D",
"",
0x26);
sk_APP_arr.emplace_back(0x0003006600000000, 0x0013, KEY_APP,
sk_APP_arr.emplace_back(0x0003006600000000, 0x0003006600000000, 0x0013, KEY_APP,
"DBF62D76FC81C8AC92372A9D631DDC9219F152C59C4B20BFF8F96B64AB065E94",
"CB5DD4BE8CF115FFB25801BC6086E729",
"B26FE6D3E3A1E766FAE79A8E6A7F48998E7FC1E4B0AD8745FF54C018C2A6CC7A0DD7525FAFEA4917",
"",
0x12);
sk_APP_arr.emplace_back(0x0003006600000000, 0x0014, KEY_APP,
sk_APP_arr.emplace_back(0x0003006600000000, 0x0003006600000000, 0x0014, KEY_APP,
"491B0D72BB21ED115950379F4564CE784A4BFAABB00E8CB71294B192B7B9F88E",
"F98843588FED8B0E62D7DDCB6F0CECF4",
"04275E8838EF95BD013B223C3DF674540932F21B534C7ED2944B9104D938FEB03B824DDB866AB26E",
"",
0x27);
sk_APP_arr.emplace_back(0x0003007400000000, 0x0016, KEY_APP,
sk_APP_arr.emplace_back(0x0003007400000000, 0x0003007400000000, 0x0016, KEY_APP,
"A106692224F1E91E1C4EBAD4A25FBFF66B4B13E88D878E8CD072F23CD1C5BF7C",
"62773C70BD749269C0AFD1F12E73909E",
"566635D3E1DCEC47243AAD1628AE6B2CEB33463FC155E4635846CE33899C5E353DDFA47FEF5694AF",
"",
0x30);
sk_APP_arr.emplace_back(0x0003007400000000, 0x0017, KEY_APP,
sk_APP_arr.emplace_back(0x0003007400000000, 0x0003007400000000, 0x0017, KEY_APP,
"4E104DCE09BA878C75DA98D0B1636F0E5F058328D81419E2A3D22AB0256FDF46",
"954A86C4629E116532304A740862EF85",
"3B7B04C71CAE2B1199D57453C038BB1B541A05AD1B94167B0AB47A9B24CAECB9000CB21407009666",
"",
0x08);
sk_APP_arr.emplace_back(0x0003007400000000, 0x0018, KEY_APP,
sk_APP_arr.emplace_back(0x0003007400000000, 0x0003007400000000, 0x0018, KEY_APP,
"1F876AB252DDBCB70E74DC4A20CD8ED51E330E62490E652F862877E8D8D0F997",
"BF8D6B1887FA88E6D85C2EDB2FBEC147",
"64A04126D77BF6B4D686F6E8F87DD150A5B014BA922D2B694FFF4453E11239A6E0B58F1703C51494",
"",
0x11);
sk_APP_arr.emplace_back(0x0004001100000000, 0x0019, KEY_APP,
sk_APP_arr.emplace_back(0x0004001100000000, 0x0004001100000000, 0x0019, KEY_APP,
"3236B9937174DF1DC12EC2DD8A318A0EA4D3ECDEA5DFB4AC1B8278447000C297",
"6153DEE781B8ADDC6A439498B816DC46",
"148DCA961E2738BAF84B2D1B6E2DA2ABD6A95F2C9571E54C6922F9ED9674F062B7F1BE5BD6FA5268",
"",
0x31);
sk_APP_arr.emplace_back(0x0004001100000000, 0x001A, KEY_APP,
sk_APP_arr.emplace_back(0x0004001100000000, 0x0004001100000000, 0x001A, KEY_APP,
"5EFD1E9961462794E3B9EF2A4D0C1F46F642AAE053B5025504130590E66F19C9",
"1AC8FA3B3C90F8FDE639515F91B58327",
"BE4B1B513536960618BFEF12A713F6673881B02F9DC616191E823FC8337CCF99ADAA6172019C0C23",
"",
0x17);
sk_APP_arr.emplace_back(0x0004001100000000, 0x001B, KEY_APP,
sk_APP_arr.emplace_back(0x0004001100000000, 0x0004001100000000, 0x001B, KEY_APP,
"66637570D1DEC098467DB207BAEA786861964D0964D4DBAF89E76F46955D181B",
"9F7B5713A5ED59F6B35CD8F8A165D4B8",
"4AB6FB1F6F0C3D9219923C1AC683137AB05DF667833CC6A5E8F590E4E28FE2EB180C7D5861117CFB",
"",
0x12);
sk_APP_arr.emplace_back(0x0004004600000000, 0x001C, KEY_APP,
sk_APP_arr.emplace_back(0x0004004600000000, 0x0004004600000000, 0x001C, KEY_APP,
"CFF025375BA0079226BE01F4A31F346D79F62CFB643CA910E16CF60BD9092752",
"FD40664E2EBBA01BF359B0DCDF543DA4",
"36C1ACE6DD5CCC0006FDF3424750FAC515FC5CFA2C93EC53C6EC2BC421708D154E91F2E7EA54A893",
"",
0x09);
sk_APP_arr.emplace_back(0x0004004600000000, 0x001D, KEY_APP,
sk_APP_arr.emplace_back(0x0004004600000000, 0x0004004600000000, 0x001D, KEY_APP,
"D202174EB65A62048F3674B59EF6FE72E1872962F3E1CD658DE8D7AF71DA1F3E",
"ACB9945914EBB7B9A31ECE320AE09F2D",
"430322887503CF52928FAAA410FD623C7321281C8825D95F5B47EF078EFCFC44454C3AB4F00BB879",
@@ -429,97 +432,97 @@ void KeyVault::LoadSelfAPPKeys()
void KeyVault::LoadSelfNPDRMKeys()
{
sk_NPDRM_arr.clear();
sk_NPDRM_arr.emplace_back(0x0001000000000000, 0x0001, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0001000000000000, 0x0001000000000000, 0x0001, KEY_NPDRM,
"F9EDD0301F770FABBA8863D9897F0FEA6551B09431F61312654E28F43533EA6B",
"A551CCB4A42C37A734A2B4F9657D5540",
"B05F9DA5F9121EE4031467E74C505C29A8E29D1022379EDFF0500B9AE480B5DAB4578A4C61C5D6BF",
"00040AB47509BED04BD96521AD1B365B86BF620A98",
0x11);
sk_NPDRM_arr.emplace_back(0x0001000000000000, 0x0002, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0001000000000000, 0x0001000000000000, 0x0002, KEY_NPDRM,
"8E737230C80E66AD0162EDDD32F1F774EE5E4E187449F19079437A508FCF9C86",
"7AAECC60AD12AED90C348D8C11D2BED5",
"05BF09CB6FD78050C78DE69CC316FF27C9F1ED66A45BFCE0A1E5A6749B19BD546BBB4602CF373440",
"",
0x0A);
sk_NPDRM_arr.emplace_back(0x0003003000000000, 0x0003, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003003000000000, 0x0003003000000000, 0x0003, KEY_NPDRM,
"1B715B0C3E8DC4C1A5772EBA9C5D34F7CCFE5B82025D453F3167566497239664",
"E31E206FBB8AEA27FAB0D9A2FFB6B62F",
"3F51E59FC74D6618D34431FA67987FA11ABBFACC7111811473CD9988FE91C43FC74605E7B8CB732D",
"",
0x08);
sk_NPDRM_arr.emplace_back(0x0003004200000000, 0x0004, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003004200000000, 0x0003004200000000, 0x0004, KEY_NPDRM,
"BB4DBF66B744A33934172D9F8379A7A5EA74CB0F559BB95D0E7AECE91702B706",
"ADF7B207A15AC601110E61DDFC210AF6",
"9C327471BAFF1F877AE4FE29F4501AF5AD6A2C459F8622697F583EFCA2CA30ABB5CD45D1131CAB30",
"00B61A91DF4AB6A9F142C326BA9592B5265DA88856",
0x16);
sk_NPDRM_arr.emplace_back(0x0003004200000000, 0x0006, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003004200000000, 0x0003004200000000, 0x0006, KEY_NPDRM,
"8B4C52849765D2B5FA3D5628AFB17644D52B9FFEE235B4C0DB72A62867EAA020",
"05719DF1B1D0306C03910ADDCE4AF887",
"2A5D6C6908CA98FC4740D834C6400E6D6AD74CF0A712CF1E7DAE806E98605CC308F6A03658F2970E",
"",
0x29);
sk_NPDRM_arr.emplace_back(0x0003005000000000, 0x0007, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0007, KEY_NPDRM,
"3946DFAA141718C7BE339A0D6C26301C76B568AEBC5CD52652F2E2E0297437C3",
"E4897BE553AE025CDCBF2B15D1C9234E",
"A13AFE8B63F897DA2D3DC3987B39389DC10BAD99DFB703838C4A0BC4E8BB44659C726CFD0CE60D0E",
"009EF86907782A318D4CC3617EBACE2480E73A46F6",
0x17);
sk_NPDRM_arr.emplace_back(0x0003005000000000, 0x0009, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0009, KEY_NPDRM,
"0786F4B0CA5937F515BDCE188F569B2EF3109A4DA0780A7AA07BD89C3350810A",
"04AD3C2F122A3B35E804850CAD142C6D",
"A1FE61035DBBEA5A94D120D03C000D3B2F084B9F4AFA99A2D4A588DF92B8F36327CE9E47889A45D0",
"",
0x2A);
sk_NPDRM_arr.emplace_back(0x0003005500000000, 0x000A, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x000A, KEY_NPDRM,
"03C21AD78FBB6A3D425E9AAB1298F9FD70E29FD4E6E3A3C151205DA50C413DE4",
"0A99D4D4F8301A88052D714AD2FB565E",
"3995C390C9F7FBBAB124A1C14E70F9741A5E6BDF17A605D88239652C8EA7D5FC9F24B30546C1E44B",
"009AC6B22A056BA9E0B6D1520F28A57A3135483F9F",
0x27);
sk_NPDRM_arr.emplace_back(0x0003005500000000, 0x000C, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x000C, KEY_NPDRM,
"357EBBEA265FAEC271182D571C6CD2F62CFA04D325588F213DB6B2E0ED166D92",
"D26E6DD2B74CD78E866E742E5571B84F",
"00DCF5391618604AB42C8CFF3DC304DF45341EBA4551293E9E2B68FFE2DF527FFA3BE8329E015E57",
"",
0x3A);
sk_NPDRM_arr.emplace_back(0x0003005600000000, 0x000D, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x000D, KEY_NPDRM,
"337A51416105B56E40D7CAF1B954CDAF4E7645F28379904F35F27E81CA7B6957",
"8405C88E042280DBD794EC7E22B74002",
"9BFF1CC7118D2393DE50D5CF44909860683411A532767BFDAC78622DB9E5456753FE422CBAFA1DA1",
"",
0x18);
sk_NPDRM_arr.emplace_back(0x0003005600000000, 0x000F, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x000F, KEY_NPDRM,
"135C098CBE6A3E037EBE9F2BB9B30218DDE8D68217346F9AD33203352FBB3291",
"4070C898C2EAAD1634A288AA547A35A8",
"BBD7CCCB556C2EF0F908DC7810FAFC37F2E56B3DAA5F7FAF53A4944AA9B841F76AB091E16B231433",
"",
0x3B);
sk_NPDRM_arr.emplace_back(0x0003006100000000, 0x0010, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003006100000000, 0x0003006100000000, 0x0010, KEY_NPDRM,
"4B3CD10F6A6AA7D99F9B3A660C35ADE08EF01C2C336B9E46D1BB5678B4261A61",
"C0F2AB86E6E0457552DB50D7219371C5",
"64A5C60BC2AD18B8A237E4AA690647E12BF7A081523FAD4F29BE89ACAC72F7AB43C74EC9AFFDA213",
"",
0x27);
sk_NPDRM_arr.emplace_back(0x0003006600000000, 0x0013, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003006600000000, 0x0003006600000000, 0x0013, KEY_NPDRM,
"265C93CF48562EC5D18773BEB7689B8AD10C5EB6D21421455DEBC4FB128CBF46",
"8DEA5FF959682A9B98B688CEA1EF4A1D",
"9D8DB5A880608DC69717991AFC3AD5C0215A5EE413328C2ABC8F35589E04432373DB2E2339EEF7C8",
"",
0x18);
sk_NPDRM_arr.emplace_back(0x0003007400000000, 0x0016, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0003007400000000, 0x0003007400000000, 0x0016, KEY_NPDRM,
"7910340483E419E55F0D33E4EA5410EEEC3AF47814667ECA2AA9D75602B14D4B",
"4AD981431B98DFD39B6388EDAD742A8E",
"62DFE488E410B1B6B2F559E4CB932BCB78845AB623CC59FDF65168400FD76FA82ED1DC60E091D1D1",
"",
0x25);
sk_NPDRM_arr.emplace_back(0x0004001100000000, 0x0019, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0004001100000000, 0x0004001100000000, 0x0019, KEY_NPDRM,
"FBDA75963FE690CFF35B7AA7B408CF631744EDEF5F7931A04D58FD6A921FFDB3",
"F72C1D80FFDA2E3BF085F4133E6D2805",
"637EAD34E7B85C723C627E68ABDD0419914EBED4008311731DD87FDDA2DAF71F856A70E14DA17B42",
"",
0x24);
sk_NPDRM_arr.emplace_back(0x0004004600000000, 0x001C, KEY_NPDRM,
sk_NPDRM_arr.emplace_back(0x0004004600000000, 0x0004004600000000, 0x001C, KEY_NPDRM,
"8103EA9DB790578219C4CEDF0592B43064A7D98B601B6C7BC45108C4047AA80F",
"246F4B8328BE6A2D394EDE20479247C5",
"503172C9551308A87621ECEE90362D14889BFED2CF32B0B3E32A4F9FE527A41464B735E1ADBC6762",
@@ -530,61 +533,61 @@ void KeyVault::LoadSelfNPDRMKeys()
void KeyVault::LoadSelfUNK7Keys()
{
sk_UNK7_arr.clear();
sk_UNK7_arr.emplace_back(0x0003003000000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0000008400000000, 0x0003003100000000, 0x0000, KEY_UNK7,
"D91166973979EA8694476B011AC62C7E9F37DA26DE1E5C2EE3D66E42B8517085",
"DC01280A6E46BC674B81A7E8801EBE6E",
"A0FC44108236141BF3517A662B027AFC1AC513A05690496C754DEB7D43BDC41B80FD75C212624EE4",
"",
0x11);
sk_UNK7_arr.emplace_back(0x0003004200000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0003004000000000, 0x0003004200000000, 0x0000, KEY_UNK7,
"B73111B0B00117E48DE5E2EE5E534C0F0EFFA4890BBB8CAD01EE0F848F91583E",
"86F56F9E5DE513894874B8BA253334B1",
"B0BA1A1AB9723BB4E87CED9637BE056066BC56E16572D43D0210A06411DBF8FEB8885CD912384AE5",
"",
0x12);
sk_UNK7_arr.emplace_back(0x0003005000000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0003005000000000, 0x0003005000000000, 0x0000, KEY_UNK7,
"8E944267C02E69A4FE474B7F5FCD7974A4F936FF4355AEC4F80EFA123858D8F6",
"908A75754E521EAC2F5A4889C6D7B72D",
"91201DA7D79E8EE2563142ECBD646DA026C963AC09E760E5390FFE24DAE6864310ABE147F8204D0B",
"",
0x13);
sk_UNK7_arr.emplace_back(0x0003005500000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0003005500000000, 0x0003005500000000, 0x0000, KEY_UNK7,
"BB31DF9A6F62C0DF853075FAA65134D9CE2240306C1731D1F7DA9B5329BD699F",
"263057225873F83940A65C8C926AC3E4",
"BC3A82A4F44C43A197070CD236FDC94FCC542D69A3E803E0AFF78D1F3DA19A79D2F61FAB5B94B437",
"",
0x23);
sk_UNK7_arr.emplace_back(0x0003005600000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0003005600000000, 0x0003005600000000, 0x0000, KEY_UNK7,
"71AA75C70A255580E4AE9BDAA0B08828C53EAA713CD0713797F143B284C1589B",
"9DED878CB6BA07121C0F50E7B172A8BF",
"387FCDAEAFF1B59CFAF79CE6215A065ACEAFFAF4048A4F217E1FF5CE67C66EC3F089DB235E52F9D3",
"",
0x29);
sk_UNK7_arr.emplace_back(0x0003006100000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0003006000000000, 0x0003006100000000, 0x0000, KEY_UNK7,
"F5D1DBC182F5083CD4EA37C431C7DAC73882C07F232D2699B1DD9FDDF1BF4195",
"D3A7C3C91CBA014FCBCA6D5570DE13FF",
"97CA8A9781F45E557E98F176EF794FCDA6B151EB3DFD1ABA12151E00AE59957C3B15628FC8875D28",
"",
0x23);
sk_UNK7_arr.emplace_back(0x0003006600000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0003006500000000, 0x0003006600000000, 0x0000, KEY_UNK7,
"BF10F09590C0152F7EF749FF4B990122A4E8E5491DA49A2D931E72EEB990F860",
"22C19C5522F7A782AFC547C2640F5BDE",
"3233BA2B284189FB1687DF653002257A0925D8EB0C64EBBE8CC7DE87F548D107DE1FD3D1D285DB4F",
"",
0x29);
sk_UNK7_arr.emplace_back(0x0003007400000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0003007000000000, 0x0003007400000000, 0x0000, KEY_UNK7,
"F11DBD2C97B32AD37E55F8E743BC821D3E67630A6784D9A058DDD26313482F0F",
"FC5FA12CA3D2D336C4B8B425D679DA55",
"19E27EE90E33EDAB16B22E688B5F704E5C6EC1062070EBF43554CD03DFDAE16D684BB8B5574DBECA",
"",
0x15);
sk_UNK7_arr.emplace_back(0x0004001100000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0004000000000000, 0x0004001100000000, 0x0000, KEY_UNK7,
"751EE949CD3ADF50A469197494A1EC358409CCBE6E85217EBDE7A87D3FF1ABD8",
"23AE4ADA4D3F798DC5ED98000337FF77",
"1BABA87CD1AD705C462D4E7427B6DAF59A50383A348A15088F0EDFCF1ADF2B5C2B2D507B2A357D36",
"",
0x1A);
sk_UNK7_arr.emplace_back(0x0004004600000000, 0x0000, KEY_UNK7,
sk_UNK7_arr.emplace_back(0x0004002000000000, 0xFFFFFFFFFFFFFFFF, 0x0000, KEY_UNK7,
"46BD0891224E0CE13E2162921D4BB76193AEEE4416A729FCDD111C5536BF87C9",
"BF036387CDB613C0AC88A6D9D2CC5316",
"A14F6D5F9AD7EBB3B7A39A7C32F13E5DC3B0BA16BDC33D39FDDF88F4AEEA6CFEEB0C0796C917A952",
@@ -604,11 +607,11 @@ SELF_KEY KeyVault::GetSelfLDRKey() const
SELF_KEY KeyVault::GetSelfLV1Key(u64 version) const
{
SELF_KEY key(0, 0, 0, "", "", "", "", 0);
SELF_KEY key(0, 0, 0, 0, "", "", "", "", 0);
for(unsigned int i = 0; i < sk_LV1_arr.size(); i++)
{
if (sk_LV1_arr[i].version == version)
if (version >= sk_LV1_arr[i].version_start && version <= sk_LV1_arr[i].version_end)
{
key = sk_LV1_arr[i];
break;
@@ -620,11 +623,11 @@ SELF_KEY KeyVault::GetSelfLV1Key(u64 version) const
SELF_KEY KeyVault::GetSelfLV2Key(u64 version) const
{
SELF_KEY key(0, 0, 0, "", "", "", "", 0);
SELF_KEY key(0, 0, 0, 0, "", "", "", "", 0);
for(unsigned int i = 0; i < sk_LV2_arr.size(); i++)
{
if (sk_LV2_arr[i].version == version)
if (version >= sk_LV2_arr[i].version_start && version <= sk_LV2_arr[i].version_end)
{
key = sk_LV2_arr[i];
break;
@@ -636,12 +639,11 @@ SELF_KEY KeyVault::GetSelfLV2Key(u64 version) const
SELF_KEY KeyVault::GetSelfISOKey(u16 revision, u64 version) const
{
SELF_KEY key(0, 0, 0, "", "", "", "", 0);
SELF_KEY key(0, 0, 0, 0, "", "", "", "", 0);
for(unsigned int i = 0; i < sk_ISO_arr.size(); i++)
{
if ((sk_ISO_arr[i].version == version) &&
(sk_ISO_arr[i].revision == revision))
if ((version >= sk_ISO_arr[i].version_start && version <= sk_ISO_arr[i].version_end) && (sk_ISO_arr[i].revision == revision))
{
key = sk_ISO_arr[i];
break;
@@ -653,7 +655,7 @@ SELF_KEY KeyVault::GetSelfISOKey(u16 revision, u64 version) const
SELF_KEY KeyVault::GetSelfAPPKey(u16 revision) const
{
SELF_KEY key(0, 0, 0, "", "", "", "", 0);
SELF_KEY key(0, 0, 0, 0, "", "", "", "", 0);
for(unsigned int i = 0; i < sk_APP_arr.size(); i++)
{
@@ -669,11 +671,11 @@ SELF_KEY KeyVault::GetSelfAPPKey(u16 revision) const
SELF_KEY KeyVault::GetSelfUNK7Key(u64 version) const
{
SELF_KEY key(0, 0, 0, "", "", "", "", 0);
SELF_KEY key(0, 0, 0, 0, "", "", "", "", 0);
for(unsigned int i = 0; i < sk_UNK7_arr.size(); i++)
{
if (sk_UNK7_arr[i].version == version)
if (version >= sk_UNK7_arr[i].version_start && version <= sk_UNK7_arr[i].version_end)
{
key = sk_UNK7_arr[i];
break;
@@ -685,7 +687,7 @@ SELF_KEY KeyVault::GetSelfUNK7Key(u64 version) const
SELF_KEY KeyVault::GetSelfNPDRMKey(u16 revision) const
{
SELF_KEY key(0, 0, 0, "", "", "", "", 0);
SELF_KEY key(0, 0, 0, 0, "", "", "", "", 0);
for(unsigned int i = 0; i < sk_NPDRM_arr.size(); i++)
{
@@ -702,7 +704,9 @@ SELF_KEY KeyVault::GetSelfNPDRMKey(u16 revision) const
SELF_KEY KeyVault::FindSelfKey(u32 type, u16 revision, u64 version)
{
// Empty key.
SELF_KEY key(0, 0, 0, "", "", "", "", 0);
SELF_KEY key(0, 0, 0, 0, "", "", "", "", 0);
key_vault_log.notice("FindSelfKey: Type:0x%x, Revision:0x%x, Version:0x%x", type, revision, version);
// Check SELF type.
switch (type)
@@ -808,4 +812,3 @@ void rap_to_rif(unsigned char* rap, unsigned char* rif)
memcpy(rif, key, 0x10);
}
+14 -8
View File
@@ -1,6 +1,7 @@
#pragma once
#pragma once
#include "Utilities/types.h"
#include "Utilities/Log.h"
#include <string>
#include <vector>
@@ -18,7 +19,8 @@ enum SELF_KEY_TYPE {
};
struct SELF_KEY {
u64 version;
u64 version_start;
u64 version_end;
u16 revision;
u32 self_type;
u8 erk[0x20];
@@ -27,7 +29,11 @@ struct SELF_KEY {
u8 priv[0x15];
u32 curve_type;
SELF_KEY(u64 ver, u16 rev, u32 type, const std::string& e, const std::string& r, const std::string& pb, const std::string& pr, u32 ct);
SELF_KEY(u64 ver_start, u64 ver_end, u16 rev, u32 type, const std::string& e, const std::string& r, const std::string& pb, const std::string& pr, u32 ct);
};
static u8 PKG_AES_KEY_IDU[0x10] = {
0x5d, 0xb9, 0x11, 0xe6, 0xb7, 0xe5, 0x0a, 0x7d, 0x32, 0x15, 0x38, 0xfd, 0x7c, 0x66, 0xf1, 0x7b
};
static u8 PKG_AES_KEY[0x10] = {
@@ -143,13 +149,13 @@ static u8 VSH_PUB[0x28] = {
0x6E, 0x73, 0x6A, 0xBF, 0x81, 0xF7, 0x0E, 0xE9, 0x16, 0x1B, 0x0D, 0xDE, 0xB0, 0x26, 0x76, 0x1A, 0xFF, 0x7B, 0xC8, 0x5B
};
static u8 SCEPKG_RIV[0x10] = {
0x4A, 0xCE, 0xF0, 0x12, 0x24, 0xFB, 0xEE, 0xDF, 0x82, 0x45, 0xF8, 0xFF, 0x10, 0x21, 0x1E, 0x6E
static u8 SCEPKG_RIV[0x10] = {
0x4A, 0xCE, 0xF0, 0x12, 0x24, 0xFB, 0xEE, 0xDF, 0x82, 0x45, 0xF8, 0xFF, 0x10, 0x21, 0x1E, 0x6E
};
static u8 SCEPKG_ERK[0x20] = {
static u8 SCEPKG_ERK[0x20] = {
0xA9, 0x78, 0x18, 0xBD, 0x19, 0x3A, 0x67, 0xA1, 0x6F, 0xE8, 0x3A, 0x85, 0x5E, 0x1B, 0xE9, 0xFB, 0x56, 0x40, 0x93, 0x8D,
0x4D, 0xBC, 0xB2, 0xCB, 0x52, 0xC5, 0xA2, 0xF8, 0xB0, 0x2B, 0x10, 0x31
0x4D, 0xBC, 0xB2, 0xCB, 0x52, 0xC5, 0xA2, 0xF8, 0xB0, 0x2B, 0x10, 0x31
};
static u8 PUP_KEY[0x40] = {
@@ -177,7 +183,7 @@ public:
void SetKlicenseeKey(u8 *key);
u8 *GetKlicenseeKey();
private:
private:
void LoadSelfLV0Keys();
void LoadSelfLDRKeys();
void LoadSelfLV1Keys();
+59 -57
View File
@@ -4,6 +4,8 @@
#include <cmath>
LOG_CHANNEL(edat_log, "EDAT");
void generate_key(int crypto_mode, int version, unsigned char *key_final, unsigned char *iv_final, unsigned char *key, unsigned char *iv)
{
int mode = crypto_mode & 0xF0000000;
@@ -78,7 +80,7 @@ bool decrypt(int hash_mode, int crypto_mode, int version, unsigned char *in, uns
}
else
{
LOG_ERROR(LOADER, "EDAT: Unknown crypto algorithm!");
edat_log.error("EDAT: Unknown crypto algorithm!");
return false;
}
@@ -96,7 +98,7 @@ bool decrypt(int hash_mode, int crypto_mode, int version, unsigned char *in, uns
}
else
{
LOG_ERROR(LOADER, "EDAT: Unknown hashing algorithm!");
edat_log.error("EDAT: Unknown hashing algorithm!");
return false;
}
}
@@ -280,7 +282,7 @@ s64 decrypt_block(const fs::file* in, u8* out, EDAT_HEADER *edat, NPD_HEADER *np
// Call main crypto routine on this data block.
if (!decrypt(hash_mode, crypto_mode, (npd->version == 4), enc_data.get(), dec_data.get(), length, key_result, iv, hash, hash_result))
{
LOG_ERROR(LOADER, "EDAT: Block at offset 0x%llx has invalid hash!", offset);
edat_log.error("EDAT: Block at offset 0x%llx has invalid hash!", offset);
return -1;
}
}
@@ -296,7 +298,7 @@ s64 decrypt_block(const fs::file* in, u8* out, EDAT_HEADER *edat, NPD_HEADER *np
{
if (res < 0)
{
LOG_ERROR(LOADER, "EDAT: Decompression failed!");
edat_log.error("EDAT: Decompression failed!");
return -1;
}
}
@@ -322,9 +324,9 @@ int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD
in->seek(0);
memset(data.get(), 0, edat->block_size);
u64 res = decrypt_block(in, data.get(), edat, npd, crypt_key, i, total_blocks, size_left);
if (res == -1)
if (res == umax)
{
LOG_ERROR(LOADER, "EDAT: Decrypt Block failed!");
edat_log.error("EDAT: Decrypt Block failed!");
return 1;
}
size_left -= res;
@@ -349,7 +351,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
{
if (edat->flags & 0x7EFFFFFE)
{
LOG_ERROR(LOADER, "EDAT: Bad header flags!");
edat_log.error("EDAT: Bad header flags!");
return 1;
}
}
@@ -357,7 +359,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
{
if (edat->flags & 0x7EFFFFE0)
{
LOG_ERROR(LOADER, "EDAT: Bad header flags!");
edat_log.error("EDAT: Bad header flags!");
return 1;
}
}
@@ -365,13 +367,13 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
{
if (edat->flags & 0x7EFFFFC0)
{
LOG_ERROR(LOADER, "EDAT: Bad header flags!");
edat_log.error("EDAT: Bad header flags!");
return 1;
}
}
else
{
LOG_ERROR(LOADER, "EDAT: Unknown version!");
edat_log.error("EDAT: Unknown version!");
return 1;
}
@@ -391,7 +393,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
hash_mode |= 0x01000000;
if (verbose)
LOG_WARNING(LOADER, "EDAT: DEBUG data detected!");
edat_log.warning("EDAT: DEBUG data detected!");
}
// Setup header key and iv buffers.
@@ -402,12 +404,12 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
if (!decrypt(hash_mode, crypto_mode, (npd->version == 4), header, empty_header, 0xA0, header_key, header_iv, key, header_hash))
{
if (verbose)
LOG_WARNING(LOADER, "EDAT: Header hash is invalid!");
edat_log.warning("EDAT: Header hash is invalid!");
// If the header hash test fails and the data is not DEBUG, then RAP/RIF/KLIC key is invalid.
if ((edat->flags & EDAT_DEBUG_DATA_FLAG) != EDAT_DEBUG_DATA_FLAG)
{
LOG_ERROR(LOADER, "EDAT: RAP/RIF/KLIC key is invalid!");
edat_log.error("EDAT: RAP/RIF/KLIC key is invalid!");
return 1;
}
}
@@ -417,7 +419,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
if (((edat->flags & EDAT_COMPRESSED_FLAG) != 0))
{
if (verbose)
LOG_WARNING(LOADER, "EDAT: COMPRESSED data detected!");
edat_log.warning("EDAT: COMPRESSED data detected!");
}
const int block_num = static_cast<int>((edat->file_size + edat->block_size - 1) / edat->block_size);
@@ -452,7 +454,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
if (!decrypt(hash_mode, crypto_mode, (npd->version == 4), metadata.get(), empty_metadata.get(), metadata_size, header_key, header_iv, key, metadata_hash))
{
if (verbose)
LOG_WARNING(LOADER, "EDAT: Metadata section hash is invalid!");
edat_log.warning("EDAT: Metadata section hash is invalid!");
}
// Checking ECDSA signatures.
@@ -480,7 +482,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
memcpy(signature_r + 01, metadata_signature, 0x14);
memcpy(signature_s + 01, metadata_signature + 0x14, 0x14);
if ((!memcmp(signature_r, zero_buf, 0x15)) || (!memcmp(signature_s, zero_buf, 0x15)))
LOG_WARNING(LOADER, "EDAT: Metadata signature is invalid!");
edat_log.warning("EDAT: Metadata signature is invalid!");
else
{
// Setup signature hash.
@@ -497,9 +499,9 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
if (!ecdsa_verify(signature_hash, signature_r, signature_s))
{
LOG_WARNING(LOADER, "EDAT: Metadata signature is invalid!");
edat_log.warning("EDAT: Metadata signature is invalid!");
if (((edat->block_size + 0ull) * block_num) > 0x100000000)
LOG_WARNING(LOADER, "EDAT: *Due to large file size, metadata signature status may be incorrect!");
edat_log.warning("EDAT: *Due to large file size, metadata signature status may be incorrect!");
}
}
@@ -511,7 +513,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
memcpy(signature_s + 01, header_signature + 0x14, 0x14);
if ((!memcmp(signature_r, zero_buf, 0x15)) || (!memcmp(signature_s, zero_buf, 0x15)))
LOG_WARNING(LOADER, "EDAT: Header signature is invalid!");
edat_log.warning("EDAT: Header signature is invalid!");
else
{
// Setup header signature hash.
@@ -522,7 +524,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
sha1(header_buf.get(), 0xD8, signature_hash );
if (!ecdsa_verify(signature_hash, signature_r, signature_s))
LOG_WARNING(LOADER, "EDAT: Header signature is invalid!");
edat_log.warning("EDAT: Header signature is invalid!");
}
}
@@ -589,9 +591,9 @@ int validate_npd_hashes(const char* file_name, const u8* klicensee, NPD_HEADER *
if (verbose)
{
if (title_hash_result)
LOG_NOTICE(LOADER, "EDAT: NPD title hash is valid!");
edat_log.notice("EDAT: NPD title hash is valid!");
else
LOG_WARNING(LOADER, "EDAT: NPD title hash is invalid!");
edat_log.warning("EDAT: NPD title hash is invalid!");
}
@@ -635,16 +637,16 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
unsigned char npd_magic[4] = {0x4E, 0x50, 0x44, 0x00}; //NPD0
if (memcmp(&NPD.magic, npd_magic, 4))
{
LOG_ERROR(LOADER, "EDAT: %s has invalid NPD header or already decrypted.", input_file_name);
edat_log.error("EDAT: %s has invalid NPD header or already decrypted.", input_file_name);
return 1;
}
if (verbose)
{
LOG_NOTICE(LOADER, "NPD HEADER");
LOG_NOTICE(LOADER, "NPD version: %d", NPD.version);
LOG_NOTICE(LOADER, "NPD license: %d", NPD.license);
LOG_NOTICE(LOADER, "NPD type: %d", NPD.type);
edat_log.notice("NPD HEADER");
edat_log.notice("NPD version: %d", NPD.version);
edat_log.notice("NPD license: %d", NPD.license);
edat_log.notice("NPD type: %d", NPD.type);
}
// Set decryption key.
@@ -655,10 +657,10 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
{
if (verbose)
{
LOG_NOTICE(LOADER, "SDAT HEADER");
LOG_NOTICE(LOADER, "SDAT flags: 0x%08X", EDAT.flags);
LOG_NOTICE(LOADER, "SDAT block size: 0x%08X", EDAT.block_size);
LOG_NOTICE(LOADER, "SDAT file size: 0x%08X", EDAT.file_size);
edat_log.notice("SDAT HEADER");
edat_log.notice("SDAT flags: 0x%08X", EDAT.flags);
edat_log.notice("SDAT block size: 0x%08X", EDAT.block_size);
edat_log.notice("SDAT file size: 0x%08X", EDAT.file_size);
}
// Generate SDAT key.
@@ -668,10 +670,10 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
{
if (verbose)
{
LOG_NOTICE(LOADER, "EDAT HEADER");
LOG_NOTICE(LOADER, "EDAT flags: 0x%08X", EDAT.flags);
LOG_NOTICE(LOADER, "EDAT block size: 0x%08X", EDAT.block_size);
LOG_NOTICE(LOADER, "EDAT file size: 0x%08X", EDAT.file_size);
edat_log.notice("EDAT HEADER");
edat_log.notice("EDAT flags: 0x%08X", EDAT.flags);
edat_log.notice("EDAT block size: 0x%08X", EDAT.block_size);
edat_log.notice("EDAT file size: 0x%08X", EDAT.file_size);
}
// Perform header validation (EDAT only).
@@ -682,7 +684,7 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
// Ignore header validation in DEBUG data.
if ((EDAT.flags & EDAT_DEBUG_DATA_FLAG) != EDAT_DEBUG_DATA_FLAG)
{
LOG_ERROR(LOADER, "EDAT: NPD hash validation failed!");
edat_log.error("EDAT: NPD hash validation failed!");
return 1;
}
}
@@ -707,48 +709,48 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
if (!test)
{
LOG_ERROR(LOADER, "EDAT: A valid RAP file is needed for this EDAT file!");
edat_log.error("EDAT: A valid RAP file is needed for this EDAT file!");
return 1;
}
}
else if ((NPD.license & 0x1) == 0x1) // Type 1: Use network activation.
{
LOG_ERROR(LOADER, "EDAT: Network license not supported!");
edat_log.error("EDAT: Network license not supported!");
return 1;
}
if (verbose)
{
int i;
LOG_NOTICE(LOADER, "DEVKLIC: ");
edat_log.notice("DEVKLIC: ");
for (i = 0; i < 0x10; i++)
LOG_NOTICE(LOADER, "%02X", devklic[i]);
edat_log.notice("%02X", devklic[i]);
LOG_NOTICE(LOADER, "RIF KEY: ");
edat_log.notice("RIF KEY: ");
for (i = 0; i < 0x10; i++)
LOG_NOTICE(LOADER, "%02X", rifkey[i]);
edat_log.notice("%02X", rifkey[i]);
}
}
if (verbose)
{
int i;
LOG_NOTICE(LOADER, "DECRYPTION KEY: ");
edat_log.notice("DECRYPTION KEY: ");
for (i = 0; i < 0x10; i++)
LOG_NOTICE(LOADER, "%02X", key[i]);
edat_log.notice("%02X", key[i]);
}
input->seek(0);
if (check_data(key, &EDAT, &NPD, input, verbose))
{
LOG_ERROR(LOADER, "EDAT: Data parsing failed!");
edat_log.error("EDAT: Data parsing failed!");
return 1;
}
input->seek(0);
if (decrypt_data(input, output, &EDAT, &NPD, key, verbose))
{
LOG_ERROR(LOADER, "EDAT: Data decryption failed!");
edat_log.error("EDAT: Data decryption failed!");
return 1;
}
@@ -779,13 +781,13 @@ bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& inpu
unsigned char npd_magic[4] = { 0x4E, 0x50, 0x44, 0x00 }; //NPD0
if (memcmp(&NPD.magic, npd_magic, 4))
{
LOG_ERROR(LOADER, "EDAT: %s has invalid NPD header or already decrypted.", input_file_name);
edat_log.error("EDAT: %s has invalid NPD header or already decrypted.", input_file_name);
return false;
}
if ((EDAT.flags & SDAT_FLAG) == SDAT_FLAG)
{
LOG_ERROR(LOADER, "EDAT: SDATA file given to edat function");
edat_log.error("EDAT: SDATA file given to edat function");
return false;
}
@@ -797,7 +799,7 @@ bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& inpu
// Ignore header validation in DEBUG data.
if ((EDAT.flags & EDAT_DEBUG_DATA_FLAG) != EDAT_DEBUG_DATA_FLAG)
{
LOG_ERROR(LOADER, "EDAT: NPD hash validation failed!");
edat_log.error("EDAT: NPD hash validation failed!");
return false;
}
}
@@ -848,18 +850,18 @@ fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name,
memcpy(devklic, custom_klic, 0x10);
else
{
LOG_ERROR(LOADER, "EDAT: Invalid custom klic!");
edat_log.error("EDAT: Invalid custom klic!");
return fs::file{};
}
break;
}
default:
LOG_ERROR(LOADER, "EDAT: Invalid mode!");
edat_log.error("EDAT: Invalid mode!");
return fs::file{};
}
// Read the RAP file, if provided.
if (rap_file_name.size())
if (!rap_file_name.empty())
{
fs::file rap(rap_file_name);
@@ -901,7 +903,7 @@ bool EDATADecrypter::ReadHeader()
// verify key
if (validate_dev_klic(dev_key.data(), &npdHeader) == 0)
{
LOG_ERROR(LOADER, "EDAT: Failed validating klic");
edat_log.error("EDAT: Failed validating klic");
return false;
}
@@ -914,12 +916,12 @@ bool EDATADecrypter::ReadHeader()
if (dec_key == std::array<u8, 0x10>{0})
{
LOG_WARNING(LOADER, "EDAT: Empty Dec key!");
edat_log.warning("EDAT: Empty Dec key!");
}
}
else if ((npdHeader.license & 0x1) == 0x1) // Type 1: Use network activation.
{
LOG_ERROR(LOADER, "EDAT: Network license not supported!");
edat_log.error("EDAT: Network license not supported!");
return false;
}
}
@@ -964,9 +966,9 @@ u64 EDATADecrypter::ReadData(u64 pos, u8* data, u64 size)
{
edata_file.seek(0);
u64 res = decrypt_block(&edata_file, &data_buf[writeOffset], &edatHeader, &npdHeader, dec_key.data(), i, total_blocks, edatHeader.file_size);
if (res == -1)
if (res == umax)
{
LOG_ERROR(LOADER, "Error Decrypting data");
edat_log.error("Error Decrypting data");
return 0;
}
writeOffset += res;
+38 -29
View File
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "utils.h"
#include "aes.h"
#include "sha1.h"
@@ -8,8 +8,16 @@
#include "Emu/VFS.h"
#include "unpkg.h"
LOG_CHANNEL(pkg_log, "PKG");
bool pkg_install(const std::string& path, atomic_t<double>& sync)
{
if (!fs::is_file(path))
{
pkg_log.error("PKG file not found!");
return false;
}
const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB
std::vector<fs::file> filelist;
@@ -70,13 +78,13 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
if (archive_read(&header, sizeof(header)) != sizeof(header))
{
LOG_ERROR(LOADER, "PKG file is too short!");
pkg_log.error("PKG file is too short!");
return false;
}
if (header.pkg_magic != "\x7FPKG"_u32)
{
LOG_ERROR(LOADER, "Not a PKG file!");
pkg_log.error("Not a PKG file!");
return false;
}
@@ -86,7 +94,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
case PKG_RELEASE_TYPE_RELEASE: break;
default:
{
LOG_ERROR(LOADER, "Unknown PKG type (0x%x)", type);
pkg_log.error("Unknown PKG type (0x%x)", type);
return false;
}
}
@@ -97,7 +105,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
case PKG_PLATFORM_TYPE_PSP: break;
default:
{
LOG_ERROR(LOADER, "Unknown PKG platform (0x%x)", platform);
pkg_log.error("Unknown PKG platform (0x%x)", platform);
return false;
}
}
@@ -105,9 +113,9 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
if (header.pkg_size > filelist[0].size())
{
// Check if multi-files pkg
if (path.size() < 7 || path.compare(path.size() - 7, 7, "_00.pkg", 7) != 0)
if (!path.ends_with("_00.pkg"))
{
LOG_ERROR(LOADER, "PKG file size mismatch (pkg_size=0x%llx)", header.pkg_size);
pkg_log.error("PKG file size mismatch (pkg_size=0x%llx)", header.pkg_size);
return false;
}
@@ -120,7 +128,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
fs::file archive_file(archive_filename);
if (!archive_file)
{
LOG_ERROR(LOADER, "Missing part of the multi-files pkg: %s", archive_filename);
pkg_log.error("Missing part of the multi-files pkg: %s", archive_filename);
return false;
}
@@ -131,7 +139,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
if (header.data_size + header.data_offset > header.pkg_size)
{
LOG_ERROR(LOADER, "PKG data size mismatch (data_size=0x%llx, data_offset=0x%llx, file_size=0x%llx)", header.data_size, header.data_offset, header.pkg_size);
pkg_log.error("PKG data size mismatch (data_size=0x%llx, data_offset=0x%llx, file_size=0x%llx)", header.data_size, header.data_offset, header.pkg_size);
return false;
}
@@ -205,7 +213,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
if (!fs::create_path(dir))
{
LOG_ERROR(LOADER, "PKG: Could not create the installation directory %s", dir);
pkg_log.error("PKG: Could not create the installation directory %s", dir);
return false;
}
@@ -285,7 +293,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
const uchar psp2t3[] = {0xAF, 0x07, 0xFD, 0x59, 0x65, 0x25, 0x27, 0xBA, 0xF1, 0x33, 0x89, 0x66, 0x8B, 0x17, 0xD9, 0xEA};
aes_context ctx;
aes_setkey_enc(&ctx, content_type == 0x15 ? psp2t1 : content_type == 0x16 ? psp2t2 : psp2t3, 128);
aes_setkey_enc(&ctx, content_type == 0x15u ? psp2t1 : content_type == 0x16u ? psp2t2 : psp2t3, 128);
aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast<const uchar*>(&header.klicensee), dec_key.data());
decrypt(0, header.file_count * sizeof(PKGEntry), dec_key.data());
}
@@ -303,12 +311,12 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
for (const auto& entry : entries)
{
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0;
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
if (entry.name_size > 256)
{
num_failures++;
LOG_ERROR(LOADER, "PKG name size is too big (0x%x)", entry.name_size);
pkg_log.error("PKG name size is too big (0x%x)", entry.name_size);
continue;
}
@@ -316,7 +324,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
std::string name{reinterpret_cast<char*>(buf.get()), entry.name_size};
LOG_NOTICE(LOADER, "Entry 0x%08x: %s", entry.type, name);
pkg_log.notice("Entry 0x%08x: %s", entry.type, name);
switch (entry.type & 0xff)
{
@@ -331,14 +339,15 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
case 0x13:
case 0x15:
case 0x16:
case 0x19:
{
const std::string path = dir + vfs::escape(name);
const bool did_overwrite = fs::is_file(path);
if (did_overwrite && (entry.type & PKG_FILE_ENTRY_OVERWRITE) == 0)
if (did_overwrite && !(entry.type & PKG_FILE_ENTRY_OVERWRITE))
{
LOG_NOTICE(LOADER, "Didn't overwrite %s", name);
pkg_log.notice("Didn't overwrite %s", name);
break;
}
@@ -352,14 +361,14 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : dec_key.data()) != block_size)
{
extract_success = false;
LOG_ERROR(LOADER, "Failed to extract file %s", path);
pkg_log.error("Failed to extract file %s", path);
break;
}
if (out.write(buf.get(), block_size) != block_size)
{
extract_success = false;
LOG_ERROR(LOADER, "Failed to write file %s", path);
pkg_log.error("Failed to write file %s", path);
break;
}
@@ -367,7 +376,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
{
if (was_null)
{
LOG_ERROR(LOADER, "Package installation cancelled: %s", dir);
pkg_log.error("Package installation cancelled: %s", dir);
out.close();
fs::remove_all(dir, true);
return false;
@@ -379,14 +388,14 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
}
if (extract_success)
{
{
if (did_overwrite)
{
LOG_WARNING(LOADER, "Overwritten file %s", name);
pkg_log.warning("Overwritten file %s", name);
}
else
{
LOG_NOTICE(LOADER, "Created file %s", name);
pkg_log.notice("Created file %s", name);
}
}
else
@@ -397,7 +406,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
else
{
num_failures++;
LOG_ERROR(LOADER, "Failed to create file %s", path);
pkg_log.error("Failed to create file %s", path);
}
break;
@@ -410,16 +419,16 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
if (fs::create_dir(path))
{
LOG_NOTICE(LOADER, "Created directory %s", name);
pkg_log.notice("Created directory %s", name);
}
else if (fs::is_dir(path))
{
LOG_WARNING(LOADER, "Reused existing directory %s", name);
pkg_log.warning("Reused existing directory %s", name);
}
else
{
num_failures++;
LOG_ERROR(LOADER, "Failed to create directory %s", path);
pkg_log.error("Failed to create directory %s", path);
}
break;
@@ -428,19 +437,19 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
default:
{
num_failures++;
LOG_ERROR(LOADER, "Unknown PKG entry type (0x%x) %s", entry.type, name);
pkg_log.error("Unknown PKG entry type (0x%x) %s", entry.type, name);
}
}
}
if (num_failures == 0)
{
LOG_SUCCESS(LOADER, "Package successfully installed to %s", dir);
pkg_log.success("Package successfully installed to %s", dir);
}
else
{
fs::remove_all(dir, true);
LOG_ERROR(LOADER, "Package installation failed: %s", dir);
pkg_log.error("Package installation failed: %s", dir);
}
return num_failures == 0;
}
+118 -111
View File
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "aes.h"
#include "sha1.h"
#include "utils.h"
@@ -203,10 +203,10 @@ void AppInfo::Load(const fs::file& f)
void AppInfo::Show()
{
LOG_NOTICE(LOADER, "AuthID: 0x%llx", authid);
LOG_NOTICE(LOADER, "VendorID: 0x%08x", vendor_id);
LOG_NOTICE(LOADER, "SELF type: 0x%08x", self_type);
LOG_NOTICE(LOADER, "Version: 0x%llx", version);
self_log.notice("AuthID: 0x%llx", authid);
self_log.notice("VendorID: 0x%08x", vendor_id);
self_log.notice("SELF type: 0x%08x", self_type);
self_log.notice("Version: 0x%llx", version);
}
void SectionInfo::Load(const fs::file& f)
@@ -221,12 +221,12 @@ void SectionInfo::Load(const fs::file& f)
void SectionInfo::Show()
{
LOG_NOTICE(LOADER, "Offset: 0x%llx", offset);
LOG_NOTICE(LOADER, "Size: 0x%llx", size);
LOG_NOTICE(LOADER, "Compressed: 0x%08x", compressed);
LOG_NOTICE(LOADER, "Unknown1: 0x%08x", unknown1);
LOG_NOTICE(LOADER, "Unknown2: 0x%08x", unknown2);
LOG_NOTICE(LOADER, "Encrypted: 0x%08x", encrypted);
self_log.notice("Offset: 0x%llx", offset);
self_log.notice("Size: 0x%llx", size);
self_log.notice("Compressed: 0x%08x", compressed);
self_log.notice("Unknown1: 0x%08x", unknown1);
self_log.notice("Unknown2: 0x%08x", unknown2);
self_log.notice("Encrypted: 0x%08x", encrypted);
}
void SCEVersionInfo::Load(const fs::file& f)
@@ -239,10 +239,10 @@ void SCEVersionInfo::Load(const fs::file& f)
void SCEVersionInfo::Show()
{
LOG_NOTICE(LOADER, "Sub-header type: 0x%08x", subheader_type);
LOG_NOTICE(LOADER, "Present: 0x%08x", present);
LOG_NOTICE(LOADER, "Size: 0x%08x", size);
LOG_NOTICE(LOADER, "Unknown: 0x%08x", unknown);
self_log.notice("Sub-header type: 0x%08x", subheader_type);
self_log.notice("Present: 0x%08x", present);
self_log.notice("Size: 0x%08x", size);
self_log.notice("Unknown: 0x%08x", unknown);
}
void ControlInfo::Load(const fs::file& f)
@@ -293,20 +293,20 @@ void ControlInfo::Load(const fs::file& f)
void ControlInfo::Show()
{
LOG_NOTICE(LOADER, "Type: 0x%08x", type);
LOG_NOTICE(LOADER, "Size: 0x%08x", size);
LOG_NOTICE(LOADER, "Next: 0x%llx", next);
self_log.notice("Type: 0x%08x", type);
self_log.notice("Size: 0x%08x", size);
self_log.notice("Next: 0x%llx", next);
if (type == 1)
{
LOG_NOTICE(LOADER, "Control flag 1: 0x%08x", control_flags.ctrl_flag1);
LOG_NOTICE(LOADER, "Unknown1: 0x%08x", control_flags.unknown1);
LOG_NOTICE(LOADER, "Unknown2: 0x%08x", control_flags.unknown2);
LOG_NOTICE(LOADER, "Unknown3: 0x%08x", control_flags.unknown3);
LOG_NOTICE(LOADER, "Unknown4: 0x%08x", control_flags.unknown4);
LOG_NOTICE(LOADER, "Unknown5: 0x%08x", control_flags.unknown5);
LOG_NOTICE(LOADER, "Unknown6: 0x%08x", control_flags.unknown6);
LOG_NOTICE(LOADER, "Unknown7: 0x%08x", control_flags.unknown7);
self_log.notice("Control flag 1: 0x%08x", control_flags.ctrl_flag1);
self_log.notice("Unknown1: 0x%08x", control_flags.unknown1);
self_log.notice("Unknown2: 0x%08x", control_flags.unknown2);
self_log.notice("Unknown3: 0x%08x", control_flags.unknown3);
self_log.notice("Unknown4: 0x%08x", control_flags.unknown4);
self_log.notice("Unknown5: 0x%08x", control_flags.unknown5);
self_log.notice("Unknown6: 0x%08x", control_flags.unknown6);
self_log.notice("Unknown7: 0x%08x", control_flags.unknown7);
}
else if (type == 2)
{
@@ -316,8 +316,8 @@ void ControlInfo::Show()
for (int i = 0; i < 20; i++)
digest_str += fmt::format("%02x", file_digest_30.digest[i]);
LOG_NOTICE(LOADER, "Digest: %s", digest_str.c_str());
LOG_NOTICE(LOADER, "Unknown: 0x%llx", file_digest_30.unknown);
self_log.notice("Digest: %s", digest_str.c_str());
self_log.notice("Unknown: 0x%llx", file_digest_30.unknown);
}
else if (size == 0x40)
{
@@ -329,9 +329,9 @@ void ControlInfo::Show()
digest_str2 += fmt::format("%02x", file_digest_40.digest2[i]);
}
LOG_NOTICE(LOADER, "Digest1: %s", digest_str1.c_str());
LOG_NOTICE(LOADER, "Digest2: %s", digest_str2.c_str());
LOG_NOTICE(LOADER, "Unknown: 0x%llx", file_digest_40.unknown);
self_log.notice("Digest1: %s", digest_str1.c_str());
self_log.notice("Digest2: %s", digest_str2.c_str());
self_log.notice("Unknown: 0x%llx", file_digest_40.unknown);
}
}
else if (type == 3)
@@ -349,16 +349,16 @@ void ControlInfo::Show()
xordigest_str += fmt::format("%02x", npdrm.xordigest[i]);
}
LOG_NOTICE(LOADER, "Magic: 0x%08x", npdrm.magic);
LOG_NOTICE(LOADER, "Unknown1: 0x%08x", npdrm.unknown1);
LOG_NOTICE(LOADER, "License: 0x%08x", npdrm.license);
LOG_NOTICE(LOADER, "Type: 0x%08x", npdrm.type);
LOG_NOTICE(LOADER, "ContentID: %s", contentid_str.c_str());
LOG_NOTICE(LOADER, "Digest: %s", digest_str.c_str());
LOG_NOTICE(LOADER, "Inverse digest: %s", invdigest_str.c_str());
LOG_NOTICE(LOADER, "XOR digest: %s", xordigest_str.c_str());
LOG_NOTICE(LOADER, "Unknown2: 0x%llx", npdrm.unknown2);
LOG_NOTICE(LOADER, "Unknown3: 0x%llx", npdrm.unknown3);
self_log.notice("Magic: 0x%08x", npdrm.magic);
self_log.notice("Unknown1: 0x%08x", npdrm.unknown1);
self_log.notice("License: 0x%08x", npdrm.license);
self_log.notice("Type: 0x%08x", npdrm.type);
self_log.notice("ContentID: %s", contentid_str.c_str());
self_log.notice("Digest: %s", digest_str.c_str());
self_log.notice("Inverse digest: %s", invdigest_str.c_str());
self_log.notice("XOR digest: %s", xordigest_str.c_str());
self_log.notice("Unknown2: 0x%llx", npdrm.unknown2);
self_log.notice("Unknown3: 0x%llx", npdrm.unknown3);
}
}
@@ -384,10 +384,10 @@ void MetadataInfo::Show()
iv_pad_str += fmt::format("%02x", iv_pad[i]);
}
LOG_NOTICE(LOADER, "Key: %s", key_str.c_str());
LOG_NOTICE(LOADER, "Key pad: %s", key_pad_str.c_str());
LOG_NOTICE(LOADER, "IV: %s", iv_str.c_str());
LOG_NOTICE(LOADER, "IV pad: %s", iv_pad_str.c_str());
self_log.notice("Key: %s", key_str.c_str());
self_log.notice("Key pad: %s", key_pad_str.c_str());
self_log.notice("IV: %s", iv_str.c_str());
self_log.notice("IV pad: %s", iv_pad_str.c_str());
}
void MetadataHeader::Load(u8* in)
@@ -412,13 +412,13 @@ void MetadataHeader::Load(u8* in)
void MetadataHeader::Show()
{
LOG_NOTICE(LOADER, "Signature input length: 0x%llx", signature_input_length);
LOG_NOTICE(LOADER, "Unknown1: 0x%08x", unknown1);
LOG_NOTICE(LOADER, "Section count: 0x%08x", section_count);
LOG_NOTICE(LOADER, "Key count: 0x%08x", key_count);
LOG_NOTICE(LOADER, "Optional header size: 0x%08x", opt_header_size);
LOG_NOTICE(LOADER, "Unknown2: 0x%08x", unknown2);
LOG_NOTICE(LOADER, "Unknown3: 0x%08x", unknown3);
self_log.notice("Signature input length: 0x%llx", signature_input_length);
self_log.notice("Unknown1: 0x%08x", unknown1);
self_log.notice("Section count: 0x%08x", section_count);
self_log.notice("Key count: 0x%08x", key_count);
self_log.notice("Optional header size: 0x%08x", opt_header_size);
self_log.notice("Unknown2: 0x%08x", unknown2);
self_log.notice("Unknown3: 0x%08x", unknown3);
}
void MetadataSectionHeader::Load(u8* in)
@@ -449,16 +449,16 @@ void MetadataSectionHeader::Load(u8* in)
void MetadataSectionHeader::Show()
{
LOG_NOTICE(LOADER, "Data offset: 0x%llx", data_offset);
LOG_NOTICE(LOADER, "Data size: 0x%llx", data_size);
LOG_NOTICE(LOADER, "Type: 0x%08x", type);
LOG_NOTICE(LOADER, "Program index: 0x%08x", program_idx);
LOG_NOTICE(LOADER, "Hashed: 0x%08x", hashed);
LOG_NOTICE(LOADER, "SHA1 index: 0x%08x", sha1_idx);
LOG_NOTICE(LOADER, "Encrypted: 0x%08x", encrypted);
LOG_NOTICE(LOADER, "Key index: 0x%08x", key_idx);
LOG_NOTICE(LOADER, "IV index: 0x%08x", iv_idx);
LOG_NOTICE(LOADER, "Compressed: 0x%08x", compressed);
self_log.notice("Data offset: 0x%llx", data_offset);
self_log.notice("Data size: 0x%llx", data_size);
self_log.notice("Type: 0x%08x", type);
self_log.notice("Program index: 0x%08x", program_idx);
self_log.notice("Hashed: 0x%08x", hashed);
self_log.notice("SHA1 index: 0x%08x", sha1_idx);
self_log.notice("Encrypted: 0x%08x", encrypted);
self_log.notice("Key index: 0x%08x", key_idx);
self_log.notice("IV index: 0x%08x", iv_idx);
self_log.notice("Compressed: 0x%08x", compressed);
}
void SectionHash::Load(const fs::file& f)
@@ -664,7 +664,7 @@ bool SCEDecrypter::LoadHeaders()
// Check SCE magic.
if (!sce_hdr.CheckMagic())
{
LOG_ERROR(LOADER, "SELF: Not a SELF file!");
self_log.error("SELF: Not a SELF file!");
return false;
}
@@ -708,7 +708,7 @@ bool SCEDecrypter::LoadMetadata(const u8 erk[32], const u8 riv[16])
if ((meta_info.key_pad[0] != 0x00) ||
(meta_info.iv_pad[0] != 0x00))
{
LOG_ERROR(LOADER, "SELF: Failed to decrypt metadata info!");
self_log.error("SELF: Failed to decrypt metadata info!");
return false;
}
@@ -832,8 +832,14 @@ std::vector<fs::file> SCEDecrypter::MakeFile()
strm.avail_out = BUFSIZE;
strm.next_in = data_buf.get()+data_buf_offset;
strm.next_out = tempbuf;
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
int ret = inflateInit(&strm);
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
while (strm.avail_in)
{
ret = inflate(&strm, Z_NO_FLUSH);
@@ -881,7 +887,6 @@ std::vector<fs::file> SCEDecrypter::MakeFile()
SELFDecrypter::SELFDecrypter(const fs::file& s)
: self_f(s)
, key_v()
, data_buf_length(0)
{
}
@@ -899,7 +904,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
// Check SCE magic.
if (!sce_hdr.CheckMagic())
{
LOG_ERROR(LOADER, "SELF: Not a SELF file!");
self_log.error("SELF: Not a SELF file!");
return false;
}
@@ -929,7 +934,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
phdr32_arr.clear();
if(elf32_hdr.e_phoff == 0 && elf32_hdr.e_phnum)
{
LOG_ERROR(LOADER, "SELF: ELF program header offset is null!");
self_log.error("SELF: ELF program header offset is null!");
return false;
}
self_f.seek(self_hdr.se_phdroff);
@@ -945,7 +950,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
if (elf64_hdr.e_phoff == 0 && elf64_hdr.e_phnum)
{
LOG_ERROR(LOADER, "SELF: ELF program header offset is null!");
self_log.error("SELF: ELF program header offset is null!");
return false;
}
@@ -997,7 +1002,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
if (elf32_hdr.e_shoff == 0 && elf32_hdr.e_shnum)
{
LOG_WARNING(LOADER, "SELF: ELF section header offset is null!");
self_log.warning("SELF: ELF section header offset is null!");
return true;
}
@@ -1014,7 +1019,7 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
shdr64_arr.clear();
if (elf64_hdr.e_shoff == 0 && elf64_hdr.e_shnum)
{
LOG_WARNING(LOADER, "SELF: ELF section header offset is null!");
self_log.warning("SELF: ELF section header offset is null!");
return true;
}
@@ -1037,46 +1042,46 @@ bool SELFDecrypter::LoadHeaders(bool isElf32, SelfAdditionalInfo* out_info)
void SELFDecrypter::ShowHeaders(bool isElf32)
{
LOG_NOTICE(LOADER, "SCE header");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("SCE header");
self_log.notice("----------------------------------------------------");
sce_hdr.Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
LOG_NOTICE(LOADER, "SELF header");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
self_log.notice("SELF header");
self_log.notice("----------------------------------------------------");
self_hdr.Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
LOG_NOTICE(LOADER, "APP INFO");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
self_log.notice("APP INFO");
self_log.notice("----------------------------------------------------");
app_info.Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
LOG_NOTICE(LOADER, "ELF header");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
self_log.notice("ELF header");
self_log.notice("----------------------------------------------------");
isElf32 ? elf32_hdr.Show() : elf64_hdr.Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
LOG_NOTICE(LOADER, "ELF program headers");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
self_log.notice("ELF program headers");
self_log.notice("----------------------------------------------------");
for(unsigned int i = 0; i < ((isElf32) ? phdr32_arr.size() : phdr64_arr.size()); i++)
isElf32 ? phdr32_arr[i].Show() : phdr64_arr[i].Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
LOG_NOTICE(LOADER, "Section info");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
self_log.notice("Section info");
self_log.notice("----------------------------------------------------");
for(unsigned int i = 0; i < secinfo_arr.size(); i++)
secinfo_arr[i].Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
LOG_NOTICE(LOADER, "SCE version info");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
self_log.notice("SCE version info");
self_log.notice("----------------------------------------------------");
scev_info.Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
LOG_NOTICE(LOADER, "Control info");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
self_log.notice("Control info");
self_log.notice("----------------------------------------------------");
for(unsigned int i = 0; i < ctrlinfo_arr.size(); i++)
ctrlinfo_arr[i].Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
LOG_NOTICE(LOADER, "ELF section headers");
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
self_log.notice("ELF section headers");
self_log.notice("----------------------------------------------------");
for(unsigned int i = 0; i < ((isElf32) ? shdr32_arr.size() : shdr64_arr.size()); i++)
isElf32 ? shdr32_arr[i].Show() : shdr64_arr[i].Show();
LOG_NOTICE(LOADER, "----------------------------------------------------");
self_log.notice("----------------------------------------------------");
}
bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
@@ -1100,13 +1105,13 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
// If not, the data has no NPDRM layer.
if (!ctrl)
{
LOG_TRACE(LOADER, "SELF: No NPDRM control info found!");
self_log.trace("SELF: No NPDRM control info found!");
return true;
}
if (ctrl->npdrm.license == 1) // Network license.
{
LOG_ERROR(LOADER, "SELF: Can't decrypt network NPDRM!");
self_log.error("SELF: Can't decrypt network NPDRM!");
return false;
}
else if (ctrl->npdrm.license == 2) // Local license.
@@ -1114,7 +1119,7 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
// Try to find a RAP file to get the key.
if (!GetKeyFromRap(ctrl->npdrm.content_id, npdrm_key))
{
LOG_ERROR(LOADER, "SELF: Can't find RAP file for NPDRM decryption!");
self_log.error("SELF: Can't find RAP file for NPDRM decryption!");
return false;
}
}
@@ -1128,7 +1133,7 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
}
else
{
LOG_ERROR(LOADER, "SELF: Invalid NPDRM license type!");
self_log.error("SELF: Invalid NPDRM license type!");
return false;
}
@@ -1194,7 +1199,7 @@ bool SELFDecrypter::LoadMetadata(u8* klic_key)
if ((meta_info.key_pad[0] != 0x00) ||
(meta_info.iv_pad[0] != 0x00))
{
LOG_ERROR(LOADER, "SELF: Failed to decrypt metadata info!");
self_log.error("SELF: Failed to decrypt metadata info!");
return false;
}
@@ -1319,11 +1324,13 @@ bool SELFDecrypter::GetKeyFromRap(u8* content_id, u8* npdrm_key)
if (!rap_file)
{
LOG_FATAL(LOADER, "Failed to load RAP file: %s. Make sure the file extension is lowercase.", rap_path);
self_log.fatal("Failed to locate the game license file: %s."
"\nEnsure the .rap license file is placed in the dev_hdd0/home/00000001/exdata folder with a lowercase file extension."
"\nIf you need assistance on dumping the license file from your PS3, read our quickstart guide: https://rpcs3.net/quickstart", rap_path);
return false;
}
LOG_NOTICE(LOADER, "Loading RAP file %s.rap", ci_str);
self_log.notice("Loading RAP file %s.rap", ci_str);
rap_file.read(rap_key, 0x10);
// Convert the RAP key.
@@ -1367,7 +1374,7 @@ static bool CheckDebugSelf(fs::file& s)
// Check for DEBUG version.
if (key_version == 0x80 || key_version == 0xc0)
{
LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header...");
self_log.warning("Debug SELF detected! Removing fake header...");
// Get the real elf offset.
s.seek(0x10);
@@ -1419,21 +1426,21 @@ fs::file decrypt_self(fs::file elf_or_self, u8* klic_key, SelfAdditionalInfo* ou
// Load the SELF file headers.
if (!self_dec.LoadHeaders(isElf32, out_info))
{
LOG_ERROR(LOADER, "SELF: Failed to load SELF file headers!");
self_log.error("SELF: Failed to load SELF file headers!");
return fs::file{};
}
// Load and decrypt the SELF file metadata.
if (!self_dec.LoadMetadata(klic_key))
{
LOG_ERROR(LOADER, "SELF: Failed to load SELF file metadata!");
self_log.error("SELF: Failed to load SELF file metadata!");
return fs::file{};
}
// Decrypt the SELF file data.
if (!self_dec.DecryptData())
{
LOG_ERROR(LOADER, "SELF: Failed to decrypt SELF file data!");
self_log.error("SELF: Failed to decrypt SELF file data!");
return fs::file{};
}
@@ -1462,14 +1469,14 @@ bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key)
// Load the SELF file headers.
if (!self_dec.LoadHeaders(isElf32))
{
LOG_ERROR(LOADER, "SELF: Failed to load SELF file headers!");
self_log.error("SELF: Failed to load SELF file headers!");
return false;
}
// Load and decrypt the SELF file metadata.
if (!self_dec.LoadMetadata(klic_key))
{
LOG_ERROR(LOADER, "SELF: Failed to load SELF file metadata!");
self_log.error("SELF: Failed to load SELF file metadata!");
return false;
}
}
+9 -7
View File
@@ -7,7 +7,9 @@
#include "Utilities/File.h"
#include "Utilities/Log.h"
struct AppInfo
LOG_CHANNEL(self_log, "SELF");
struct AppInfo
{
u64 authid;
u32 vendor_id;
@@ -338,7 +340,7 @@ struct SelfHeader
u64 se_controloff;
u64 se_controlsize;
u64 pad;
void Load(const fs::file& f);
void Show(){}
};
@@ -387,7 +389,7 @@ class SELFDecrypter
SceHeader sce_hdr;
SelfHeader self_hdr;
AppInfo app_info;
// ELF64 header and program header/section header arrays.
Elf64_Ehdr elf64_hdr;
std::vector<Elf64_Shdr> shdr64_arr;
@@ -412,7 +414,7 @@ class SELFDecrypter
std::unique_ptr<u8[]> data_keys;
u32 data_keys_length;
std::unique_ptr<u8[]> data_buf;
u32 data_buf_length;
u32 data_buf_length = 0;
// Main key vault instance.
KeyVault key_v;
@@ -469,9 +471,9 @@ private:
// Check for errors (TODO: Probably safe to remove this once these changes have passed testing.)
switch (rv)
{
case Z_MEM_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_MEM_ERROR!"); break;
case Z_BUF_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_BUF_ERROR!"); break;
case Z_DATA_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_DATA_ERROR!"); break;
case Z_MEM_ERROR: self_log.error("MakeELF encountered a Z_MEM_ERROR!"); break;
case Z_BUF_ERROR: self_log.error("MakeELF encountered a Z_BUF_ERROR!"); break;
case Z_DATA_ERROR: self_log.error("MakeELF encountered a Z_DATA_ERROR!"); break;
default: break;
}
+7 -8
View File
@@ -1,5 +1,4 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "OpenALBackend.h"
@@ -7,23 +6,23 @@
#pragma comment(lib, "OpenAL32.lib")
#endif
LOG_CHANNEL(OpenAL);
#define checkForAlError(sit) do { ALenum g_last_al_error = alGetError(); if(g_last_al_error != AL_NO_ERROR) fmt::throw_exception("%s: OpenAL error 0x%04x", sit, g_last_al_error); } while(0)
#define checkForAlcError(sit) do { ALCenum g_last_alc_error = alcGetError(m_device); if(g_last_alc_error != ALC_NO_ERROR) fmt::throw_exception("%s: OpenALC error 0x%04x", sit, g_last_alc_error); } while(0)
#define checkForAlError(sit) do { ALenum g_last_al_error = alGetError(); if(g_last_al_error != AL_NO_ERROR) OpenAL.error("%s: OpenAL error 0x%04x", sit, g_last_al_error); } while(0)
#define checkForAlcError(sit) do { ALCenum g_last_alc_error = alcGetError(m_device); if(g_last_alc_error != ALC_NO_ERROR) { OpenAL.error("%s: OpenALC error 0x%04x", sit, g_last_alc_error); return; }} while(0)
OpenALBackend::OpenALBackend()
: m_sampling_rate(get_sampling_rate())
, m_sample_size(get_sample_size())
{
ALCdevice* m_device = alcOpenDevice(nullptr);
checkForAlcError("OpenALBackend->alcOpenDevice");
checkForAlcError("alcOpenDevice");
ALCcontext* m_context = alcCreateContext(m_device, nullptr);
checkForAlcError("OpenALBackend->alcCreateContext");
checkForAlcError("alcCreateContext");
alcMakeContextCurrent(m_context);
checkForAlcError("OpenALBackend->alcMakeContextCurrent");
checkForAlcError("alcMakeContextCurrent");
if (get_channels() == 2)
{
@@ -128,7 +127,7 @@ bool OpenALBackend::AddData(const void* src, u32 num_samples)
// Fail if there are no free buffers remaining
if (m_num_unqueued == 0)
{
LOG_WARNING(GENERAL, "OpenALBackend : no unqueued buffers remaining");
OpenAL.warning("No unqueued buffers remaining");
return false;
}
+8 -7
View File
@@ -3,14 +3,15 @@
#endif
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/system_config.h"
#include "ALSABackend.h"
LOG_CHANNEL(ALSA);
static void error(int err, const char* reason)
{
LOG_ERROR(GENERAL, "ALSA: %s failed: %s\n", reason, snd_strerror(err));
ALSA.error("ALSA: %s failed: %s\n", reason, snd_strerror(err));
}
static bool check(int err, const char* reason)
@@ -105,7 +106,7 @@ void ALSABackend::Open(u32 num_buffers)
if (!check(snd_pcm_prepare(tls_handle), "snd_pcm_prepare"))
return;
LOG_NOTICE(GENERAL, "ALSA: bufsize_frames=%u, period_frames=%u", bufsize_frames, period_frames);
ALSA.notice("bufsize_frames=%u, period_frames=%u", bufsize_frames, period_frames);
}
void ALSABackend::Close()
@@ -137,7 +138,7 @@ bool ALSABackend::AddData(const void* src, u32 num_samples)
if (res == -EAGAIN)
{
LOG_WARNING(GENERAL, "ALSA: EAGAIN");
ALSA.warning("EAGAIN");
return false;
}
@@ -147,16 +148,16 @@ bool ALSABackend::AddData(const void* src, u32 num_samples)
if (res < 0)
{
LOG_WARNING(GENERAL, "ALSA: failed to recover (%d)", res);
ALSA.warning("Failed to recover (%d)", res);
return false;
}
return false;
}
if (res != num_frames)
if (res + 0u != num_frames)
{
LOG_WARNING(GENERAL, "ALSA: error (%d)", res);
ALSA.warning("Error (%d)", res);
return false;
}
+68
View File
@@ -0,0 +1,68 @@
#include "stdafx.h"
#include "AudioBackend.h"
#include "Emu/system_config.h"
/*
* Helper methods
*/
u32 AudioBackend::get_sampling_rate()
{
const u32 sampling_period_multiplier_u32 = g_cfg.audio.sampling_period_multiplier;
if (sampling_period_multiplier_u32 == 100)
return DEFAULT_AUDIO_SAMPLING_RATE;
const f32 sampling_period_multiplier = sampling_period_multiplier_u32 / 100.0f;
const f32 sampling_rate_multiplier = 1.0f / sampling_period_multiplier;
return static_cast<u32>(f32{DEFAULT_AUDIO_SAMPLING_RATE} * sampling_rate_multiplier);
}
u32 AudioBackend::get_sample_size()
{
return g_cfg.audio.convert_to_u16 ? sizeof(u16) : sizeof(float);
}
u32 AudioBackend::get_channels()
{
return g_cfg.audio.downmix_to_2ch ? 2 : 8;
}
bool AudioBackend::has_capability(u32 cap) const
{
return (cap & GetCapabilities()) == cap;
}
void AudioBackend::dump_capabilities(std::string& out) const
{
u32 count = 0;
u32 capabilities = GetCapabilities();
if (capabilities & PLAY_PAUSE_FLUSH)
{
fmt::append(out, "PLAY_PAUSE_FLUSH");
count++;
}
if (capabilities & IS_PLAYING)
{
fmt::append(out, "%sIS_PLAYING", count > 0 ? " | " : "");
count++;
}
if (capabilities & GET_NUM_ENQUEUED_SAMPLES)
{
fmt::append(out, "%sGET_NUM_ENQUEUED_SAMPLES", count > 0 ? " | " : "");
count++;
}
if (capabilities & SET_FREQUENCY_RATIO)
{
fmt::append(out, "%sSET_FREQUENCY_RATIO", count > 0 ? " | " : "");
count++;
}
if (count == 0)
{
fmt::append(out, "NONE");
}
}
+11 -58
View File
@@ -1,7 +1,6 @@
#pragma once
#include "Utilities/types.h"
#include "Emu/System.h"
enum : u32
{
@@ -35,6 +34,12 @@ public:
virtual bool AddData(const void* src, u32 num_samples) = 0;
/*
* This virtual method should be reimplemented if backend can fail to be initialized under non-error conditions
* eg. when there is no audio devices attached
*/
virtual bool Initialized() const { return true; }
/*
* Virtual methods - should be implemented depending on backend capabilities
*/
@@ -89,65 +94,13 @@ public:
/*
* Helper methods
*/
static u32 get_sampling_rate()
{
const u32 sampling_period_multiplier_u32 = g_cfg.audio.sampling_period_multiplier;
static u32 get_sampling_rate();
if (sampling_period_multiplier_u32 == 100)
return DEFAULT_AUDIO_SAMPLING_RATE;
static u32 get_sample_size();
const f32 sampling_period_multiplier = sampling_period_multiplier_u32 / 100.0f;
const f32 sampling_rate_multiplier = 1.0f / sampling_period_multiplier;
return static_cast<u32>(DEFAULT_AUDIO_SAMPLING_RATE * sampling_rate_multiplier);
}
static u32 get_channels();
static u32 get_sample_size()
{
return g_cfg.audio.convert_to_u16 ? sizeof(u16) : sizeof(float);
}
bool has_capability(u32 cap) const;
static u32 get_channels()
{
return g_cfg.audio.downmix_to_2ch ? 2 : 8;
}
bool has_capability(u32 cap) const
{
return (cap & GetCapabilities()) == cap;
}
void dump_capabilities(std::string& out) const
{
u32 count = 0;
u32 capabilities = GetCapabilities();
if (capabilities & PLAY_PAUSE_FLUSH)
{
fmt::append(out, "PLAY_PAUSE_FLUSH");
count++;
}
if (capabilities & IS_PLAYING)
{
fmt::append(out, "%sIS_PLAYING", count > 0 ? " | " : "");
count++;
}
if (capabilities & GET_NUM_ENQUEUED_SAMPLES)
{
fmt::append(out, "%sGET_NUM_ENQUEUED_SAMPLES", count > 0 ? " | " : "");
count++;
}
if (capabilities & SET_FREQUENCY_RATIO)
{
fmt::append(out, "%sSET_FREQUENCY_RATIO", count > 0 ? " | " : "");
count++;
}
if (count == 0)
{
fmt::append(out, "NONE");
}
}
void dump_capabilities(std::string& out) const;
};
+4 -4
View File
@@ -15,8 +15,8 @@ struct WAVHeader
RIFFHeader(u32 size)
: ID("RIFF"_u32)
, WAVE("WAVE"_u32)
, Size(size)
, WAVE("WAVE"_u32)
{
}
} RIFF;
@@ -53,10 +53,10 @@ struct WAVHeader
WAVHeader() = default;
WAVHeader(u16 ch)
: ID("data"_u32)
, Size(0)
: RIFF(sizeof(RIFFHeader) + sizeof(FMTHeader))
, FMT(ch)
, RIFF(sizeof(RIFFHeader) + sizeof(FMTHeader))
, ID("data"_u32)
, Size(0)
{
}
};
+16 -9
View File
@@ -2,7 +2,12 @@
#error "FAudio support disabled but still being built."
#endif
#include "stdafx.h"
#include "FAudioBackend.h"
#include "Emu/system_config.h"
#include "Emu/System.h"
LOG_CHANNEL(FAudio_, "FAudio");
FAudioBackend::FAudioBackend()
{
@@ -11,13 +16,15 @@ FAudioBackend::FAudioBackend()
res = FAudioCreate(&m_instance, 0, FAUDIO_DEFAULT_PROCESSOR);
if (res)
{
fmt::throw_exception("FAudioCreate() failed(0x%08x)", res);
FAudio_.fatal("FAudioCreate() failed(0x%08x)", res);
return;
}
res = FAudio_CreateMasteringVoice(m_instance, &m_master_voice, g_cfg.audio.downmix_to_2ch ? 2 : 8, 48000, 0, 0, nullptr);
if (res)
{
fmt::throw_exception("FAudio_CreateMasteringVoice() failed(0x%08x)", res);
FAudio_.fatal("FAudio_CreateMasteringVoice() failed(0x%08x)", res);
return;
}
}
@@ -48,7 +55,7 @@ void FAudioBackend::Play()
u32 res = FAudioSourceVoice_Start(m_source_voice, 0, FAUDIO_COMMIT_NOW);
if (res)
{
LOG_ERROR(GENERAL, "FAudioSourceVoice_Start() failed(0x%08x)", res);
FAudio_.error("FAudioSourceVoice_Start() failed(0x%08x)", res);
Emu.Pause();
}
}
@@ -60,7 +67,7 @@ void FAudioBackend::Pause()
u32 res = FAudioSourceVoice_Stop(m_source_voice, 0, FAUDIO_COMMIT_NOW);
if (res)
{
LOG_ERROR(GENERAL, "FAudioSourceVoice_Stop() failed(0x%08x)", res);
FAudio_.error("FAudioSourceVoice_Stop() failed(0x%08x)", res);
Emu.Pause();
}
}
@@ -72,7 +79,7 @@ void FAudioBackend::Flush()
u32 res = FAudioSourceVoice_FlushSourceBuffers(m_source_voice);
if (res)
{
LOG_ERROR(GENERAL, "FAudioSourceVoice_FlushSourceBuffers() failed(0x%08x)", res);
FAudio_.error("FAudioSourceVoice_FlushSourceBuffers() failed(0x%08x)", res);
Emu.Pause();
}
}
@@ -111,7 +118,7 @@ void FAudioBackend::Open(u32 /* num_buffers */)
u32 res = FAudio_CreateSourceVoice(m_instance, &m_source_voice, &waveformatex, 0, FAUDIO_DEFAULT_FREQ_RATIO, nullptr, nullptr, nullptr);
if (res)
{
LOG_ERROR(GENERAL, "FAudio_CreateSourceVoice() failed(0x%08x)", res);
FAudio_.error("FAudio_CreateSourceVoice() failed(0x%08x)", res);
Emu.Pause();
}
@@ -128,7 +135,7 @@ bool FAudioBackend::AddData(const void* src, u32 num_samples)
if (state.BuffersQueued >= MAX_AUDIO_BUFFERS)
{
LOG_WARNING(GENERAL, "XAudio2Backend : too many buffers enqueued (%d)", state.BuffersQueued);
FAudio_.warning("Too many buffers enqueued (%d)", state.BuffersQueued);
return false;
}
@@ -146,7 +153,7 @@ bool FAudioBackend::AddData(const void* src, u32 num_samples)
u32 res = FAudioSourceVoice_SubmitSourceBuffer(m_source_voice, &buffer, nullptr);
if (res)
{
LOG_ERROR(GENERAL, "FAudioSourceVoice_SubmitSourceBuffer() failed(0x%08x)", res);
FAudio_.error("FAudioSourceVoice_SubmitSourceBuffer() failed(0x%08x)", res);
Emu.Pause();
return false;
}
@@ -170,7 +177,7 @@ f32 FAudioBackend::SetFrequencyRatio(f32 new_ratio)
u32 res = FAudioSourceVoice_SetFrequencyRatio(m_source_voice, new_ratio, FAUDIO_COMMIT_NOW);
if (res)
{
LOG_ERROR(GENERAL, "FAudioSourceVoice_SetFrequencyRatio() failed(0x%08x)", res);
FAudio_.error("FAudioSourceVoice_SetFrequencyRatio() failed(0x%08x)", res);
Emu.Pause();
return 1.0f;
}
-203
View File
@@ -1,203 +0,0 @@
#ifndef _WIN32
#error "XAudio27 can only be built on Windows."
#endif
#include "Utilities/Log.h"
#include "Utilities/StrFmt.h"
#include "Emu/System.h"
#include "XAudio2Backend.h"
#include "3rdparty/XAudio2_7/XAudio2.h"
class XAudio27Library : public XAudio2Backend::XAudio2Library
{
const HMODULE tls_xaudio2_lib;
IXAudio2* tls_xaudio2_instance{};
IXAudio2MasteringVoice* tls_master_voice{};
IXAudio2SourceVoice* tls_source_voice{};
public:
XAudio27Library(void* lib2_7)
: tls_xaudio2_lib(static_cast<HMODULE>(lib2_7))
{
HRESULT hr = S_OK;
hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : CoInitializeEx() failed(0x%08x)", (u32)hr);
Emu.Pause();
return;
}
hr = XAudio2Create(&tls_xaudio2_instance, 0, XAUDIO2_DEFAULT_PROCESSOR);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : XAudio2Create() failed(0x%08x)", (u32)hr);
Emu.Pause();
return;
}
hr = tls_xaudio2_instance->CreateMasteringVoice(&tls_master_voice, g_cfg.audio.downmix_to_2ch ? 2 : 8, 48000);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : CreateMasteringVoice() failed(0x%08x)", (u32)hr);
tls_xaudio2_instance->Release();
Emu.Pause();
}
}
~XAudio27Library()
{
if (tls_source_voice != nullptr)
{
tls_source_voice->Stop();
tls_source_voice->DestroyVoice();
}
if (tls_master_voice != nullptr)
{
tls_master_voice->DestroyVoice();
}
if (tls_xaudio2_instance != nullptr)
{
tls_xaudio2_instance->StopEngine();
tls_xaudio2_instance->Release();
}
CoUninitialize();
FreeLibrary(tls_xaudio2_lib);
}
virtual void play() override
{
HRESULT hr = tls_source_voice->Start();
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : Start() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
virtual void flush() override
{
HRESULT hr = tls_source_voice->FlushSourceBuffers();
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : FlushSourceBuffers() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
virtual void stop() override
{
HRESULT hr = tls_source_voice->Stop();
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : Stop() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
virtual bool is_playing() override
{
XAUDIO2_VOICE_STATE state;
tls_source_voice->GetState(&state);
return state.BuffersQueued > 0 || state.pCurrentBufferContext != nullptr;
}
virtual void open() override
{
HRESULT hr;
const u32 sample_size = AudioBackend::get_sample_size();
const u32 channels = AudioBackend::get_channels();
const u32 sampling_rate = AudioBackend::get_sampling_rate();
WAVEFORMATEX waveformatex;
waveformatex.wFormatTag = g_cfg.audio.convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
waveformatex.nChannels = channels;
waveformatex.nSamplesPerSec = sampling_rate;
waveformatex.nAvgBytesPerSec = static_cast<DWORD>(sampling_rate * channels * sample_size);
waveformatex.nBlockAlign = channels * sample_size;
waveformatex.wBitsPerSample = sample_size * 8;
waveformatex.cbSize = 0;
hr = tls_xaudio2_instance->CreateSourceVoice(&tls_source_voice, &waveformatex, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : CreateSourceVoice() failed(0x%08x)", (u32)hr);
Emu.Pause();
return;
}
tls_source_voice->SetVolume(channels == 2 ? 1.0f : 4.0f);
}
virtual bool add(const void* src, u32 num_samples) override
{
XAUDIO2_VOICE_STATE state;
tls_source_voice->GetState(&state);
// XAudio 2.7 bug workaround, when it says "SimpList: non-growable list ran out of room for new elements" and hits int 3
if (state.BuffersQueued >= MAX_AUDIO_BUFFERS)
{
LOG_WARNING(GENERAL, "XAudio2Backend : too many buffers enqueued (%d, pos=%u)", state.BuffersQueued, state.SamplesPlayed);
return false;
}
XAUDIO2_BUFFER buffer;
buffer.AudioBytes = num_samples * AudioBackend::get_sample_size();
buffer.Flags = 0;
buffer.LoopBegin = XAUDIO2_NO_LOOP_REGION;
buffer.LoopCount = 0;
buffer.LoopLength = 0;
buffer.pAudioData = (const BYTE*)src;
buffer.pContext = 0;
buffer.PlayBegin = 0;
buffer.PlayLength = AUDIO_BUFFER_SAMPLES;
HRESULT hr = tls_source_voice->SubmitSourceBuffer(&buffer);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : AddData() failed(0x%08x)", (u32)hr);
Emu.Pause();
return false;
}
return true;
}
virtual u64 enqueued_samples() override
{
XAUDIO2_VOICE_STATE state;
tls_source_voice->GetState(&state);
// all buffers contain AUDIO_BUFFER_SAMPLES, so we can easily calculate how many samples there are remaining
return (AUDIO_BUFFER_SAMPLES - state.SamplesPlayed % AUDIO_BUFFER_SAMPLES) + (state.BuffersQueued * AUDIO_BUFFER_SAMPLES);
}
virtual f32 set_freq_ratio(f32 new_ratio) override
{
new_ratio = std::clamp(new_ratio, XAUDIO2_MIN_FREQ_RATIO, XAUDIO2_DEFAULT_FREQ_RATIO);
HRESULT hr = tls_source_voice->SetFrequencyRatio(new_ratio);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : SetFrequencyRatio() failed(0x%08x)", (u32)hr);
Emu.Pause();
return 1.0f;
}
return new_ratio;
}
};
XAudio2Backend::XAudio2Library* XAudio2Backend::xa27_init(void* lib2_7)
{
return new XAudio27Library(lib2_7);
}
-215
View File
@@ -1,215 +0,0 @@
#ifndef _WIN32
#error "XAudio28 can only be built on Windows."
#endif
#include "Utilities/Log.h"
#include "Utilities/StrFmt.h"
#include "Emu/System.h"
#include "XAudio2Backend.h"
#include "3rdparty/minidx12/Include/xaudio2.h"
class XAudio28Library : public XAudio2Backend::XAudio2Library
{
const HMODULE tls_xaudio2_lib;
IXAudio2* tls_xaudio2_instance{};
IXAudio2MasteringVoice* tls_master_voice{};
IXAudio2SourceVoice* tls_source_voice{};
public:
XAudio28Library(void* lib2_8)
: tls_xaudio2_lib(static_cast<HMODULE>(lib2_8))
{
const auto create = (XAudio2Create)GetProcAddress(tls_xaudio2_lib, "XAudio2Create");
HRESULT hr = S_OK;
hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : CoInitializeEx() failed(0x%08x)", (u32)hr);
Emu.Pause();
return;
}
hr = create(&tls_xaudio2_instance, 0, XAUDIO2_DEFAULT_PROCESSOR);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : XAudio2Create() failed(0x%08x)", (u32)hr);
Emu.Pause();
return;
}
hr = tls_xaudio2_instance->CreateMasteringVoice(&tls_master_voice, g_cfg.audio.downmix_to_2ch ? 2 : 8, 48000);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : CreateMasteringVoice() failed(0x%08x)", (u32)hr);
tls_xaudio2_instance->Release();
Emu.Pause();
}
}
~XAudio28Library()
{
if (tls_source_voice != nullptr)
{
tls_source_voice->Stop();
tls_source_voice->DestroyVoice();
}
if (tls_master_voice != nullptr)
{
tls_master_voice->DestroyVoice();
}
if (tls_xaudio2_instance != nullptr)
{
tls_xaudio2_instance->StopEngine();
tls_xaudio2_instance->Release();
}
CoUninitialize();
FreeLibrary(tls_xaudio2_lib);
}
virtual void play() override
{
AUDIT(tls_source_voice != nullptr);
HRESULT hr = tls_source_voice->Start();
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : Start() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
virtual void flush() override
{
AUDIT(tls_source_voice != nullptr);
HRESULT hr = tls_source_voice->FlushSourceBuffers();
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : FlushSourceBuffers() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
virtual void stop() override
{
AUDIT(tls_source_voice != nullptr);
HRESULT hr = tls_source_voice->Stop();
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : Stop() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
virtual bool is_playing() override
{
AUDIT(tls_source_voice != nullptr);
XAUDIO2_VOICE_STATE state;
tls_source_voice->GetState(&state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
return state.BuffersQueued > 0 || state.pCurrentBufferContext != nullptr;
}
virtual void open() override
{
HRESULT hr;
const u32 sample_size = AudioBackend::get_sample_size();
const u32 channels = AudioBackend::get_channels();
const u32 sampling_rate = AudioBackend::get_sampling_rate();
WAVEFORMATEX waveformatex;
waveformatex.wFormatTag = g_cfg.audio.convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
waveformatex.nChannels = channels;
waveformatex.nSamplesPerSec = sampling_rate;
waveformatex.nAvgBytesPerSec = static_cast<DWORD>(sampling_rate * channels * sample_size);
waveformatex.nBlockAlign = channels * sample_size;
waveformatex.wBitsPerSample = sample_size * 8;
waveformatex.cbSize = 0;
hr = tls_xaudio2_instance->CreateSourceVoice(&tls_source_voice, &waveformatex, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : CreateSourceVoice() failed(0x%08x)", (u32)hr);
Emu.Pause();
return;
}
AUDIT(tls_source_voice != nullptr);
tls_source_voice->SetVolume(channels == 2 ? 1.0f : 4.0f);
}
virtual bool add(const void* src, u32 num_samples) override
{
AUDIT(tls_source_voice != nullptr);
XAUDIO2_VOICE_STATE state;
tls_source_voice->GetState(&state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
if (state.BuffersQueued >= MAX_AUDIO_BUFFERS)
{
LOG_WARNING(GENERAL, "XAudio2Backend : too many buffers enqueued (%d)", state.BuffersQueued);
return false;
}
XAUDIO2_BUFFER buffer;
buffer.AudioBytes = num_samples * AudioBackend::get_sample_size();
buffer.Flags = 0;
buffer.LoopBegin = XAUDIO2_NO_LOOP_REGION;
buffer.LoopCount = 0;
buffer.LoopLength = 0;
buffer.pAudioData = (const BYTE*)src;
buffer.pContext = 0;
buffer.PlayBegin = 0;
buffer.PlayLength = AUDIO_BUFFER_SAMPLES;
HRESULT hr = tls_source_voice->SubmitSourceBuffer(&buffer);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : AddData() failed(0x%08x)", (u32)hr);
Emu.Pause();
return false;
}
return true;
}
virtual u64 enqueued_samples() override
{
XAUDIO2_VOICE_STATE state;
tls_source_voice->GetState(&state);
// all buffers contain AUDIO_BUFFER_SAMPLES, so we can easily calculate how many samples there are remaining
return (AUDIO_BUFFER_SAMPLES - state.SamplesPlayed % AUDIO_BUFFER_SAMPLES) + (state.BuffersQueued * AUDIO_BUFFER_SAMPLES);
}
virtual f32 set_freq_ratio(f32 new_ratio) override
{
new_ratio = std::clamp(new_ratio, XAUDIO2_MIN_FREQ_RATIO, XAUDIO2_DEFAULT_FREQ_RATIO);
HRESULT hr = tls_source_voice->SetFrequencyRatio(new_ratio);
if (FAILED(hr))
{
LOG_ERROR(GENERAL, "XAudio2Backend : SetFrequencyRatio() failed(0x%08x)", (u32)hr);
Emu.Pause();
return 1.0f;
}
return new_ratio;
}
};
XAudio2Backend::XAudio2Library* XAudio2Backend::xa28_init(void* lib2_8)
{
return new XAudio28Library(lib2_8);
}
+143 -36
View File
@@ -4,89 +4,196 @@
#include "Utilities/Log.h"
#include "Utilities/StrFmt.h"
#include "Emu/System.h"
#include "Emu/system_config.h"
#include "XAudio2Backend.h"
#include <Windows.h>
#pragma comment(lib, "xaudio2_9redist.lib")
LOG_CHANNEL(XAudio);
XAudio2Backend::XAudio2Backend()
{
Microsoft::WRL::ComPtr<IXAudio2> instance;
HRESULT hr = XAudio2Create(instance.GetAddressOf(), 0, XAUDIO2_DEFAULT_PROCESSOR);
if (FAILED(hr))
{
XAudio.error("XAudio2Create() failed(0x%08x)", (u32)hr);
return;
}
hr = instance->CreateMasteringVoice(&m_master_voice, g_cfg.audio.downmix_to_2ch ? 2 : 8, 48000);
if (FAILED(hr))
{
XAudio.error("CreateMasteringVoice() failed(0x%08x)", (u32)hr);
return;
}
// All succeeded, "commit"
m_xaudio2_instance = std::move(instance);
}
XAudio2Backend::~XAudio2Backend()
{
if (m_source_voice != nullptr)
{
m_source_voice->Stop();
m_source_voice->DestroyVoice();
}
if (m_master_voice != nullptr)
{
m_master_voice->DestroyVoice();
}
if (m_xaudio2_instance != nullptr)
{
m_xaudio2_instance->StopEngine();
}
}
void XAudio2Backend::Play()
{
lib->play();
AUDIT(m_source_voice != nullptr);
HRESULT hr = m_source_voice->Start();
if (FAILED(hr))
{
XAudio.error("Start() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
void XAudio2Backend::Close()
{
lib->stop();
lib->flush();
Pause();
Flush();
}
void XAudio2Backend::Pause()
{
lib->stop();
AUDIT(m_source_voice != nullptr);
HRESULT hr = m_source_voice->Stop();
if (FAILED(hr))
{
XAudio.error("Stop() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
void XAudio2Backend::Open(u32 /* num_buffers */)
{
if (lib.get() == nullptr)
HRESULT hr;
const u32 sample_size = AudioBackend::get_sample_size();
const u32 channels = AudioBackend::get_channels();
const u32 sampling_rate = AudioBackend::get_sampling_rate();
WAVEFORMATEX waveformatex;
waveformatex.wFormatTag = g_cfg.audio.convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
waveformatex.nChannels = channels;
waveformatex.nSamplesPerSec = sampling_rate;
waveformatex.nAvgBytesPerSec = static_cast<DWORD>(sampling_rate * channels * sample_size);
waveformatex.nBlockAlign = channels * sample_size;
waveformatex.wBitsPerSample = sample_size * 8;
waveformatex.cbSize = 0;
hr = m_xaudio2_instance->CreateSourceVoice(&m_source_voice, &waveformatex, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
if (FAILED(hr))
{
void* hmodule;
if (hmodule = LoadLibraryExW(L"XAudio2_9.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))
{
// XAudio 2.9 uses the same code as XAudio 2.8
lib.reset(xa28_init(hmodule));
LOG_SUCCESS(GENERAL, "XAudio 2.9 initialized");
}
else if (hmodule = LoadLibraryExW(L"XAudio2_8.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))
{
lib.reset(xa28_init(hmodule));
LOG_SUCCESS(GENERAL, "XAudio 2.8 initialized");
}
else if (hmodule = LoadLibraryExW(L"XAudio2_7.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))
{
lib.reset(xa27_init(hmodule));
LOG_SUCCESS(GENERAL, "XAudio 2.7 initialized");
}
else
{
fmt::throw_exception("No supported XAudio2 library found");
}
XAudio.error("CreateSourceVoice() failed(0x%08x)", (u32)hr);
Emu.Pause();
return;
}
lib->open();
AUDIT(m_source_voice != nullptr);
m_source_voice->SetVolume(channels == 2 ? 1.0f : 4.0f);
}
bool XAudio2Backend::IsPlaying()
{
return lib->is_playing();
AUDIT(m_source_voice != nullptr);
XAUDIO2_VOICE_STATE state;
m_source_voice->GetState(&state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
return state.BuffersQueued > 0 || state.pCurrentBufferContext != nullptr;
}
bool XAudio2Backend::AddData(const void* src, u32 num_samples)
{
return lib->add(src, num_samples);
AUDIT(m_source_voice != nullptr);
XAUDIO2_VOICE_STATE state;
m_source_voice->GetState(&state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
if (state.BuffersQueued >= MAX_AUDIO_BUFFERS)
{
XAudio.warning("Too many buffers enqueued (%d)", state.BuffersQueued);
return false;
}
XAUDIO2_BUFFER buffer;
buffer.AudioBytes = num_samples * AudioBackend::get_sample_size();
buffer.Flags = 0;
buffer.LoopBegin = XAUDIO2_NO_LOOP_REGION;
buffer.LoopCount = 0;
buffer.LoopLength = 0;
buffer.pAudioData = static_cast<const BYTE*>(src);
buffer.pContext = nullptr;
buffer.PlayBegin = 0;
buffer.PlayLength = AUDIO_BUFFER_SAMPLES;
HRESULT hr = m_source_voice->SubmitSourceBuffer(&buffer);
if (FAILED(hr))
{
XAudio.error("AddData() failed(0x%08x)", (u32)hr);
Emu.Pause();
return false;
}
return true;
}
void XAudio2Backend::Flush()
{
lib->flush();
AUDIT(m_source_voice != nullptr);
HRESULT hr = m_source_voice->FlushSourceBuffers();
if (FAILED(hr))
{
XAudio.error("FlushSourceBuffers() failed(0x%08x)", (u32)hr);
Emu.Pause();
}
}
u64 XAudio2Backend::GetNumEnqueuedSamples()
{
return lib->enqueued_samples();
AUDIT(m_source_voice != nullptr);
XAUDIO2_VOICE_STATE state;
m_source_voice->GetState(&state);
// all buffers contain AUDIO_BUFFER_SAMPLES, so we can easily calculate how many samples there are remaining
return static_cast<u64>(AUDIO_BUFFER_SAMPLES - state.SamplesPlayed % AUDIO_BUFFER_SAMPLES) + (state.BuffersQueued * AUDIO_BUFFER_SAMPLES);
}
f32 XAudio2Backend::SetFrequencyRatio(f32 new_ratio)
{
return lib->set_freq_ratio(new_ratio);
new_ratio = std::clamp(new_ratio, XAUDIO2_MIN_FREQ_RATIO, XAUDIO2_DEFAULT_FREQ_RATIO);
HRESULT hr = m_source_voice->SetFrequencyRatio(new_ratio);
if (FAILED(hr))
{
XAudio.error("SetFrequencyRatio() failed(0x%08x)", (u32)hr);
Emu.Pause();
return 1.0f;
}
return new_ratio;
}
+9 -19
View File
@@ -6,28 +6,16 @@
#include "Emu/Audio/AudioBackend.h"
#include <xaudio2redist.h>
#include <wrl/client.h>
class XAudio2Backend : public AudioBackend
class XAudio2Backend final : public AudioBackend
{
public:
class XAudio2Library
{
public:
virtual void play() = 0;
virtual void flush() = 0;
virtual void stop() = 0;
virtual void open() = 0;
virtual bool is_playing() = 0;
virtual bool add(const void*, u32) = 0;
virtual u64 enqueued_samples() = 0;
virtual f32 set_freq_ratio(f32) = 0;
};
private:
static XAudio2Library* xa27_init(void*);
static XAudio2Library* xa28_init(void*);
std::unique_ptr<XAudio2Library> lib = nullptr;
Microsoft::WRL::ComPtr<IXAudio2> m_xaudio2_instance;
IXAudio2MasteringVoice* m_master_voice{};
IXAudio2SourceVoice* m_source_voice{};
public:
XAudio2Backend();
@@ -38,6 +26,8 @@ public:
static const u32 capabilities = PLAY_PAUSE_FLUSH | IS_PLAYING | GET_NUM_ENQUEUED_SAMPLES | SET_FREQUENCY_RATIO;
virtual u32 GetCapabilities() const override { return capabilities; };
virtual bool Initialized() const override { return m_xaudio2_instance != nullptr; }
virtual void Open(u32 /* num_buffers */) override;
virtual void Close() override;
+39 -12
View File
@@ -1,8 +1,11 @@
add_library(rpcs3_emu
IdManager.cpp
System.cpp
system_config.cpp
system_config_types.cpp
VFS.cpp
GDB.cpp
title.cpp
)
target_link_libraries(rpcs3_emu
@@ -26,6 +29,8 @@ target_include_directories(rpcs3_emu
target_sources(rpcs3_emu PRIVATE
../util/atomic.cpp
../util/atomic2.cpp
../util/shared_cptr.cpp
../util/fixed_typemap.cpp
../../Utilities/bin_patch.cpp
../../Utilities/cond.cpp
../../Utilities/Config.cpp
@@ -88,6 +93,7 @@ target_sources(rpcs3_emu PRIVATE
# Audio
target_sources(rpcs3_emu PRIVATE
Audio/AudioDumper.cpp
Audio/AudioBackend.cpp
Audio/AL/OpenALBackend.cpp
)
@@ -110,13 +116,12 @@ if(USE_FAUDIO AND SDL2_FOUND AND NOT SDL2_VERSION VERSION_LESS 2.0.9)
endif()
if(WIN32)
target_include_directories(rpcs3_emu PUBLIC "${RPCS3_SRC_DIR}/../3rdparty/XAudio2Redist/include")
target_link_libraries(rpcs3_emu PRIVATE "${RPCS3_SRC_DIR}/../3rdparty/XAudio2Redist/libs/xaudio2_9redist.lib")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DELAYLOAD:xaudio2_9redist.dll")
target_sources(rpcs3_emu PRIVATE
Audio/XAudio2/XAudio27Backend.cpp
Audio/XAudio2/XAudio28Backend.cpp
Audio/XAudio2/XAudio2Backend.cpp
)
# Slimmed down version of minidx9 for XAudio2_7 only
include_directories(BEFORE "${RPCS3_SRC_DIR}/../3rdparty/XAudio2_7")
endif()
target_link_libraries(rpcs3_emu
@@ -142,7 +147,11 @@ target_sources(rpcs3_emu PRIVATE
Cell/SPURecompiler.cpp
Cell/SPUThread.cpp
Cell/lv2/lv2.cpp
Cell/lv2/sys_bdemu.cpp
Cell/lv2/sys_btsetting.cpp
Cell/lv2/sys_cond.cpp
Cell/lv2/sys_console.cpp
Cell/lv2/sys_crypto_engine.cpp
Cell/lv2/sys_config.cpp
Cell/lv2/sys_dbg.cpp
Cell/lv2/sys_event.cpp
@@ -150,7 +159,9 @@ target_sources(rpcs3_emu PRIVATE
Cell/lv2/sys_fs.cpp
Cell/lv2/sys_gamepad.cpp
Cell/lv2/sys_gpio.cpp
Cell/lv2/sys_hid.cpp
Cell/lv2/sys_interrupt.cpp
Cell/lv2/sys_io.cpp
Cell/lv2/sys_lwcond.cpp
Cell/lv2/sys_lwmutex.cpp
Cell/lv2/sys_memory.cpp
@@ -162,14 +173,18 @@ target_sources(rpcs3_emu PRIVATE
Cell/lv2/sys_process.cpp
Cell/lv2/sys_prx.cpp
Cell/lv2/sys_rsx.cpp
Cell/lv2/sys_rsxaudio.cpp
Cell/lv2/sys_rwlock.cpp
Cell/lv2/sys_semaphore.cpp
Cell/lv2/sys_spu.cpp
Cell/lv2/sys_sm.cpp
Cell/lv2/sys_ss.cpp
Cell/lv2/sys_storage.cpp
Cell/lv2/sys_time.cpp
Cell/lv2/sys_timer.cpp
Cell/lv2/sys_trace.cpp
Cell/lv2/sys_tty.cpp
Cell/lv2/sys_uart.cpp
Cell/lv2/sys_usbd.cpp
Cell/lv2/sys_vm.cpp
Cell/Modules/cellAdec.cpp
@@ -177,6 +192,7 @@ target_sources(rpcs3_emu PRIVATE
Cell/Modules/cellAtracMulti.cpp
Cell/Modules/cellAudio.cpp
Cell/Modules/cellAudioOut.cpp
Cell/Modules/cellAuthDialog.cpp
Cell/Modules/cellAvconfExt.cpp
Cell/Modules/cellBgdl.cpp
Cell/Modules/cellCamera.cpp
@@ -284,7 +300,7 @@ target_sources(rpcs3_emu PRIVATE
Cell/Modules/StaticHLE.cpp
Cell/Modules/sys_game.cpp
Cell/Modules/sys_heap.cpp
Cell/Modules/sys_io.cpp
Cell/Modules/sys_io_.cpp
Cell/Modules/sys_libc_.cpp
Cell/Modules/sys_libc.cpp
Cell/Modules/sys_lv2dbg.cpp
@@ -327,9 +343,12 @@ target_link_libraries(rpcs3_emu
# Io
target_sources(rpcs3_emu PRIVATE
Io/KeyboardHandler.cpp
Io/pad_config.cpp
Io/pad_config_types.cpp
Io/PadHandler.cpp
Io/usb_device.cpp
Io/Skylander.cpp
Io/GHLtar.cpp
)
@@ -359,23 +378,28 @@ target_sources(rpcs3_emu PRIVATE
RSX/Common/TextureUtils.cpp
RSX/Common/VertexProgramDecompiler.cpp
RSX/Null/NullGSRender.cpp
RSX/Overlays/overlay_animation.cpp
RSX/Overlays/overlay_edit_text.cpp
RSX/Overlays/overlay_font.cpp
RSX/Overlays/overlay_fonts.cpp
RSX/Overlays/overlay_list_view.cpp
RSX/Overlays/overlay_message_dialog.cpp
RSX/Overlays/overlay_osk.cpp
RSX/Overlays/overlay_perf_metrics.cpp
RSX/Overlays/overlay_progress_bar.cpp
RSX/Overlays/overlay_save_dialog.cpp
RSX/Overlays/overlay_utils.cpp
RSX/Overlays/overlays.cpp
RSX/Overlays/overlay_shader_compile_notification.cpp
RSX/Overlays/overlay_trophy_notification.cpp
RSX/Overlays/Shaders/shader_loading_dialog.cpp
RSX/Overlays/Shaders/shader_loading_dialog_native.cpp
RSX/Capture/rsx_capture.cpp
RSX/Capture/rsx_replay.cpp
RSX/GL/GLCommonDecompiler.cpp
RSX/GL/GLFragmentProgram.cpp
RSX/GL/GLGSRender.cpp
RSX/GL/GLHelpers.cpp
RSX/GL/GLPresent.cpp
RSX/GL/GLRenderTargets.cpp
RSX/GL/GLTexture.cpp
RSX/GL/GLVertexBuffers.cpp
@@ -394,6 +418,7 @@ if(TARGET 3rdparty_vulkan)
RSX/VK/VKGSRender.cpp
RSX/VK/VKHelpers.cpp
RSX/VK/VKMemAlloc.cpp
RSX/VK/VKPresent.cpp
RSX/VK/VKProgramPipeline.cpp
RSX/VK/VKRenderPass.cpp
RSX/VK/VKResolveHelper.cpp
@@ -415,11 +440,13 @@ target_link_libraries(rpcs3_emu
)
# Setup cotire
option(UNITY_BUILD_EMU "Use unity build for rpcs3_emu target" OFF)
if (USE_COTIRE)
# Setup cotire
option(UNITY_BUILD_EMU "Use unity build for rpcs3_emu target" OFF)
set_target_properties(rpcs3_emu PROPERTIES
COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h"
COTIRE_ADD_UNITY_BUILD ${UNITY_BUILD_EMU})
set_target_properties(rpcs3_emu PROPERTIES
COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h"
COTIRE_ADD_UNITY_BUILD ${UNITY_BUILD_EMU})
cotire(rpcs3_emu)
cotire(rpcs3_emu)
endif()
+49 -40
View File
@@ -2,6 +2,7 @@
#include "CPUThread.h"
#include "Emu/System.h"
#include "Emu/system_config.h"
#include "Emu/Memory/vm_locking.h"
#include "Emu/IdManager.h"
#include "Emu/GDB.h"
@@ -15,6 +16,9 @@
DECLARE(cpu_thread::g_threads_created){0};
DECLARE(cpu_thread::g_threads_deleted){0};
LOG_CHANNEL(profiler);
LOG_CHANNEL(sys_log, "SYS");
template <>
void fmt_class_string<cpu_flag>::format(std::string& out, u64 arg)
{
@@ -115,7 +119,7 @@ struct cpu_prof
}
}
LOG_NOTICE(GENERAL, "Thread [0x%08x]: %u samples (%.4f%% idle):%s", id, samples, 100. * idle / samples, results);
profiler.notice("Thread [0x%08x]: %u samples (%.4f%% idle):%s", id, samples, 100. * idle / samples, results);
}
};
@@ -149,7 +153,7 @@ struct cpu_prof
}
else
{
LOG_FATAL(GENERAL, "Invalid Thread ID: 0x%08x", id);
profiler.error("Invalid Thread ID: 0x%08x", id);
continue;
}
@@ -211,7 +215,7 @@ struct cpu_prof
if (flush)
{
LOG_SUCCESS(GENERAL, "Flushing profiling results...");
profiler.success("Flushing profiling results...");
// Print all results and cleanup
for (auto& [id, info] : threads)
@@ -293,7 +297,7 @@ void cpu_thread::operator()()
if (c != 0)
{
LOG_FATAL(GENERAL,"could not disable denormals");
sys_log.fatal("Could not disable denormals.");
}
}
@@ -310,7 +314,7 @@ void cpu_thread::operator()()
// Register thread in g_cpu_array
if (!g_cpu_array_sema.try_inc(sizeof(g_cpu_array_bits) * 8))
{
LOG_FATAL(GENERAL, "Too many threads");
sys_log.fatal("Too many threads.");
Emu.Pause();
return;
}
@@ -319,27 +323,23 @@ void cpu_thread::operator()()
for (u32 i = 0;; i = (i + 1) % ::size32(g_cpu_array_bits))
{
if (LIKELY(~g_cpu_array_bits[i]))
const auto [bits, ok] = g_cpu_array_bits[i].fetch_op([](u64& bits) -> u64
{
const u64 found = g_cpu_array_bits[i].atomic_op([](u64& bits) -> u64
if (~bits) [[likely]]
{
// Find empty array slot and set its bit
if (LIKELY(~bits))
{
const u64 bit = utils::cnttz64(~bits, true);
bits |= 1ull << bit;
return bit;
}
return 64;
});
if (LIKELY(found < 64))
{
// Fixup
array_slot = i * 64 + found;
break;
// Set lowest clear bit
bits |= bits + 1;
return true;
}
return false;
});
if (ok) [[likely]]
{
// Get actual slot number
array_slot = i * 64 + utils::cnttz64(~bits, false);
break;
}
}
@@ -362,8 +362,8 @@ void cpu_thread::operator()()
catch (const std::exception& e)
{
Emu.Pause();
LOG_FATAL(GENERAL, "%s thrown: %s", typeid(e).name(), e.what());
LOG_NOTICE(GENERAL, "\n%s", dump());
sys_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
sys_log.notice("\n%s", dump());
break;
}
@@ -387,11 +387,6 @@ void cpu_thread::operator()()
g_cpu_suspend_lock.lock_unlock();
}
void cpu_thread::on_abort()
{
state += cpu_flag::exit;
}
cpu_thread::~cpu_thread()
{
vm::cleanup_unlock(*this);
@@ -517,7 +512,7 @@ void cpu_thread::notify()
}
else
{
fmt::throw_exception("Invalid cpu_thread type");
fmt::throw_exception("Invalid cpu_thread type" HERE);
}
}
@@ -534,7 +529,24 @@ void cpu_thread::abort()
}
else
{
fmt::throw_exception("Invalid cpu_thread type");
fmt::throw_exception("Invalid cpu_thread type" HERE);
}
}
std::string cpu_thread::get_name() const
{
// Downcast to correct type
if (id_type() == 1)
{
return thread_ctrl::get_name(*static_cast<const named_thread<ppu_thread>*>(this));
}
else if (id_type() == 2)
{
return thread_ctrl::get_name(*static_cast<const named_thread<spu_thread>*>(this));
}
else
{
fmt::throw_exception("Invalid cpu_thread type" HERE);
}
}
@@ -572,7 +584,7 @@ cpu_thread::suspend_all::suspend_all(cpu_thread* _this) noexcept
}
});
if (LIKELY(ok))
if (ok) [[likely]]
{
break;
}
@@ -609,7 +621,7 @@ void cpu_thread::stop_all() noexcept
if (g_tls_current_cpu_thread)
{
// Report unsupported but unnecessary case
LOG_FATAL(GENERAL, "cpu_thread::stop_all() has been called from a CPU thread.");
sys_log.fatal("cpu_thread::stop_all() has been called from a CPU thread.");
return;
}
else
@@ -623,24 +635,21 @@ void cpu_thread::stop_all() noexcept
});
}
LOG_NOTICE(GENERAL, "All CPU threads have been signaled.");
sys_log.notice("All CPU threads have been signaled.");
while (g_cpu_array_sema)
{
std::this_thread::sleep_for(10ms);
}
// Workaround for remaining threads (TODO)
std::this_thread::sleep_for(1300ms);
LOG_NOTICE(GENERAL, "All CPU threads have been stopped.");
sys_log.notice("All CPU threads have been stopped.");
}
void cpu_thread::flush_profilers() noexcept
{
if (!g_fxo->get<cpu_profiler>())
{
LOG_FATAL(GENERAL, "cpu_thread::flush_profilers() has been called incorrectly." HERE);
profiler.fatal("cpu_thread::flush_profilers() has been called incorrectly." HERE);
return;
}
+3 -4
View File
@@ -37,7 +37,6 @@ protected:
public:
virtual ~cpu_thread();
void operator()();
void on_abort();
// Self identifier
const u32 id;
@@ -75,7 +74,7 @@ public:
}
// Check thread type
u32 id_type()
u32 id_type() const
{
return id >> 24;
}
@@ -89,8 +88,8 @@ public:
// Thread stats for external observation
static atomic_t<u64> g_threads_created, g_threads_deleted;
// Get thread name
virtual std::string get_name() const = 0;
// Get thread name (as assigned to named_thread)
std::string get_name() const;
// Get CPU state dump
virtual std::string dump() const;
+1 -1
View File
@@ -40,7 +40,7 @@ void cpu_translator::initialize(llvm::LLVMContext& context, llvm::ExecutionEngin
cpu == "bdver2" ||
cpu == "bdver3" ||
cpu == "bdver4" ||
cpu.substr(0, 5) == "znver")
cpu.startswith("znver"))
{
m_use_fma = true;
}
+22 -1
View File
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#ifdef LLVM_AVAILABLE
@@ -2729,6 +2729,23 @@ public:
return result;
}
// TODO: Support doubles
auto fre(value_t<f32[4]> a)
{
decltype(a) result;
const auto av = a.eval(m_ir);
result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rcp.ps", av->getType(), av->getType()).getCallee(), {av});
return result;
}
auto frsqe(value_t<f32[4]> a)
{
decltype(a) result;
const auto av = a.eval(m_ir);
result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rsqrt.ps", av->getType(), av->getType()).getCallee(), {av});
return result;
}
template <typename T1, typename T2>
value_t<u8[16]> pshufb(T1 a, T2 b)
{
@@ -2824,4 +2841,8 @@ struct fmt_unveil<llvm::TypeSize, void>
}
};
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
#endif
+1 -7
View File
@@ -1,12 +1,6 @@
#include "stdafx.h"
#include "stdafx.h"
#include "MFC.h"
#include "Utilities/sysinfo.h"
#include "Emu/Memory/vm.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/lv2/sys_sync.h"
#include "Emu/System.h"
template <>
void fmt_class_string<MFC>::format(std::string& out, u64 arg)
{
+16 -26
View File
@@ -1,5 +1,4 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_sync.h"
@@ -265,15 +264,15 @@ class AudioDecoder : public ppu_thread
{
public:
squeue_t<AdecTask> job;
volatile bool is_closed;
volatile bool is_finished;
bool just_started;
bool just_finished;
volatile bool is_closed = false;
volatile bool is_finished = false;
bool just_started = false;
bool just_finished = false;
AVCodec* codec;
AVInputFormat* input_format;
AVCodecContext* ctx;
AVFormatContext* fmt;
AVCodec* codec = nullptr;
AVInputFormat* input_format = nullptr;
AVCodecContext* ctx = nullptr;
AVFormatContext* fmt = nullptr;
u8* io_buf;
struct AudioReader
@@ -297,7 +296,7 @@ public:
const u32 memSize;
const vm::ptr<CellAdecCbMsg> cbFunc;
const u32 cbArg;
u32 memBias;
u32 memBias = 0;
AdecTask task;
u64 last_pts, first_pts;
@@ -313,20 +312,11 @@ public:
, type(type)
, memAddr(addr)
, memSize(size)
, memBias(0)
, cbFunc(func)
, cbArg(arg)
, is_closed(false)
, is_finished(false)
, just_started(false)
, just_finished(false)
, codec(nullptr)
, input_format(nullptr)
, ctx(nullptr)
, fmt(nullptr)
{
av_register_all();
avcodec_register_all();
//av_register_all();
//avcodec_register_all();
switch (type)
{
@@ -453,7 +443,7 @@ public:
reader.addr = task.au.addr;
reader.size = task.au.size;
reader.has_ats = use_ats_headers;
//LOG_NOTICE(HLE, "Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts);
//cellAdec.notice("Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts);
if (just_started)
{
@@ -513,7 +503,7 @@ public:
{
fmt::throw_exception("avformat_new_stream() failed" HERE);
}
ctx = fmt->streams[0]->codec; // TODO: check data
//ctx = fmt->streams[0]->codec; // TODO: check data
opts = nullptr;
av_dict_set(&opts, "refcounted_frames", "1", 0);
@@ -573,7 +563,7 @@ public:
int got_frame = 0;
int decode = avcodec_decode_audio4(ctx, frame.data, &got_frame, &au);
int decode = 0; //avcodec_decode_audio4(ctx, frame.data, &got_frame, &au);
if (decode <= 0)
{
@@ -610,7 +600,7 @@ public:
frame.userdata = task.au.userdata;
frame.size = frame.data->nb_samples * frame.data->channels * nbps;
//LOG_NOTICE(HLE, "got audio frame (pts=0x%llx, nb_samples=%d, ch=%d, sample_rate=%d, nbps=%d)",
//cellAdec.notice("got audio frame (pts=0x%llx, nb_samples=%d, ch=%d, sample_rate=%d, nbps=%d)",
//frame.pts, frame.data->nb_samples, frame.data->channels, frame.data->sample_rate, nbps);
if (frames.push(frame, &is_closed))
@@ -714,7 +704,7 @@ next:
adec.reader.addr = adec.task.au.addr;
adec.reader.size = adec.task.au.size;
adec.reader.has_ats = adec.use_ats_headers;
//LOG_NOTICE(HLE, "Audio AU: size = 0x%x, pts = 0x%llx", adec.task.au.size, adec.task.au.pts);
//cellAdec.notice("Audio AU: size = 0x%x, pts = 0x%llx", adec.task.au.size, adec.task.au.pts);
}
break;
-1
View File
@@ -1,5 +1,4 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "cellAtrac.h"
@@ -1,5 +1,4 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "cellAtracMulti.h"
+67 -21
View File
@@ -1,6 +1,4 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_process.h"
@@ -59,8 +57,8 @@ cell_audio_config::cell_audio_config()
audio_ringbuffer::audio_ringbuffer(cell_audio_config& _cfg)
: cfg(_cfg)
, backend(_cfg.backend)
: backend(_cfg.backend)
, cfg(_cfg)
, buf_sz(AUDIO_BUFFER_SAMPLES * _cfg.audio_channels)
, emu_paused(Emu.IsPaused())
{
@@ -458,11 +456,37 @@ void cell_audio_thread::advance(u64 timestamp, bool reset)
std::array<u64, MAX_AUDIO_EVENT_QUEUES> event_sources;
u32 queue_count = 0;
for (const auto& key_pair : keys)
event_period++;
for (const auto& key_inf : keys)
{
if (auto queue = lv2_event_queue::find(key_pair.first))
if (const auto queue = lv2_event_queue::find(key_inf.key))
{
event_sources[queue_count] = key_pair.second;
if (key_inf.flags & CELL_AUDIO_EVENTFLAG_NOMIX)
{
continue;
}
u32 periods = 1;
if (key_inf.flags & CELL_AUDIO_EVENTFLAG_DECIMATE_2)
{
periods *= 2;
}
if (key_inf.flags & CELL_AUDIO_EVENTFLAG_DECIMATE_4)
{
// If both flags are set periods is set to x8
periods *= 4;
}
if ((event_period ^ key_inf.start_period) & (periods - 1))
{
// The time has not come for this key to receive event
continue;
}
event_sources[queue_count] = key_inf.source;
queues[queue_count++] = queue;
}
}
@@ -982,6 +1006,7 @@ error_code cellAudioQuit(ppu_thread& ppu)
// TODO
g_audio->keys.clear();
g_audio->key_count = 0;
g_audio->event_period = 0;
g_audio->init = 0;
return CELL_OK;
@@ -1375,10 +1400,8 @@ error_code cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key,
return AudioCreateNotifyEventQueue(id, key, queue_type);
}
error_code cellAudioSetNotifyEventQueue(u64 key)
error_code AudioSetNotifyEventQueue(u64 key, u32 iFlags)
{
cellAudio.warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
const auto g_audio = g_fxo->get<cell_audio>();
std::lock_guard lock(g_audio->mutex);
@@ -1395,32 +1418,40 @@ error_code cellAudioSetNotifyEventQueue(u64 key)
for (const auto& k : g_audio->keys) // check for duplicates
{
if (k.first == key)
if (k.key == key)
{
return CELL_AUDIO_ERROR_TRANS_EVENT;
}
}
// Set unique source associated with the key
g_audio->keys.emplace_back(key, ((process_getpid() + 1ull) << 32) + (lv2_event_port::id_base + g_audio->key_count * lv2_event_port::id_step));
g_audio->key_count = (g_audio->key_count + 1) % lv2_event_port::id_count;
g_audio->keys.push_back({g_audio->event_period, iFlags, ((process_getpid() + u64{}) << 32) + lv2_event_port::id_base + (g_audio->key_count++ * lv2_event_port::id_step), key});
g_audio->key_count %= lv2_event_port::id_count;
return CELL_OK;
}
error_code cellAudioSetNotifyEventQueue(u64 key)
{
cellAudio.warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
return AudioSetNotifyEventQueue(key, 0);
}
error_code cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
// TODO
if (iFlags & (~0u >> 5))
{
return CELL_AUDIO_ERROR_PARAM;
}
return CELL_OK;
return AudioSetNotifyEventQueue(key, iFlags);
}
error_code cellAudioRemoveNotifyEventQueue(u64 key)
error_code AudioRemoveNotifyEventQueue(u64 key, u32 iFlags)
{
cellAudio.warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
const auto g_audio = g_fxo->get<cell_audio>();
std::lock_guard lock(g_audio->mutex);
@@ -1432,8 +1463,13 @@ error_code cellAudioRemoveNotifyEventQueue(u64 key)
for (auto i = g_audio->keys.cbegin(); i != g_audio->keys.cend(); i++)
{
if (i->first == key)
if (i->key == key)
{
if (i->flags != iFlags)
{
break;
}
g_audio->keys.erase(i);
return CELL_OK;
@@ -1443,13 +1479,23 @@ error_code cellAudioRemoveNotifyEventQueue(u64 key)
return CELL_AUDIO_ERROR_TRANS_EVENT;
}
error_code cellAudioRemoveNotifyEventQueue(u64 key)
{
cellAudio.warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
return AudioRemoveNotifyEventQueue(key, 0);
}
error_code cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
// TODO
if (iFlags & (~0u >> 5))
{
return CELL_AUDIO_ERROR_PARAM;
}
return CELL_OK;
return AudioRemoveNotifyEventQueue(key, iFlags);
}
error_code cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
+13 -3
View File
@@ -194,7 +194,7 @@ public:
const u64 minimum_block_period = audio_block_period / 2; // the block period will not be dynamically lowered below this value (usecs)
const u64 maximum_block_period = (6 * audio_block_period) / 5; // the block period will not be dynamically increased above this value (usecs)
const u32 desired_full_buffers = buffering_enabled ? static_cast<u32>(desired_buffer_duration / audio_block_period) + 1 : 2;
const u32 desired_full_buffers = buffering_enabled ? static_cast<u32>(desired_buffer_duration / audio_block_period) + 3 : 2;
const u32 num_allocated_buffers = desired_full_buffers + EXTRA_AUDIO_BUFFERS; // number of ringbuffer buffers
const f32 period_average_alpha = 0.02f; // alpha factor for the m_average_period rolling average
@@ -235,7 +235,7 @@ private:
std::unique_ptr<AudioDumper> m_dump;
std::unique_ptr<float[]> buffer[MAX_AUDIO_BUFFERS];
const float silence_buffer[AUDIO_MAX_CHANNELS_COUNT * AUDIO_BUFFER_SAMPLES] = { 0 };
const float silence_buffer[u32{AUDIO_MAX_CHANNELS_COUNT} * u32{AUDIO_BUFFER_SAMPLES}] = { 0 };
bool backend_open = false;
bool playing = false;
@@ -342,7 +342,17 @@ public:
atomic_t<u32> init = 0;
u32 key_count = 0;
std::vector<std::pair<u64, u64>> keys;
u8 event_period = 0;
struct key_info
{
u8 start_period; // Starting event_period
u32 flags; // iFlags
u64 source; // Event source
u64 key; // Key
};
std::vector<key_info> keys;
std::array<audio_port, AUDIO_PORT_COUNT> ports;
u64 m_last_period_end = 0;
+17 -16
View File
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "Utilities/BEType.h"
@@ -15,23 +15,24 @@ enum CellAudioInError
CELL_AUDIO_IN_ERROR_CONDITION_BUSY = 0x8002b267,
};
enum
enum CellAudioInDeviceMode
{
CELL_AUDIO_IN_SINGLE_DEVICE_MODE = 0,
CELL_AUDIO_IN_MULTI_DEVICE_MODE = 1,
CELL_AUDIO_IN_MULTI_DEVICE_MODE_2 = 2,
CELL_AUDIO_IN_SINGLE_DEVICE_MODE = 0,
CELL_AUDIO_IN_MULTI_DEVICE_MODE = 1,
CELL_AUDIO_IN_MULTI_DEVICE_MODE_2 = 2,
CELL_AUDIO_IN_MULTI_DEVICE_MODE_10 = 10,
};
enum CellAudioInPortType
{
CELL_AUDIO_IN_PORT_USB = 3,
CELL_AUDIO_IN_PORT_USB = 3,
CELL_AUDIO_IN_PORT_BLUETOOTH = 4,
};
enum CellAudioInDeviceState
{
CELL_AUDIO_IN_DEVICE_STATE_UNAVAILABLE = 0,
CELL_AUDIO_IN_DEVICE_STATE_AVAILABLE = 1,
CELL_AUDIO_IN_DEVICE_STATE_AVAILABLE = 1,
};
enum CellAudioInCodingType
@@ -42,19 +43,19 @@ enum CellAudioInCodingType
enum CellAudioInChnum
{
CELL_AUDIO_IN_CHNUM_NONE = 0,
CELL_AUDIO_IN_CHNUM_1 = 1,
CELL_AUDIO_IN_CHNUM_2 = 2,
CELL_AUDIO_IN_CHNUM_1 = 1,
CELL_AUDIO_IN_CHNUM_2 = 2,
};
enum CellAudioInFs
{
CELL_AUDIO_IN_FS_UNDEFINED = 0x00,
CELL_AUDIO_IN_FS_8KHZ = 0x01,
CELL_AUDIO_IN_FS_12KHZ = 0x02,
CELL_AUDIO_IN_FS_16KHZ = 0x04,
CELL_AUDIO_IN_FS_24KHZ = 0x08,
CELL_AUDIO_IN_FS_32KHZ = 0x10,
CELL_AUDIO_IN_FS_48KHZ = 0x20,
CELL_AUDIO_IN_FS_8KHZ = 0x01,
CELL_AUDIO_IN_FS_12KHZ = 0x02,
CELL_AUDIO_IN_FS_16KHZ = 0x04,
CELL_AUDIO_IN_FS_24KHZ = 0x08,
CELL_AUDIO_IN_FS_32KHZ = 0x10,
CELL_AUDIO_IN_FS_48KHZ = 0x20,
};
struct CellAudioInSoundMode
@@ -80,7 +81,7 @@ struct CellAudioInDeviceInfo
struct CellAudioInRegistrationOption
{
//(Omitted)
be_t<u32> reserved;
};
struct CellAudioInDeviceConfiguration
+1 -15
View File
@@ -3,7 +3,7 @@
#include "cellAudioOut.h"
extern logs::channel cellSysutil;
LOG_CHANNEL(cellSysutil);
template<>
void fmt_class_string<CellAudioOutError>::format(std::string& out, u64 arg)
@@ -283,18 +283,6 @@ error_code cellAudioOutSetCopyControl(u32 audioOut, u32 control)
return CELL_OK;
}
error_code cellAudioOutConfigure2()
{
cellSysutil.todo("cellAudioOutConfigure2()");
return CELL_OK;
}
error_code cellAudioOutGetConfiguration2()
{
cellSysutil.todo("cellAudioOutGetConfiguration2()");
return CELL_OK;
}
error_code cellAudioOutRegisterCallback()
{
cellSysutil.todo("cellAudioOutRegisterCallback()");
@@ -312,13 +300,11 @@ void cellSysutil_AudioOut_init()
{
REG_FUNC(cellSysutil, cellAudioOutGetState);
REG_FUNC(cellSysutil, cellAudioOutConfigure);
REG_FUNC(cellSysutil, cellAudioOutConfigure2);
REG_FUNC(cellSysutil, cellAudioOutGetSoundAvailability);
REG_FUNC(cellSysutil, cellAudioOutGetSoundAvailability2);
REG_FUNC(cellSysutil, cellAudioOutGetDeviceInfo);
REG_FUNC(cellSysutil, cellAudioOutGetNumberOfDevice);
REG_FUNC(cellSysutil, cellAudioOutGetConfiguration);
REG_FUNC(cellSysutil, cellAudioOutGetConfiguration2);
REG_FUNC(cellSysutil, cellAudioOutSetCopyControl);
REG_FUNC(cellSysutil, cellAudioOutRegisterCallback);
REG_FUNC(cellSysutil, cellAudioOutUnregisterCallback);

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