Compare commits

..

313 Commits

Author SHA1 Message Date
Ani 0064976c43 Bump version to 0.0.4 2017-11-12 18:13:22 +00:00
Ani 4bdb6674eb GUI: Style fix for Kuroi (Dark)
Small style fix for Kuroi (Dark) Theme
2017-11-12 18:13:22 +00:00
Ani c7f7d7ef5b Fixes commit count on GIT-VERSION
AppVeyor: Fetches commit count from unshallowed upstream instead of fetching from HEAD (will always be 3 since we clone with depth of 3)
2017-11-12 18:13:22 +00:00
Robbie 2c19fdf092 Fix off by one error in trophies (#3715) 2017-11-12 17:36:13 +00:00
Ofek 8fc9862614 Fix cellGameGet(Set)Param (#3690)
* Fix cellGameGet(Set)Param
2017-11-11 22:22:38 +00:00
Talkashie 55d84414ee Stub sceNpSnsFbCheckConfig (#3720) 2017-11-11 22:18:32 +04:00
Talkashie 8c0bdd71d9 Correct two typos and a couple of other nitpicky things (#3721)
Correct two typos and a couple of other nitpicky things
2017-11-11 12:56:59 +00:00
kd-11 3c9126d91f rsx: Ignore FENCE instruction as it seems like its ignored on realhw
- This is likely a compiler hint for performance reasons and not a mandate
2017-11-09 14:39:50 +03:00
kd-11 8b4836a12f rsx: Fix shader cache version check 2017-11-09 14:39:50 +03:00
kd-11 b2a7eee1ec rsx: Bump shader cache ver and fix blit engine crash
- Disables blit operations if the target will have a size of 0 in any dimension
- Bumps shader cache ver to 1.1
2017-11-09 14:39:50 +03:00
kd-11 ed21bb309f rsx: Minor fixups
- Fix texture cache blit behaviour when src has AA enabled and dst is a blit dst texture with or without AA
-- This requires handling AA resolve by removing a half downscale on multisampled axes

- Return all ones when a vertex attribute is disabled.
-- Some games forget to enable vertex attributes actually needed by the fs
2017-11-08 13:15:34 +03:00
kd-11 7b3e4f5e3d vk: Hotfix
- facepalm: Do not enable depth comparison mode if masquerading as RGBA color!
2017-11-08 13:15:34 +03:00
kd-11 30b3af0d12 vk: Cleanup, simplify renderpass management 2017-11-08 13:15:34 +03:00
kd-11 541cb4062b vk: Fix shader logging
- Do not overwrite logged programs
2017-11-08 13:15:34 +03:00
kd-11 4e9160104a rsx/vk/gl: Cleanup and refector glsl::getFunctionImpl
- Both backends now generate very similar code
2017-11-08 13:15:34 +03:00
kd-11 86fa379c78 rsx/vk: Fix unnormalized converted textures 2017-11-08 13:15:34 +03:00
kd-11 8733505d0a rsx: Minor fixes
- texture_cache: Fix internal size calculation for subresources
- vk: Delay dynamic state updates until just about to draw to ensure no flush has discarded the cb state
2017-11-08 13:15:34 +03:00
kd-11 242611aa46 gl/qt: Catch segfaults in wglDeleteContext with SEH (AMD windows driver)
- In rare cases the driver derefs a nullptr and dies, taking the emulator with it
- From testing, it seems the vram is indeed freed when this happens so its "safe" to continue
2017-11-08 13:15:34 +03:00
kd-11 baa5a261a5 rsx: Rewrite invalidate_range_impl_base in a way that makes sense. Fixes wcb hanging 2017-11-08 13:15:34 +03:00
kd-11 3730b9d1da rsx: More fixes
- Support for raster offsets in surface descriptors (looks to be unused)
- Do not tag disabled render targets when using MRT (pitch = 64)
- Add missing notify_surface_changed() call for openGL
2017-11-08 13:15:34 +03:00
kd-11 0d35363ea0 rsx: Minor optimization - dont update sampler state if texture state registers have not changed 2017-11-08 13:15:34 +03:00
kd-11 75504b3f5e rsx: Rework context handling and stop leaking the GL ccontext
- GL contexts are external handles that require manual lifecycle management
2017-11-08 13:15:34 +03:00
kd-11 4ca98e53a6 rsx: Fix for unnormalized texture access 2017-11-08 13:15:34 +03:00
kd-11 300a36d3d6 rsx: Fixes for cubemap reconstruction
- Do not abort generation if sides are missing, replace with blank surfaces instead
- Make cubemaps scale with res scaling
2017-11-08 13:15:34 +03:00
kd-11 60c7a508a7 rsx: Refactor create_subresource_view(deferred_subresource&) and implement a subresource cache
- This limits the number of times an image is copied and improves performance
2017-11-08 13:15:34 +03:00
kd-11 1fa18757fc rsx: Implement render-to-cubemap; Also simplify unnormalized samplers [WIP, DELETE SHADER CACHE, VERY SLOW]
- Enables real-time cubemap reflections
- TODO: Vulkan is broke; rsx is very slow with this feature
2017-11-08 13:15:34 +03:00
kd-11 fbb7186e66 rsx/gl: Addendum - Fix fragment shader to consume texture scale parameters 2017-11-08 13:15:34 +03:00
kd-11 0961a43997 rsx: Implement 1D<->2D image type casts 2017-11-08 13:15:34 +03:00
kd-11 7037504dcf rsx: Workaround for missing AA flags on some surfaces
- This just doesnt work right yet. It looks like AA is being used dynamically? (RDR)
- TODO: Try to locate flags to set AA if AA mode is not changed
2017-11-08 13:15:34 +03:00
kd-11 2385029eab gl: Shift code around to increase work done after memory transfer operations
- The current code is slower because memory operations are too close to their draw calls
-- This is mainly an issue with proprietary AMD drivers
2017-11-08 13:15:34 +03:00
kd-11 eed55a446c rsx: Minor optimization
- Defer resolving image copy operations to the binding step
2017-11-08 13:15:34 +03:00
kd-11 bbcb6b6851 rsx: Fbo fixes 2
- Use AA mode to predict surface compression. Compression mode is useless without AA activated
- Rewrites most image subresource fetch routines to use the new heuristic
- Fix rsx::thread::find_tile. FEED000(X) can be substituted for (X) in the code
-- Fixes alot of failures when looking for tiled regions

rsx: Fix antialiased unnormalized coords
- scaling factors are inverse to allow proper coordinates to be computed in fs
2017-11-08 13:15:34 +03:00
kd-11 b95630d84a rsx: Minor fixups
- Optimize framebuffer memory invalidate conditions
- Fix texture sampling of AA textures (wider by 2x surfaces)
2017-11-08 13:15:34 +03:00
kd-11 af1d3c2aa6 rsx: Improve surface store resource management
- vk: Use frame testing to determine invalidated resources that can be safely deleted
2017-11-08 13:15:34 +03:00
kd-11 ec3e5c547f rsx: More fixes
- Tag surface store to help determine when contents have been invalidated
- Crop framebuffer textures if they are not the requested dimensions!
2017-11-08 13:15:34 +03:00
kd-11 963a87fed5 rsx: Critical fixes
- Remove generic throws from the rsx pipeline. Stops the rsx thread from silently dying leaving the emulator in a hung state
- Hackplement add_signed and reverse_subtract_signed blend modes
2017-11-08 13:15:34 +03:00
kd-11 173d05b54f rsx: Optimizations
- Reimplement fragment program fetch and rewrite texture upload mechanism
-- All of these steps should only be done at most once per draw call
-- Eliminates continously checking the surface store for overlapping addresses as well

addenda - critical fixes
- gl: Bind TIU before starting texture operations as they will affect the currently bound texture
- vk: Reuse sampler objects if possible
- rsx: Support for depth resampling for depth textures obtained via blit engine

vk/rsx: Minor fixes
- Fix accidental imageview dereference when using WCB if texture memory occupies FB memory
- Invalidate dirty framebuffers (strict mode only)
- Normalize line endings because VS is dumb
2017-11-08 13:15:34 +03:00
Zion Nimchuk 865bb47462 HEAD or master will no longer show up in the titlebar 2017-11-08 12:49:22 +04:00
scribam 3e7ed8a831 PPUTranslator minor changes 2017-11-08 08:34:00 +04:00
Zion 3a49a77c07 Fix git-branch in title... again (#3704)
Fix git-branch in title... again
2017-11-08 01:22:41 +00:00
Zion Nimchuk 6782b22637 Make cellMouseGetDataList return CELL_MOUSE_ERROR_NO_DEVICE if mouse handler is set to null 2017-11-04 19:55:32 +00:00
scribam 4600094829 [RSX] Fix uninitialized value before usage 2017-11-04 01:28:53 +03:00
kd-11 daaa83b9ca rsx: Fix for framebuffer validation 2017-11-04 00:08:30 +03:00
Robbie 3288050680 Have trophy manager reject games that have invalid usr data rather than dying. 2017-11-03 21:15:43 +03:00
Robbie b8c29ae957 Make it so that TROPUSR doesn't crash on "bad" imput. 2017-11-03 21:15:43 +03:00
Robbie 47bacc0ef0 Make trophy dialog smarter and not need the silly file. Can load all games by default now. 2017-11-03 21:15:43 +03:00
Tahir Akhlaq 3d0dced4bd change CryptAcquireContextW to try CRYPT_NEWKEYSET flag if key container doesnt exist already < https://msdn.microsoft.com/en-us/library/windows/desktop/aa379886(v=vs.85).aspx > 2017-11-03 14:17:37 +03:00
kd-11 30bba09fed disable fb testing for partial framebuffer resources 2017-11-02 14:35:19 +03:00
kd-11 31b07f2c5c rsx: Tweaks
- Optimize get_surface_subresource
- Add check_program_status time to draw call setup statistics. It can slow down games significantly
2017-11-02 14:35:19 +03:00
kd-11 f7063bb57b vk: Improved handling of swap_bytes behaviour when using WCB 2017-11-02 14:35:19 +03:00
kd-11 e4ef85b6e0 rsx: Experimental; Try to calculate pixel offset using nv3062 pitch register since we know the target block is defined with 3062 registers 2017-11-02 14:35:19 +03:00
Nekotekina b7c2088489 Add supporters 2017-11-01 05:07:12 +03:00
Nekotekina 59cd0a9c7f Implement set_native_priority (posix) 2017-11-01 05:07:12 +03:00
Nekotekina af107df0b4 Fix NPDRM exitspawn 2017-11-01 05:07:12 +03:00
Nekotekina 0e7e40f2cb Fix /dev_bdvd/ for exitspawn 2017-11-01 05:07:11 +03:00
Nekotekina 0b788f5b43 Add Delete LLVM Cache option 2017-11-01 05:07:11 +03:00
scribam db5c2500c2 Update PPA urls to the latest version of Qt 2017-10-31 09:29:12 +00:00
scribam a1496eb1f1 Revert Qt requirements to version 5.7 for Linux 2017-10-31 09:29:12 +00:00
Robbie 4aa89132d7 Implement Trophy Manager. 2017-10-29 18:48:33 +03:00
Ani 9b8eb089b1 Handle device not ready in fs::error. Solves #3592 2017-10-29 16:52:12 +03:00
MRG95 c1f08ce58d Added breakpoint list
Added a list widget that displays all the currently active breakpoints. You can rename each one for convenience, delete them in bulk, or double click to jump to that address.
2017-10-29 16:17:05 +03:00
MRG95 09a0d046f4 Repositioned current instruction to middle
As soon as I tried the debugger, i wanted to move it to the middle almost instantly. Checked the code and found it sitting right here but commented out. Why? This is awesome.
2017-10-29 16:17:05 +03:00
Unknown 0741698f13 Qt: Fix Save Data Dialog initial size 2017-10-29 15:52:46 +03:00
kd-11 c2ac05f734 rsx: Fix for rsx thread lockup due to nested access violations when WCB is enabled 2017-10-29 15:25:17 +03:00
kd-11 f8f5f9f418 vk: Allow swapchain create to fail with an error 2017-10-29 15:25:17 +03:00
kd-11 7e6d6b45d4 nvidia facepalm 2017-10-29 15:25:17 +03:00
kd-11 361e80f7dc rsx: Tag cache blocks returned on access violation to validate data passed
to flush_all is up to date. Should prevent recursive exceptions

Partially revert Jarves' fix to invalidate cache on tile unbind. This will
need alot more work. Fixes hangs
2017-10-29 15:25:17 +03:00
kd-11 395b4bfa45 gsframe: Break waiting is emulator is stopped suddenly
- Keeps the queue from hanging the GUI
2017-10-29 15:25:17 +03:00
kd-11 ce2b790d8f rsx/qt: GsFrame improvements
- Identify minimize/restore events as separate from regular resize and do not react to them
- Enable message queue consumption after loading the shaders cache. Also hides the frame in this step
-- This fixes the 'start fullscreen' bug when running vulkan
2017-10-29 15:25:17 +03:00
Nekotekina 1ffc1e82b0 fixup 2017-10-28 23:39:10 +03:00
Nekotekina 8520ca7ef7 Audio: add Buffer Count setting 2017-10-28 23:24:08 +03:00
Nekotekina 89fba1c385 ppu_acontext draft 2017-10-28 23:24:08 +03:00
Nekotekina 00a0d37455 Add cmdline support 2017-10-28 23:24:08 +03:00
scribam dbb2251f93 [Qt] Fix uninitialised values before usage 2017-10-28 13:56:32 +03:00
kd-11 7abf755a57 rsx: Avoid false positives by early rejection. Should keep cache thashing to a minimum 2017-10-28 13:26:16 +03:00
kd-11 055f0e2e4a rsx: Export more information about affected cache sections when handling violations
- This allows for better handling of deferred flushes.
-- There's still no guarantee that cache contents will have changed between the set acquisition and following flush operation
-- Hopefully this is rare enough that it doesnt cause serious issues for now
2017-10-28 13:26:16 +03:00
kd-11 49f4da3016 rsx: Fixes
- vk: Always reopen primary command buffers. They should only be closed in flush_command_queue
- If uploading a texture and there are collisions with protected buffers, do not rebuild the cache
- Perform writes via flush before reprotecting pages that were not trampled
- Only flush no pages once
2017-10-28 13:26:16 +03:00
kd-11 bf234dc668 rsx: Implement memory tags for strict mode to validate render target memory 2017-10-28 13:26:16 +03:00
kd-11 11bd65c2b5 vulkan: Flush queue before attempting to copy texture memory! 2017-10-28 13:26:16 +03:00
Jake e0d1ac676e rsx: invalidate surface store address when tile is unbound 2017-10-28 12:46:20 +03:00
Jake 494cbac78b spu: save and restore mfc cmd after processing 2017-10-28 12:46:20 +03:00
Jake 0d46a8e786 spu: Implement readch(mfc_cmd) 2017-10-28 12:46:20 +03:00
Jake 626b9f93c4 rsx: make dmactrl get 'readonly' 2017-10-28 12:46:20 +03:00
Zangetsu38 53f9defb07 Trophy: use system language setting 2017-10-27 14:09:50 +01:00
Robbie 4bf8d1e41f Fix off by one error. Sigh. 2017-10-26 20:31:55 +01:00
Robbie 936c817bd8 Fix focus issue in trophies. 2017-10-26 20:31:55 +01:00
kd-11 9c9495621c rsx: Fix critical bug concerning transient data layout in memory 2017-10-26 00:35:45 +03:00
kd-11 d53673c6f7 rsx: Disable draw call batching when strict mode is enabled
- Minor bugs have been observed with it always enabled
2017-10-26 00:35:45 +03:00
kd-11 882e949f80 vk: Fix for infinite hanging in the access violation handler 2017-10-24 22:59:09 +03:00
kd-11 e6849a59a2 rsx: Better detection of framebuffer memory copy operations
- Still requires texture stitching to work correctly, but matching dimensions works well for now
2017-10-24 22:59:09 +03:00
kd-11 6918e265ec rsx/vk: Be a little more frugal with texture memory to avoid running out of VRAM on 1GB cards 2017-10-24 22:59:09 +03:00
kd-11 e9f293f522 rsx: Improve separate treatment of write exceptions vs read exceptions
- Optimizes search functionality and avoids thrashing valid sections
2017-10-24 22:59:09 +03:00
kd-11 5fc36d64b6 fix build 2017-10-24 22:59:09 +03:00
kd-11 95e6d78689 rsx: Workaround for 0 pitch textures.
- Should these be ignored? Needs investigation
2017-10-24 22:59:09 +03:00
kd-11 f4a666345a rsx: Even more texture cache fixes
- Fix subresource sampling
- Invalidate memory range before uploading textures to prevent hangs
2017-10-24 22:59:09 +03:00
kd-11 7a5c88a8d1 rsx: Only transfer framebuffer contents if memory contents are compatible 2017-10-24 22:59:09 +03:00
kd-11 0de0dded53 rsx: Texture fixes continued
- Fix buffer invalidate behaviour (wcb)
- Disable auto rebuild with only framebuffer storage getting rebuilt
- Fix vulkan subresource sampling
2017-10-24 22:59:09 +03:00
kd-11 5e58cf6079 rsx: Restructuring [WIP]
- Refactor invalidate memory functions into one function
- Add cached object rebuilding functionality to avoid throwing away useful memory on an invalidate
- Added debug monitoring of texture unit VRAM usage
2017-10-24 22:59:09 +03:00
Robbie b0737d1c90 Make a basic trophy notification dialog (#3204)
* Make trophy notification dialog.

* Fix bug where trophy state doesn't persist with game reboot.
2017-10-24 18:43:05 +03:00
Robbie 779ed75a19 Save manager improvements (#3631)
* Make size of manager only 60% of screen height initially at most.

* Add ability to delete/select multiple entries.

* Add ability to open up save dir and fix how it's done in
game_list_frame.

* Make delete much cleaner.
2017-10-24 18:09:38 +03:00
Unknown dbf1573e89 Update Readme to Qt 5.8 2017-10-24 15:11:37 +01:00
kd-11 96fd8556f2 Silence annoying experimental build warning
- Compiling locally on VS defines BRANCH to "" (empty $BRANCH envvar) and defines _MSC_VER. The pdb check is useless since it will never be reached
2017-10-22 00:14:40 +03:00
kd-11 8f324dfc0a vk: Enable primitive restart workaround for polaris and vega on linux as well
- Looks like it might be a hardware erratum
2017-10-22 00:14:40 +03:00
Unknown 34a6085cc0 Qt: add "clear" option to tty log contextmenu 2017-10-19 15:13:17 +01:00
Megamouse b3efa75206 [Qt] UI improvements (#3558)
* Qt: Show tooltips in description box

* Qt: implement description subscription

* Qt: add gamelist resize for ctrl-+/-/wheel (simple zoom)

* Qt: handle strict mode in gui tab

* Qt: more highdpi stuff

* Qt: remove old tooltips from settings_dialog

* Qt: conform cpublit tooltip to new subscription model
2017-10-19 14:29:48 +03:00
toccata10 b90a7dc66a evdev: add analog to dpad option (#3551)
* evdev Analog to digital option

* rewrite conditions on axis rotation

* a bit of cleanup
2017-10-19 13:41:02 +03:00
Megamouse 200557c036 [Qt] Add syntax highlighter (#3550)
* Qt: Add syntax highlighter

* Qt: add syntax highlighter to cg_disasm

The glsl part is pretty much finished.
The asm is still missing a few rules.
Colors are not yet fully decided

* Qt: add filter for syntax highlighter
2017-10-19 12:58:39 +03:00
kd-11 472cb3b1c2 gl: Check for vendor_string ATI for AMD cards. It seems AMD is still using the ATI openGL stack 2017-10-19 12:22:52 +03:00
kd-11 d8ee6a2edb add RX 550 to AMD vulkan cards with restart bug 2017-10-19 12:22:52 +03:00
kd-11 ddcacb8258 general fixes; Force u32 return type for index_count and add RX Vega to primitive restart blacklist 2017-10-19 12:22:52 +03:00
kd-11 a8e1754fa4 rsx: Allow clear_surface command for depth-only passes. Removes invalidate cache hack 2017-10-19 12:22:52 +03:00
kd-11 5db45c3699 rsx: More fixes
- Workaround for AMD glMultiDrawArrays bug
- Disable disjoint command submission when multidraw support is disabled
2017-10-19 12:22:52 +03:00
kd-11 89dcafbe41 rsx: Reimplement index buffer generation
- Emulate primitive restart in software whenever we get the chance
- Ensure PRIMITIVE_RESTART is never active when LIST topologies are active
- Reimplement TRIANGLE_FAN, POLYGON and QUAD expansion
2017-10-19 12:22:52 +03:00
kd-11 3d05e61f7e rsx/vk: Workaround for polaris primitive restart bug 2017-10-19 12:22:52 +03:00
Zangetsu38 5146f3ec47 Fix compile VS 2017-10-16 18:42:03 +03:00
scribam 170a95f5df Add BRANCH as a preprocessor definition taken from an environment variable 2017-10-15 18:20:02 +01:00
scribam c661578906 Bump Qt version to 5.9.2 for Travis 2017-10-15 14:23:48 +01:00
scribam f20e0c2898 rpcs3.vcxproj: remove unused paths in AdditionalLibraryDirectories 2017-10-15 14:23:48 +01:00
scribam 64b2ae3cd5 appveyor.yml: use Visual Studio solution to build the project and cleanup 2017-10-15 14:23:48 +01:00
kd-11 a11d66f52d update vulkan submodules (#3600) 2017-10-15 14:37:52 +03:00
Megamouse 304a4a1b61 GUI: add some visual studio filters (#3375) 2017-10-14 19:06:20 +03:00
Henrique Jung 76b7103fed [CMake] Build LLVM from the submodule if there's no suitable version
When RPCS3 is compiled with LLVM (default option), CMake only tries to
find LLVM on the default system installation. So the OS must have a
sytstem-wide installation of LLVM of at least version 4.0, which is not
available on many GNU/Linux distributions (e.g. Ubuntu 16.04, Debian
Stretch). If CMake can not find a suitable version, it silently falls
back to compile RPCS3 without LLVM.

This patch makes CMake defaults to compile the LLVM submodule if and
only if a suitable LLVM version is not found installed on the system.
Due to a build time check on LLVM, in-tree builds will not work when
building the submodule (LLVM does not allow in-source builds). For this
reason, the instruction for building on CMake were updated.
2017-10-14 14:54:10 +03:00
kd-11 1572d01c53 qt: Add cpu blit emulation override to the debug tab 2017-10-14 14:19:14 +03:00
kd-11 86bf61ad35 rsx: Fix memory protection
- Fixes hanging when wcb is enabled
2017-10-14 14:19:14 +03:00
kd-11 479aa91368 rsx: Add a debug option to force full software emulation of blit engine 2017-10-14 14:19:14 +03:00
kd-11 bb398c4a08 travis: Dont try to upload appiamges if UPLOAD_URL is missing 2017-10-13 15:23:48 +03:00
kd-11 eab9d06981 rsx: Texture cache fixes
- Fix src/dst framebuffer detection
- Silence some warnings
2017-10-13 15:23:48 +03:00
Zangetsu38 c63ff05e6e Fix compile VS for Optional submodule 2017-10-13 05:14:12 +03:00
scribam 0129c54ab6 Move optional.hpp as a submodule 2017-10-12 18:00:24 +03:00
kd-11 c570410e06 rsx: Stop executing broken command queues if the application fails to recover in 3 retries 2017-10-12 13:51:29 +03:00
kd-11 9af71699a4 rsx: Minor fixes
- Dont skip cb if a problem occurs, just spin on it instead to allow possibility of recovery
- Vulkan cleanup for the die_with_error helper
2017-10-12 13:51:29 +03:00
kd-11 58860614e3 rsx/qt: Implement native window hooks for win32 windows to allow communication between WndProc thread and rsx::thread
- This communication is important in communicating window events. Helps properly synchronize swapchain management on vulkan and stops nvidia crashing
- Do not block the message queue lest the driver detect window as not responding
2017-10-12 13:51:29 +03:00
Farseer e8bde583ef Remove sysutil callback 2017-10-12 04:46:10 +03:00
Nekotekina 5b19908996 Escape problematic characters in VFS
With full-width <>:"\|?*
2017-10-11 22:01:37 +03:00
Nekotekina 19f3bb8cb0 Allow shader cache dialog cancellation 2017-10-11 20:06:33 +03:00
Nekotekina ac64792d99 Optimize PPU module loading
I'm garbage 🤦
2017-10-11 20:06:33 +03:00
Nekotekina efe140bc0c Fix instruction editor a bit 2017-10-11 20:06:33 +03:00
Nekotekina df2fc13b7a Add PPU instruction stat dumper
Needs PPU Debug option to activate and PPU Interpreter
Dumps after Resume (after Pause)
Fix utils::memory_decommit, clean vm.cpp
2017-10-11 20:06:33 +03:00
kd-11 f5d450f24c vk: Better vsync mode selection (#3571) 2017-10-11 19:10:49 +03:00
yzwduck 2e5f8c0786 Rename outputs correctly when writing default values to them (#3574)
- Fix for undeclared variable errors
2017-10-11 01:50:43 +03:00
scribam 9bcc298b18 Remove unused rsx-debugger submodule and the rsx_program_decompiler entry in .gitmodules (#3542) 2017-10-11 01:22:32 +03:00
kd-11 5a03db7d2e rsx: Improve memory protection behavior when strict mode is off 2017-10-10 12:10:41 +03:00
kd-11 91ef202ee7 vulkan: Better VkResult handling 2017-10-10 12:10:41 +03:00
Zion Nimchuk 6d6b281270 Fix gentoo LLVM linking 2017-10-09 22:46:36 +01:00
Zion Nimchuk a3c49bea2c Revert "Add option to build using llvm shared libs and document other cmake options"
This reverts commit 6f33953861.
2017-10-09 22:46:36 +01:00
kd-11 1d375cb13c vulkan: Fix window resize race condition when doing flip 2017-10-09 20:25:41 +03:00
Megamouse 20ad9a13b8 Qt: add high resolution settings to gui tab 2017-10-09 20:25:41 +03:00
kd-11 fc0f98b5db rsx: Res scaling improvements
- gl: Reintroduce the wcb hw downscaling
- rsx: Clamp scalable render target size with a config var
2017-10-09 20:25:41 +03:00
kd-11 3fe37ede97 rsx: Fixups
- gl: Remove redundant texstorage1D call
- gl: Disable the wcb scaling code as it doesnt work right yet [WIP]
- vk: Fix wcb reads
2017-10-09 20:25:41 +03:00
kd-11 55df3cdf67 vulkan: Implement vsync 2017-10-09 20:25:41 +03:00
kd-11 6e8107a5cb rsx: Implement AF override 2017-10-09 20:25:41 +03:00
kd-11 7bee4064a6 gl/wcb: Use temporary scaled image to implement bilinear filter 2017-10-09 20:25:41 +03:00
kd-11 12ab03b0b5 rsx/gl: Implement resolution scaling
rsx: Revise wpos calculation to take resolution scale into account
2017-10-09 20:25:41 +03:00
kd-11 47202d5839 rsx: Set up patch functionality for program coeffecients 2017-10-09 20:25:41 +03:00
Robbie 47b121a700 PPU Page Faults (#3309)
I guess I'll merge it and fix some issues later myself.
2017-10-08 23:37:54 +03:00
scribam d53b640bcf Change compiler requirements in cmake script to match with the values listed in the README.md file 2017-10-08 14:50:31 +03:00
Unknown 78ef467138 Qt: fix fullscreen icon 2017-10-08 13:34:46 +03:00
Unknown b7f6bd4c91 Qt: extend drag and drop to mainwindow 2017-10-08 13:34:46 +03:00
Unknown e272acd7c1 Qt: sort game_list_frame members 2017-10-08 13:34:46 +03:00
Unknown 93d2ac887d Qt: add spu and ppu debug checkboxes to debug tab 2017-10-08 13:34:46 +03:00
Megamouse a84cc1d3bb Qt: move Render_Info to emu_settings.h 2017-10-08 13:34:46 +03:00
Nekotekina cc594ad353 Add supporters 2017-10-05 19:51:37 +03:00
Nekotekina beab5291bb mutex.cpp: minor update
New concept (incomplete)
2017-10-05 19:51:37 +03:00
Nekotekina 3907dd0444 Implement SYS_NET_SO_REUSEPORT 2017-10-05 19:51:37 +03:00
Nekotekina 3d64b65813 Fix /dev/urandom typo 2017-10-05 19:51:37 +03:00
Nekotekina ab4e66a0bf Add cellVdec hack (stolen TLS) 2017-10-05 19:51:37 +03:00
Nekotekina 144f6809bf Implement CALL_FUNC 2017-10-05 19:51:37 +03:00
Nekotekina d296e6021d libbeisobmf.sprx 2017-10-05 19:51:37 +03:00
Nekotekina 45a855ef1f Fix cellKb 2017-10-05 19:51:37 +03:00
Nekotekina e5f756205c sys_net full rewrite
Implement sys_net syscalls
Clean libnet functions
Use libnet.sprx
Use libhttp.sprx
Use libssl.sprx
Use librudp.sprx
Implement sys_ss_random_number_generator
2017-10-05 19:51:37 +03:00
Talkashie 6335fa8df1 Update tooltips.json (#3529) 2017-10-05 19:34:48 +03:00
Megamouse b2605206b1 Qt: fix gamegrid regression: mismatch between entry count and grid size 2017-10-05 17:10:18 +01:00
Zion Nimchuk 33182650ca Add a GitHub issue template, hopefully help with invalid issue spam. 2017-10-05 11:30:39 +01:00
Megamouse 0ca1f82059 [Qt] fix experimental build warning layout and smoothen gamelist scrolling (#3532)
* Qt: fix layout of "experimental build warning" for dpi scaling

and remove compiler warning in welcome_dialog.ui

* Qt: smoothen gamelist/-grid scrolling by setting singlestep value

and fix missing scroll and deselect on gamegrid

* Qt: show all bootable categories in gamegrid
2017-10-05 05:22:02 +03:00
toccata10 0c5cb4824b Add Deadzones for evdev gamepads (#3519) 2017-10-05 04:59:35 +03:00
Megamouse cf83b796e1 Qt: include debug tool colors in stylesheet (#3527)
Qt: include debug tool colors in stylesheet
2017-10-04 23:10:24 +01:00
kd-11 b338c81907 spu: Fixes (#3526)
* spu: Rewrite interpreter fast FM
- Partially implement accurate FM
- Fix FMA/FMS/FNMS by removing an optimization that does not work for INF (cmpunord)
- cmpunord does not catch all cases of an extended result/overflow
- NOTE: FM still does not handle corner cases well (e.g inf * 1.2 because SPU does not have concept of inf)
2017-10-04 20:58:06 +03:00
Megamouse 81b3e7e449 Qt: disable viewport settings on custom configs 2017-10-03 01:34:26 +03:00
scribam 425ddd13e5 [Qt] Fix repository urls to install Qt 2017-10-03 00:41:56 +03:00
Megamouse eb8af974dc Qt: add old log style to Kuroi 2017-09-28 18:23:17 +03:00
Megamouse 3067c8bd27 Qt: fix tty objectname and add tty text color to stylesheet 2017-09-28 18:23:17 +03:00
jjsat 632c8872cd Respect the controller setting when returning data from cellPadGetData. 2017-09-28 12:15:54 +03:00
Megamouse 9650218bb8 Qt: fix log stacking bug when wordwrap occurs 2017-09-28 01:46:20 +03:00
Megamouse 0b51102167 Qt: add log colors to stylesheet
and silence some compiler warnings
2017-09-28 01:46:20 +03:00
Megamouse ca36d08893 Qt: use rgba lambda for default stylesheet 2017-09-28 01:46:20 +03:00
Megamouse a358384900 Qt: support thumbnail icons in stylesheets 2017-09-28 01:46:20 +03:00
Megamouse 77a75305c7 Qt: implement GetOpaqueImageArea 2017-09-28 01:46:20 +03:00
Ryan Gonzalez 85b9809b39 Fix evdev axis reversal (#3303) 2017-09-28 01:13:57 +03:00
Zion Nimchuk d36de7d54f AppVeyor git branch in title fix #2 2017-09-28 00:50:24 +03:00
Jake 2b1c757084 ds4: Fix initial connection issue and hotplug/dongle calibration detection 2017-09-24 22:03:49 +03:00
kd-11 e7db0c7d99 vk: Clamp unreleased texture metric
- TODO: Find the leaking references
2017-09-23 16:46:41 +03:00
kd-11 393e3b702f rsx: Clean up debug overlays. Add unreleased textures metric to track texture memory 2017-09-23 16:46:41 +03:00
kd-11 23ad687e7e vk: New images always should be UNDEFINED or PREINITIALIZED 2017-09-23 16:46:41 +03:00
kd-11 a04ecdbe0a vulkan: Use frameid to determine texture storage to discard 2017-09-23 16:46:41 +03:00
kd-11 9ee21af524 vulkan: Optimize memory allocation 2017-09-23 16:46:41 +03:00
kd-11 b74cdcde00 rsx: Make the 3rd texture dimension matter
- Affects cube maps and texture3D surfaces
2017-09-23 16:46:41 +03:00
kd-11 4d83d749a0 rsx: Texture cache fixes
- Update section flags when requested
- Fix nullptr dereference: cached_dest will be null if dst_is_render_target is true
2017-09-23 16:46:41 +03:00
Zion 8e66e719fa Fix branch name for AppVeyor Builds (#3472) 2017-09-22 13:26:43 +03:00
kd-11 c6e6f4afea vs/qt: Explicitly reference target output to avoid failing post-build step
- Referencing the whole build folder will err if there is any non-qt exe in the folder
2017-09-21 20:05:07 +03:00
kd-11 d0148728c6 rsx: Fixes
- Fix section scanning range for early reject
- Specify IMAGE_ASPECT_STENCIL when uploading image_from_cpu
2017-09-21 20:05:07 +03:00
kd-11 dfc564f837 gl: Check that fence is not empty before calling destroy 2017-09-21 20:05:07 +03:00
Farseer 2b0edf6cde Allow null argument
Should fix Jak 2
2017-09-21 17:31:46 +03:00
Henrique Jung daa7520d1d Deploy QT DLLs using windeployqt tool (#3432)
* Deploy QT DLLs using windeployqt tool

Replace the old mechanism that manually copy the DLLs using either CMake
or VS built-in functions. The new approach uses the windeployqt tool
provided by the QT project that automatically detect the needed DLLs and
perform the necessary copying.

This approach should be more robust if there's an upstream change on QT
project regarding DLLs usage.

* QT DLLs: do not ship RPCS3 with ANGLE and software-OpenGL

According to https://doc.qt.io/qt-5/windows-requirements.html ANGLE is
useful for applications that use OpenGL ES by removing the need to
install OpenGL drivers, redirecting OpenGL calls to DirectX instead.
RPCS does not uses OpenGL ES so it's better to just remove it from the
binary distribution.

opengl32sw.dll is a fallback mechanism when ANGLE libraries are not
available that uses a software backend for OpenGL. It's unlikely that
RPCS3 will work using software-OpenGL, so there's little point into
shipping them.

* QT DLLs: do not ship with SVG and translation files

Like the other removed QT libraries: they are not needed right now. We
can deploy them if they become useful someday.
2017-09-21 16:53:20 +03:00
kd-11 3499d089e7 rsx: Texture cache fixes and improvements
rsx: Conditional lock hack removed
vulkan - Fixes
- Remove unused texture class
- Fix native pitch calculation (WCB)
rsx: Catch hanging begin/end pairs when flushing deferred draw calls
vulkan: Register DXT compressed formats
vulkan: Register depth formats
gl: Workaround for 'texture stitching' when gathering flip surface
- TODO: Add a proper flip hack option
rsx: Fix texture memory size calculation
- DXT textures dont have real pitch. Since pitch is used to calculate memory size, make sure it always evaluates to rsx_size
rsx: Fix cpu copy detection
rsx: Validate blit dst surface and dont make assumptions about region blit order
- Also relax restrictions on memory owned by the blit engine if strict rendering is not enabled
rsx: Fix depth texture detection
rsx: Do not manually offset into dst. The overlapped range check does so automatically
rsx: Minor optimizations
rsx: Minor fixes
- Fix to detect incompatible formats when using GPU texture scaling and show message
- Better 'is_depth_texture' algorithm to eliminate false positives
2017-09-21 16:17:06 +03:00
kd-11 6b96a2022a rsx: Add support for non-projective shadow sampling
- Fixes missing shadows in persona 5

vk: Enable polygon depth bias a.k.a polygonOffset
- Fixes shadow acne in persona 5
2017-09-21 16:17:06 +03:00
kd-11 3836b40bf7 rsx: Fixups 2017-09-21 16:17:06 +03:00
kd-11 571dbfb7b1 rsx: Texture cache improvements
- Limits buffer size to min 720 in the Y axis (1024 section causes conflicts in some cases - TODO)
rsx: Fixups to allow large textures for blit operation
- Also includes checks for both leaking sections and blit regions for vulkan
hotfix for hanging when using WCB
addendum - unlock both ro and no blocks before attempting to copy memory blocks
gl: Fixups for ARB_explicit_uniform_location
- Forces glsl v 430 to make use of the extension
rsx/vk: Rework texture cache to minimize recursive access violations
- Also modifies the vulkan commandbuffer begin/end/submit mechanism
gl: Fix cached_texture_section::is_flushable to take memory protection into account
rsx: Fix blit dst offset calculation
2017-09-21 16:17:06 +03:00
kd-11 10e25eb362 rsx: Fix multidraw range splits again
rsx: Hotfix for disjoint range detection
2017-09-21 16:17:06 +03:00
kd-11 45d0e821dc gl: Minor optimizations
rsx: Texture cache - improvements to locking
rsx: Minor optimizations to get_current_vertex_program and begin-end batch flushes
rsx: Optimize texture cache storage
- Manages storage in blocks of 16MB
rsx/vk/gl: Fix swizzled texture input
gl: Hotfix for compressed texture formats
2017-09-21 16:17:06 +03:00
kd-11 e37a2a8f7d rsx: Texture cache fixes and improvments
gl/vk/rsx: Refactoring; unify texture cache code
gl: Fixups
- Removes rsx::gl::texture class and leave gl::texture intact
- Simplify texture create and upload mechanisms
- Re-enable texture uploads with the new texture cache mechanism
rsx: texture cache - check if bit region fits into dst texture before attempting to copy
gl/vk: Cleanup
- Set initial texture layout to DST_OPTIMAL since it has no data in it anyway at the start
- Move structs outside of classes to avoid clutter
2017-09-21 16:17:06 +03:00
kd-11 07c83f6e44 gl: cleanup; fix program linkage on mesa using GL_ARB_explicit_uniform_location, also make use of ARB_multidraw 2017-09-21 16:17:06 +03:00
kd-11 061824a7ec rsx: Add support for batched multidraw
gl: Fix multidraw [WIP]
rsx: Ignore vertex base when data source is generated using arithmetic
vk: Check pending flag before doing fence poke
vk/gl: Fix for inlined array and immediate draws
rsx: Collapse joined draws when batching
2017-09-21 16:17:06 +03:00
kd-11 abb56a354d rsx: Bug fixes and improvements
rsx: Try to skip unknown commands without discarding entire cb
2017-09-21 16:17:06 +03:00
kd-11 9359b8c170 rsx/fp: Shader decompiler fixes
- Requires proper 2-pass impl
rsx/fp: Catch hanging code blocks
rsx/fp: Don't pause on scaling error
2017-09-21 16:17:06 +03:00
kd-11 2d0f1f27a8 esx: Fixes to the texture cache
rsx: Blit engine improvements
- Always handle blits to and from framebuffers through the GPU
- Handle depth surfaces properly when using GL
- Check for format mismatches when blitting to the surface store [WIP]
2017-09-21 16:17:06 +03:00
kd-11 73312fc363 rsx: Several fixes and improvements
- Do not ignore non-centered pixel blitting
- Register method ac00+16
- Bump texture memory heap to account for GPU texture scaling requirements (vulkan)
- Explicit MRT location index output to better convey intent (openGL)
2017-09-21 16:17:06 +03:00
kd-11 deb590cb05 rsx/vk: Bug fixes
- Make each frame context own its own memory
- Fix GPU blit
- Fix image layout transitions in flip

vk: Improve frame-local memory usage tracking to prevent overwrites
- Also slightly bumps VRAM requirements for stream buffers to help with running out of storage
- Fixes flickering and missing graphics in some cases. Flickering is still there and needs more work
vk: Up vertex attribute heap size and increase the guard size on it
vulkan: Reorganize memory management
vulkan: blit cleanup
vulkan: blit engine improvements
- Override existing image mapping when conflicts detected
- Allow blitting of depth/stencil surfaces
2017-09-21 16:17:06 +03:00
kd-11 2033f3f7dc rsx/vk/gl: Refactoring and reimplementation of blit engine
Fix rsx offscreen-render-to-display-buffer-blit surface reads
- Also, properly scale display output height if reading from compressed tile

gl: Fix broken dst height computation
- The extra padding is only there to force power-of-2 sizes and isnt used

gl: Ignore compression scaling if output is rendered to in a renderpass

rsx/gl/vk: Cleanup for GPU texture scaling. Initial impl [WIP]
- TODO: Refactor more shared code into RSX/common
2017-09-21 16:17:06 +03:00
Nekotekina 3e3160d7ac Minor VFS fix 2017-09-21 14:34:09 +03:00
Nekotekina dd919c76b8 cellAudio: use error_code 2017-09-20 14:27:52 +03:00
Nekotekina a6a0f13264 Remove unnecessary include git-version.h 2017-09-20 14:26:42 +03:00
Nekotekina b9a0c107ab Fix library loading mode 'both' 2017-09-20 14:26:42 +03:00
Nekotekina 5c93acefd9 Try to fix some fs errors 2017-09-19 15:07:07 +03:00
Nekotekina a428dac71c sys_fs_mkdir: implement ENOENT 2017-09-19 15:07:07 +03:00
Nekotekina 3901f08fa0 Fix error on loading a library twice 2017-09-19 15:07:07 +03:00
Nekotekina 519f21db18 Exitspawn support renewal
Implemented _sys_process_exit2 syscall
Rewritten sys_game_process_exitspawn
Rewritten sys_game_process_exitspawn2
Implemented _sys_process_atexitspawn
Implemented _sys_process_at_Exitspawn
And some other changes
2017-09-19 15:07:07 +03:00
Nekotekina 18d472b7e1 Patch: new 'load' syntax
[load, path_name1] - load sequence
[load, path_name2, -0x40] - same, but modify the addresses by -64
2017-09-19 15:07:07 +03:00
Nekotekina bc098d6b9c Rewrite _sys_strncat 2017-09-19 15:07:07 +03:00
Nekotekina 22ff8abd7d Rewrite _sys_strncpy 2017-09-19 15:07:07 +03:00
Nekotekina 871ccfd32c Rewrite _sys_strrchr 2017-09-19 15:07:07 +03:00
Nekotekina 7a79e184c5 Rewrite _sys_strchr 2017-09-19 15:07:07 +03:00
Nekotekina 0e72cc879f Rewrite _sys_strcpy 2017-09-19 15:07:07 +03:00
Nekotekina 13304bd18b Rewrite _sys_strcat 2017-09-19 15:07:07 +03:00
Nekotekina a4b824c50a Rewrite _sys_strncmp 2017-09-19 15:07:07 +03:00
Nekotekina ccc87081f3 Rewrite _sys_strcmp 2017-09-19 15:07:07 +03:00
Nekotekina 800ba9d902 Rewrite _sys_strlen 2017-09-19 15:07:07 +03:00
Nekotekina 015b9fdf8b Fix _sys_strncasecmp 2017-09-19 15:07:07 +03:00
Nekotekina 83f93202d0 Rewrite _sys_memcmp 2017-09-19 15:07:07 +03:00
Nekotekina ae2ea02377 Implemented _sys_prx_load_module_on_memcontainer 2017-09-19 15:07:07 +03:00
Nekotekina 4fe4521881 Implemented __sys_look_ctype_table
Implemented _sys_tolower, _sys_toupper
Fixed _sys_strncasecmp
2017-09-19 15:07:07 +03:00
Nekotekina b83575bcbb Remove unnecessary newline in Log.cpp 2017-09-19 15:07:07 +03:00
Nekotekina 17175e1c23 Fixed global variables in Log.cpp 2017-09-19 15:07:07 +03:00
Nekotekina cc57719856 Restore UTF-8 in Log.cpp 2017-09-19 15:07:07 +03:00
Nekotekina b9b71ccbc1 Implemented syscall _sys_process_exit 2017-09-19 15:07:07 +03:00
Nekotekina e789b969b0 Implemented MFF_HIDDEN for VNIDs
Minor refactoring
Now possible: ```REF_FUNC(...).flag(MFF_HIDDEN);```
2017-09-19 15:07:07 +03:00
Nekotekina be44024a1a Fix initial log message 2017-09-19 15:07:07 +03:00
Nekotekina c7d4a30646 Backup logs to old_logs/ 2017-09-19 15:07:07 +03:00
Nekotekina 837c5dddee Add <typeinfo> 2017-09-19 15:07:07 +03:00
Nekotekina 669b1385cc Move sys_process_exit 2017-09-19 15:07:07 +03:00
scribam 01ffaab3e0 Silent some compiler warnings 2017-09-19 13:21:12 +03:00
Robbie d5fb7180d0 HGA calls sys_rsx_context_attribute before calling sys_rsx_memory_allocate. This inevitably causes RPCS3 to crash. Add nullptr check to prevent this. 2017-09-18 21:24:13 +01:00
Megamouse b141b43c1c [Qt] fix graphics adapter selection and rebase for less redundancy 2017-09-17 21:05:54 +01:00
Megamouse cad91e114d Qt: add char count label to osk dialog 2017-09-17 12:39:52 +03:00
Megamouse db51779682 Qt: settings_dialog layout fix (hack) 2017-09-17 11:40:41 +03:00
Peter Mcteague c18e71ca29 Add git_branch to git-version.h, add display version info to gs_frame and add branch and version to log. (#3186)
* Added version number and branch name to gs_frame and log file. This also involved making the files that generate git-version.h , get the branch.
2017-09-16 14:54:25 +03:00
Alex Touchet 6a54b3929e Update Visual Studio 2015 URL 2017-09-15 10:53:27 +03:00
myfreeweb 07af701afe Vulkan: use pkg-config instead of checking for Linux (#3440)
Makes Vulkan optional on Linux / makes it possible on FreeBSD.
2017-09-14 21:02:09 +03:00
Nekotekina 669d953529 Implement fs::error::notempty 2017-09-14 00:23:23 +03:00
Nekotekina 22d8b57027 Improve lv2_memory object 2017-09-14 00:23:23 +03:00
Nekotekina 0e691e2c51 sys_mmapper: minor range fix 2017-09-14 00:23:23 +03:00
Nekotekina ae1e9e78db sys_fs: use g_tls_error for diagnostic
Affected syscalls:
sys_fs_open
sys_fs_opendir
sys_fs_stat
sys_fs_mkdir
sys_fs_fcntl (get free space)
2017-09-14 00:23:23 +03:00
Nekotekina e00aedd1a0 fs: minor fix 2017-09-14 00:23:23 +03:00
Zion Nimchuk 4a10dcc549 Fix buffer overrun in cert loading, made it more accurate. Fixes #3408 2017-09-13 17:40:57 +03:00
Megamouse 553f67d7e3 Qt: improve gamelist refresh, fix some more scroll issues
despite earlier efforts with modelindex and so on the annoying scroll jump still surfaced sometimes, so we only scrollTo index on selected occasions from now on.
Furthermore we don't need to refresh the gamelist if no custom config has been applied, so this will only be needed on accept from now on
2017-09-11 23:17:32 +03:00
Megamouse fac8a520f0 Qt: Remove duplicate gui repaints in settings dialog
ApplyGuiOptions(true) already forces GuiStylesheetRequest and therefore RepaintGui in main_window if necessary.
We don't need GuiRepaintRequest on accept because there should be no option left that doesn't repaint immediately
2017-09-11 23:17:32 +03:00
Megamouse f0358f85fc [Qt] fix small buttons/missing icons in the toolbar (Doppelgänger) (#3413)
* Qt: use lambda for colorizedIcon in main_window and game_list_frame

* Qt: enable AA_UseHighDpiPixmaps for better looking icons

* Qt: use iconSize instead of sizehint for linux, add some comments
2017-09-10 20:46:39 +03:00
Henrique Jung 4b9fa8ec6d CMake build: copy QT DLLs files to bin directory
AppVeyor build relies on CMake to build the VS project files, which then
is used to build RPCS3, so we must tell CMake to copy Qt DLLs files the
same way VS build does.
2017-09-10 19:25:54 +03:00
Henrique Jung 45cdf6af3b VS build: delete QT DLLs from bin directory
Commit 6cfb184b1e added these files when
implementing a very large code refactoring. They seems to be unecessary
since there's a couple of VS post-build scripts that copy the files from
the user local QT installation to the bin directory every time the rpcs3
project is built. So their presence in the repository only makes cloning
it a little slower.
2017-09-10 19:25:54 +03:00
Robbie 47685bef39 If the loop is never entered, then the jit is null. 2017-09-10 18:51:59 +03:00
Megamouse b11f9e0405 [Qt] add scrollbar to about dialog (#3417)
* Qt: add scrollbar to about dialog

* move contributors
2017-09-10 14:03:24 +03:00
Henrique Jung 84e7de0a78 VS build: copy Qt5WinExtras.dll to bin directory
When building RPCS3 on Visual Studio, there's some DLLs that are copied
from the local QT installation to the RPCS3's output directory using a
post-build script. However, one of these DLL was missing, which is
required for running the program on debug mode (for release versions,
the file is already present on git).

This commit just add the additional command that is needed to copy the
file.
2017-09-10 01:27:22 +01:00
scribam f39e2b999f [Qt] Delete "ui" pointer in destructor 2017-09-09 20:29:42 +01:00
Megamouse cd4b28b4d7 Qt / OpenGL: fix delete_context 2017-09-09 19:46:10 +01:00
Megamouse 2db2114a45 Qt: add Refresh button to gamepad settings, minor cleanup 2017-09-09 19:46:10 +01:00
Megamouse 4b11a62b4d Qt: fix gamepad settings layout issue 2017-09-09 19:46:10 +01:00
RipleyTom 0457f23b13 Pad Refactoring
Adds a window to setup multiple input types as once
All controllers are now handled by a single thread
[hcorion] evdev refactor
2017-09-09 00:55:03 +01:00
Peter Mcteague a6ba7ed21c Fixed a line where event->ingore() was called after break. 2017-09-09 00:33:53 +01:00
Peter Mcteague 5326912bc0 Added ignoring of keyboard shortcuts to keyboard_pad_handler
This fixes an issue where pressing keyboard shortcuts will input them to
the game.
2017-09-09 00:33:53 +01:00
Megamouse be46c82aaa [Qt] style adjustments 6
rename members and clean headers for gamelist and main window
adjust some more connects
2017-09-08 19:23:34 +01:00
Megamouse 43bae9f9d7 [Qt] style adjustments 5
rename even more members and clean headers
adjust some more connects
move some function bodies to cpp
2017-09-08 19:23:34 +01:00
Megamouse 95231c4dee [Qt] style adjustments 4
rename more members and clean headers
adjust some connects
2017-09-08 19:23:34 +01:00
Megamouse a95e01290e [Qt] style adjustments 3
rename some members and clean headers
2017-09-08 19:23:34 +01:00
Farseer 0cbbd3a5b1 Trophy fixes
Should fix Kung Fu Panda 2 Raging Blast 2
2017-09-08 20:10:57 +03:00
Zion Nimchuk d8f3354ce3 Fix some of libpng known incorrect profile spam 2017-09-08 17:23:16 +01:00
RipleyTom e4105f46de Implement _sys_prx_get_module_info 2017-09-08 00:06:53 +03:00
Megamouse 9a1ee9e984 use single line titles in gamelist and recent games menu 2017-09-07 21:26:44 +01:00
Zion Nimchuk 7c897d5019 Weird tlou fix 2017-09-06 21:44:58 +01:00
Zion Nimchuk bfe2bccc51 Implement progress bar in taskbar for non-windows platforms, Fixes #2605 2017-09-06 21:44:58 +01:00
Zion Nimchuk 11aa0be04a Change MacOSX -> MacOS, add warning about glvnd, Fixes #2949 2017-09-06 21:44:58 +01:00
Zion Nimchuk d2cae96e8d Add option to build using llvm shared libs and document other cmake options 2017-09-06 21:44:58 +01:00
Megamouse 8e955297ef [Qt] style adjustments 2
some more of the same
2017-09-06 17:15:38 +01:00
Megamouse 205f6a9000 [Qt] style adjustments 1
mainly move { to newline
get rid of some lines here, add some lines there
2017-09-06 17:15:38 +01:00
jjsat 4558f93f92 Convert endianess before passing buffers to setsockopt. 2017-09-06 00:14:15 +03:00
jjsat 634c411946 Fix sys_tty_write() if called with pwritelen == NULL. 2017-09-06 00:14:15 +03:00
Megamouse d4d0d35e05 game_list_frame: force single line text in list items 2017-09-05 21:44:46 +03:00
scribam f4f36a3cb1 .travis.yml: remove "dist: trusty" as it is now the default distribution 2017-09-05 17:46:38 +01:00
scribam 21d70a75d5 .travis.yml: remove GCC_COLORS variable export and duplicated "brew update;" instruction 2017-09-05 17:46:38 +01:00
scribam 47ed9aa1b9 .travis.yml: rework binutils package update 2017-09-05 17:46:38 +01:00
scribam b60ac78c58 Remove coverity and coveralls references 2017-09-05 17:46:38 +01:00
Nekotekina 83e139cd1a Improve sys_fs_ftruncate
Handle stream API lock (EBUSY)
Handle append mode
2017-09-04 02:15:29 +03:00
Nekotekina b415b0e737 fs: atomic truncation 2017-09-04 02:15:29 +03:00
Nekotekina 2e510e5ca0 Fix rXml limitation
(trophies)
2017-09-04 02:15:28 +03:00
Nekotekina 1262263f5c Fix sys_event_port_connect_ipc 2017-09-04 02:15:28 +03:00
Nekotekina 9b9e2bcafb Move sys_gamepad filter 2017-09-04 02:15:28 +03:00
RipleyTom cde29aba64 multi pkg fix 2017-09-04 00:10:15 +01:00
scribam 34cf1ff7c7 Remove old wxWidgets-related references 2017-09-03 23:12:36 +01:00
Zion Nimchuk cc880b53aa Add cross-platform implementation of cellHttpUtilParseUri 2017-09-04 00:37:36 +03:00
Zion Nimchuk 8ad44dd00f Implement cellSslCertificateLoader 2017-09-04 00:37:36 +03:00
Megamouse 9440e65452 settings_dialog: minor connect simplification 2017-09-02 15:22:58 +03:00
Megamouse 5cb6815bf3 GUI: Fix Repaint on stylesheet change 2017-09-02 15:22:58 +03:00
Ofek caab400258 Various fixes (Trophy, Gcm corrections, stack alloc) (#2894)
* Fixed sys_get_random_number generating less bytes than needed, and ceiling the buffer size in 0x1000 instead of failing
* Corrected alignment check in libgcm
* Now calling callback of sceNpManagerRegisterCallback
* Fixed trophies
2017-09-02 14:43:44 +03:00
Megamouse d3f13ab8a3 fix da build 2017-09-02 12:04:22 +03:00
Talkashie ca6064b109 sys_usbd stuff (#3346)
* Create sys_usbd.cpp

* Create sys_usbd.h

* Update lv2.cpp
2017-09-02 04:21:42 +03:00
320 changed files with 23216 additions and 12314 deletions
+24
View File
@@ -0,0 +1,24 @@
<!---
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/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.
--->
-1
View File
@@ -59,7 +59,6 @@ rpcs3/git-version.h
# Visual Studio Files
.vs/*
*.ipch
*.vspx
*.psess
*.VC.*
+7 -10
View File
@@ -8,16 +8,13 @@
[submodule "llvm"]
path = llvm
url = https://github.com/llvm-mirror/llvm
branch = release_50
[submodule "rsx_program_decompiler"]
path = rsx_program_decompiler
url = https://github.com/RPCS3/rsx_program_decompiler
branch = release_40
[submodule "GSL"]
path = 3rdparty/GSL
url = https://github.com/Microsoft/GSL.git
[submodule "libpng"]
path = 3rdparty/libpng
url = https://github.com/Zangetsu38/libpng
url = https://github.com/RPCS3/libpng
ignore = dirty
[submodule "Vulkan/glslang"]
path = Vulkan/glslang
@@ -34,13 +31,13 @@
[submodule "3rdparty/cereal"]
path = 3rdparty/cereal
url = https://github.com/USCiLab/cereal.git
[submodule "rsx-debugger"]
path = rsx-debugger
url = https://github.com/RPCS3/rsx-debugger.git
[submodule "3rdparty/zlib"]
path = 3rdparty/zlib
url = https://github.com/madler/zlib
[submodule "3rdparty/hidapi"]
path = 3rdparty/hidapi
url = https://github.com/Zangetsu38/hidapi
branch = master
url = https://github.com/RPCS3/hidapi
branch = master
[submodule "3rdparty/Optional"]
path = 3rdparty/Optional
url = https://github.com/akrzemi1/Optional.git
+14 -43
View File
@@ -1,6 +1,5 @@
language: cpp
sudo: required
dist: trusty
os:
- linux
@@ -17,19 +16,10 @@ cache:
directories:
- $HOME/hombebrew_cache
env:
global:
- secure: BXyNziNYFLqLtY6Q58BDEUpRJr81HUtHpxf2Sr646bDcbG0Rf2rb2utqHZJ1Om926WdH7RqHuoVti4dr2X1lh4nHMkLD7MrIrfIkNN5T9aZdk19uw9IyMtz/cXon7/wqVo24tVqtBI0UghFxKii/GTDJEvRKgfpPp1e1vKSNGa4=
# Which Travis environment to run Coverity on
- coverity_scan_run_condition='"$TRAVIS_OS_NAME" = linux -a "$CC" = gcc'
# Test mode is for testing if it's working with Coverity. Change to true if testing, to avoid reaching the quota.
- coverity_scan_script_test_mode=false
matrix:
exclude:
- os: osx
compiler: gcc
git:
submodules: false
@@ -40,7 +30,6 @@ before_install:
fi;
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CXX" = "g++" ]; then
export CXX="g++-5" CC="gcc-5" CXXFLAGS="-Wno-format-security";
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01';
fi;
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
wget http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run ;
@@ -48,33 +37,24 @@ before_install:
export QT_QPA_PLATFORM=minimal ;
./qt-unified-linux-x64-online.run --script qt-installer-noninteractive.qs --no-force-installations ;
fi;
# Add coverall for C++ so coverall.io could be triggered. Even it should be --coverage and gcov.
# Install updated libglew-dev since the version provided by trusty is outdated
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
pip install --user cpp-coveralls requests[security];
wget http://mirrors.kernel.org/ubuntu/pool/main/g/glew/libglew-dev_1.13.0-2_amd64.deb;
wget http://mirrors.kernel.org/ubuntu/pool/main/g/glew/libglew1.13_1.13.0-2_amd64.deb;
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
sudo dpkg -i libglew1.13_1.13.0-2_amd64.deb libglew-dev_1.13.0-2_amd64.deb libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
else
brew update; brew update;
brew update;
brew install ccache glew llvm40;
fi;
# We need to update binutils to a newer version to link against the ffmpeg libs on.
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
sudo add-apt-repository ppa:jonathonf/binutils -y ;
sudo apt-get update ;
sudo apt-get install binutils -y;
ld --version ;
fi;
before_script:
- git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
- git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi 3rdparty/Optional Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
- mkdir build
- cd build
- export CMAKE_PREFIX_PATH=~/Qt/5.9.1/gcc_64/lib/cmake
- export CMAKE_PREFIX_PATH=~/Qt/5.9.2/gcc_64/lib/cmake
- if [ "$TRAVIS_PULL_REQUEST" = false ]; then
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH";
else
@@ -83,21 +63,21 @@ before_script:
- cmake .. -DCMAKE_INSTALL_PREFIX=/usr;
- make -j 3
- # AppImage generation
- if [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
export LD_LIBRARY_PATH=~/Qt/5.9.1/gcc_64/lib;
- if [ -n "$UPLOAD_URL" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
export LD_LIBRARY_PATH=~/Qt/5.9.2/gcc_64/lib;
make DESTDIR=appdir install ; find appdir/ ;
find ../bin ;
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" ;
chmod a+x linuxdeployqt*.AppImage ;
export PATH=~/Qt/5.9.1/gcc_64/bin/:${PATH} ;
export PATH=~/Qt/5.9.2/gcc_64/bin/:${PATH} ;
./linuxdeployqt*.AppImage --appimage-extract ;
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ;
mkdir ./appdir/usr/plugins/xcbglintegrations/ ;
mkdir ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.9.1/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.9.1/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
cp ~/Qt/5.9.2/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
cp ~/Qt/5.9.2/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
cp ~/Qt/5.9.2/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
cp ~/Qt/5.9.2/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
export PATH=${TRAVIS_BUILD_DIR}/build/squashfs-root/usr/bin/:${PATH} ;
./squashfs-root/usr/bin/appimagetool ${TRAVIS_BUILD_DIR}/build/appdir ;
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq ;
@@ -109,14 +89,15 @@ script:
#- echo "--Shell Export Lists START--" ; export -p; echo "--Shell Export Lists STOP--";
# And to ensure the versions of toolchain
- echo "--CXX version?"; "$CXX" --version; echo "--CXX version confirmed";
#- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -j 3; fi
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- sourceline: 'ppa:jonathonf/binutils' # We need to update binutils to a newer version to link against the ffmpeg libs on.
packages:
- binutils
- cmake
- libasound2-dev
- libopenal-dev
@@ -134,18 +115,8 @@ addons:
- libstdc++-5-dev
- lib32stdc++6
- zlib1g-dev
# We need to install qt 5.9.1 manually because the version trusty provides is too old.
# We need to install qt 5.9.2 manually because the version trusty provides is too old.
#- qtbase5-dev
- libudev-dev
- libevdev-dev
- libpulse-dev
coverity_scan:
project:
name: $TRAVIS_REPO_SLUG
description: "PS3 emulator/debugger"
notification_email: nekotekina@gmail.com
build_command: "make -j 3"
branch_pattern: coverity_scan
after_success:
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "$TRAVIS_OS_NAME" = linux ]; then coveralls --extension .c --extension .cpp --extension .h; fi
Vendored Submodule
+1
Submodule 3rdparty/Optional added at f27e79084a
+23 -14
View File
@@ -3,7 +3,6 @@ RPCS3
[![Build Status](https://travis-ci.org/RPCS3/rpcs3.svg?branch=master)](https://travis-ci.org/RPCS3/rpcs3)
[![Build status](https://ci.appveyor.com/api/projects/status/411c4clmiohtx7eo/branch/master?svg=true)](https://ci.appveyor.com/project/rpcs3/rpcs3/branch/master)
[![Coverity Status](https://img.shields.io/coverity/scan/3960.svg)](https://scan.coverity.com/projects/3960)
The world's first open-source PlayStation 3 emulator/debugger written in C++ for Windows and Linux.
@@ -21,22 +20,23 @@ If you want to contribute please take a look at the [Coding Style](https://githu
## Dependencies
### Windows
* [Visual Studio 2017](https://www.visualstudio.com/downloads/)
* [Visual C++ Redistributable Packages for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572)
* [Visual Studio 2015](https://www.visualstudio.com/vs/older-downloads/)
* [Visual C++ Redistributable Packages for Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48145)
* [Cmake 3.1.0+](https://www.cmake.org/download/) (required; add to PATH)
* [Python 3.3+](https://www.python.org/downloads/) (required; add to PATH)
* [Qt 5.9+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.9\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
* [Qt 5.8+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.8\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
* [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
### Linux
* [Qt 5.9+](https://www.qt.io/download-open-source/)
* [Qt 5.7+](https://www.qt.io/download-open-source/)
* GCC 5.1+ or Clang 3.5.0+ ([not GCC 6.1](https://github.com/RPCS3/rpcs3/issues/1691))
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default`
* Arch: `sudo pacman -S glew openal cmake llvm qt5-base`
* Fedora: `sudo dnf install cmake qt5-devel vulkan-devel glew glew-devel`
**If you have a NVIDIA GPU, you may need to install the libglvnd package.**
### Mac OSX
Mac OSX is not supported at this moment because it doesn't meet system requirements (OpenGL 4.3)
### MacOS
MacOS is not supported at this moment because it doesn't meet system requirements (OpenGL 4.3)
* Xcode 6+ (tested with Xcode 6.4)
* Install with Homebrew: `brew install glew llvm qt cmake`
@@ -47,7 +47,7 @@ To initialize the repository don't forget to execute `git submodule update --ini
### Configuring Qt
*If you're using Visual Studio 2017 without Qt plugin support (or simply dont want to use it):*
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.9\msvc2017_64\` </br>
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.8\msvc2015_64\` </br>
*If you wish to use the Visual Studio plugin for Qt:* </br>
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.8\msvc2015_64`. </br>
@@ -58,15 +58,16 @@ To initialize the repository don't forget to execute `git submodule update --ini
2) Press *BUILD* > *Build Solution* or *Rebuild Solution*. </br>
## Building on Linux & Mac OSX:
## Building on Linux & Mac OS:
1) `git clone https://github.com/RPCS3/rpcs3.git` </br>
2) `cd rpcs3/` </br>
3) `git submodule update --init` </br>
4) `cmake CMakeLists.txt && make GitVersion && make` </br>
4) `cd ../ && mkdir rpcs3_build && cd rpcs3_build`
4) `cmake ../rpcs3/ && make GitVersion && make` </br>
5) Run RPCS3 with `./bin/rpcs3` </br>
If you are on OSX and want to build with brew llvm and qt don't forget to add the following environment variables
If you are on MacOS and want to build with brew llvm and qt don't forget to add the following environment variables
* `LLVM_DIR=/usr/local/opt/llvm/` (or wherever llvm was installed).
* `Qt5_DIR=/usr/local/opt/qt/lib/cmake/Qt5` (or wherever qt was installed).
@@ -74,14 +75,22 @@ If you are on OSX and want to build with brew llvm and qt don't forget to add th
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
## CMake Build Options (Linux & Mac OSX)
## CMake Build Options (Linux & Mac OS)
- ```-DUSE_SYSTEM_LIBPNG=ON/OFF``` (default = *OFF*) </br>
- ```-DUSE_SYSTEM_LIBPNG=ON/OFF``` (default = *OFF*)
Build against the shared libpng instead of using the builtin one. libpng 1.6+ highly recommended. Try this option if you get version conflict errors or only see black game icons.
- ```-DUSE_SYSTEM_FFMPEG=ON/OFF``` (default = *OFF*) </br>
- ```-DUSE_SYSTEM_FFMPEG=ON/OFF``` (default = *OFF*)
Build against the shared ffmpeg libraries instead of using the builtin patched version. Try this if the builtin version breaks the OpenGL renderer for you.
- ```-DWITHOUT_LLVM=ON/OFF``` (default = *OFF*)
This forces RPCS3 to build without LLVM, not recommended.
- ```-DWITH_GDB=ON/OFF``` (default = *OFF*)
This Builds RPCS3 with support for debugging PS3 games using gdb.
- ```-DUSE_VULKAN=ON/OFF``` (default = *ON*)
This builds RPCS3 with Vulkan support.
## License
+2
View File
@@ -3,6 +3,8 @@
#include "yaml-cpp/yaml.h"
#include <typeinfo>
namespace cfg
{
logs::channel cfg("CFG");
+13 -17
View File
@@ -8,6 +8,7 @@
#include <algorithm>
#include <cstring>
#include <cerrno>
#include <typeinfo>
using namespace std::literals::string_literals;
@@ -94,6 +95,8 @@ static fs::error to_error(DWORD e)
case ERROR_DIRECTORY: return fs::error::inval;
case ERROR_INVALID_NAME: return fs::error::inval;
case ERROR_SHARING_VIOLATION: return fs::error::acces;
case ERROR_DIR_NOT_EMPTY: return fs::error::notempty;
case ERROR_NOT_READY: return fs::error::noent;
default: fmt::throw_exception("Unknown Win32 error: %u.", e);
}
}
@@ -128,6 +131,7 @@ static fs::error to_error(int e)
case EEXIST: return fs::error::exist;
case EINVAL: return fs::error::inval;
case EACCES: return fs::error::acces;
case ENOTEMPTY: return fs::error::notempty;
default: fmt::throw_exception("Unknown system error: %d.", e);
}
}
@@ -675,18 +679,17 @@ bool fs::truncate_file(const std::string& path, u64 length)
#ifdef _WIN32
// Open the file
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE)
{
g_tls_error = to_error(GetLastError());
return false;
}
LARGE_INTEGER distance;
distance.QuadPart = length;
FILE_END_OF_FILE_INFO _eof;
_eof.EndOfFile.QuadPart = length;
// Seek and truncate
if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN) || !SetEndOfFile(handle))
if (!SetFileInformationByHandle(handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
{
g_tls_error = to_error(GetLastError());
CloseHandle(handle);
@@ -715,7 +718,7 @@ bool fs::utime(const std::string& path, s64 atime, s64 mtime)
#ifdef _WIN32
// Open the file
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE)
{
g_tls_error = to_error(GetLastError());
@@ -846,23 +849,15 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
bool trunc(u64 length) override
{
LARGE_INTEGER old, pos;
FILE_END_OF_FILE_INFO _eof;
_eof.EndOfFile.QuadPart = length;
pos.QuadPart = 0;
if (!SetFilePointerEx(m_handle, pos, &old, FILE_CURRENT)) // get old position
if (!SetFileInformationByHandle(m_handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
{
g_tls_error = to_error(GetLastError());
return false;
}
pos.QuadPart = length;
if (!SetFilePointerEx(m_handle, pos, NULL, FILE_BEGIN)) // set new position
{
g_tls_error = to_error(GetLastError());
return false;
}
verify("file::trunc" HERE), SetEndOfFile(m_handle), SetFilePointerEx(m_handle, old, NULL, FILE_BEGIN);
return true;
}
@@ -1458,6 +1453,7 @@ void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
case fs::error::noent: return "Not found";
case fs::error::exist: return "Already exists";
case fs::error::acces: return "Access violation";
case fs::error::notempty: return "Not empty";
}
return unknown;
+1
View File
@@ -502,6 +502,7 @@ namespace fs
noent,
exist,
acces,
notempty,
};
// Error code returned
+2 -2
View File
@@ -258,11 +258,11 @@ struct MemoryManager : llvm::RTDyldMemoryManager
return RTDyldMemoryManager::registerEHFrames(addr, load_addr, size);
}
virtual void deregisterEHFrames() override
virtual void deregisterEHFrames(u8* addr, u64 load_addr, std::size_t size) override
{
LOG_ERROR(GENERAL, "deregisterEHFrames() called"); // Not expected
return RTDyldMemoryManager::deregisterEHFrames();
return RTDyldMemoryManager::deregisterEHFrames(addr, load_addr, size);
}
};
-23
View File
@@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+265
View File
@@ -0,0 +1,265 @@
/*
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
* https://github.com/corporateshark/LUrlParser
*
* The MIT License (MIT)
*
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "LUrlParser.h"
#include <algorithm>
#include <cstring>
#include <stdlib.h>
// check if the scheme name is valid
static bool IsSchemeValid( const std::string& SchemeName )
{
for ( auto c : SchemeName )
{
if ( !isalpha( c ) && c != '+' && c != '-' && c != '.' ) return false;
}
return true;
}
bool LUrlParser::clParseURL::GetPort( int* OutPort ) const
{
if ( !IsValid() ) { return false; }
int Port = atoi( m_Port.c_str() );
if ( Port <= 0 || Port > 65535 ) { return false; }
if ( OutPort ) { *OutPort = Port; }
return true;
}
// based on RFC 1738 and RFC 3986
LUrlParser::clParseURL LUrlParser::clParseURL::ParseURL( const std::string& URL )
{
LUrlParser::clParseURL Result;
const char* CurrentString = URL.c_str();
/*
* <scheme>:<scheme-specific-part>
* <scheme> := [a-z\+\-\.]+
* For resiliency, programs interpreting URLs should treat upper case letters as equivalent to lower case in scheme names
*/
// try to read scheme
{
const char* LocalString = strchr( CurrentString, ':' );
if ( !LocalString )
{
return clParseURL( LUrlParserError_NoUrlCharacter );
}
// save the scheme name
Result.m_Scheme = std::string( CurrentString, LocalString - CurrentString );
if ( !IsSchemeValid( Result.m_Scheme ) )
{
return clParseURL( LUrlParserError_InvalidSchemeName );
}
// scheme should be lowercase
std::transform( Result.m_Scheme.begin(), Result.m_Scheme.end(), Result.m_Scheme.begin(), ::tolower );
// skip ':'
CurrentString = LocalString+1;
}
/*
* //<user>:<password>@<host>:<port>/<url-path>
* any ":", "@" and "/" must be normalized
*/
// skip "//"
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash );
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash );
// check if the user name and password are specified
bool bHasUserName = false;
const char* LocalString = CurrentString;
while ( *LocalString )
{
if ( *LocalString == '@' )
{
// user name and password are specified
bHasUserName = true;
break;
}
else if ( *LocalString == '/' )
{
// end of <host>:<port> specification
bHasUserName = false;
break;
}
LocalString++;
}
// user name and password
LocalString = CurrentString;
if ( bHasUserName )
{
// read user name
while ( *LocalString && *LocalString != ':' && *LocalString != '@' ) LocalString++;
Result.m_UserName = std::string( CurrentString, LocalString - CurrentString );
// proceed with the current pointer
CurrentString = LocalString;
if ( *CurrentString == ':' )
{
// skip ':'
CurrentString++;
// read password
LocalString = CurrentString;
while ( *LocalString && *LocalString != '@' ) LocalString++;
Result.m_Password = std::string( CurrentString, LocalString - CurrentString );
CurrentString = LocalString;
}
// skip '@'
if ( *CurrentString != '@' )
{
return clParseURL( LUrlParserError_NoAtSign );
}
CurrentString++;
}
bool bHasBracket = ( *CurrentString == '[' );
// go ahead, read the host name
LocalString = CurrentString;
while ( *LocalString )
{
if ( bHasBracket && *LocalString == ']' )
{
// end of IPv6 address
LocalString++;
break;
}
else if ( !bHasBracket && ( *LocalString == ':' || *LocalString == '/' ) )
{
// port number is specified
break;
}
LocalString++;
}
Result.m_Host = std::string( CurrentString, LocalString - CurrentString );
CurrentString = LocalString;
// is port number specified?
if ( *CurrentString == ':' )
{
CurrentString++;
// read port number
LocalString = CurrentString;
while ( *LocalString && *LocalString != '/' ) LocalString++;
Result.m_Port = std::string( CurrentString, LocalString - CurrentString );
CurrentString = LocalString;
}
// end of string
if ( !*CurrentString )
{
Result.m_ErrorCode = LUrlParserError_Ok;
return Result;
}
// skip '/'
if ( *CurrentString != '/' )
{
return clParseURL( LUrlParserError_NoSlash );
}
CurrentString++;
// parse the path
LocalString = CurrentString;
while ( *LocalString && *LocalString != '#' && *LocalString != '?' ) LocalString++;
Result.m_Path = std::string( CurrentString, LocalString - CurrentString );
CurrentString = LocalString;
// check for query
if ( *CurrentString == '?' )
{
// skip '?'
CurrentString++;
// read query
LocalString = CurrentString;
while ( *LocalString && *LocalString != '#' ) LocalString++;
Result.m_Query = std::string( CurrentString, LocalString - CurrentString );
CurrentString = LocalString;
}
// check for fragment
if ( *CurrentString == '#' )
{
// skip '#'
CurrentString++;
// read fragment
LocalString = CurrentString;
while ( *LocalString ) LocalString++;
Result.m_Fragment = std::string( CurrentString, LocalString - CurrentString );
CurrentString = LocalString;
}
Result.m_ErrorCode = LUrlParserError_Ok;
return Result;
}
+78
View File
@@ -0,0 +1,78 @@
/*
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
* https://github.com/corporateshark/LUrlParser
*
* The MIT License (MIT)
*
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
#include <string>
namespace LUrlParser
{
enum LUrlParserError
{
LUrlParserError_Ok = 0,
LUrlParserError_Uninitialized = 1,
LUrlParserError_NoUrlCharacter = 2,
LUrlParserError_InvalidSchemeName = 3,
LUrlParserError_NoDoubleSlash = 4,
LUrlParserError_NoAtSign = 5,
LUrlParserError_UnexpectedEndOfLine = 6,
LUrlParserError_NoSlash = 7,
};
class clParseURL
{
public:
LUrlParserError m_ErrorCode;
std::string m_Scheme;
std::string m_Host;
std::string m_Port;
std::string m_Path;
std::string m_Query;
std::string m_Fragment;
std::string m_UserName;
std::string m_Password;
clParseURL()
: m_ErrorCode( LUrlParserError_Uninitialized )
{}
/// return 'true' if the parsing was successful
bool IsValid() const { return m_ErrorCode == LUrlParserError_Ok; }
/// helper to convert the port number to int, return 'true' if the port is valid (within the 0..65535 range)
bool GetPort( int* OutPort ) const;
/// parse the URL
static clParseURL ParseURL( const std::string& URL );
private:
explicit clParseURL( LUrlParserError ErrorCode )
: m_ErrorCode( ErrorCode )
{}
};
} // namespace LUrlParser
+50 -49
View File
@@ -76,6 +76,30 @@ 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;
u64 stamp;
std::string prefix;
std::string text;
};
struct file_listener : public file_writer, public listener
{
file_listener(const std::string& name);
@@ -84,6 +108,12 @@ namespace logs
// Encode level, current thread name, channel name and write log message
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;
// Messages for delayed listener initialization
std::vector<stored_message> messages;
};
static file_listener* get_logger()
@@ -135,39 +165,9 @@ namespace logs
channel SPU("SPU");
channel ARMv7("ARMv7");
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;
u64 stamp;
std::string prefix;
std::string text;
};
// Channel registry mutex
semaphore<> g_mutex;
// Channel registry
std::unordered_map<std::string, channel_info> g_channels;
// Messages for delayed listener initialization
std::vector<stored_message> g_messages;
// Must be set to true in main()
atomic_t<bool> g_init{false};
@@ -175,7 +175,7 @@ namespace logs
{
semaphore_lock lock(g_mutex);
for (auto&& pair : g_channels)
for (auto&& pair : get_logger()->channels)
{
pair.second.set_level(level::notice);
}
@@ -185,7 +185,7 @@ namespace logs
{
semaphore_lock lock(g_mutex);
g_channels[ch_name].set_level(value);
get_logger()->channels[ch_name].set_level(value);
}
// Must be called in main() to stop accumulating messages in g_messages
@@ -194,7 +194,7 @@ namespace logs
if (!g_init)
{
semaphore_lock lock(g_mutex);
g_messages.clear();
get_logger()->messages.clear();
g_init = true;
}
}
@@ -218,7 +218,7 @@ void logs::listener::add(logs::listener* _new)
}
// Send initial messages
for (const auto& msg : g_messages)
for (const auto& msg : get_logger()->messages)
{
_new->log(msg.stamp, msg.m, msg.prefix, msg.text);
}
@@ -234,7 +234,7 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
{
semaphore_lock lock(g_mutex);
auto& info = g_channels[ch->name];
auto& info = get_logger()->channels[ch->name];
if (info.pointer && info.pointer != ch)
{
@@ -274,10 +274,10 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
}
// Store message additionally
g_messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
get_logger()->messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
}
}
// Send message to all listeners
while (lis)
{
@@ -289,11 +289,11 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
[[noreturn]] extern void catch_all_exceptions();
logs::file_writer::file_writer(const std::string& name)
: m_name(fs::get_config_dir() + name)
: m_name(name)
{
try
{
if (!m_file.open(m_name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
if (!m_file.open(fs::get_config_dir() + name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
{
fmt::throw_exception("Can't create file %s (error %s)", name, fs::g_tls_error);
}
@@ -306,11 +306,13 @@ logs::file_writer::file_writer(const std::string& name)
m_fptr = (uchar*)::mmap(0, s_log_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_file.get_handle(), 0);
#endif
verify(m_name.c_str()), m_fptr;
verify(name.c_str()), m_fptr;
std::memset(m_fptr, '\n', s_log_size);
// Rotate backups (TODO)
fs::rename(m_name + ".gz", m_name + "1.gz", true);
fs::remove_file(fs::get_config_dir() + name + "1.gz");
fs::create_dir(fs::get_config_dir() + "old_logs");
fs::rename(fs::get_config_dir() + m_name + ".gz", fs::get_config_dir() + "old_logs/" + m_name + ".gz", true);
}
catch (...)
{
@@ -337,7 +339,7 @@ logs::file_writer::~file_writer()
if (deflate(&zs, Z_FINISH) != Z_STREAM_ERROR)
{
fs::file(m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
fs::file(fs::get_config_dir() + m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
}
if (deflateEnd(&zs) != Z_OK)
@@ -348,12 +350,10 @@ logs::file_writer::~file_writer()
#ifdef _WIN32
UnmapViewOfFile(m_fptr);
CloseHandle(m_fmap);
m_file.seek(m_size);
SetEndOfFile(m_file.get_handle());
#else
::munmap(m_fptr, s_log_size);
m_file.trunc(m_size);
#endif
m_file.trunc(m_size);
}
void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
@@ -395,10 +395,11 @@ 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\n%s", rpcs3::version.to_string(), utils::get_system_info());
ver.text = fmt::format("RPCS3 v%s | %s\n%s", rpcs3::version.to_string(), rpcs3::get_branch(), utils::get_system_info());
file_writer::log(logs::level::always, ver.text.data(), ver.text.size());
file_writer::log(logs::level::always, "\n", 1);
g_messages.emplace_back(std::move(ver));
messages.emplace_back(std::move(ver));
}
void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& _text)
@@ -431,7 +432,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
text += prefix;
text += "} ";
}
if (msg.ch && '\0' != *msg.ch->name)
{
text += msg.ch->name;
@@ -441,7 +442,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
{
text += "TODO: ";
}
text += _text;
text += '\n';
-98
View File
@@ -1,98 +0,0 @@
#pragma once
class MTProgressDialog : public wxDialog
{
wxGauge** m_gauge;
wxStaticText** m_msg;
wxArrayLong m_maximum;
const u8 m_cores;
static const uint layout = 16;
static const uint maxdial = 65536;
wxArrayInt m_lastupdate;
public:
MTProgressDialog(wxWindow* parent, const wxSize& size, const wxString& title,
const wxString& msg, const wxArrayLong& maximum, const u8 cores)
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition)
, m_maximum(maximum)
, m_cores(cores)
{
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
m_gauge = new wxGauge*[m_cores];
m_msg = new wxStaticText*[m_cores];
m_lastupdate.SetCount(cores);
for(uint i=0; i<m_cores; ++i)
{
m_lastupdate[i] = -1;
m_msg[i] = new wxStaticText(this, wxID_ANY, msg);
sizer->Add(m_msg[i], 0, wxLEFT | wxTOP, layout);
m_gauge[i] = new wxGauge(this, wxID_ANY, maxdial,
wxDefaultPosition, wxDefaultSize,
wxGA_HORIZONTAL );
sizer->Add(m_gauge[i], 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, layout);
m_gauge[i]->SetValue(0);
sizer->AddSpacer(5);
}
SetSizerAndFit(sizer);
if(size != wxDefaultSize)
{
SetSize(size);
}
else
{
wxSize ws;
ws.x = 400;
ws.y = GetSize().y + 8;
SetSize(ws);
}
m_maximum.SetCount(m_cores);
Show();
}
void Update(const u8 thread_id, const u64 value, const wxString& msg)
{
if(thread_id > m_cores) return;
const int curupdate = (int)(((double)value/(double)m_maximum[thread_id])*1000);
if(curupdate == m_lastupdate[thread_id]) return;
m_lastupdate[thread_id] = curupdate;
m_msg[thread_id]->SetLabel(msg);
if(value >= (u32)m_maximum[thread_id]) return;
m_gauge[thread_id]->SetValue(((double)value / (double)m_maximum[thread_id]) * maxdial);
}
const u32 GetMaxValue(const uint thread_id) const
{
if(thread_id > m_cores) return 0;
return m_maximum[thread_id];
}
void SetMaxFor(const uint thread_id, const u64 val)
{
if(thread_id > m_cores) return;
m_maximum[thread_id] = val;
m_lastupdate[thread_id] = 0;
}
virtual void Close(bool force = false)
{
m_lastupdate.Empty();
m_maximum.Empty();
wxDialog::Close(force);
}
};
+76 -12
View File
@@ -3,7 +3,10 @@
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/RawSPUThread.h"
#include "Emu/Cell/lv2/sys_mmapper.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Thread.h"
#include <typeinfo>
#ifdef _WIN32
#include <Windows.h>
@@ -1258,9 +1261,60 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
return true;
}
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
if (cpu)
{
if (fxm::check<page_fault_notification_entries>())
{
for (const auto& entry : fxm::get<page_fault_notification_entries>()->entries)
{
auto mem = vm::get(vm::any, entry.start_addr);
if (!mem)
{
continue;
}
if (entry.start_addr <= addr && addr <= addr + mem->size - 1)
{
// Place the page fault event onto table so that other functions [sys_mmapper_free_address and ppu pagefault funcs]
// know that this thread is page faulted and where.
auto pf_entries = fxm::get_always<page_fault_event_entries>();
{
semaphore_lock pf_lock(pf_entries->pf_mutex);
page_fault_event pf_event{ cpu->id, addr };
pf_entries->events.emplace_back(pf_event);
}
// Now, we notify the game that a page fault occurred so it can rectify it.
// Note, for data3, were the memory readable AND we got a page fault, it must be due to a write violation since reads are allowed.
be_t<u64> data1 = addr;
be_t<u64> data2 = (SYS_MEMORY_PAGE_FAULT_TYPE_PPU_THREAD << 32) + cpu->id; // TODO: fix hack for now that assumes PPU thread always.
be_t<u64> data3 = vm::check_addr(addr, a_size, vm::page_readable) ? SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY : SYS_MEMORY_PAGE_FAULT_CAUSE_NON_MAPPED;
LOG_ERROR(MEMORY, "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(entry.port_id, data1, data2, data3);
// If we fail due to being busy, wait a bit and try again.
while (sending_error == CELL_EBUSY)
{
lv2_obj::sleep(*cpu, 1000);
thread_ctrl::wait_for(1000);
sending_error = sys_event_port_send(entry.port_id, data1, data2, data3);
}
if (sending_error)
{
fmt::throw_exception("Unknown error %x while trying to pass page fault.", sending_error.value);
}
lv2_obj::sleep(*cpu);
thread_ctrl::wait();
return true;
}
}
}
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
cpu->state += cpu_flag::dbg_pause;
cpu->check_state();
@@ -1830,20 +1884,30 @@ void thread_ctrl::set_native_priority(int priority)
HANDLE _this_thread = GetCurrentThread();
INT native_priority = THREAD_PRIORITY_NORMAL;
switch (priority)
{
default:
case 0:
break;
case 1:
if (priority > 0)
native_priority = THREAD_PRIORITY_ABOVE_NORMAL;
break;
case -1:
if (priority < 0)
native_priority = THREAD_PRIORITY_BELOW_NORMAL;
break;
}
SetThreadPriority(_this_thread, native_priority);
if (!SetThreadPriority(_this_thread, native_priority))
{
LOG_ERROR(GENERAL, "SetThreadPriority() failed: 0x%x", GetLastError());
}
#else
int policy;
struct sched_param param;
pthread_getschedparam(pthread_self(), &policy, &param);
if (priority > 0)
param.sched_priority = sched_get_priority_max(policy);
if (priority < 0)
param.sched_priority = sched_get_priority_min(policy);
if (int err = pthread_setschedparam(pthread_self(), policy, &param))
{
LOG_ERROR(GENERAL, "pthraed_setschedparam() failed: %d", err);
}
#endif
}
+1 -1
View File
@@ -70,7 +70,7 @@ namespace utils
void memory_decommit(void* pointer, std::size_t size)
{
#ifdef _WIN32
verify(HERE), ::VirtualFree(pointer, 0, MEM_DECOMMIT);
verify(HERE), ::VirtualFree(pointer, size, MEM_DECOMMIT);
#else
verify(HERE), ::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
#endif
+30 -1
View File
@@ -10,6 +10,7 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
{
switch (value)
{
case patch_type::load: return "load";
case patch_type::byte: return "byte";
case patch_type::le16: return "le16";
case patch_type::le32: return "le32";
@@ -45,10 +46,33 @@ void patch_engine::append(const std::string& patch)
struct patch info{};
info.type = static_cast<patch_type>(type64);
info.offset = patch[1].as<u32>();
info.offset = patch[1].as<u32>(0);
switch (info.type)
{
case patch_type::load:
{
// Special syntax: copy named sequence (must be loaded before)
const auto found = m_map.find(patch[1].Scalar());
if (found != m_map.end())
{
// Address modifier (optional)
const u32 mod = patch[2].as<u32>(0);
for (const auto& rd : found->second)
{
info = rd;
info.offset += mod;
data.emplace_back(info);
}
continue;
}
// TODO: error
break;
}
case patch_type::bef32:
case patch_type::lef32:
{
@@ -90,6 +114,11 @@ std::size_t patch_engine::apply(const std::string& name, u8* dst) const
switch (p.type)
{
case patch_type::load:
{
// Invalid in this context
break;
}
case patch_type::byte:
{
*ptr = static_cast<u8>(p.value);
+1
View File
@@ -7,6 +7,7 @@
enum class patch_type
{
load,
byte,
le16,
le32,
-10
View File
@@ -1,10 +0,0 @@
Copyright (C) 2011-2012 Andrzej Krzemienski
Distributed under the Boost Software License, Version 1.0
(see accompanying file LICENSE_1_0.txt or a copy at
http://www.boost.org/LICENSE_1_0.txt)
The idea and interface is based on Boost.Optional library
authored by Fernando Luis Cacciola Carballal
Home at https://github.com/akrzemi1/Optional
+2 -2
View File
@@ -731,9 +731,9 @@ struct area_base
{
return{ x1 * size.width, y1 * size.height, x2 * size.width, y2 * size.height };
}
constexpr area_base operator * (const T& value) const
constexpr area_base operator * (const f32& value) const
{
return{ x1 * value, y1 * value, x2 * value, y2 * value };
return{ (T)(x1 * value), (T)(y1 * value), (T)(x2 * value), (T)(y2 * value) };
}
template<typename NT>
+30
View File
@@ -16,6 +16,7 @@ rem // Official git repository and contact information can be found at
rem // https://github.com/RPCS3/rpcs3 and http://rpcs3.net/.
setlocal ENABLEDELAYEDEXPANSION
setlocal ENABLEEXTENSIONS
set GIT_VERSION_FILE=%~p0..\rpcs3\git-version.h
if not defined GIT (
@@ -47,15 +48,43 @@ if errorlevel 1 (
echo // This is a generated file. > "%GIT_VERSION_FILE%"
echo. >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_VERSION "unknown" >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_BRANCH "unknown" >> "%GIT_VERSION_FILE%"
echo. >> "%GIT_VERSION_FILE%"
echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_FILE%"
goto done
)
rem // Get commit count from HEAD by default
for /F %%I IN ('call %GIT% rev-list HEAD --count') do set GIT_VERSION=%%I
rem // If we're in AppVeyor and we're building for master: Get commit count from unshallowed upstream
if defined APPVEYOR (
if not defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
call %GIT% remote add upstream https://github.com/RPCS3/RPCS3.git
call %GIT% fetch --unshallow upstream
for /F %%I IN ('call %GIT% rev-list --count upstream/master') do set GIT_VERSION=%%I
)
)
if defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
if "%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"=="master" (
for /f "tokens=1* delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set user=%%a
set "GIT_BRANCH=!user!/%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"
) else (
set GIT_BRANCH=%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%
)
) else (
for /F %%I IN ('call %GIT% rev-parse --abbrev-ref HEAD') do set GIT_BRANCH=%%I
)
rem // Get last commit (shortened) and concat after commit count in GIT_VERSION
for /F %%I IN ('call %GIT% rev-parse --short HEAD') do set GIT_VERSION=%GIT_VERSION%-%%I
rem // Echo obtained GIT_VERSION for debug purposes if needed
echo %GIT_VERSION%
rem // Don't modify the file if it already has the current version.
if exist "%GIT_VERSION_FILE%" (
findstr /C:"%GIT_VERSION%" "%GIT_VERSION_FILE%" > NUL
@@ -67,6 +96,7 @@ if exist "%GIT_VERSION_FILE%" (
echo // This is a generated file. > "%GIT_VERSION_FILE%"
echo. >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_VERSION "%GIT_VERSION%" >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_BRANCH ^"%GIT_BRANCH%^" >> "%GIT_VERSION_FILE%"
echo. >> "%GIT_VERSION_FILE%"
echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_FILE%"
echo #define RPCS3_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_FILE%"
+83 -1
View File
@@ -1,7 +1,12 @@
#include "mutex.h"
#include "sync.h"
#include <limits.h>
#include <climits>
#include <vector>
#include <algorithm>
// TLS variable for tracking owned mutexes
thread_local std::vector<shared_mutex*> g_tls_locks;
void shared_mutex::imp_lock_shared(s64 _old)
{
@@ -217,12 +222,14 @@ void shared_mutex::imp_unlock(s64 _old)
void shared_mutex::imp_lock_upgrade()
{
// TODO
unlock_shared();
lock();
}
void shared_mutex::imp_lock_degrade()
{
// TODO
unlock();
lock_shared();
}
@@ -250,3 +257,78 @@ bool shared_mutex::try_lock_degrade()
// TODO
return m_value.compare_and_swap_test(0, c_one - c_min);
}
safe_reader_lock::safe_reader_lock(shared_mutex& mutex)
: m_mutex(mutex)
, m_is_owned(false)
{
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
{
m_is_owned = true;
if (m_is_owned)
{
m_mutex.lock_shared();
g_tls_locks.emplace_back(&m_mutex);
return;
}
// TODO: order locks
}
}
safe_reader_lock::~safe_reader_lock()
{
if (m_is_owned)
{
m_mutex.unlock_shared();
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
return;
}
// TODO: order locks
}
safe_writer_lock::safe_writer_lock(shared_mutex& mutex)
: m_mutex(mutex)
, m_is_owned(false)
, m_is_upgraded(false)
{
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
{
m_is_owned = true;
if (m_is_owned)
{
m_mutex.lock_shared();
g_tls_locks.emplace_back(&m_mutex);
return;
}
// TODO: order locks
}
if (m_mutex.is_reading())
{
m_is_upgraded = true;
m_mutex.lock_upgrade();
}
}
safe_writer_lock::~safe_writer_lock()
{
if (m_is_upgraded)
{
m_mutex.lock_degrade();
return;
}
if (m_is_owned)
{
m_mutex.unlock();
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
return;
}
// TODO: order locks
}
+58
View File
@@ -95,6 +95,11 @@ public:
imp_lock_degrade();
}
}
bool is_reading() const
{
return (m_value.load() % c_one) != 0;
}
};
// Simplified shared (reader) lock implementation.
@@ -171,3 +176,56 @@ public:
unlock();
}
};
// Safe reader lock. Can be recursive above other safe locks (reader or writer).
class safe_reader_lock final
{
shared_mutex& m_mutex;
bool m_is_owned;
void lock()
{
m_mutex.lock_shared();
}
void unlock()
{
m_mutex.unlock_shared();
}
friend class cond_variable;
public:
safe_reader_lock(const safe_reader_lock&) = delete;
explicit safe_reader_lock(shared_mutex& mutex);
~safe_reader_lock();
};
// Safe writer lock. Can be recursive above other safe locks. Performs upgrade and degrade operations above existing reader lock if necessary.
class safe_writer_lock final
{
shared_mutex& m_mutex;
bool m_is_owned;
bool m_is_upgraded;
void lock()
{
m_mutex.lock();
}
void unlock()
{
m_mutex.unlock();
}
friend class cond_variable;
public:
safe_writer_lock(const safe_writer_lock&) = delete;
explicit safe_writer_lock(shared_mutex& mutex);
~safe_writer_lock();
};
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -61,10 +61,9 @@ rXmlDocument::rXmlDocument() : handle()
{
}
void rXmlDocument::Load(const std::string & path)
void rXmlDocument::Read(const std::string& data)
{
// TODO: Unsure of use of c_str.
handle.load_file(path.c_str());
handle.load_buffer(data.data(), data.size());
}
std::shared_ptr<rXmlNode> rXmlDocument::GetRoot()
+1 -1
View File
@@ -24,7 +24,7 @@ struct rXmlDocument
rXmlDocument();
rXmlDocument(const rXmlDocument& other) = delete;
rXmlDocument &operator=(const rXmlDocument& other) = delete;
void Load(const std::string & path);
void Read(const std::string& data);
std::shared_ptr<rXmlNode> GetRoot();
pugi::xml_document handle;
+21 -1
View File
@@ -48,7 +48,7 @@
#define CONCATENATE_DETAIL(x, y) x ## y
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE_DETAIL(x) #x ""
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
#define HERE "\n(in file " __FILE__ ":" STRINGIZE(__LINE__) ")"
@@ -534,6 +534,26 @@ inline u64 cntlz64(u64 arg, bool nonzero = false)
#endif
}
inline u32 cnttz32(u32 arg, bool nonzero = false)
{
#ifdef _MSC_VER
ulong res;
return _BitScanForward(&res, arg) || nonzero ? res : 32;
#else
return arg || nonzero ? __builtin_ctzll(arg) : 32;
#endif
}
inline u64 cnttz64(u64 arg, bool nonzero = false)
{
#ifdef _MSC_VER
ulong res;
return _BitScanForward64(&res, arg) || nonzero ? res : 64;
#else
return arg || nonzero ? __builtin_ctzll(arg) : 64;
#endif
}
// Helper function, used by ""_u16, ""_u32, ""_u64
constexpr u8 to_u8(char c)
{
+1 -1
View File
@@ -19,7 +19,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+8 -8
View File
@@ -19,12 +19,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,20 +39,20 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
</NMakeReBuildCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m</NMakeCleanCommandLine>
</PropertyGroup>
<ItemDefinitionGroup>
+8 -8
View File
@@ -19,12 +19,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,24 +39,24 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
</NMakeCleanCommandLine>
</PropertyGroup>
+72 -34
View File
@@ -1,44 +1,82 @@
version: '0.0.3-{build}'
#---------------------------------#
# general configuration #
#---------------------------------#
os: Visual Studio 2017
platform: x64
clone_folder: C:\rpcs3
clone_depth: 3
test: off
# version format
version: '0.0.4-{build}'
configuration:
# Release
- ReleaseLLVM
#---------------------------------#
# environment configuration #
#---------------------------------#
before_build:
- ps: $env:Date="$(git show -s --date=short --format='%ad')"
- git submodule update --init 3rdparty/ffmpeg 3rdparty/pugixml asmjit 3rdparty/GSL 3rdparty/libpng Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers Utilities/yaml-cpp 3rdparty/cereal 3rdparty/zlib 3rdparty/hidapi
- 7z x zlib.7z -aos -oC:\rpcs3\ > null
- 7z x vulkan.7z -aos -oC:\rpcs3\Vulkan > null
- set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%/#%APPVEYOR_PULL_REQUEST_NUMBER%
- if "%APPVEYOR_PULL_REQUEST_NUMBER%"=="" (set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%)
- set CXXFLAGS=-DBRANCH=%BRANCH%
- if %configuration%==Release (cmake -G "Visual Studio 15 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 15 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/lib/cmake/llvm -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
# Build worker image (VM template)
image: Visual Studio 2015
build_script:
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
# clone directory
clone_folder: c:\projects\rpcs3
install:
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -FileName llvmlibs.7z
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
- if not exist zlib.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B-HVE3xvheVFX05lRFdnZlh5aUU" -FileName zlib.7z
- set QTDIR=C:\Qt\5.9.1\msvc2017_64
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
- set PATH=C:\Program Files (x86)\MSBuild\15.0\Bin;%QTDIR%;%PATH%
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
# set clone depth
clone_depth: 3 # clone entire repository history if not defined
artifacts:
- path: bin
name: 'rpcs3-v0.0.3-$(Date)-$(COMMIT_SHA)_win64'
type: zip
# environment variables
environment:
QTDIR: C:\Qt\5.9.1\msvc2015_64
# build cache to preserve files/folders between builds
cache:
- llvmlibs.7z -> appveyor.yml
- vulkan.7z -> appveyor.yml
- zlib.7z -> appveyor.yml
# scripts that run after cloning repository
install:
- git submodule update --init 3rdparty/cereal 3rdparty/ffmpeg 3rdparty/GSL 3rdparty/hidapi 3rdparty/libpng 3rdparty/Optional 3rdparty/pugixml 3rdparty/zlib asmjit Utilities/yaml-cpp Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
#---------------------------------#
# build configuration #
#---------------------------------#
# build platform, i.e. x86, x64, Any CPU. This setting is optional.
platform: x64
# build Configuration, i.e. Debug, Release, etc.
configuration: Release - LLVM
build:
parallel: true # enable MSBuild parallel builds
project: rpcs3.sln # path to Visual Studio solution or project
# MSBuild verbosity level
verbosity: normal
# scripts to run before build
before_build:
- set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%/#%APPVEYOR_PULL_REQUEST_NUMBER%
- if "%APPVEYOR_PULL_REQUEST_NUMBER%"=="" (set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%)
- set PATH=%PATH%;%QTDIR%
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -FileName llvmlibs.7z
- 7z x llvmlibs.7z -aos -o%APPVEYOR_BUILD_FOLDER% > null
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
- 7z x vulkan.7z -aos -o"%APPVEYOR_BUILD_FOLDER%\lib\%CONFIGURATION%-%PLATFORM%" > null
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
before_package:
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.exp
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.lib
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.pdb
- set COMMIT_DATE=%APPVEYOR_REPO_COMMIT_TIMESTAMP:~0,10%
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
#---------------------------------#
# tests configuration #
#---------------------------------#
# to disable automatic tests
test: off
#---------------------------------#
# artifacts configuration #
#---------------------------------#
# pushing entire folder as a zip archive
artifacts:
- path: bin
name: 'rpcs3-v0.0.4-$(COMMIT_DATE)-$(COMMIT_SHA)_win64'
+1 -1
View File
@@ -93,7 +93,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+123 -41
View File
@@ -40,7 +40,7 @@ QWidget {
/* Mouse tooltips */
QToolTip {
border: 1px solid #323232;
border: 0.05em solid #323232;
background-color: #323232;
color: #ecf0f1;
}
@@ -49,29 +49,29 @@ QToolTip {
QHeaderView::section {
background-color: #323232;
color: #ecf0f1;
padding-left: 4px;
border: 1px solid #323232;
padding-left: 0.2em;
border: 0.05em solid #323232;
}
/* Settings Dialog: Tabs */
QTabBar::tab {
color: #ecf0f1;
border: 1px solid #444;
border: 0.05em solid #444;
border-bottom-style: none;
background-color: #333333;
padding-left: 16px;
padding-right: 16px;
padding-top: 4px;
padding-bottom: 4px;
margin-right: -2px;
padding-left: 0.9em;
padding-right: 0.9em;
padding-top: 0.2em;
padding-bottom: 0.2em;
margin-right: -0.2em;
}
QTabBar::tab:last {
margin-right: 0px;
margin-right: 0em;
}
QTabBar::tab:!selected {
color: #b1b1b1;
border-bottom-style: solid;
margin-top: 3px;
margin-top: 0.15em;
background-color: #292929;
}
QTabBar::tab:hover {
@@ -81,11 +81,11 @@ QTabBar::tab:hover {
/* Checkboxes */
QCheckBox::indicator {
border-radius: 2px;
border: 1px solid #ecf0f1;
width: 10px;
height: 10px;
margin-top: 1px;
border-radius: 0.1em;
border: 0.05em solid #ecf0f1;
margin-top: 0.05em;
width: 0.8em;
height: 0.8em;
}
QCheckBox::indicator:checked {
background-color: #2ecc71; /* Green */
@@ -99,11 +99,11 @@ QCheckBox::indicator::disabled {
/* Radio Buttons */
QRadioButton::indicator {
border-radius: 6px;
border: 1px solid #ecf0f1;
width: 10px;
height: 10px;
margin-top: 1px;
border-radius: 0.4em;
border: 0.05em solid;
border-color: white;
width: 0.8em;
height: 0.8em;
}
QRadioButton::indicator:checked {
background-color: #2ecc71; /* Green */
@@ -119,10 +119,10 @@ QRadioButton::indicator::disabled {
QComboBox {
background-color: #404040;
color: #fff;
border: 1px solid #1e1e1e;
border-radius: 3px;
padding-bottom: 2px;
padding-left: 4px;
border: 0.05em solid #1e1e1e;
border-radius: 0.15em;
padding-bottom: 0.2em;
padding-left: 0.4em;
}
QComboBox::disabled {
background-color: #828790;
@@ -131,15 +131,15 @@ QComboBox::disabled {
/* Group Boxes (Settings Dialog) */
QGroupBox {
margin-top: 17px;
font-size: 13px;
border: 1px solid #bdc3c7;
border-radius: 4px;
margin-top: 1em;
font-size: 8pt;
border: 0.05em solid #bdc3c7;
border-radius: 0.3em;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top center;
padding: 5px 10px 5px 10px;
subcontrol-position: top;
padding: 0.3em 0.5em 0.3em 0.5em;
color: #fff;
}
@@ -154,19 +154,19 @@ QPushButton::disabled {
/* Log and Debugger borders */
QTextEdit {
border: 1px solid #828790;
border: 0.05em solid #828790;
}
/* For dock buttons to be visible */
QDockWidget::close-button, QDockWidget::float-button {
background-color: #bdc3c7;
border: 1px solid #000;
border-radius: 4px;
border: 0.05em solid #000;
border-radius: 0.3em;
}
/* Disable ugly borders */
QTabWidget::pane {
border: 0px solid #828790;
border: 0em solid #828790;
}
/* Top menu bar */
@@ -174,14 +174,14 @@ QMenuBar::item:selected {
background: #444444;
}
QMenu::item {
padding-left: 20px;
padding-right: 15px;
padding-top: 4px;
padding-bottom: 4px;
padding-left: 1.5em;
padding-right: 0.75em;
padding-top: 0.25em;
padding-bottom: 0.25em;
}
QMenu::item:selected {
background: #444444;
border: 1px solid #bdc3c7;
border: 0.05em solid #bdc3c7;
}
QMenu::item:disabled {
background-color: #444444;
@@ -223,7 +223,7 @@ QLabel#color_button {
/* Seachbar on main toolbar */
QLineEdit#mw_searchbar {
margin-left:14px;
margin-left: 0.7em;
color: #ecf0f1;
}
@@ -246,3 +246,85 @@ QLabel#gamelist_icon_background_color {
QLabel#gamelist_toolbar_icon_color {
background-color: #e3e3e3;
}
/* Set Windows Taskbar Thumbnail colors */
QLabel#thumbnail_icon_color {
color: #444444;
}
/* Set Log colors */
QTextEdit#log_frame {
background-color: #000000; /* Black */
}
QLabel#log_level_always {
color: #00ffff; /* Cyan */
}
QLabel#log_level_fatal {
color: #ff00ff; /* Fuchsia */
}
QLabel#log_level_error {
color: #ff0000; /* Red */
}
QLabel#log_level_todo {
color: #ff6000; /* Orange */
}
QLabel#log_level_success {
color: #00ff00; /* Green */
}
QLabel#log_level_warning {
color: #ffff00; /* Yellow */
}
QLabel#log_level_notice {
color: #ffffff; /* White */
}
QLabel#log_level_trace {
color: #808080; /* Gray */
}
QLabel#log_stack {
color: #ffffff; /* White */
}
/* Set TTY colors */
QTextEdit#tty_frame {
background-color: #000000; /* Black */
}
QLabel#tty_text {
color: #ffffff; /* White */
}
/* RSX Debugger */
QLabel#rsx_debugger_display_buffer {
background-color: #323232;
}
/* Kernel Explorer */
QDialog#kernel_explorer {
background-color: #323232;
}
/* Memory Viewer */
QDialog#memory_viewer {
background-color: #323232;
}
QLabel#memory_viewer_address_panel {
color: #00cbff; /* Font Color: Blue */
background-color: #323232;
}
QLabel#memory_viewer_hex_panel {
color: #bdc3c7; /* Font Color: Grey */
background-color: #323232;
}
QLabel#memory_viewer_ascii_panel {
color: #bdc3c7; /* Font Color: Grey */
background-color: #323232;
}
/* Debugger colors */
QLabel#debugger_frame_breakpoint {
color: #000000; /* Font Color: Black */
background-color: #ffff00; /* Yellow */
}
QLabel#debugger_frame_pc {
color: #000000; /* Font Color: Black */
background-color: #00ff00; /* Green */
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
Submodule llvm updated: a3b2103ffc...4423e35117
+8 -8
View File
@@ -18,12 +18,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -39,30 +39,30 @@
<NMakePreprocessorDefinitions>
</NMakePreprocessorDefinitions>
<NMakeBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
</NMakeCleanCommandLine>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakePreprocessorDefinitions />
<NMakeBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m
</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m
</NMakeCleanCommandLine>
</PropertyGroup>
+1 -1
View File
@@ -32,7 +32,7 @@ Controller.prototype.ComponentSelectionPageCallback = function() {
var widget = gui.currentPageWidget();
widget.deselectAll();
widget.selectComponent("qt.591.gcc_64");
widget.selectComponent("qt.592.gcc_64");
gui.clickButton(buttons.NextButton);
}
+2 -2
View File
@@ -20,14 +20,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
+2 -2
View File
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.13
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjitsrc\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
EndProject
+77 -19
View File
@@ -6,25 +6,31 @@ set(CMAKE_CXX_STANDARD 14)
include(CheckCCompilerFlag)
# Qt section
find_package(Qt5 5.9 COMPONENTS Widgets)
find_package(Qt5 5.7 COMPONENTS Widgets)
if (WIN32)
find_package(Qt5WinExtras REQUIRED)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras)
include_directories(${Qt5Widgets_INCLUDE_DIRS} ${Qt5WinExtras_INCLUDE_DIRS})
else()
set(RPCS3_QT_LIBS Qt5::Widgets)
include_directories(${Qt5Widgets_INCLUDE_DIRS})
find_package(Qt5DBus)
if (Qt5DBus_FOUND)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::DBus)
add_definitions(-DHAVE_QTDBUS)
else()
set(RPCS3_QT_LIBS Qt5::Widgets)
endif()
include_directories(${Qt5Widgets_INCLUDE_DIRS})
endif()
# Let's make sure we have Qt before we continue
if (NOT Qt5Widgets_FOUND)
if (Qt5Widgets_VERSION VERSION_LESS 5.9.0)
message("Minimum supported Qt5 version is 5.9! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
if (Qt5Widgets_VERSION VERSION_LESS 5.7.0)
message("Minimum supported Qt5 version is 5.7! 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 an up-to-date qt5 version.
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt59-xenial
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt59-trusty
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-xenial
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-trusty
just make sure to run
source /opt/qt59/bin/qt59-env.sh
before re-running cmake")
@@ -38,7 +44,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.9\\msvc2017_64\\)")
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.8\\msvc2017_64\\)")
elseif("${CMAKE_SYSTEM}" MATCHES "Linux")
message(FATAL_ERROR "Make sure to install your distro's qt5 package!")
else()
@@ -134,15 +140,17 @@ else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /DYNAMICBASE:NO /BASE:0x10000 /FIXED")
endif()
set(ADDITIONAL_LIBS "")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
#on some Linux distros shm_unlink and similar functions are in librt only
set(ADDITIONAL_LIBS "rt" "X11")
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "rt")
elseif(NOT MSVC AND NOT CMAKE_CXX_FLAGS MATCHES "LIBICONV_PLUG")
#it seems like glibc includes the iconv functions we use but other libc
#implementations like the one on OSX don't seem implement them
set(ADDITIONAL_LIBS "iconv")
else()
set(ADDITIONAL_LIBS "")
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "iconv")
endif()
if(UNIX AND NOT APPLE)
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "X11")
endif()
if(NOT RPCS3_SRC_DIR)
@@ -158,6 +166,29 @@ find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
if (NOT WITHOUT_LLVM)
find_package(LLVM 4.0 CONFIG)
if (NOT LLVM_FOUND)
message("System LLVM was not found, LLVM will be built from the submodule.")
set(LLVM_TARGETS_TO_BUILD "X86" CACHE INTERNAL "")
option(LLVM_BUILD_RUNTIME OFF)
option(LLVM_BUILD_TOOLS OFF)
option(LLVM_INCLUDE_DOCS OFF)
option(LLVM_INCLUDE_EXAMPLES OFF)
option(LLVM_INCLUDE_TESTS OFF)
option(LLVM_INCLUDE_TOOLS OFF)
option(LLVM_INCLUDE_UTILS OFF)
option(WITH_POLLY OFF)
# LLVM needs to be built out-of-tree
add_subdirectory(../llvm ../llvm_build)
set(LLVM_DIR "${CMAKE_CURRENT_BINARY_DIR}/../llvm_build/lib/cmake/llvm/")
# now tries to find LLVM again
find_package(LLVM 4.0 CONFIG)
if (NOT LLVM_FOUND)
message(WARNING "Couldn't build LLVM from the submodule. You might need to run `git submodule update --init`")
endif()
endif()
endif()
@@ -170,6 +201,7 @@ else()
option(USE_ALSA "ALSA audio backend" ON)
option(USE_PULSE "PulseAudio audio backend" ON)
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
option(USE_VULKAN "Vulkan render backend" ON)
endif()
if(USE_ALSA)
@@ -199,6 +231,15 @@ if(USE_LIBEVDEV)
list(APPEND ADDITIONAL_LIBS ${LIBEVDEV_LDFLAGS})
endif()
endif()
if(NOT WIN32 AND USE_VULKAN)
find_package(Vulkan)
if(VULKAN_FOUND)
add_definitions(-DHAVE_VULKAN)
list(APPEND ADDITIONAL_LIBS ${VULKAN_LIBRARY})
else()
message("WARNING! USE_VULKAN was enabled, but libvulkan was not found. RPCS3 will be compiled without Vulkan support.")
endif()
endif()
# Select the version of libpng to use, default is builtin
if(USE_SYSTEM_LIBPNG)
@@ -241,6 +282,7 @@ ${LLVM_INCLUDE_DIRS}
"${RPCS3_SRC_DIR}/../3rdparty/GL"
"${RPCS3_SRC_DIR}/../3rdparty/stblib"
"${RPCS3_SRC_DIR}/../3rdparty/cereal/include"
"${RPCS3_SRC_DIR}/../3rdparty/Optional"
)
if(WIN32)
@@ -255,9 +297,9 @@ else()
add_definitions(${LLVM_DEFINITIONS})
add_definitions(-DLLVM_AVAILABLE)
if (CMAKE_BUILD_TYPE STREQUAL "Release")
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler)
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler)
else()
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
endif()
if (NOT MSVC)
@@ -291,7 +333,7 @@ RPCS3_SRC
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit/*.cpp"
)
if (NOT WIN32 AND "${CMAKE_SYSTEM}" MATCHES "Linux")
if (NOT WIN32 AND VULKAN_FOUND)
# Compile glslang and SPIRV modules needed for glsl compilation
file(
GLOB_RECURSE
@@ -300,7 +342,6 @@ if (NOT WIN32 AND "${CMAKE_SYSTEM}" MATCHES "Linux")
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/MachineIndependent/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/OSDependent/Unix/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/OGLCompilersDLL/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/hlsl/*.cpp"
"${RPCS3_SRC_DIR}/../Vulkan/glslang/SPIRV/*.cpp"
)
@@ -309,8 +350,7 @@ endif()
#File exclusion section
#Ignore vulkan if not on windows or linux
if(NOT WIN32 AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux")
if(NOT WIN32 AND NOT VULKAN_FOUND)
set (EXCLUDE_FILES "/RSX/VK/")
endif()
@@ -353,10 +393,13 @@ else()
if(APPLE)
target_link_libraries(rpcs3 hidapi-mac "-framework CoreFoundation" "-framework IOKit")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(rpcs3 hidapi-hidraw udev vulkan)
target_link_libraries(rpcs3 hidapi-hidraw udev)
else()
target_link_libraries(rpcs3 hidapi-libusb usb)
endif()
if(VULKAN_FOUND)
target_link_libraries(rpcs3 ${VULKAN_LIBRARIES})
endif()
target_link_libraries(rpcs3 ${CMAKE_DL_LIBS} -lpthread ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
if (USE_SYSTEM_FFMPEG)
link_libraries(${FFMPEG_LIBRARY_DIR})
@@ -384,6 +427,21 @@ target_link_libraries(rpcs3 ${RPCS3_QT_LIBS})
set_target_properties(rpcs3 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h")
if (MSVC)
# Under Windows, some QT DLLs need to be in the same directory of the compiled
# RPCS3 binary, so call the windeployqt tool that will take care of copying
# them from the local QT installation at the end of the build.
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations --debug ${CMAKE_BINARY_DIR}/bin
)
else()
add_custom_command(TARGET rpcs3 POST_BUILD
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations ${CMAKE_BINARY_DIR}/bin
)
endif()
endif()
cotire(rpcs3)
# Unix installation
+7 -6
View File
@@ -4,6 +4,7 @@
#include "sha1.h"
#include "key_vault.h"
#include "Utilities/StrFmt.h"
#include "Emu/VFS.h"
#include "unpkg.h"
bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>& sync, const std::string& pkg_filepath)
@@ -120,7 +121,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
u64 cursize = pkg_f.size();
while (cursize != header.pkg_size)
{
std::string archive_filename = fmt::format("%s_%2d.pkg", name_wo_number, filelist.size());
std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, filelist.size());
fs::file archive_file(archive_filename);
if (!archive_file)
@@ -285,7 +286,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : dec_key.data());
const std::string name(reinterpret_cast<char*>(buf.get()), entry.name_size);
std::string name{reinterpret_cast<char*>(buf.get()), entry.name_size};
LOG_NOTICE(LOADER, "Entry 0x%08x: %s", entry.type, name);
@@ -303,17 +304,17 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
case 0x15:
case 0x16:
{
const std::string path = dir + name;
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) == 0)
{
LOG_NOTICE(LOADER, "Didn't overwrite %s", name);
break;
}
if (fs::file out{ path, fs::rewrite })
if (fs::file out{path, fs::rewrite})
{
for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE)
{
@@ -358,7 +359,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
case PKG_FILE_ENTRY_FOLDER:
case 0x12:
{
const std::string path = dir + name;
const std::string path = dir + vfs::escape(name);
if (fs::create_dir(path))
{
+1 -1
View File
@@ -31,7 +31,7 @@
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+6 -4
View File
@@ -50,6 +50,8 @@ OpenALThread::OpenALThread()
{
m_format = g_cfg.audio.convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32;
}
m_buffers = std::make_unique<ALuint[]>(g_cfg.audio.frames);
}
OpenALThread::~OpenALThread()
@@ -83,7 +85,7 @@ void OpenALThread::Close()
if (alIsSource(m_source))
alDeleteSources(1, &m_source);
alDeleteBuffers(g_al_buffers_count, m_buffers);
alDeleteBuffers(g_cfg.audio.frames, m_buffers.get());
checkForAlError("alDeleteBuffers");
}
@@ -98,7 +100,7 @@ void OpenALThread::Open(const void* src, int size)
alGenSources(1, &m_source);
checkForAlError("alGenSources");
alGenBuffers(g_al_buffers_count, m_buffers);
alGenBuffers(g_cfg.audio.frames, m_buffers.get());
checkForAlError("alGenBuffers");
alSourcei(m_source, AL_LOOPING, AL_FALSE);
@@ -106,13 +108,13 @@ void OpenALThread::Open(const void* src, int size)
m_buffer_size = size;
for (uint i = 0; i<g_al_buffers_count; ++i)
for (int i = 0; i < g_cfg.audio.frames; ++i)
{
alBufferData(m_buffers[i], m_format, src, m_buffer_size, 48000);
checkForAlError("alBufferData");
}
alSourceQueueBuffers(m_source, g_al_buffers_count, m_buffers);
alSourceQueueBuffers(m_source, g_cfg.audio.frames, m_buffers.get());
checkForAlError("alSourceQueueBuffers");
Play();
}
+2 -3
View File
@@ -2,15 +2,14 @@
#include "Emu/Audio/AudioThread.h"
#include "3rdparty/OpenAL/include/alext.h"
#include <memory>
class OpenALThread : public AudioThread
{
private:
static const uint g_al_buffers_count = 24;
ALint m_format;
ALuint m_source;
ALuint m_buffers[g_al_buffers_count];
std::unique_ptr<ALuint[]> m_buffers;
ALsizei m_buffer_size;
public:
+1 -1
View File
@@ -59,7 +59,7 @@ ALSAThread::ALSAThread()
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, hw_params, g_cfg.audio.downmix_to_2ch ? 2 : 8), "snd_pcm_hw_params_set_channels"))
return;
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, 8 * 256), "snd_pcm_hw_params_set_buffer_size"))
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, g_cfg.audio.frames * 256), "snd_pcm_hw_params_set_buffer_size"))
return;
if (!check(snd_pcm_hw_params_set_period_size(s_tls_handle, hw_params, 256, 0), "snd_pcm_hw_params_set_period_size"))
+1
View File
@@ -4,6 +4,7 @@
#include "CPUThread.h"
#include "Emu/IdManager.h"
#include "Utilities/GDBDebugServer.h"
#include <typeinfo>
#ifdef _WIN32
#include <Windows.h>
+55 -25
View File
@@ -12,6 +12,34 @@
logs::channel cellAudio("cellAudio");
template <>
void fmt_class_string<CellAudioError>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](CellAudioError value)
{
switch (value)
{
STR_CASE(CELL_AUDIO_ERROR_ALREADY_INIT);
STR_CASE(CELL_AUDIO_ERROR_AUDIOSYSTEM);
STR_CASE(CELL_AUDIO_ERROR_NOT_INIT);
STR_CASE(CELL_AUDIO_ERROR_PARAM);
STR_CASE(CELL_AUDIO_ERROR_PORT_FULL);
STR_CASE(CELL_AUDIO_ERROR_PORT_ALREADY_RUN);
STR_CASE(CELL_AUDIO_ERROR_PORT_NOT_OPEN);
STR_CASE(CELL_AUDIO_ERROR_PORT_NOT_RUN);
STR_CASE(CELL_AUDIO_ERROR_TRANS_EVENT);
STR_CASE(CELL_AUDIO_ERROR_PORT_OPEN);
STR_CASE(CELL_AUDIO_ERROR_SHAREDMEMORY);
STR_CASE(CELL_AUDIO_ERROR_MUTEX);
STR_CASE(CELL_AUDIO_ERROR_EVENT_QUEUE);
STR_CASE(CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND);
STR_CASE(CELL_AUDIO_ERROR_TAG_NOT_FOUND);
}
return unknown;
});
}
void audio_config::on_init(const std::shared_ptr<void>& _this)
{
m_buffer.set(vm::alloc(AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT, vm::main));
@@ -29,6 +57,8 @@ void audio_config::on_init(const std::shared_ptr<void>& _this)
void audio_config::on_task()
{
thread_ctrl::set_native_priority(1);
AudioDumper m_dump(g_cfg.audio.dump_to_file ? 2 : 0); // Init AudioDumper for 2 channels if enabled
float buf2ch[2 * BUFFER_SIZE]{}; // intermediate buffer for 2 channels
@@ -309,12 +339,12 @@ void audio_config::on_task()
case 8: m_dump.WriteData(&buf8ch, sizeof(buf8ch)); break; // write file data (8 ch)
}
cellAudio.trace("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)",
time_pos, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
cellAudio.trace("Audio perf: (access=%d, AddData=%d, events=%d, dump=%d)",
stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
}
}
s32 cellAudioInit()
error_code cellAudioInit()
{
cellAudio.warning("cellAudioInit()");
@@ -329,7 +359,7 @@ s32 cellAudioInit()
return CELL_OK;
}
s32 cellAudioQuit()
error_code cellAudioQuit()
{
cellAudio.warning("cellAudioQuit()");
@@ -344,7 +374,7 @@ s32 cellAudioQuit()
return CELL_OK;
}
s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
{
cellAudio.warning("cellAudioPortOpen(audioParam=*0x%x, portNum=*0x%x)", audioParam, portNum);
@@ -444,7 +474,7 @@ s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portN
return CELL_OK;
}
s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
error_code cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
{
cellAudio.warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig);
@@ -479,7 +509,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
return CELL_OK;
}
s32 cellAudioPortStart(u32 portNum)
error_code cellAudioPortStart(u32 portNum)
{
cellAudio.warning("cellAudioPortStart(portNum=%d)", portNum);
@@ -504,7 +534,7 @@ s32 cellAudioPortStart(u32 portNum)
}
}
s32 cellAudioPortClose(u32 portNum)
error_code cellAudioPortClose(u32 portNum)
{
cellAudio.warning("cellAudioPortClose(portNum=%d)", portNum);
@@ -529,7 +559,7 @@ s32 cellAudioPortClose(u32 portNum)
}
}
s32 cellAudioPortStop(u32 portNum)
error_code cellAudioPortStop(u32 portNum)
{
cellAudio.warning("cellAudioPortStop(portNum=%d)", portNum);
@@ -554,7 +584,7 @@ s32 cellAudioPortStop(u32 portNum)
}
}
s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
error_code cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
{
cellAudio.trace("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp);
@@ -584,7 +614,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
return CELL_OK;
}
s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
error_code cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
{
cellAudio.trace("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag);
@@ -627,7 +657,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
return CELL_OK;
}
s32 cellAudioSetPortLevel(u32 portNum, float level)
error_code cellAudioSetPortLevel(u32 portNum, float level)
{
cellAudio.trace("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level);
@@ -662,7 +692,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level)
return CELL_OK;
}
s32 cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
error_code cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
{
cellAudio.warning("cellAudioCreateNotifyEventQueue(id=*0x%x, key=*0x%x)", id, key);
@@ -693,7 +723,7 @@ s32 cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
s32 cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
error_code cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
{
cellAudio.todo("cellAudioCreateNotifyEventQueueEx(id=*0x%x, key=*0x%x, iFlags=0x%x)", id, key, iFlags);
@@ -707,7 +737,7 @@ s32 cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFl
return CELL_AUDIO_ERROR_EVENT_QUEUE;
}
s32 cellAudioSetNotifyEventQueue(u64 key)
error_code cellAudioSetNotifyEventQueue(u64 key)
{
cellAudio.warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
@@ -733,7 +763,7 @@ s32 cellAudioSetNotifyEventQueue(u64 key)
return CELL_OK;
}
s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
error_code cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
@@ -742,7 +772,7 @@ s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
return CELL_OK;
}
s32 cellAudioRemoveNotifyEventQueue(u64 key)
error_code cellAudioRemoveNotifyEventQueue(u64 key)
{
cellAudio.warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
@@ -768,7 +798,7 @@ s32 cellAudioRemoveNotifyEventQueue(u64 key)
return CELL_AUDIO_ERROR_TRANS_EVENT;
}
s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
error_code cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
@@ -777,7 +807,7 @@ s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
return CELL_OK;
}
s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
error_code cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
{
cellAudio.trace("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
@@ -812,7 +842,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
return CELL_OK;
}
s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
error_code cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
{
cellAudio.trace("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
@@ -881,7 +911,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volu
return CELL_OK;
}
s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
{
cellAudio.trace("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume);
@@ -935,25 +965,25 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
return CELL_OK;
}
s32 cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
error_code cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
{
cellAudio.todo("cellAudioMiscSetAccessoryVolume(devNum=%d, volume=%f)", devNum, volume);
return CELL_OK;
}
s32 cellAudioSendAck(u64 data3)
error_code cellAudioSendAck(u64 data3)
{
cellAudio.todo("cellAudioSendAck(data3=0x%llx)", data3);
return CELL_OK;
}
s32 cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
error_code cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
{
cellAudio.todo("cellAudioSetPersonalDevice(iPersonalStream=%d, iDevice=%d)", iPersonalStream, iDevice);
return CELL_OK;
}
s32 cellAudioUnsetPersonalDevice(s32 iPersonalStream)
error_code cellAudioUnsetPersonalDevice(s32 iPersonalStream)
{
cellAudio.todo("cellAudioUnsetPersonalDevice(iPersonalStream=%d)", iPersonalStream);
return CELL_OK;
+1 -1
View File
@@ -5,7 +5,7 @@
namespace vm { using namespace ps3; }
// Error codes
enum
enum CellAudioError : u32
{
CELL_AUDIO_ERROR_ALREADY_INIT = 0x80310701,
CELL_AUDIO_ERROR_AUDIOSYSTEM = 0x80310702,
+1 -1
View File
@@ -152,7 +152,7 @@ s32 cellVideoOutSetCopyControl(u32 videoOut, u32 control)
DECLARE(ppu_module_manager::cellAvconfExt)("cellSysutilAvconfExt", []()
{
REG_VNID(cellSysutilAvconfExt, 0x00000000u, g_gamma).init = []
REG_VAR(cellSysutilAvconfExt, g_gamma).flag(MFF_HIDDEN).init = []
{
// Test
*g_gamma = 1.0f;
+1 -1
View File
@@ -554,7 +554,7 @@ s32 cellFontExtend(u32 a1, u32 a2, u32 a3)
//Something happens
}
//Something happens?
return -1;
return CELL_OK;
}
s32 cellFontRenderCharGlyphImageVertical()
+8 -8
View File
@@ -1035,22 +1035,22 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
REG_FUNC(sys_fs, cellFsChangeFileSizeWithoutAllocation);
REG_FUNC(sys_fs, cellFsChmod);
REG_FUNC(sys_fs, cellFsChown);
REG_FUNC(sys_fs, cellFsClose).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsClosedir).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsClose).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsClosedir).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsFcntl);
REG_FUNC(sys_fs, cellFsFdatasync);
REG_FUNC(sys_fs, cellFsFGetBlockSize).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsFGetBlockSize).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsFGetBlockSize2);
REG_FUNC(sys_fs, cellFsFstat).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsFsync);
REG_FUNC(sys_fs, cellFsFtruncate).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsFtruncate).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsGetBlockSize);
REG_FUNC(sys_fs, cellFsGetBlockSize2);
REG_FUNC(sys_fs, cellFsGetDirectoryEntries);
REG_FUNC(sys_fs, cellFsGetFreeSize);
REG_FUNC(sys_fs, cellFsGetPath);
REG_FUNC(sys_fs, cellFsLink);
REG_FUNC(sys_fs, cellFsLseek).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsLseek).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsLsnGetCDA);
REG_FUNC(sys_fs, cellFsLsnGetCDASize);
REG_FUNC(sys_fs, cellFsLsnLock);
@@ -1063,8 +1063,8 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
REG_FUNC(sys_fs, cellFsOpen);
REG_FUNC(sys_fs, cellFsOpen2);
REG_FUNC(sys_fs, cellFsOpendir);
REG_FUNC(sys_fs, cellFsRead).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsReaddir).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsRead).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsReaddir).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsReadWithOffset);
REG_FUNC(sys_fs, cellFsRegisterConversionCallback);
REG_FUNC(sys_fs, cellFsRename);
@@ -1095,6 +1095,6 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
REG_FUNC(sys_fs, cellFsUnlink);
REG_FUNC(sys_fs, cellFsUnregisterL10nCallbacks);
REG_FUNC(sys_fs, cellFsUtime);
REG_FUNC(sys_fs, cellFsWrite).flags = MFF_PERFECT;
REG_FUNC(sys_fs, cellFsWrite).flag(MFF_PERFECT);
REG_FUNC(sys_fs, cellFsWriteWithOffset);
});
+10
View File
@@ -659,6 +659,11 @@ error_code cellGameGetParamString(s32 id, vm::ptr<char> buf, u32 bufsize)
{
cellGame.warning("cellGameGetParamString(id=%d, buf=*0x%x, bufsize=%d)", id, buf, bufsize);
if (!buf || bufsize == 0)
{
return CELL_GAME_ERROR_PARAM;
}
const auto prm = fxm::get<content_permission>();
if (!prm)
@@ -685,6 +690,11 @@ error_code cellGameSetParamString(s32 id, vm::cptr<char> buf)
{
cellGame.warning("cellGameSetParamString(id=%d, buf=*0x%x)", id, buf);
if (!buf)
{
return CELL_GAME_ERROR_PARAM;
}
const auto prm = fxm::get<content_permission>();
if (!prm)
+6 -6
View File
@@ -595,7 +595,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
return CELL_GCM_ERROR_INVALID_VALUE;
}
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
{
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
@@ -603,7 +603,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12)))
{
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ENUM");
return CELL_GCM_ERROR_INVALID_ENUM;
}
@@ -1171,7 +1171,7 @@ s32 cellGcmSetDefaultCommandBufferAndSegmentWordSize(u32 bufferSize, u32 segment
const auto& put = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).put;
const auto& get = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).get;
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2)
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2 || segmentSize >= 0x80000000)
{
return CELL_GCM_ERROR_FAILURE;
}
@@ -1220,7 +1220,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
return CELL_GCM_ERROR_INVALID_VALUE;
}
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
{
cellGcmSys.error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ALIGNMENT");
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
@@ -1484,5 +1484,5 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []()
REG_FUNC(cellGcmSys, cellGcmGpadCaptureSnapshot);
// Special
REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN;
});
REG_FUNC(cellGcmSys, cellGcmCallback).flag(MFF_HIDDEN);
});
+61 -51
View File
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Utilities/LUrlParser.h"
#include "cellHttpUtil.h"
@@ -14,50 +15,15 @@ logs::channel cellHttpUtil("cellHttpUtil");
s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<void> pool, u32 size, vm::ptr<u32> required)
{
#ifdef _WIN32
URL_COMPONENTS stUrlComp;
ZeroMemory(&stUrlComp, sizeof(URL_COMPONENTS));
stUrlComp.dwStructSize = sizeof(URL_COMPONENTS);
wchar_t lpszScheme[MAX_PATH] = { 0 };
wchar_t lpszHostName[MAX_PATH] = { 0 };
wchar_t lpszPath[MAX_PATH] = { 0 };
wchar_t lpszUserName[MAX_PATH] = { 0 };
wchar_t lpszPassword[MAX_PATH] = { 0 };
stUrlComp.lpszScheme = lpszScheme;
stUrlComp.dwSchemeLength = MAX_PATH;
stUrlComp.lpszHostName = lpszHostName;
stUrlComp.dwHostNameLength = MAX_PATH;
stUrlComp.lpszUrlPath = lpszPath;
stUrlComp.dwUrlPathLength = MAX_PATH;
stUrlComp.lpszUserName = lpszUserName;
stUrlComp.dwUserNameLength = MAX_PATH;
stUrlComp.lpszPassword = lpszPassword;
stUrlComp.dwPasswordLength = MAX_PATH;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
LPCWSTR stupidTypeUrlString = converter.from_bytes(str.get_ptr()).c_str();
if (!::WinHttpCrackUrl(stupidTypeUrlString, (DWORD)(LONG_PTR)wcslen(stupidTypeUrlString), ICU_ESCAPE, &stUrlComp))
cellHttpUtil.trace("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required);
LUrlParser::clParseURL URL = LUrlParser::clParseURL::ParseURL(str.get_ptr());
if ( URL.IsValid() )
{
cellHttpUtil.error("Error %u in WinHttpCrackUrl.\n", GetLastError());
}
else
{
std::string scheme = converter.to_bytes(lpszScheme);
std::string host = converter.to_bytes(lpszHostName);
std::string path = converter.to_bytes(lpszPath);
std::string username = converter.to_bytes(lpszUserName);
std::string password = converter.to_bytes(lpszPassword);
std::string scheme = URL.m_Scheme;
std::string host = URL.m_Host;
std::string path = URL.m_Path;
std::string username = URL.m_UserName;
std::string password = URL.m_Password;
u32 schemeOffset = 0;
u32 hostOffset = scheme.length() + 1;
@@ -67,10 +33,13 @@ s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<v
u32 totalSize = passwordOffset + password.length() + 1;
//called twice, first to setup pool, then to populate.
if (!uri) {
if (!uri)
{
*required = totalSize;
return CELL_OK;
} else {
}
else
{
std::strncpy((char*)vm::base(pool.addr() + schemeOffset), (char*)scheme.c_str(), scheme.length() + 1);
std::strncpy((char*)vm::base(pool.addr() + hostOffset), (char*)host.c_str(), host.length() + 1);
std::strncpy((char*)vm::base(pool.addr() + pathOffset), (char*)path.c_str(), path.length() + 1);
@@ -82,14 +51,55 @@ s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<v
uri->path.set(pool.addr() + pathOffset);
uri->username.set(pool.addr() + usernameOffset);
uri->password.set(pool.addr() + passwordOffset);
uri->port = stUrlComp.nPort;
if (URL.m_Port != "")
{
int port = stoi(URL.m_Port);
uri->port = port;
}
else
{
uri->port = (u32)80;
}
return CELL_OK;
}
}
#else
cellHttpUtil.todo("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required);
#endif
return CELL_OK;
else
{
std::string parseError;
switch(URL.m_ErrorCode)
{
case LUrlParser::LUrlParserError_Ok:
parseError = "No error, URL was parsed fine";
break;
case LUrlParser::LUrlParserError_Uninitialized:
parseError = "Error, LUrlParser is uninitialized";
break;
case LUrlParser::LUrlParserError_NoUrlCharacter:
parseError = "Error, the URL has invalid characters";
break;
case LUrlParser::LUrlParserError_InvalidSchemeName:
parseError = "Error, the URL has an invalid scheme";
break;
case LUrlParser::LUrlParserError_NoDoubleSlash:
parseError = "Error, the URL did not contain a double slash";
break;
case LUrlParser::LUrlParserError_NoAtSign:
parseError = "Error, the URL did not contain an @ sign";
break;
case LUrlParser::LUrlParserError_UnexpectedEndOfLine:
parseError = "Error, unexpectedly got the end of the line";
break;
case LUrlParser::LUrlParserError_NoSlash:
parseError = "Error, URI didn't contain a slash";
break;
default:
parseError = "Error, unkown error #" + std::to_string(static_cast<int>(URL.m_ErrorCode));
break;
}
cellHttpUtil.error("%s, while parsing URI, %s.", parseError, str.get_ptr());
return -1;
}
}
s32 cellHttpUtilParseUriPath(vm::ptr<CellHttpUriPath> path, vm::cptr<char> str, vm::ptr<void> pool, u32 size, vm::ptr<u32> required)
+9
View File
@@ -177,6 +177,9 @@ error_code cellKbSetCodeType(u32 port_no, u32 type)
if (!handler)
return CELL_KB_ERROR_UNINITIALIZED;
if (port_no >= handler->GetKeyboards().size())
return CELL_KB_ERROR_INVALID_PARAMETER;
KbConfig& current_config = handler->GetConfig(port_no);
current_config.code_type = type;
@@ -197,6 +200,9 @@ error_code cellKbSetReadMode(u32 port_no, u32 rmode)
if (!handler)
return CELL_KB_ERROR_UNINITIALIZED;
if (port_no >= handler->GetKeyboards().size())
return CELL_KB_ERROR_INVALID_PARAMETER;
KbConfig& current_config = handler->GetConfig(port_no);
current_config.read_mode = rmode;
@@ -213,6 +219,9 @@ error_code cellKbGetConfiguration(u32 port_no, vm::ptr<CellKbConfig> config)
if (!handler)
return CELL_KB_ERROR_UNINITIALIZED;
if (port_no >= handler->GetKeyboards().size())
return CELL_KB_ERROR_INVALID_PARAMETER;
const KbConfig& current_config = handler->GetConfig(port_no);
config->arrange = current_config.arrange;
config->read_mode = current_config.read_mode;
+13 -8
View File
@@ -74,7 +74,7 @@ s32 cellMouseGetInfo(vm::ptr<CellMouseInfo> info)
for (u32 i=0; i<CELL_MAX_MICE; i++) info->vendor_id[i] = current_info.vendor_id[i];
for (u32 i=0; i<CELL_MAX_MICE; i++) info->product_id[i] = current_info.product_id[i];
for (u32 i=0; i<CELL_MAX_MICE; i++) info->status[i] = current_info.status[i];
return CELL_OK;
}
@@ -96,7 +96,7 @@ s32 cellMouseInfoTabletMode(u32 port_no, vm::ptr<CellMouseInfoTablet> info)
info->is_supported = 0; // Unimplemented: (0=Tablet mode is not supported)
info->mode = 1; // Unimplemented: (1=Mouse mode)
return CELL_OK;
}
@@ -115,7 +115,7 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
{
return CELL_MOUSE_ERROR_NO_DEVICE;
}
MouseData& current_data = handler->GetData(port_no);
data->update = current_data.update;
data->buttons = current_data.buttons;
@@ -134,22 +134,27 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
s32 cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
{
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
sys_io.todo("cellMouseGetDataList(port_no=%d, data=0x%x", port_no, data);
if (g_cfg.io.mouse == mouse_handler::null)
return CELL_MOUSE_ERROR_NO_DEVICE;
else
{
data->list_num = 0;
return CELL_OK;
}
}
s32 cellMouseSetTabletMode(u32 port_no, u32 mode)
{
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
}
s32 cellMouseGetTabletDataList(u32 port_no, u32 data_addr)
{
UNIMPLEMENTED_FUNC(sys_io);
return CELL_OK;
}
+4
View File
@@ -156,6 +156,10 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
{
strcpy_trunc(info->netmask, "255.255.255.255");
}
else if (code == CELL_NET_CTL_INFO_HTTP_PROXY_CONFIG)
{
info->http_proxy_config = 0;
}
return CELL_OK;
}
+180 -145
View File
@@ -3,7 +3,7 @@
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Io/PadHandler.h"
#include "pad_thread.h"
#include "cellPad.h"
extern logs::channel sys_io;
@@ -12,7 +12,7 @@ s32 cellPadInit(u32 max_connect)
{
sys_io.warning("cellPadInit(max_connect=%d)", max_connect);
const auto handler = fxm::import<PadHandlerBase>(Emu.GetCallbacks().get_pad_handler);
const auto handler = fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler);
if (!handler)
return CELL_PAD_ERROR_ALREADY_INITIALIZED;
@@ -26,7 +26,7 @@ s32 cellPadEnd()
{
sys_io.notice("cellPadEnd()");
if (!fxm::remove<PadHandlerBase>())
if (!fxm::remove<pad_thread>())
return CELL_PAD_ERROR_UNINITIALIZED;
return CELL_OK;
@@ -36,7 +36,7 @@ s32 cellPadClearBuf(u32 port_no)
{
sys_io.trace("cellPadClearBuf(port_no=%d)", port_no);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -51,20 +51,20 @@ s32 cellPadClearBuf(u32 port_no)
//Set 'm_buffer_cleared' to force a resend of everything
//might as well also reset everything in our pad 'buffer' to nothing as well
std::vector<Pad>& pads = handler->GetPads();
Pad& pad = pads[port_no];
auto& pads = handler->GetPads();
auto pad = pads[port_no];
pad.m_buffer_cleared = true;
pad.m_analog_left_x = pad.m_analog_left_y = pad.m_analog_right_x = pad.m_analog_right_y = 128;
pad->m_buffer_cleared = true;
pad->m_analog_left_x = pad->m_analog_left_y = pad->m_analog_right_x = pad->m_analog_right_y = 128;
pad.m_digital_1 = pad.m_digital_2 = 0;
pad.m_press_right = pad.m_press_left = pad.m_press_up = pad.m_press_down = 0;
pad.m_press_triangle = pad.m_press_circle = pad.m_press_cross = pad.m_press_square = 0;
pad.m_press_L1 = pad.m_press_L2 = pad.m_press_R1 = pad.m_press_R2 = 0;
pad->m_digital_1 = pad->m_digital_2 = 0;
pad->m_press_right = pad->m_press_left = pad->m_press_up = pad->m_press_down = 0;
pad->m_press_triangle = pad->m_press_circle = pad->m_press_cross = pad->m_press_square = 0;
pad->m_press_L1 = pad->m_press_L2 = pad->m_press_R1 = pad->m_press_R2 = 0;
//~399 on sensor y is a level non moving controller
pad.m_sensor_y = 399;
pad.m_sensor_x = pad.m_sensor_z = pad.m_sensor_g = 512;
pad->m_sensor_y = 399;
pad->m_sensor_x = pad->m_sensor_z = pad->m_sensor_g = 512;
return CELL_OK;
}
@@ -73,12 +73,12 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
{
sys_io.trace("cellPadGetData(port_no=%d, data=*0x%x)", port_no, data);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
std::vector<Pad>& pads = handler->GetPads();
auto& pads = handler->GetPads();
const PadInfo& rinfo = handler->GetInfo();
@@ -89,39 +89,39 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
Pad& pad = pads[port_no];
auto pad = pads[port_no];
u16 d1Initial, d2Initial;
d1Initial = pad.m_digital_1;
d2Initial = pad.m_digital_2;
d1Initial = pad->m_digital_1;
d2Initial = pad->m_digital_2;
bool btnChanged = false;
for(Button& button : pad.m_buttons)
for(Button& button : pad->m_buttons)
{
//here we check btns, and set pad accordingly,
//if something changed, set btnChanged
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
{
if (button.m_pressed) pad.m_digital_1 |= button.m_outKeyCode;
else pad.m_digital_1 &= ~button.m_outKeyCode;
if (button.m_pressed) pad->m_digital_1 |= button.m_outKeyCode;
else pad->m_digital_1 &= ~button.m_outKeyCode;
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_LEFT:
if (pad.m_press_left != button.m_value) btnChanged = true;
pad.m_press_left = button.m_value;
if (pad->m_press_left != button.m_value) btnChanged = true;
pad->m_press_left = button.m_value;
break;
case CELL_PAD_CTRL_DOWN:
if (pad.m_press_down != button.m_value) btnChanged = true;
pad.m_press_down = button.m_value;
if (pad->m_press_down != button.m_value) btnChanged = true;
pad->m_press_down = button.m_value;
break;
case CELL_PAD_CTRL_RIGHT:
if (pad.m_press_right != button.m_value) btnChanged = true;
pad.m_press_right = button.m_value;
if (pad->m_press_right != button.m_value) btnChanged = true;
pad->m_press_right = button.m_value;
break;
case CELL_PAD_CTRL_UP:
if (pad.m_press_up != button.m_value) btnChanged = true;
pad.m_press_up = button.m_value;
if (pad->m_press_up != button.m_value) btnChanged = true;
pad->m_press_up = button.m_value;
break;
//These arent pressure btns
case CELL_PAD_CTRL_R3:
@@ -133,42 +133,42 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
}
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
{
if (button.m_pressed) pad.m_digital_2 |= button.m_outKeyCode;
else pad.m_digital_2 &= ~button.m_outKeyCode;
if (button.m_pressed) pad->m_digital_2 |= button.m_outKeyCode;
else pad->m_digital_2 &= ~button.m_outKeyCode;
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_SQUARE:
if (pad.m_press_square != button.m_value) btnChanged = true;
pad.m_press_square = button.m_value;
if (pad->m_press_square != button.m_value) btnChanged = true;
pad->m_press_square = button.m_value;
break;
case CELL_PAD_CTRL_CROSS:
if (pad.m_press_cross != button.m_value) btnChanged = true;
pad.m_press_cross = button.m_value;
if (pad->m_press_cross != button.m_value) btnChanged = true;
pad->m_press_cross = button.m_value;
break;
case CELL_PAD_CTRL_CIRCLE:
if (pad.m_press_circle != button.m_value) btnChanged = true;
pad.m_press_circle = button.m_value;
if (pad->m_press_circle != button.m_value) btnChanged = true;
pad->m_press_circle = button.m_value;
break;
case CELL_PAD_CTRL_TRIANGLE:
if (pad.m_press_triangle != button.m_value) btnChanged = true;
pad.m_press_triangle = button.m_value;
if (pad->m_press_triangle != button.m_value) btnChanged = true;
pad->m_press_triangle = button.m_value;
break;
case CELL_PAD_CTRL_R1:
if (pad.m_press_R1 != button.m_value) btnChanged = true;
pad.m_press_R1 = button.m_value;
if (pad->m_press_R1 != button.m_value) btnChanged = true;
pad->m_press_R1 = button.m_value;
break;
case CELL_PAD_CTRL_L1:
if (pad.m_press_L1 != button.m_value) btnChanged = true;
pad.m_press_L1 = button.m_value;
if (pad->m_press_L1 != button.m_value) btnChanged = true;
pad->m_press_L1 = button.m_value;
break;
case CELL_PAD_CTRL_R2:
if (pad.m_press_R2 != button.m_value) btnChanged = true;
pad.m_press_R2 = button.m_value;
if (pad->m_press_R2 != button.m_value) btnChanged = true;
pad->m_press_R2 = button.m_value;
break;
case CELL_PAD_CTRL_L2:
if (pad.m_press_L2 != button.m_value) btnChanged = true;
pad.m_press_L2 = button.m_value;
if (pad->m_press_L2 != button.m_value) btnChanged = true;
pad->m_press_L2 = button.m_value;
break;
default: break;
}
@@ -182,96 +182,131 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
}
}
for (const AnalogStick& stick : pad.m_sticks)
for (const AnalogStick& stick : pad->m_sticks)
{
switch (stick.m_offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
if (pad.m_analog_left_x != stick.m_value) btnChanged = true;
pad.m_analog_left_x = stick.m_value;
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
pad->m_analog_left_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
if (pad.m_analog_left_y != stick.m_value) btnChanged = true;
pad.m_analog_left_y = stick.m_value;
if (pad->m_analog_left_y != stick.m_value) btnChanged = true;
pad->m_analog_left_y = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
if (pad.m_analog_right_x != stick.m_value) btnChanged = true;
pad.m_analog_right_x = stick.m_value;
if (pad->m_analog_right_x != stick.m_value) btnChanged = true;
pad->m_analog_right_x = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
if (pad.m_analog_right_y != stick.m_value) btnChanged = true;
pad.m_analog_right_y = stick.m_value;
if (pad->m_analog_right_y != stick.m_value) btnChanged = true;
pad->m_analog_right_y = stick.m_value;
break;
default: break;
}
}
for (const AnalogSensor& sensor : pad.m_sensors)
for (const AnalogSensor& sensor : pad->m_sensors)
{
switch (sensor.m_offset)
{
case CELL_PAD_BTN_OFFSET_SENSOR_X:
if (pad.m_sensor_x != sensor.m_value) btnChanged = true;
pad.m_sensor_x = sensor.m_value;
if (pad->m_sensor_x != sensor.m_value) btnChanged = true;
pad->m_sensor_x = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_Y:
if (pad.m_sensor_y != sensor.m_value) btnChanged = true;
pad.m_sensor_y = sensor.m_value;
if (pad->m_sensor_y != sensor.m_value) btnChanged = true;
pad->m_sensor_y = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_Z:
if (pad.m_sensor_z != sensor.m_value) btnChanged = true;
pad.m_sensor_z = sensor.m_value;
if (pad->m_sensor_z != sensor.m_value) btnChanged = true;
pad->m_sensor_z = sensor.m_value;
break;
case CELL_PAD_BTN_OFFSET_SENSOR_G:
if (pad.m_sensor_g != sensor.m_value) btnChanged = true;
pad.m_sensor_g = sensor.m_value;
if (pad->m_sensor_g != sensor.m_value) btnChanged = true;
pad->m_sensor_g = sensor.m_value;
break;
default: break;
}
}
if (d1Initial != pad.m_digital_1 || d2Initial != pad.m_digital_2)
if (d1Initial != pad->m_digital_1 || d2Initial != pad->m_digital_2)
{
btnChanged = true;
}
//not sure if this should officially change with capabilities/portsettings :(
data->len = 24;
// the real hardware only fills the buffer up to "len" elements (16 bit each)
if (pad->m_port_setting & CELL_PAD_SETTING_SENSOR_ON)
{
// report back new data every ~10 ms even if the input doesn't change
// this is observed behaviour when using a Dualshock 3 controller
static std::chrono::time_point<steady_clock> last_update[CELL_PAD_MAX_PORT_NUM] = { };
const std::chrono::time_point<steady_clock> now = steady_clock::now();
if (pad.m_buffer_cleared)
{
pad.m_buffer_cleared = false;
if (btnChanged || pad->m_buffer_cleared || (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_update[port_no]).count() >= 10))
{
data->len = CELL_PAD_LEN_CHANGE_SENSOR_ON;
last_update[port_no] = now;
}
else
{
data->len = CELL_PAD_LEN_NO_CHANGE;
}
}
else if (!btnChanged)
else if (btnChanged || pad->m_buffer_cleared)
{
data->len = 0;
// only give back valid data if a controller state changed
data->len = (pad->m_port_setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT;
}
else
{
// report no state changes
data->len = CELL_PAD_LEN_NO_CHANGE;
}
pad->m_buffer_cleared = false;
// only update parts of the output struct depending on the controller setting
if (data->len > CELL_PAD_LEN_NO_CHANGE)
{
memset(data->button, 0, sizeof(data->button));
data->button[0] = 0x0; // always 0
// bits 15-8 reserved, 7-4 = 0x7, 3-0: data->len/2;
data->button[1] = (0x7 << 4) | std::min(data->len / 2, 15);
data->button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad->m_digital_1;
data->button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad->m_digital_2;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad->m_analog_right_x;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = pad->m_analog_right_y;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = pad->m_analog_left_x;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = pad->m_analog_left_y;
data->button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad->m_press_right;
data->button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad->m_press_left;
data->button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad->m_press_up;
data->button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad->m_press_down;
}
if (data->len >= CELL_PAD_LEN_CHANGE_PRESS_ON)
{
data->button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad->m_press_triangle;
data->button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad->m_press_circle;
data->button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad->m_press_cross;
data->button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad->m_press_square;
data->button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad->m_press_L1;
data->button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad->m_press_L2;
data->button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad->m_press_R1;
data->button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad->m_press_R2;
}
if (data->len == CELL_PAD_LEN_CHANGE_SENSOR_ON)
{
data->button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad->m_sensor_x;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad->m_sensor_y;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad->m_sensor_z;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad->m_sensor_g;
}
data->button[0] = 0x0; // always 0
// bits 15-8 reserved, 7-4 = 0x7, 3-0: data->len/2;
data->button[1] = (0x7 << 4) | std::min(data->len / 2, 15);
//lets still send new data anyway, not sure whats expected still
data->button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad.m_digital_1;
data->button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad.m_digital_2;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad.m_analog_right_x;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = pad.m_analog_right_y;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = pad.m_analog_left_x;
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = pad.m_analog_left_y;
data->button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad.m_press_right;
data->button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad.m_press_left;
data->button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad.m_press_up;
data->button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad.m_press_down;
data->button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad.m_press_triangle;
data->button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad.m_press_circle;
data->button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad.m_press_cross;
data->button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad.m_press_square;
data->button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad.m_press_L1;
data->button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad.m_press_L2;
data->button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad.m_press_R1;
data->button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad.m_press_R2;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad.m_sensor_x;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad.m_sensor_y;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad.m_sensor_z;
data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad.m_sensor_g;
return CELL_OK;
}
@@ -280,7 +315,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
{
sys_io.trace("cellPadPeriphGetInfo(info=*0x%x)", info);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -293,7 +328,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
std::vector<Pad>& pads = handler->GetPads();
auto& pads = handler->GetPads();
// TODO: Support other types of controllers
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
@@ -301,10 +336,10 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
if (i >= pads.size())
break;
info->port_status[i] = pads[i].m_port_status;
info->port_setting[i] = pads[i].m_port_setting;
info->device_capability[i] = pads[i].m_device_capability;
info->device_type[i] = pads[i].m_device_type;
info->port_status[i] = pads[i]->m_port_status;
info->port_setting[i] = pads[i]->m_port_setting;
info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;
info->pclass_type[i] = CELL_PAD_PCLASS_TYPE_STANDARD;
info->pclass_profile[i] = 0x0;
}
@@ -315,7 +350,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
s32 cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
{
sys_io.trace("cellPadPeriphGetData(port_no=%d, data=*0x%x)", port_no, data);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -342,7 +377,7 @@ s32 cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<CellPadDa
{
sys_io.trace("cellPadGetDataExtra(port_no=%d, device_type=*0x%x, device_type=*0x%x)", port_no, device_type, data);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -370,7 +405,7 @@ s32 cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
{
sys_io.trace("cellPadSetActDirect(port_no=%d, param=*0x%x)", port_no, param);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -391,7 +426,7 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
{
sys_io.trace("cellPadGetInfo(info=*0x%x)", info);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -403,15 +438,15 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
std::vector<Pad>& pads = handler->GetPads();
auto& pads = handler->GetPads();
for (u32 i=0; i<CELL_MAX_PADS; ++i)
{
if (i >= pads.size())
break;
info->status[i] = pads[i].m_port_status;
pads[i].m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->status[i] = pads[i]->m_port_status;
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->product_id[i] = 0x0268;
info->vendor_id[i] = 0x054C;
}
@@ -423,7 +458,7 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
{
sys_io.trace("cellPadGetInfo2(info=*0x%x)", info);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -435,18 +470,18 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
info->now_connect = rinfo.now_connect;
info->system_info = rinfo.system_info;
std::vector<Pad>& pads = handler->GetPads();
auto& pads = handler->GetPads();
for (u32 i=0; i<CELL_PAD_MAX_PORT_NUM; ++i)
{
if (i >= pads.size())
break;
info->port_status[i] = pads[i].m_port_status;
pads[i].m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = pads[i].m_port_setting;
info->device_capability[i] = pads[i].m_device_capability;
info->device_type[i] = pads[i].m_device_type;
info->port_status[i] = pads[i]->m_port_status;
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
info->port_setting[i] = pads[i]->m_port_setting;
info->device_capability[i] = pads[i]->m_device_capability;
info->device_type[i] = pads[i]->m_device_type;
}
return CELL_OK;
@@ -456,7 +491,7 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
{
sys_io.trace("cellPadGetCapabilityInfo(port_no=%d, data_addr:=0x%x)", port_no, info.addr());
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -468,10 +503,10 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const std::vector<Pad>& pads = handler->GetPads();
const auto& pads = handler->GetPads();
//Should return the same as device capability mask, psl1ght has it backwards in pad.h
info->info[0] = pads[port_no].m_device_capability;
//Should return the same as device capability mask, psl1ght has it backwards in pad->h
info->info[0] = pads[port_no]->m_device_capability;
return CELL_OK;
}
@@ -480,7 +515,7 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
{
sys_io.trace("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -492,8 +527,8 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
std::vector<Pad>& pads = handler->GetPads();
pads[port_no].m_port_setting = port_setting;
auto& pads = handler->GetPads();
pads[port_no]->m_port_setting = port_setting;
return CELL_OK;
}
@@ -502,7 +537,7 @@ s32 cellPadInfoPressMode(u32 port_no)
{
sys_io.trace("cellPadInfoPressMode(port_no=%d)", port_no);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -514,16 +549,16 @@ s32 cellPadInfoPressMode(u32 port_no)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const std::vector<Pad>& pads = handler->GetPads();
const auto& pads = handler->GetPads();
return (pads[port_no].m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
}
s32 cellPadInfoSensorMode(u32 port_no)
{
sys_io.trace("cellPadInfoSensorMode(port_no=%d)", port_no);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -535,16 +570,16 @@ s32 cellPadInfoSensorMode(u32 port_no)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
const std::vector<Pad>& pads = handler->GetPads();
const auto& pads = handler->GetPads();
return (pads[port_no].m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
}
s32 cellPadSetPressMode(u32 port_no, u32 mode)
{
sys_io.trace("cellPadSetPressMode(port_no=%d, mode=%d)", port_no, mode);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -559,12 +594,12 @@ s32 cellPadSetPressMode(u32 port_no, u32 mode)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
std::vector<Pad>& pads = handler->GetPads();
auto& pads = handler->GetPads();
if (mode)
pads[port_no].m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
else
pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
return CELL_OK;
}
@@ -573,7 +608,7 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
{
sys_io.trace("cellPadSetSensorMode(port_no=%d, mode=%d)", port_no, mode);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -588,12 +623,12 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
if (port_no >= rinfo.now_connect)
return CELL_PAD_ERROR_NO_DEVICE;
std::vector<Pad>& pads = handler->GetPads();
auto& pads = handler->GetPads();
if (mode)
pads[port_no].m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
else
pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
return CELL_OK;
}
@@ -602,7 +637,7 @@ s32 cellPadLddRegisterController()
{
sys_io.todo("cellPadLddRegisterController()");
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -614,7 +649,7 @@ s32 cellPadLddDataInsert(s32 handle, vm::ptr<CellPadData> data)
{
sys_io.todo("cellPadLddDataInsert(handle=%d, data=*0x%x)", handle, data);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -626,7 +661,7 @@ s32 cellPadLddGetPortNo(s32 handle)
{
sys_io.todo("cellPadLddGetPortNo(handle=%d)", handle);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
@@ -638,7 +673,7 @@ s32 cellPadLddUnregisterController(s32 handle)
{
sys_io.todo("cellPadLddUnregisterController(handle=%d)", handle);
const auto handler = fxm::get<PadHandlerBase>();
const auto handler = fxm::get<pad_thread>();
if (!handler)
return CELL_PAD_ERROR_UNINITIALIZED;
+9
View File
@@ -27,6 +27,15 @@ enum
CELL_PAD_PCLASS_TYPE_NAVIGATION = 0x05,
};
// Length returned in CellPadData struct
enum
{
CELL_PAD_LEN_NO_CHANGE = 0,
CELL_PAD_LEN_CHANGE_DEFAULT = 8,
CELL_PAD_LEN_CHANGE_PRESS_ON = 20,
CELL_PAD_LEN_CHANGE_SENSOR_ON = 24,
};
struct CellPadData
{
be_t<s32> len;
+3 -3
View File
@@ -1,7 +1,5 @@
#pragma once
#include "sys_net.h"
namespace vm { using namespace ps3; }
// Return Codes
@@ -79,7 +77,9 @@ enum
CELL_RUDP_POLL_EV_ERROR = 0x0008,
};
using CellRudpEventHandler = s32(s32 event_id, s32 soc, vm::cptr<u8> data, u32 datalen, vm::cptr<sys_net::sockaddr> addr, u32 addrlen, vm::ptr<void> arg);
struct sys_net_sockaddr;
using CellRudpEventHandler = s32(s32 event_id, s32 soc, vm::cptr<u8> data, u32 datalen, vm::cptr<sys_net_sockaddr> addr, u32 addrlen, vm::ptr<void> arg);
using CellRudpAllocatorFuncAlloc = vm::ptr<void>(u32 size);
using CellRudpAllocatorFuncFree = void(vm::ptr<void> ptr);
+7 -3
View File
@@ -103,13 +103,15 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" });
// get the saves matching the supplied prefix
for (const auto& entry : fs::dir(base_dir))
for (auto&& entry : fs::dir(base_dir))
{
if (!entry.is_directory)
{
continue;
}
entry.name = vfs::unescape(entry.name);
for (const auto& prefix : prefix_list)
{
if (entry.name.substr(0, prefix.size()) == prefix)
@@ -453,8 +455,10 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
auto file_list = statGet->fileList.get_ptr();
for (const auto& entry : fs::dir(dir_path))
for (auto&& entry : fs::dir(dir_path))
{
entry.name = vfs::unescape(entry.name);
// only files, system files ignored, fileNum is limited by setBuf->fileListMax
if (!entry.is_directory && entry.name != "PARAM.SFO" && statGet->fileListNum++ < setBuf->fileListMax)
{
@@ -1083,7 +1087,7 @@ s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<Cell
void cellSysutil_SaveData_init()
{
REG_VNID(cellSysutil, 0x00000000u, g_savedata_context);
REG_VAR(cellSysutil, g_savedata_context).flag(MFF_HIDDEN);
// libsysutil functions:
REG_FUNC(cellSysutil, cellSaveDataEnableOverlay);
+1 -1
View File
@@ -66,5 +66,5 @@ error_code cellSpudllHandleConfigSetDefaultValues(vm::ptr<CellSpudllHandleConfig
DECLARE(ppu_module_manager::cellSpudll)("cellSpudll", []()
{
REG_FUNC(cellSpudll, cellSpudllGetImageSize);
REG_FUNC(cellSpudll, cellSpudllHandleConfigSetDefaultValues).flags = MFF_PERFECT;
REG_FUNC(cellSpudll, cellSpudllHandleConfigSetDefaultValues).flag(MFF_PERFECT);
});
+71 -4
View File
@@ -1,11 +1,21 @@
#include "stdafx.h"
#include <bitset>
#include <string>
#include "Emu/Cell/PPUModule.h"
#include "Utilities/File.h"
#include "Emu/VFS.h"
logs::channel cellSsl("cellSsl");
s32 cellSslInit()
namespace vm { using namespace ps3; }
enum SpecialCerts { BaltimoreCert = 6, Class3G2V2Cert = 13, ClassSSV4Cert = 15, EntrustNetCert = 18, GTECyberTrustGlobalCert = 23 };
s32 cellSslInit(vm::ptr<void> pool, u32 poolSize)
{
UNIMPLEMENTED_FUNC(cellSsl);
cellSsl.todo("cellSslInit(pool=0x%x, poolSize=%d)", pool, poolSize);
return CELL_OK;
}
@@ -15,9 +25,66 @@ s32 cellSslEnd()
return CELL_OK;
}
s32 cellSslCertificateLoader()
std::string getCert(const std::string certPath, const int certID, const bool isNormalCert)
{
UNIMPLEMENTED_FUNC(cellSsl);
int newID = certID;
// The 'normal' certs have some special rules for loading.
if (isNormalCert && certID >= BaltimoreCert && certID <= GTECyberTrustGlobalCert)
{
if (certID == BaltimoreCert)
newID = GTECyberTrustGlobalCert;
else if (certID == Class3G2V2Cert)
newID = BaltimoreCert;
else if (certID == EntrustNetCert)
newID = ClassSSV4Cert;
else
newID = certID - 1;
}
std::string filePath = fmt::format("%sCA%02d.cer", certPath, newID);
if (!fs::exists(filePath))
{
cellSsl.error("Can't find certificate file %s, do you have the PS3 firmware installed?", filePath);
return "";
}
return fs::file(filePath).to_string();
}
s32 cellSslCertificateLoader(u64 flag, vm::ptr<char> buffer, u32 size, vm::ptr<u32> required)
{
cellSsl.trace("cellSslCertificateLoader(flag=%llu, buffer=0x%x, size=%zu, required=0x%x)", flag, buffer, size, required);
const std::bitset<58> flagBits(flag);
const std::string certPath = vfs::get("/dev_flash/") + "data/cert/";
if (required)
{
*required = 0;
for (int i = 1; i <= flagBits.size(); i++)
{
if (!flagBits[i-1])
continue;
// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
*required += (u32)(getCert(certPath, i, flagBits[BaltimoreCert-1]).size());
}
}
else
{
std::string final;
for (int i = 1; i <= flagBits.size(); i++)
{
if (!flagBits[i-1])
continue;
// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
final.append(getCert(certPath, i, flagBits[BaltimoreCert-1]));
}
memset(buffer.get_ptr(), '\0', size - 1);
memcpy(buffer.get_ptr(), final.c_str(), final.size());
}
return CELL_OK;
}
+5 -8
View File
@@ -100,11 +100,8 @@ void fmt_class_string<CellSysutilLang>::format(std::string& out, u64 arg)
});
}
// For test
enum systemparam_id_name : s32 {};
template <>
void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
void fmt_class_string<CellSysutilParamId>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto value)
{
@@ -133,13 +130,13 @@ void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
});
}
s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
s32 cellSysutilGetSystemParamInt(CellSysutilParamId id, vm::ptr<s32> value)
{
cellSysutil.warning("cellSysutilGetSystemParamInt(id=0x%x(%s), value=*0x%x)", id, id, value);
// TODO: load this information from config (preferably "sys/" group)
switch(id)
switch (id)
{
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG:
*value = g_cfg.sys.language;
@@ -208,13 +205,13 @@ s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
return CELL_OK;
}
s32 cellSysutilGetSystemParamString(systemparam_id_name id, vm::ptr<char> buf, u32 bufsize)
s32 cellSysutilGetSystemParamString(CellSysutilParamId id, vm::ptr<char> buf, u32 bufsize)
{
cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, id, buf, bufsize);
memset(buf.get_ptr(), 0, bufsize);
switch(id)
switch (id)
{
case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME:
memcpy(buf.get_ptr(), "Unknown", 8); // for example
+1 -1
View File
@@ -14,7 +14,7 @@ enum
};
// Parameter IDs
enum
enum CellSysutilParamId: s32
{
// Integers
CELL_SYSUTIL_SYSTEMPARAM_ID_LANG = 0x0111,
+30 -3
View File
@@ -3,6 +3,8 @@
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_sync.h"
#include "Emu/Cell/lv2/sys_ppu_thread.h"
#include "sysPrxForUser.h"
extern "C"
{
@@ -74,11 +76,14 @@ struct vdec_thread : ppu_thread
u32 frc_set{}; // Frame Rate Override
u64 next_pts{};
u64 next_dts{};
u64 ppu_tid{};
std::mutex mutex;
std::queue<vdec_frame> out;
u32 max_frames = 60;
atomic_t<u32> au_count{0};
vdec_thread(s32 type, u32 profile, u32 addr, u32 size, vm::ptr<CellVdecCbMsg> func, u32 arg, u32 prio, u32 stack)
: ppu_thread("HLE Video Decoder", prio, stack)
, type(type)
@@ -351,6 +356,11 @@ struct vdec_thread : ppu_thread
cb_func(*this, id, vcmd == vdec_cmd::decode ? CELL_VDEC_MSG_TYPE_AUDONE : CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, cb_arg);
lv2_obj::sleep(*this);
}
if (vcmd == vdec_cmd::decode)
{
au_count--;
}
while (std::lock_guard<std::mutex>{mutex}, max_frames && out.size() > max_frames)
{
@@ -397,7 +407,7 @@ u32 vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0 */, vm::ptr<C
attr->decoderVerLower = 0x280000; // from dmux
attr->decoderVerUpper = 0x260000;
attr->memSize = 4 * 1024 * 1024; // 4 MB
attr->cmdDepth = 16;
attr->cmdDepth = 4;
return CELL_OK;
}
@@ -415,7 +425,7 @@ s32 cellVdecQueryAttrEx(vm::cptr<CellVdecTypeEx> type, vm::ptr<CellVdecAttr> att
return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr);
}
s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
s32 cellVdecOpen(ppu_thread& ppu, vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
{
cellVdec.warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
@@ -425,12 +435,17 @@ s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm
// Hack: store thread id (normally it should be pointer)
*handle = vdec->id;
vm::var<u64> _tid;
CALL_FUNC(ppu, sys_ppu_thread_create, ppu, +_tid, 1148, 0, 900, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, vm::null);
vdec->gpr[13] = idm::get<ppu_thread>(*_tid)->gpr[13];
vdec->ppu_tid = *_tid;
vdec->run();
return CELL_OK;
}
s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
s32 cellVdecOpenEx(ppu_thread& ppu, vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> res, vm::cptr<CellVdecCb> cb, vm::ptr<u32> handle)
{
cellVdec.warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
@@ -440,6 +455,11 @@ s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> r
// Hack: store thread id (normally it should be pointer)
*handle = vdec->id;
vm::var<u64> _tid;
CALL_FUNC(ppu, sys_ppu_thread_create, ppu, +_tid, 1148, 0, 900, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, vm::null);
vdec->gpr[13] = idm::get<ppu_thread>(*_tid)->gpr[13];
vdec->ppu_tid = *_tid;
vdec->run();
return CELL_OK;
@@ -467,6 +487,8 @@ s32 cellVdecClose(ppu_thread& ppu, u32 handle)
vdec->notify();
vdec->join();
idm::remove<ppu_thread>(handle);
CALL_FUNC(ppu, sys_interrupt_thread_disestablish, ppu, vdec->ppu_tid);
return CELL_OK;
}
@@ -513,6 +535,11 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInf
return CELL_VDEC_ERROR_ARG;
}
if (vdec->au_count.fetch_op([](u32& c) { if (c < 4) c++; }) >= 4)
{
return CELL_VDEC_ERROR_BUSY;
}
// TODO: check info
vdec->cmd_list
({
+1 -1
View File
@@ -256,7 +256,7 @@ s32 cellVideoOutUnregisterCallback(u32 slot)
void cellSysutil_VideoOut_init()
{
REG_FUNC(cellSysutil, cellVideoOutGetState);
REG_FUNC(cellSysutil, cellVideoOutGetResolution).flags = MFF_PERFECT;
REG_FUNC(cellSysutil, cellVideoOutGetResolution).flag(MFF_PERFECT);
REG_FUNC(cellSysutil, cellVideoOutConfigure);
REG_FUNC(cellSysutil, cellVideoOutGetConfiguration);
REG_FUNC(cellSysutil, cellVideoOutGetDeviceInfo);
+27 -34
View File
@@ -1,13 +1,14 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "sysPrxForUser.h"
#include "Emu/IdManager.h"
#include "Crypto/unedat.h"
#include "Crypto/unself.h"
#include "cellRtc.h"
#include "sceNp.h"
#include "cellSysutil.h"
logs::channel sceNp("sceNp");
@@ -43,7 +44,15 @@ s32 sceNpTerm()
s32 npDrmIsAvailable(vm::cptr<u8> k_licensee_addr, vm::cptr<char> drm_path)
{
const std::string& enc_drm_path = drm_path.get_ptr();
std::array<u8, 0x10> k_licensee{};
if (k_licensee_addr)
{
std::copy_n(k_licensee_addr.get_ptr(), k_licensee.size(), k_licensee.begin());
sceNp.notice("npDrmIsAvailable(): KLicense key %s", *reinterpret_cast<be_t<v128, 1>*>(k_licensee.data()));
}
const std::string enc_drm_path = drm_path.get_ptr();
if (!fs::is_file(vfs::get(enc_drm_path)))
{
@@ -51,20 +60,6 @@ s32 npDrmIsAvailable(vm::cptr<u8> k_licensee_addr, vm::cptr<char> drm_path)
return CELL_ENOENT;
}
std::string k_licensee_str = "";
std::array<u8, 0x10> k_licensee{0};
if (k_licensee_addr)
{
for (s8 i = 0; i < 0x10; i++)
{
k_licensee[i] = *(k_licensee_addr + i);
k_licensee_str += fmt::format("%02x", k_licensee[i]);
}
sceNp.notice("npDrmIsAvailable(): KLicense key %s", k_licensee_str);
}
auto npdrmkeys = fxm::get_always<LoadedNpdrmKeys_t>();
npdrmkeys->devKlic.fill(0);
@@ -184,27 +179,29 @@ s32 sceNpDrmGetTimelimit(vm::cptr<char> path, vm::ptr<u64> time_remain)
return CELL_OK;
}
s32 sceNpDrmProcessExitSpawn(vm::cptr<u8> klicensee, vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
s32 sceNpDrmProcessExitSpawn(ppu_thread& ppu, vm::cptr<u8> klicensee, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
{
sceNp.warning("sceNpDrmProcessExitSpawn() -> sys_game_process_exitspawn");
sceNp.warning("sceNpDrmProcessExitSpawn(klicensee=*0x%x, path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", klicensee, path, argv, envp, data, data_size, prio, flags);
sceNp.warning("klicensee: 0x%x", klicensee);
npDrmIsAvailable(klicensee, path);
sys_game_process_exitspawn(path, argv_addr, envp_addr, data_addr, data_size, prio, flags);
if (s32 error = npDrmIsAvailable(klicensee, path))
{
return error;
}
sys_game_process_exitspawn(ppu, path, argv, envp, data, data_size, prio, flags);
return CELL_OK;
}
s32 sceNpDrmProcessExitSpawn2(vm::cptr<u8> klicensee, vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
s32 sceNpDrmProcessExitSpawn2(ppu_thread& ppu, vm::cptr<u8> klicensee, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
{
sceNp.warning("sceNpDrmProcessExitSpawn2() -> sys_game_process_exitspawn2");
sceNp.warning("sceNpDrmProcessExitSpawn2(klicensee=*0x%x, path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", klicensee, path, argv, envp, data, data_size, prio, flags);
sceNp.warning("klicensee: 0x%x", klicensee);
npDrmIsAvailable(klicensee, path);
sys_game_process_exitspawn2(path, argv_addr, envp_addr, data_addr, data_size, prio, flags);
if (s32 error = npDrmIsAvailable(klicensee, path))
{
return error;
}
sys_game_process_exitspawn2(ppu, path, argv, envp, data, data_size, prio, flags);
return CELL_OK;
}
@@ -905,16 +902,12 @@ s32 sceNpLookupTitleSmallStorageAsync()
s32 sceNpManagerRegisterCallback(vm::ptr<SceNpManagerCallback> callback, vm::ptr<void> arg)
{
sceNp.todo("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg);
sceNp.warning("sceNpManagerRegisterCallback(callback=*0x%x, arg=*0x%x)", callback, arg);
if (!callback)
{
return SCE_NP_ERROR_INVALID_ARGUMENT;
}
else
{
return SCE_NP_ERROR_NOT_INITIALIZED;
}
return CELL_OK;
}
+2 -1
View File
@@ -147,7 +147,8 @@ s32 sceNpSnsFbCheckThrottle()
s32 sceNpSnsFbCheckConfig()
{
fmt::throw_exception("Unimplemented" HERE);
sceNpSns.todo("sceNpSnsFbCheckConfig()");
return CELL_OK;
}
s32 sceNpSnsFbLoadThrottle()
+82 -28
View File
@@ -16,6 +16,10 @@
logs::channel sceNpTrophy("sceNpTrophy");
TrophyNotificationBase::~TrophyNotificationBase()
{
}
struct trophy_context_t
{
static const u32 id_base = 1;
@@ -181,9 +185,8 @@ error_code sceNpTrophyCreateContext(vm::ptr<u32> context, vm::cptr<SceNpCommunic
sceNpTrophy.warning("sceNpTrophyCreateContext term=%s data=%s num=%d", commId->term, commId->data, commId->num);
if (commId->term)
{
char trimchar[9];
memcpy(trimchar, commId->data, sizeof(trimchar));
trimchar[8] = 0;
char trimchar[10] = { 0 };
memcpy(trimchar, commId->data, sizeof(trimchar) - 1);
deleteTerminateChar(trimchar, commId->term);
name = fmt::format("%s_%02d", trimchar, commId->num);
}
@@ -265,7 +268,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle,
const size_t kTargetBufferLength = 31;
char target[kTargetBufferLength + 1];
target[kTargetBufferLength] = 0;
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", /*rpcs3::config.system.language.value()*/0));
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", static_cast<s32>(g_cfg.sys.language)));
if (trp.ContainsEntry(target))
{
@@ -287,7 +290,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle,
for (s32 i = 0; i <= 18; i++)
{
strcpy_trunc(target, fmt::format("TROP_%02d.SFM", i));
if (i != /*rpcs3::config.system.language.value()*/0)
if (i != g_cfg.sys.language)
{
trp.RemoveEntry(target);
}
@@ -398,12 +401,15 @@ error_code sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGa
}
// TODO: Get the path of the current user
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM");
fs::file config(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));
if (!config)
{
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
}
// TODO: rXmlDocument can open only real file
verify(HERE), !fs::get_virtual_device(path);
rXmlDocument doc;
doc.Load(path);
doc.Read(config.to_string());
for (std::shared_ptr<rXmlNode> n = doc.GetRoot()->GetChildren(); n; n = n->GetNext())
{
@@ -474,7 +480,7 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
}
if (trophyId >= (s32)ctxt->tropusr->GetTrophiesCount())
if (trophyId < 0 || trophyId >= (s32)ctxt->tropusr->GetTrophiesCount())
return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID;
if (ctxt->tropusr->GetTrophyUnlockState(trophyId))
return SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED;
@@ -483,7 +489,45 @@ error_code sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::pt
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPUSR.DAT";
ctxt->tropusr->Save(trophyPath);
*platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
if (platinumId)
{
*platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
}
if (g_cfg.misc.show_trophy_popups)
{
// Figure out how many zeros are needed for padding. (either 0, 1, or 2)
std::string padding = "";
if (trophyId < 10)
{
padding = "00";
}
else if (trophyId < 100)
{
padding = "0";
}
// Get icon for the notification.
std::string trophyIconPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROP" + padding + std::to_string(trophyId) + ".PNG";
fs::file trophyIconFile = fs::file(vfs::get(trophyIconPath));
u32 iconSize = trophyIconFile.size();
std::vector<uchar> trophyIconData;
trophyIconFile.read(trophyIconData, iconSize);
vm::ptr<SceNpTrophyDetails> details = vm::make_var(SceNpTrophyDetails());
vm::ptr<SceNpTrophyData> _ = vm::make_var(SceNpTrophyData());
s32 ret = sceNpTrophyGetTrophyInfo(context, handle, trophyId, details, _);
if (ret != CELL_OK)
{
sceNpTrophy.error("Failed to get info for trophy dialog. Error code %x", ret);
*details = SceNpTrophyDetails();
}
Emu.CallAfter([det = *details, trophyIconData]() {
Emu.GetCallbacks().get_trophy_notification_dialog()->ShowTrophyNotification(det, trophyIconData);
});
}
return CELL_OK;
}
@@ -551,15 +595,25 @@ error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::p
}
// TODO: Get the path of the current user
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM");
fs::file config(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"));
if (!config)
{
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
}
// TODO: rXmlDocument can open only real file
verify(HERE), !fs::get_virtual_device(path);
rXmlDocument doc;
doc.Load(path);
doc.Read(config.to_string());
auto trophy_base = doc.GetRoot();
if (trophy_base->GetChildren()->GetName() == "trophyconf")
{
trophy_base = trophy_base->GetChildren();
}
bool found = false;
for (std::shared_ptr<rXmlNode> n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) {
for (std::shared_ptr<rXmlNode> n = trophy_base->GetChildren(); n; n = n->GetNext())
{
if (n->GetName() == "trophy" && (trophyId == atoi(n->GetAttribute("id").c_str())))
{
found = true;
@@ -676,21 +730,21 @@ error_code sceNpTrophyGetGameIcon(u32 context, u32 handle, vm::ptr<void> buffer,
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
}
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/ICON0.PNG");
fs::file icon_file(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/ICON0.PNG"));
if (!fs::exists(path))
if (!icon_file)
{
return SCE_NP_TROPHY_ERROR_UNKNOWN_FILE;
}
fs::file gameIconFile(path);
const u32 icon_size = ::size32(icon_file);
if (buffer && *size >= gameIconFile.size())
if (buffer && *size >= icon_size)
{
gameIconFile.read(buffer.get_ptr(), gameIconFile.size());
icon_file.read(buffer.get_ptr(), icon_size);
}
*size = gameIconFile.size();
*size = icon_size;
return CELL_OK;
}
@@ -729,21 +783,21 @@ error_code sceNpTrophyGetTrophyIcon(u32 context, u32 handle, s32 trophyId, vm::p
return hidden ? SCE_NP_TROPHY_ERROR_HIDDEN : SCE_NP_TROPHY_ERROR_LOCKED;
}
const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + fmt::format("/TROP%03d.PNG", trophyId));
fs::file icon_file(vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + fmt::format("/TROP%03d.PNG", trophyId)));
if (!fs::exists(path))
if (!icon_file)
{
return SCE_NP_TROPHY_ERROR_UNKNOWN_FILE;
}
fs::file trophyIconFile(path);
const u32 icon_size = ::size32(icon_file);
if (buffer && *size >= trophyIconFile.size())
if (buffer && *size >= icon_size)
{
trophyIconFile.read(buffer.get_ptr(), trophyIconFile.size());
icon_file.read(buffer.get_ptr(), icon_size);
}
*size = trophyIconFile.size();
*size = icon_size;
return CELL_OK;
}
+11
View File
@@ -137,3 +137,14 @@ enum
};
using SceNpTrophyStatusCallback = s32(u32 context, u32 status, s32 completed, s32 total, vm::ptr<void> arg);
// Forward declare this function since trophyunlock needs it
error_code sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceNpTrophyDetails> details, vm::ptr<SceNpTrophyData> data);
class TrophyNotificationBase
{
public:
virtual ~TrophyNotificationBase();
virtual s32 ShowTrophyNotification(const SceNpTrophyDetails& trophy, const std::vector<uchar>& trophyIconBfr) = 0;
};
+41 -20
View File
@@ -2,8 +2,10 @@
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_mutex.h"
#include "Emu/Cell/lv2/sys_interrupt.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "Emu/Cell/lv2/sys_ss.h"
#include "sysPrxForUser.h"
logs::channel sysPrxForUser("sysPrxForUser");
@@ -13,6 +15,9 @@ extern u64 get_system_time();
extern fs::file g_tty;
vm::gvar<s32> sys_prx_version; // ???
vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
extern vm::gvar<u32> g_ppu_exit_mutex;
s64 sys_time_get_system_time()
{
@@ -21,16 +26,34 @@ s64 sys_time_get_system_time()
return get_system_time();
}
s64 _sys_process_atexitspawn()
void sys_process_exit(ppu_thread& ppu, s32 status)
{
sysPrxForUser.todo("_sys_process_atexitspawn()");
return CELL_OK;
sysPrxForUser.warning("sys_process_exit(status=%d)", status);
sys_mutex_lock(ppu, *g_ppu_exit_mutex, 0);
// TODO (process atexit)
return _sys_process_exit(ppu, status, 0, 0);
}
s64 _sys_process_at_Exitspawn()
void _sys_process_atexitspawn(vm::ptr<void()> func)
{
sysPrxForUser.todo("_sys_process_at_Exitspawn");
return CELL_OK;
sysPrxForUser.warning("_sys_process_atexitspawn(0x%x)", func);
if (!*g_ppu_atexitspawn)
{
*g_ppu_atexitspawn = func;
}
}
void _sys_process_at_Exitspawn(vm::ptr<void()> func)
{
sysPrxForUser.warning("_sys_process_at_Exitspawn(0x%x)", func);
if (!*g_ppu_at_Exitspawn)
{
*g_ppu_at_Exitspawn = func;
}
}
s32 sys_process_is_stack(u32 p)
@@ -49,24 +72,23 @@ s32 sys_process_get_paramsfo(vm::ptr<char> buffer)
return _sys_process_get_paramsfo(buffer);
}
s32 sys_get_random_number(vm::ptr<u8> addr, u64 size)
s32 sys_get_random_number(vm::ptr<void> addr, u64 size)
{
sysPrxForUser.warning("sys_get_random_number(addr=*0x%x, size=%d)", addr, size);
if (size > 4096)
size = 4096;
for (u32 i = 0; i < (u32)size - 1; i++)
if (size > 0x1000)
{
addr[i] = rand() % 256;
return CELL_EINVAL;
}
return CELL_OK;
}
switch (u32 rs = sys_ss_random_number_generator(2, addr, size))
{
case 0x80010501: return CELL_ENOMEM;
case 0x80010503: return CELL_EAGAIN;
case 0x80010509: return CELL_EINVAL;
default: if (rs) return CELL_EABORT;
}
s32 __sys_look_ctype_table()
{
UNIMPLEMENTED_FUNC(sysPrxForUser);
return CELL_OK;
}
@@ -231,10 +253,11 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
sysPrxForUser_sys_rsxaudio_init();
REG_VAR(sysPrxForUser, sys_prx_version); // 0x7df066cf
REG_VAR(sysPrxForUser, g_ppu_atexitspawn).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_at_Exitspawn).flag(MFF_HIDDEN);
REG_FUNC(sysPrxForUser, sys_time_get_system_time);
// TODO: split syscalls and liblv2 functions
REG_FUNC(sysPrxForUser, sys_process_exit);
REG_FUNC(sysPrxForUser, _sys_process_atexitspawn);
REG_FUNC(sysPrxForUser, _sys_process_at_Exitspawn);
@@ -243,8 +266,6 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
REG_FUNC(sysPrxForUser, sys_get_random_number);
REG_FUNC(sysPrxForUser, __sys_look_ctype_table);
REG_FUNC(sysPrxForUser, console_getc);
REG_FUNC(sysPrxForUser, console_putc);
REG_FUNC(sysPrxForUser, console_write);
+5
View File
@@ -52,4 +52,9 @@ error_code sys_lwcond_signal_all(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond);
error_code sys_lwcond_signal_to(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id);
error_code sys_lwcond_wait(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout);
error_code sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::cptr<char> threadname);
error_code sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih);
void sys_ppu_thread_exit(ppu_thread& CPU, u64 val);
void sys_game_process_exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
void sys_game_process_exitspawn2(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags);
+122 -117
View File
@@ -2,148 +2,153 @@
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_mutex.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "sysPrxForUser.h"
extern logs::channel sysPrxForUser;
extern vm::gvar<u32> g_ppu_exit_mutex;
extern vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
extern vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
void sys_game_process_exitspawn(vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
static u32 get_string_array_size(vm::cpptr<char> list, u32& out_count)
{
std::string _path = path.get_ptr();
const std::string& from = "//";
const std::string& to = "/";
//out_count = 0;
u32 result = 8;
size_t start_pos = 0;
while ((start_pos = _path.find(from, start_pos)) != std::string::npos) {
_path.replace(start_pos, from.length(), to);
start_pos += to.length();
for (u32 i = 0; list; i++)
{
if (const vm::cptr<char> str = list[i])
{
out_count++;
result += (((u32)std::strlen(str.get_ptr()) + 0x10) & -0x10) + 8;
continue;
}
break;
}
sysPrxForUser.todo("sys_game_process_exitspawn()");
sysPrxForUser.warning("path: %s", _path.c_str());
sysPrxForUser.warning("argv: 0x%x", argv_addr);
sysPrxForUser.warning("envp: 0x%x", envp_addr);
sysPrxForUser.warning("data: 0x%x", data_addr);
sysPrxForUser.warning("data_size: 0x%x", data_size);
sysPrxForUser.warning("prio: %d", prio);
sysPrxForUser.warning("flags: %d", flags);
std::vector<std::string> argv;
std::vector<std::string> env;
if (argv_addr)
{
auto argvp = vm::cpptr<char>::make(argv_addr);
while (argvp && *argvp)
{
argv.push_back(argvp[0].get_ptr());
argvp++;
}
for (auto &arg : argv)
{
sysPrxForUser.trace("argument: %s", arg.c_str());
}
}
if (envp_addr)
{
auto envp = vm::cpptr<char>::make(envp_addr);
while (envp && *envp)
{
env.push_back(envp[0].get_ptr());
envp++;
}
for (auto &en : env)
{
sysPrxForUser.trace("env_argument: %s", en.c_str());
}
}
// TODO: execute the file in <path> with the args in argv
// and the environment parameters in envp and copy the data
// from data_addr into the adress space of the new process
// then kill the current process
Emu.Pause();
sysPrxForUser.success("Process finished");
Emu.CallAfter([=, path = vfs::get(_path)]()
{
Emu.Stop();
Emu.BootGame(path, true);
});
return result;
}
void sys_game_process_exitspawn2(vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags)
static u32 get_exitspawn_size(vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32& arg_count, u32& env_count)
{
std::string _path = path.get_ptr();
const std::string& from = "//";
const std::string& to = "/";
arg_count = 1;
env_count = 0;
size_t start_pos = 0;
while ((start_pos = _path.find(from, start_pos)) != std::string::npos) {
_path.replace(start_pos, from.length(), to);
start_pos += to.length();
u32 result = (((u32)std::strlen(path.get_ptr()) + 0x10) & -0x10) + 8;
result += get_string_array_size(argv, arg_count);
result += get_string_array_size(envp, env_count);
if ((arg_count + env_count) % 2)
{
result += 8;
}
return result;
}
static void put_string_array(vm::pptr<char, u32, u64> pstr, vm::ptr<char>& str, u32 count, vm::cpptr<char> list)
{
for (u32 i = 0; i < count; i++)
{
const u32 len = (u32)std::strlen(list[i].get_ptr());
std::memcpy(str.get_ptr(), list[i].get_ptr(), len + 1);
pstr[i] = str;
str += (len + 0x10) & -0x10;
}
sysPrxForUser.warning("sys_game_process_exitspawn2()");
sysPrxForUser.warning("path: %s", _path.c_str());
sysPrxForUser.warning("argv: 0x%x", argv_addr);
sysPrxForUser.warning("envp: 0x%x", envp_addr);
sysPrxForUser.warning("data: 0x%x", data_addr);
sysPrxForUser.warning("data_size: 0x%x", data_size);
sysPrxForUser.warning("prio: %d", prio);
sysPrxForUser.warning("flags: %d", flags);
pstr[count] = vm::null;
}
std::vector<std::string> argv;
std::vector<std::string> env;
static void put_exitspawn(vm::ptr<void> out, vm::cptr<char> path, u32 argc, vm::cpptr<char> argv, u32 envc, vm::cpptr<char> envp)
{
vm::pptr<char, u32, u64> pstr = vm::cast(out.addr());
vm::ptr<char> str = vm::static_ptr_cast<char>(out) + (argc + envc + (argc + envc) % 2) * 8 + 0x10;
if (argv_addr)
const u32 len = (u32)std::strlen(path.get_ptr());
std::memcpy(str.get_ptr(), path.get_ptr(), len + 1);
*pstr++ = str;
str += (len + 0x10) & -0x10;
put_string_array(pstr, str, argc - 1, argv);
put_string_array(pstr + argc, str, envc, envp);
}
static void exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 _flags)
{
sys_mutex_lock(ppu, *g_ppu_exit_mutex, 0);
u32 arg_count = 0;
u32 env_count = 0;
u32 alloc_size = get_exitspawn_size(path, argv, envp, arg_count, env_count);
if (alloc_size > 0x1000)
{
auto argvp = vm::cpptr<char>::make(argv_addr);
while (argvp && *argvp)
{
argv.push_back(argvp[0].get_ptr());
argvp++;
}
for (auto &arg : argv)
{
sysPrxForUser.trace("argument: %s", arg.c_str());
}
argv = vm::null;
envp = vm::null;
arg_count = 0;
env_count = 0;
alloc_size = get_exitspawn_size(path, vm::null, vm::null, arg_count, env_count);
}
if (envp_addr)
{
auto envp = vm::cpptr<char>::make(envp_addr);
while (envp && *envp)
{
env.push_back(envp[0].get_ptr());
envp++;
}
alloc_size += 0x30;
for (auto &en : env)
{
sysPrxForUser.trace("env_argument: %s", en.c_str());
}
if (data_size > 0)
{
alloc_size += 0x1030;
}
// TODO: execute the file in <path> with the args in argv
// and the environment parameters in envp and copy the data
// from data_addr into the adress space of the new process
// then kill the current process
u32 alloc_addr = vm::alloc(alloc_size, vm::main);
Emu.Pause();
sysPrxForUser.success("Process finished");
Emu.CallAfter([=, path = vfs::get(_path)]()
if (!alloc_addr)
{
Emu.Stop();
Emu.BootGame(path, true);
});
// TODO (process atexit)
return _sys_process_exit(ppu, CELL_ENOMEM, 0, 0);
}
return;
put_exitspawn(vm::cast(alloc_addr + 0x30), path, arg_count, argv, env_count, envp);
if (data_size)
{
std::memcpy(vm::base(alloc_addr + alloc_size - 0x1000), vm::base(data), std::min<u32>(data_size, 0x1000));
}
vm::ptr<sys_exit2_param> arg = vm::cast(alloc_addr);
arg->x0 = 0x85;
arg->this_size = 0x30;
arg->next_size = alloc_size - 0x30;
arg->prio = prio;
arg->flags = _flags;
arg->args = vm::cast(alloc_addr + 0x30);
if ((_flags >> 62) == 0 && *g_ppu_atexitspawn)
{
// Execute atexitspawn
g_ppu_atexitspawn->operator()(ppu);
}
if ((_flags >> 62) == 1 && *g_ppu_at_Exitspawn)
{
// Execute at_Exitspawn
g_ppu_at_Exitspawn->operator()(ppu);
}
// TODO (process atexit)
return _sys_process_exit2(ppu, 0, arg, alloc_size, 0x10000000);
}
void sys_game_process_exitspawn(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
{
sysPrxForUser.warning("sys_game_process_exitspawn(path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", path, argv, envp, data, data_size, prio, flags);
return exitspawn(ppu, path, argv, envp, data, data_size, prio, (flags & 0xf0) | (1ull << 63));
}
void sys_game_process_exitspawn2(ppu_thread& ppu, vm::cptr<char> path, vm::cpptr<char> argv, vm::cpptr<char> envp, u32 data, u32 data_size, s32 prio, u64 flags)
{
sysPrxForUser.warning("sys_game_process_exitspawn2(path=%s, argv=**0x%x, envp=**0x%x, data=*0x%x, data_size=0x%x, prio=%d, flags=0x%x)", path, argv, envp, data, data_size, prio, flags);
return exitspawn(ppu, path, argv, envp, data, data_size, prio, (flags >> 62) >= 2 ? flags & 0xf0 : flags & 0xc0000000000000f0ull);
}
s32 sys_game_board_storage_read()
+1 -1
View File
@@ -16,5 +16,5 @@ void sys_libc_memcpy(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
DECLARE(ppu_module_manager::sys_libc)("sys_libc", []()
{
REG_FNID(sys_libc, "memcpy", sys_libc_memcpy).flags = MFF_FORCED_HLE;
REG_FNID(sys_libc, "memcpy", sys_libc_memcpy).flag(MFF_FORCED_HLE);
});
+184 -43
View File
@@ -72,6 +72,51 @@ static std::string ps3_fmt(ppu_thread& context, vm::cptr<char> fmt, u32 g_count)
return result;
}
static const std::array<s16, 129> s_ctype_table
{
0,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x408,
8, 8, 8, 8,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x18,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0x10, 0x10, 0x10, 0x10, 0x20,
};
s16 __sys_look_ctype_table(s32 ch)
{
sysPrxForUser.trace("__sys_look_ctype_table(ch=%d)", ch);
verify("__sys_look_ctype_table" HERE), ch >= -1 && ch <= 127;
return s_ctype_table[ch + 1];
}
s32 _sys_tolower(s32 ch)
{
sysPrxForUser.trace("_sys_tolower(ch=%d)", ch);
verify("_sys_tolower" HERE), ch >= -1 && ch <= 127;
return s_ctype_table[ch + 1] & 1 ? ch + 0x20 : ch;
}
s32 _sys_toupper(s32 ch)
{
sysPrxForUser.trace("_sys_toupper(ch=%d)", ch);
verify("_sys_toupper" HERE), ch >= -1 && ch <= 127;
return s_ctype_table[ch + 1] & 2 ? ch - 0x20 : ch;
}
vm::ptr<void> _sys_memset(vm::ptr<void> dst, s32 value, u32 size)
{
sysPrxForUser.trace("_sys_memset(dst=*0x%x, value=%d, size=0x%x)", dst, value, size);
@@ -90,11 +135,26 @@ vm::ptr<void> _sys_memcpy(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
return dst;
}
s32 _sys_memcmp(vm::cptr<void> buf1, vm::cptr<void> buf2, u32 size)
s32 _sys_memcmp(vm::cptr<u8> buf1, vm::cptr<u8> buf2, u32 size)
{
sysPrxForUser.trace("_sys_memcmp(buf1=*0x%x, buf2=*0x%x, size=%d)", buf1, buf2, size);
return std::memcmp(buf1.get_ptr(), buf2.get_ptr(), size);
for (u32 i = 0; i < size; i++)
{
const u8 b1 = buf1[i], b2 = buf2[i];
if (b1 < b2)
{
return -1;
}
if (b1 > b2)
{
return 1;
}
}
return 0;
}
vm::ptr<u8> _sys_memchr(vm::ptr<u8> buf, u8 ch, s32 size)
@@ -129,82 +189,160 @@ vm::ptr<void> _sys_memmove(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
return dst;
}
s64 _sys_strlen(vm::cptr<char> str)
u32 _sys_strlen(vm::cptr<char> str)
{
sysPrxForUser.trace("_sys_strlen(str=%s)", str);
return std::strlen(str.get_ptr());
if (!str)
{
return 0;
}
for (u32 i = 0;; i++)
{
if (str[i] == '\0')
{
return i;
}
}
}
s32 _sys_strcmp(vm::cptr<char> str1, vm::cptr<char> str2)
{
sysPrxForUser.trace("_sys_strcmp(str1=%s, str2=%s)", str1, str2);
return std::strcmp(str1.get_ptr(), str2.get_ptr());
for (u32 i = 0;; i++)
{
const u8 ch1 = str1[i], ch2 = str2[i];
if (ch1 < ch2)
return -1;
if (ch1 > ch2)
return 1;
if (ch1 == '\0')
return 0;
}
}
s32 _sys_strncmp(vm::cptr<char> str1, vm::cptr<char> str2, s32 max)
s32 _sys_strncmp(vm::cptr<char> str1, vm::cptr<char> str2, u32 max)
{
sysPrxForUser.trace("_sys_strncmp(str1=%s, str2=%s, max=%d)", str1, str2, max);
return std::strncmp(str1.get_ptr(), str2.get_ptr(), max);
for (u32 i = 0; i < max; i++)
{
const u8 ch1 = str1[i], ch2 = str2[i];
if (ch1 < ch2)
return -1;
if (ch1 > ch2)
return 1;
if (ch1 == '\0')
break;
}
return 0;
}
vm::ptr<char> _sys_strcat(vm::ptr<char> dest, vm::cptr<char> source)
vm::ptr<char> _sys_strcat(vm::ptr<char> dst, vm::cptr<char> src)
{
sysPrxForUser.trace("_sys_strcat(dest=*0x%x, source=%s)", dest, source);
sysPrxForUser.trace("_sys_strcat(dst=*0x%x %s, src=%s)", dst, dst, src);
verify(HERE), std::strcat(dest.get_ptr(), source.get_ptr()) == dest.get_ptr();
auto str = dst;
return dest;
while (*str)
{
str++;
}
for (u32 i = 0;; i++)
{
if (!(str[i] = src[i]))
{
return dst;
}
}
}
vm::cptr<char> _sys_strchr(vm::cptr<char> str, s32 ch)
vm::cptr<char> _sys_strchr(vm::cptr<char> str, char ch)
{
sysPrxForUser.trace("_sys_strchr(str=%s, ch=0x%x)", str, ch);
sysPrxForUser.trace("_sys_strchr(str=%s, ch=%d)", str, ch);
return vm::cptr<char>::make(vm::get_addr(strchr(str.get_ptr(), ch)));
for (u32 i = 0;; i++)
{
const char ch1 = str[i];
if (ch1 == ch)
return str + i;
if (ch1 == '\0')
return vm::null;
}
}
vm::ptr<char> _sys_strncat(vm::ptr<char> dest, vm::cptr<char> source, u32 len)
vm::ptr<char> _sys_strncat(vm::ptr<char> dst, vm::cptr<char> src, u32 max)
{
sysPrxForUser.trace("_sys_strncat(dest=*0x%x, source=%s, len=%d)", dest, source, len);
sysPrxForUser.trace("_sys_strncat(dst=*0x%x %s, src=%s, max=%u)", dst, dst, src, max);
verify(HERE), std::strncat(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr();
auto str = dst;
return dest;
while (*str)
{
str++;
}
for (u32 i = 0; i < max; i++)
{
if (!(str[i] = src[i]))
{
return dst;
}
}
str[max] = '\0';
return dst;
}
vm::ptr<char> _sys_strcpy(vm::ptr<char> dest, vm::cptr<char> source)
vm::ptr<char> _sys_strcpy(vm::ptr<char> dst, vm::cptr<char> src)
{
sysPrxForUser.trace("_sys_strcpy(dest=*0x%x, source=%s)", dest, source);
sysPrxForUser.trace("_sys_strcpy(dst=*0x%x, src=%s)", dst, src);
verify(HERE), std::strcpy(dest.get_ptr(), source.get_ptr()) == dest.get_ptr();
return dest;
for (u32 i = 0;; i++)
{
if (!(dst[i] = src[i]))
{
return dst;
}
}
}
vm::ptr<char> _sys_strncpy(vm::ptr<char> dest, vm::cptr<char> source, u32 len)
vm::ptr<char> _sys_strncpy(vm::ptr<char> dst, vm::cptr<char> src, s32 len)
{
sysPrxForUser.trace("_sys_strncpy(dest=*0x%x, source=%s, len=%d)", dest, source, len);
sysPrxForUser.trace("_sys_strncpy(dst=*0x%x %s, src=%s, len=%d)", dst, dst, src, len);
if (!dest || !source)
if (!dst || !src)
{
return vm::null;
}
verify(HERE), std::strncpy(dest.get_ptr(), source.get_ptr(), len) == dest.get_ptr();
for (s32 i = 0; i < len; i++)
{
if (!(dst[i] = src[i]))
{
for (++i; i < len; i++)
{
dst[i] = '\0';
}
return dest;
return dst;
}
}
return dst;
}
s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, s32 n)
s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, u32 n)
{
sysPrxForUser.trace("_sys_strncasecmp(str1=%s, str2=%s, n=%d)", str1, str2, n);
for (u32 i = 0; i < n; i++)
{
const int ch1 = tolower(str1[i]), ch2 = tolower(str2[i]);
const int ch1 = _sys_tolower(str1[i]), ch2 = _sys_tolower(str2[i]);
if (ch1 < ch2)
return -1;
if (ch1 > ch2)
@@ -215,21 +353,22 @@ s32 _sys_strncasecmp(vm::cptr<char> str1, vm::cptr<char> str2, s32 n)
return 0;
}
vm::ptr<char> _sys_strrchr(vm::cptr<char> str, s32 character)
vm::cptr<char> _sys_strrchr(vm::cptr<char> str, char ch)
{
sysPrxForUser.trace("_sys_strrchr(str=%s, character=%c)", str, (char)character);
sysPrxForUser.trace("_sys_strrchr(str=%s, ch=%d)", str, ch);
return vm::ptr<char>::make(vm::get_addr(strrchr(str.get_ptr(), character)));
}
vm::cptr<char> res = vm::null;
s32 _sys_tolower()
{
fmt::throw_exception("Unimplemented" HERE);
}
for (u32 i = 0;; i++)
{
const char ch1 = str[i];
if (ch1 == ch)
res = str + i;
if (ch1 == '\0')
break;
}
s32 _sys_toupper()
{
fmt::throw_exception("Unimplemented" HERE);
return res;
}
u32 _sys_malloc(u32 size)
@@ -320,6 +459,10 @@ s32 _sys_qsort()
void sysPrxForUser_sys_libc_init()
{
REG_FUNC(sysPrxForUser, __sys_look_ctype_table);
REG_FUNC(sysPrxForUser, _sys_tolower);
REG_FUNC(sysPrxForUser, _sys_toupper);
REG_FUNC(sysPrxForUser, _sys_memset);
REG_FUNC(sysPrxForUser, _sys_memcpy);
REG_FUNC(sysPrxForUser, _sys_memcmp);
@@ -336,8 +479,6 @@ void sysPrxForUser_sys_libc_init()
REG_FUNC(sysPrxForUser, _sys_strncpy);
REG_FUNC(sysPrxForUser, _sys_strncasecmp);
REG_FUNC(sysPrxForUser, _sys_strrchr);
REG_FUNC(sysPrxForUser, _sys_tolower);
REG_FUNC(sysPrxForUser, _sys_toupper);
REG_FUNC(sysPrxForUser, _sys_malloc);
REG_FUNC(sysPrxForUser, _sys_memalign);
File diff suppressed because it is too large Load Diff
-245
View File
@@ -1,245 +0,0 @@
#if defined(__FreeBSD__)
#include <sys/select.h>
#undef fds_bits
#endif
#pragma once
namespace vm { using namespace ps3; }
namespace sys_net
{
// It turns out SOL_SOCKET is equal to 1 on Linux, but 0xffff on Windows, and it appears the PS3 uses 0xffff, like Windows
#define PS3_SOL_SOCKET 0xffff
// Error codes
enum
{
SYS_NET_ENOENT = 2,
SYS_NET_EINTR = 4,
SYS_NET_EBADF = 9,
SYS_NET_ENOMEM = 12,
SYS_NET_EACCES = 13,
SYS_NET_EFAULT = 14,
SYS_NET_EBUSY = 16,
SYS_NET_EINVAL = 22,
SYS_NET_EMFILE = 24,
SYS_NET_ENOSPC = 28,
SYS_NET_EPIPE = 32,
SYS_NET_EAGAIN = 35,
SYS_NET_EWOULDBLOCK = SYS_NET_EAGAIN,
SYS_NET_EINPROGRESS = 36,
SYS_NET_EALREADY = 37,
SYS_NET_EDESTADDRREQ = 39,
SYS_NET_EMSGSIZE = 40,
SYS_NET_EPROTOTYPE = 41,
SYS_NET_ENOPROTOOPT = 42,
SYS_NET_EPROTONOSUPPORT = 43,
SYS_NET_EOPNOTSUPP = 45,
SYS_NET_EPFNOSUPPORT = 46,
SYS_NET_EAFNOSUPPORT = 47,
SYS_NET_EADDRINUSE = 48,
SYS_NET_EADDRNOTAVAIL = 49,
SYS_NET_ENETDOWN = 50,
SYS_NET_ENETUNREACH = 51,
SYS_NET_ECONNABORTED = 53,
SYS_NET_ECONNRESET = 54,
SYS_NET_ENOBUFS = 55,
SYS_NET_EISCONN = 56,
SYS_NET_ENOTCONN = 57,
SYS_NET_ESHUTDOWN = 58,
SYS_NET_ETOOMANYREFS = 59,
SYS_NET_ETIMEDOUT = 60,
SYS_NET_ECONNREFUSED = 61,
SYS_NET_EHOSTDOWN = 64,
SYS_NET_EHOSTUNREACH = 65,
};
// Socket types
enum
{
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_DGRAM_P2P = 6,
SOCK_STREAM_P2P = 10,
};
// Socket options
// Note: All options are prefixed with "OP_" to prevent name conflicts.
enum
{
OP_SO_SNDBUF = 0x1001,
OP_SO_RCVBUF = 0x1002,
OP_SO_SNDLOWAT = 0x1003,
OP_SO_RCVLOWAT = 0x1004,
OP_SO_SNDTIMEO = 0x1005,
OP_SO_RCVTIMEO = 0x1006,
OP_SO_ERROR = 0x1007,
OP_SO_TYPE = 0x1008,
OP_SO_NBIO = 0x1100, // Non-blocking IO
OP_SO_TPPOLICY = 0x1101,
OP_SO_REUSEADDR = 0x0004,
OP_SO_KEEPALIVE = 0x0008,
OP_SO_BROADCAST = 0x0020,
OP_SO_LINGER = 0x0080,
OP_SO_OOBINLINE = 0x0100,
OP_SO_REUSEPORT = 0x0200,
OP_SO_ONESBCAST = 0x0800,
OP_SO_USECRYPTO = 0x1000,
OP_SO_USESIGNATURE = 0x2000,
};
// TCP options
enum
{
OP_TCP_NODELAY = 1,
OP_TCP_MAXSEG = 2,
OP_TCP_MSS_TO_ADVERTISE = 3,
};
// IP protocols
// Note: Proctols are prefixed with "PROTO_" to prevent name conflicts
enum
{
PROTO_IPPROTO_IP = 0,
PROTO_IPPROTO_ICMP = 1,
PROTO_IPPROTO_IGMP = 2,
PROTO_IPPROTO_TCP = 6,
PROTO_IPPROTO_UDP = 17,
PROTO_IPPROTO_ICMPV6 = 58,
};
// only for reference, no need to use it
using in_addr_t = u32;
using in_port_t = u16;
using sa_family_t = u8;
using socklen_t = u32;
struct fd_set
{
be_t<u32> fds_bits[32];
};
struct hostent
{
vm::bptr<char> h_name;
vm::bpptr<char> h_aliases;
be_t<s32> h_addrtype;
be_t<s32> h_length;
vm::bpptr<char> h_addr_list;
};
struct in_addr
{
be_t<u32> s_addr;
};
struct iovec
{
be_t<s32> zero1;
vm::bptr<void> iov_base;
be_t<s32> zero2;
be_t<u32> iov_len;
};
struct ip_mreq
{
be_t<u32> imr_multiaddr;
be_t<u32> imr_interface;
};
struct msghdr
{
be_t<s32> zero1;
vm::bptr<void> msg_name;
be_t<u32> msg_namelen;
be_t<s32> pad1;
be_t<s32> zero2;
vm::bptr<iovec> msg_iov;
be_t<s32> msg_iovlen;
be_t<s32> pad2;
be_t<s32> zero3;
vm::bptr<void> msg_control;
be_t<u32> msg_controllen;
be_t<s32> msg_flags;
};
struct pollfd
{
be_t<s32> fd;
be_t<s16> events;
be_t<s16> revents;
};
struct sockaddr
{
u8 sa_len;
u8 sa_family;
char sa_data[14];
};
struct sockaddr_dl
{
u8 sdl_len;
u8 sdl_family;
be_t<u16> sdl_index;
u8 sdl_type;
u8 sdl_nlen;
u8 sdl_alen;
u8 sdl_slen;
char sdl_data[12];
};
struct sockaddr_in
{
u8 sin_len;
u8 sin_family;
be_t<u16> sin_port;
be_t<u32> sin_addr;
char sin_zero[8];
};
struct sockaddr_in_p2p
{
u8 sin_len;
u8 sin_family;
be_t<u16> sin_port;
be_t<u32> sin_addr;
be_t<u16> sin_vport;
char sin_zero[6];
};
struct timeval
{
be_t<s64> tv_sec;
be_t<s64> tv_usec;
};
struct sys_net_sockinfo_t
{
be_t<s32> s;
be_t<s32> proto;
be_t<s32> recv_queue_length;
be_t<s32> send_queue_length;
in_addr local_adr;
be_t<s32> local_port;
in_addr remote_adr;
be_t<s32> remote_port;
be_t<s32> state;
};
}
struct sys_net_initialize_parameter_t
{
vm::bptr<void> memory;
be_t<s32> memory_size;
be_t<s32> flags;
};
// PS3 libnet socket struct
struct net_socket_t
{
std::intptr_t native_handle;
};
+737
View File
@@ -0,0 +1,737 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/IdManager.h"
#include "sys_net_.h"
namespace vm { using namespace ps3; }
logs::channel libnet("libnet");
struct sys_net_tls_data
{
be_t<s32> _errno;
be_t<s32> _h_errno;
char addr[16];
};
// TODO
thread_local vm::ptr<sys_net_tls_data> g_tls_net_data{};
static NEVER_INLINE vm::ptr<sys_net_tls_data> get_tls()
{
// Allocate if not initialized
if (!g_tls_net_data)
{
g_tls_net_data.set(vm::alloc(sizeof(decltype(g_tls_net_data)::type), vm::main));
// Initial values
g_tls_net_data->_errno = SYS_NET_EBUSY;
thread_ctrl::atexit([addr = g_tls_net_data.addr()]
{
vm::dealloc_verbose_nothrow(addr, vm::main);
});
}
return g_tls_net_data;
}
s32 sys_net_accept(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
{
libnet.todo("accept(s=%d, addr=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen);
return 0;
}
s32 sys_net_bind(s32 s, vm::cptr<sys_net_sockaddr> addr, u32 addrlen)
{
libnet.todo("bind(s=%d, addr=*0x%x, addrlen=%u)", s, addr, addrlen);
return 0;
}
s32 sys_net_connect(s32 s, vm::ptr<sys_net_sockaddr> addr, u32 addrlen)
{
libnet.todo("connect(s=%d, addr=*0x%x, addrlen=%u)", s, addr, addrlen);
return 0;
}
s32 sys_net_gethostbyaddr()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_gethostbyname()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_getpeername(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_getsockname(s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_getsockopt(s32 s, s32 level, s32 optname, vm::ptr<void> optval, vm::ptr<u32> optlen)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
u32 sys_net_inet_addr(vm::cptr<char> cp)
{
libnet.todo("inet_addr(cp=%s)", cp);
return 0xffffffff;
}
s32 sys_net_inet_aton()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_inet_lnaof()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_inet_makeaddr()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_inet_netof()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_inet_network()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
vm::ptr<char> sys_net_inet_ntoa(u32 in)
{
libnet.todo("inet_ntoa(in=0x%x)", in);
return vm::null;
}
vm::cptr<char> sys_net_inet_ntop(s32 af, vm::ptr<void> src, vm::ptr<char> dst, u32 size)
{
libnet.todo("inet_ntop(af=%d, src=%s, dst=*0x%x, size=%d)", af, src, dst, size);
return vm::null;
}
s32 sys_net_inet_pton(s32 af, vm::cptr<char> src, vm::ptr<char> dst)
{
libnet.todo("inet_pton(af=%d, src=%s, dst=*0x%x)", af, src, dst);
return 0;
}
s32 sys_net_listen(s32 s, s32 backlog)
{
libnet.todo("listen(s=%d, backlog=%d)", s, backlog);
return 0;
}
s32 sys_net_recv(s32 s, vm::ptr<void> buf, u32 len, s32 flags)
{
libnet.todo("recv(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
return 0;
}
s32 sys_net_recvfrom(s32 s, vm::ptr<void> buf, u32 len, s32 flags, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
{
libnet.todo("recvfrom(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, paddrlen=*0x%x)", s, buf, len, flags, addr, paddrlen);
return 0;
}
s32 sys_net_recvmsg(s32 s, vm::ptr<sys_net_msghdr> msg, s32 flags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_send(s32 s, vm::cptr<void> buf, u32 len, s32 flags)
{
libnet.todo("send(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags);
return 0;
}
s32 sys_net_sendmsg(s32 s, vm::cptr<sys_net_msghdr> msg, s32 flags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_sendto(s32 s, vm::cptr<void> buf, u32 len, s32 flags, vm::cptr<sys_net_sockaddr> addr, u32 addrlen)
{
libnet.todo("sendto(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, addrlen=%d)", s, buf, len, flags, addr, addrlen);
return 0;
}
s32 sys_net_setsockopt(s32 s, s32 level, s32 optname, vm::cptr<void> optval, u32 optlen)
{
libnet.todo("setsockopt(s=%d, level=%d, optname=%d, optval=*0x%x, optlen=%d)", s, level, optname, optval, optlen);
return 0;
}
s32 sys_net_shutdown(s32 s, s32 how)
{
libnet.todo("shutdown(s=%d, how=%d)", s, how);
return 0;
}
s32 sys_net_socket(s32 family, s32 type, s32 protocol)
{
libnet.todo("socket(family=%d, type=%d, protocol=%d)", family, type, protocol);
return 0;
}
s32 sys_net_socketclose(s32 s)
{
libnet.warning("socketclose(s=%d)", s);
return 0;
}
s32 sys_net_socketpoll(vm::ptr<sys_net_pollfd> fds, s32 nfds, s32 ms)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_socketselect(s32 nfds, vm::ptr<sys_net_fd_set> readfds, vm::ptr<sys_net_fd_set> writefds, vm::ptr<sys_net_fd_set> exceptfds, vm::ptr<sys_net_timeval> timeout)
{
libnet.todo("socketselect(nfds=%d, readfds=*0x%x, writefds=*0x%x, exceptfds=*0x%x, timeout=*0x%x)", nfds, readfds, writefds, exceptfds, timeout);
return 0;
}
s32 sys_net_initialize_network_ex(vm::ptr<sys_net_initialize_parameter_t> param)
{
libnet.todo("sys_net_initialize_network_ex(param=*0x%x)", param);
return CELL_OK;
}
s32 sys_net_get_udpp2p_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_set_udpp2p_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_lib_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_if_ctl()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_if_list()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_netemu_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_routing_table_af()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_sockinfo(s32 s, vm::ptr<sys_net_sockinfo_t> p, s32 n)
{
libnet.todo("sys_net_get_sockinfo(s=%d, p=*0x%x, n=%d)", s, p, n);
return CELL_OK;
}
s32 sys_net_close_dump(s32 id, vm::ptr<s32> pflags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_set_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_show_nameserver()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
vm::ptr<s32> _sys_net_errno_loc()
{
libnet.warning("_sys_net_errno_loc()");
return get_tls().ptr(&sys_net_tls_data::_errno);
}
s32 sys_net_set_resolver_configurations()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_show_route()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_read_dump(s32 id, vm::ptr<void> buf, s32 len, vm::ptr<s32> pflags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_abort_resolver()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_abort_socket()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_set_lib_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_get_sockinfo_ex()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_open_dump(s32 len, s32 flags)
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_show_ifconfig()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_finalize_network()
{
libnet.todo("sys_net_finalize_network()");
return CELL_OK;
}
vm::ptr<s32> _sys_net_h_errno_loc()
{
libnet.warning("_sys_net_h_errno_loc()");
return get_tls().ptr(&sys_net_tls_data::_h_errno);
}
s32 sys_net_set_netemu_test_param()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_net_free_thread_context(u64 tid, s32 flags)
{
libnet.todo("sys_net_free_thread_context(tid=0x%x, flags=%d)", tid, flags);
return CELL_OK;
}
s32 _sys_net_lib_abort()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_bnet_control()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 __sys_net_lib_calloc()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_free()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_get_system_time()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_if_nametoindex()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_ioctl()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 __sys_net_lib_malloc()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_rand()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 __sys_net_lib_realloc()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_reset_libnetctl_queue()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_set_libnetctl_queue()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_thread_create()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_thread_exit()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_thread_join()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_clear()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_create()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_destroy()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_signal()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sync_wait()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_sysctl()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sys_net_lib_usleep()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_abort()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_close()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_get_if_id()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_get_status()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_if_down()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_get_key_value()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_if_up()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 sys_netset_open()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_get_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_add_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_add_name_server_with_char()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_flush_route()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_set_default_gateway()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_set_ip_and_mask()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
s32 _sce_net_set_name_server()
{
UNIMPLEMENTED_FUNC(libnet);
return CELL_OK;
}
DECLARE(ppu_module_manager::sys_net)("sys_net", []()
{
REG_FNID(sys_net, "accept", sys_net_accept);
REG_FNID(sys_net, "bind", sys_net_bind);
REG_FNID(sys_net, "connect", sys_net_connect);
REG_FNID(sys_net, "gethostbyaddr", sys_net_gethostbyaddr);
REG_FNID(sys_net, "gethostbyname", sys_net_gethostbyname);
REG_FNID(sys_net, "getpeername", sys_net_getpeername);
REG_FNID(sys_net, "getsockname", sys_net_getsockname);
REG_FNID(sys_net, "getsockopt", sys_net_getsockopt);
REG_FNID(sys_net, "inet_addr", sys_net_inet_addr);
REG_FNID(sys_net, "inet_aton", sys_net_inet_aton);
REG_FNID(sys_net, "inet_lnaof", sys_net_inet_lnaof);
REG_FNID(sys_net, "inet_makeaddr", sys_net_inet_makeaddr);
REG_FNID(sys_net, "inet_netof", sys_net_inet_netof);
REG_FNID(sys_net, "inet_network", sys_net_inet_network);
REG_FNID(sys_net, "inet_ntoa", sys_net_inet_ntoa);
REG_FNID(sys_net, "inet_ntop", sys_net_inet_ntop);
REG_FNID(sys_net, "inet_pton", sys_net_inet_pton);
REG_FNID(sys_net, "listen", sys_net_listen);
REG_FNID(sys_net, "recv", sys_net_recv);
REG_FNID(sys_net, "recvfrom", sys_net_recvfrom);
REG_FNID(sys_net, "recvmsg", sys_net_recvmsg);
REG_FNID(sys_net, "send", sys_net_send);
REG_FNID(sys_net, "sendmsg", sys_net_sendmsg);
REG_FNID(sys_net, "sendto", sys_net_sendto);
REG_FNID(sys_net, "setsockopt", sys_net_setsockopt);
REG_FNID(sys_net, "shutdown", sys_net_shutdown);
REG_FNID(sys_net, "socket", sys_net_socket);
REG_FNID(sys_net, "socketclose", sys_net_socketclose);
REG_FNID(sys_net, "socketpoll", sys_net_socketpoll);
REG_FNID(sys_net, "socketselect", sys_net_socketselect);
REG_FUNC(sys_net, sys_net_initialize_network_ex);
REG_FUNC(sys_net, sys_net_get_udpp2p_test_param);
REG_FUNC(sys_net, sys_net_set_udpp2p_test_param);
REG_FUNC(sys_net, sys_net_get_lib_name_server);
REG_FUNC(sys_net, sys_net_if_ctl);
REG_FUNC(sys_net, sys_net_get_if_list);
REG_FUNC(sys_net, sys_net_get_name_server);
REG_FUNC(sys_net, sys_net_get_netemu_test_param);
REG_FUNC(sys_net, sys_net_get_routing_table_af);
REG_FUNC(sys_net, sys_net_get_sockinfo);
REG_FUNC(sys_net, sys_net_close_dump);
REG_FUNC(sys_net, sys_net_set_test_param);
REG_FUNC(sys_net, sys_net_show_nameserver);
REG_FUNC(sys_net, _sys_net_errno_loc);
REG_FUNC(sys_net, sys_net_set_resolver_configurations);
REG_FUNC(sys_net, sys_net_show_route);
REG_FUNC(sys_net, sys_net_read_dump);
REG_FUNC(sys_net, sys_net_abort_resolver);
REG_FUNC(sys_net, sys_net_abort_socket);
REG_FUNC(sys_net, sys_net_set_lib_name_server);
REG_FUNC(sys_net, sys_net_get_test_param);
REG_FUNC(sys_net, sys_net_get_sockinfo_ex);
REG_FUNC(sys_net, sys_net_open_dump);
REG_FUNC(sys_net, sys_net_show_ifconfig);
REG_FUNC(sys_net, sys_net_finalize_network);
REG_FUNC(sys_net, _sys_net_h_errno_loc);
REG_FUNC(sys_net, sys_net_set_netemu_test_param);
REG_FUNC(sys_net, sys_net_free_thread_context);
REG_FUNC(sys_net, _sys_net_lib_abort);
REG_FUNC(sys_net, _sys_net_lib_bnet_control);
REG_FUNC(sys_net, __sys_net_lib_calloc);
REG_FUNC(sys_net, _sys_net_lib_free);
REG_FUNC(sys_net, _sys_net_lib_get_system_time);
REG_FUNC(sys_net, _sys_net_lib_if_nametoindex);
REG_FUNC(sys_net, _sys_net_lib_ioctl);
REG_FUNC(sys_net, __sys_net_lib_malloc);
REG_FUNC(sys_net, _sys_net_lib_rand);
REG_FUNC(sys_net, __sys_net_lib_realloc);
REG_FUNC(sys_net, _sys_net_lib_reset_libnetctl_queue);
REG_FUNC(sys_net, _sys_net_lib_set_libnetctl_queue);
REG_FUNC(sys_net, _sys_net_lib_thread_create);
REG_FUNC(sys_net, _sys_net_lib_thread_exit);
REG_FUNC(sys_net, _sys_net_lib_thread_join);
REG_FUNC(sys_net, _sys_net_lib_sync_clear);
REG_FUNC(sys_net, _sys_net_lib_sync_create);
REG_FUNC(sys_net, _sys_net_lib_sync_destroy);
REG_FUNC(sys_net, _sys_net_lib_sync_signal);
REG_FUNC(sys_net, _sys_net_lib_sync_wait);
REG_FUNC(sys_net, _sys_net_lib_sysctl);
REG_FUNC(sys_net, _sys_net_lib_usleep);
REG_FUNC(sys_net, sys_netset_abort);
REG_FUNC(sys_net, sys_netset_close);
REG_FUNC(sys_net, sys_netset_get_if_id);
REG_FUNC(sys_net, sys_netset_get_key_value);
REG_FUNC(sys_net, sys_netset_get_status);
REG_FUNC(sys_net, sys_netset_if_down);
REG_FUNC(sys_net, sys_netset_if_up);
REG_FUNC(sys_net, sys_netset_open);
REG_FUNC(sys_net, _sce_net_add_name_server);
REG_FUNC(sys_net, _sce_net_add_name_server_with_char);
REG_FUNC(sys_net, _sce_net_flush_route);
REG_FUNC(sys_net, _sce_net_get_name_server);
REG_FUNC(sys_net, _sce_net_set_default_gateway);
REG_FUNC(sys_net, _sce_net_set_ip_and_mask);
REG_FUNC(sys_net, _sce_net_set_name_server);
});
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#include "Emu/Cell/lv2/sys_net.h"
#include "Emu/Memory/vm.h"
struct sys_net_sockinfo_t
{
be_t<s32> s;
be_t<s32> proto;
be_t<s32> recv_queue_length;
be_t<s32> send_queue_length;
sys_net_in_addr local_adr;
be_t<s32> local_port;
sys_net_in_addr remote_adr;
be_t<s32> remote_port;
be_t<s32> state;
};
struct sys_net_sockinfo_ex_t
{
be_t<s32> s;
be_t<s32> proto;
be_t<s32> recv_queue_length;
be_t<s32> send_queue_length;
sys_net_in_addr local_adr;
be_t<s32> local_port;
sys_net_in_addr remote_adr;
be_t<s32> remote_port;
be_t<s32> state;
be_t<s32> socket_type;
be_t<s32> local_vport;
be_t<s32> remote_vport;
be_t<s32> reserved[8];
};
struct sys_net_initialize_parameter_t
{
vm::ps3::bptr<void> memory;
be_t<s32> memory_size;
be_t<s32> flags;
};
+11 -5
View File
@@ -13,6 +13,7 @@ extern logs::channel sysPrxForUser;
vm::gvar<sys_lwmutex_t> g_ppu_atexit_lwm;
vm::gvar<vm::ptr<void()>[8]> g_ppu_atexit;
vm::gvar<u32> g_ppu_exit_mutex; // sys_process_exit2 mutex
vm::gvar<u32> g_ppu_once_mutex;
vm::gvar<sys_lwmutex_t> g_ppu_prx_lwm;
@@ -112,6 +113,10 @@ void sys_initialize_tls(ppu_thread& ppu, u64 main_thread_id, u32 tls_seg_addr, u
attr->name_u64 = "_lv2ppu\0"_u64;
sys_mutex_create(g_ppu_once_mutex, attr);
attr->recursive = SYS_SYNC_RECURSIVE;
attr->name_u64 = "_lv2tls\0"_u64;
sys_mutex_create(g_ppu_exit_mutex, attr);
lwa->protocol = SYS_SYNC_PRIORITY;
lwa->recursive = SYS_SYNC_RECURSIVE;
lwa->name_u64 = "_lv2prx\0"_u64;
@@ -266,12 +271,13 @@ error_code sys_interrupt_thread_disestablish(ppu_thread& ppu, u32 ih)
void sysPrxForUser_sys_ppu_thread_init()
{
// Private
REG_VNID(sysPrxForUser, 0x00000000u, g_ppu_atexit_lwm);
REG_VNID(sysPrxForUser, 0x00000001u, g_ppu_once_mutex);
REG_VNID(sysPrxForUser, 0x00000002u, g_ppu_atexit);
REG_VNID(sysPrxForUser, 0x00000003u, g_ppu_prx_lwm);
REG_VAR(sysPrxForUser, g_ppu_atexit_lwm).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_once_mutex).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_atexit).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_prx_lwm).flag(MFF_HIDDEN);
REG_VAR(sysPrxForUser, g_ppu_exit_mutex).flag(MFF_HIDDEN);
REG_FUNC(sysPrxForUser, sys_initialize_tls);
REG_FUNC(sysPrxForUser, sys_initialize_tls).args = {"main_thread_id", "tls_seg_addr", "tls_seg_size", "tls_mem_size"}; // Test
REG_FUNC(sysPrxForUser, sys_ppu_thread_create);
REG_FUNC(sysPrxForUser, sys_ppu_thread_get_id);
REG_FUNC(sysPrxForUser, sys_ppu_thread_exit);
File diff suppressed because it is too large Load Diff
+747
View File
@@ -6,6 +6,7 @@
#include "Utilities/bit_set.h"
#include "Utilities/BEType.h"
#include "PPUOpcodes.h"
// PPU Function Attributes
enum class ppu_attr : u32
@@ -50,6 +51,7 @@ struct ppu_segment
u32 size;
u32 type;
u32 flags;
u32 filesz;
};
// PPU Module Information
@@ -62,6 +64,16 @@ struct ppu_module
std::vector<ppu_segment> secs;
std::vector<ppu_function> funcs;
// Copy info without functions
void copy_part(const ppu_module& info)
{
name = info.name;
path = info.path;
relocs = info.relocs;
segs = info.segs;
secs = info.secs;
}
void analyse(u32 lib_toc, u32 entry);
void validate(u32 reloc);
};
@@ -930,3 +942,738 @@ struct ppu_iname
return value;
}
};
// PPU Analyser Context
struct ppu_acontext
{
// General-purpose register range
struct spec_gpr
{
// Integral range: normalized undef = (0;UINT64_MAX), unnormalized undefs are possible (when max = min - 1)
// Bit range: constant 0 = (0;0), constant 1 = (1;1), normalized undef = (0;1), unnormalized undef = (1;0)
u64 imin = 0; // Integral range begin
u64 imax = -1; // Integral range end
u64 bmin = 0; // Bit range begin
u64 bmax = -1; // Bit range end
void set_undef()
{
imin = 0;
imax = -1;
bmin = 0;
bmax = -1;
}
// (Number of possible values - 1), 0 = const
u64 div() const
{
return imax - imin;
}
// Return zero bits for zeros, ones for ones or undefs
u64 mask() const
{
return bmin | bmax;
}
// Return one bits for ones, zeros for zeros or undefs
u64 ones() const
{
return bmin & bmax;
}
// Return one bits for undefs
u64 undefs() const
{
return bmin ^ bmax;
}
// Return number of trailing zero bits
u64 tz() const
{
return ::cnttz64(mask());
}
// Range NOT
spec_gpr operator ~() const
{
spec_gpr r;
r.imin = ~imax;
r.imax = ~imin;
r.bmin = ~bmax;
r.bmax = ~bmin;
return r;
}
// Range ADD
spec_gpr operator +(const spec_gpr& rhs) const
{
spec_gpr r{};
const u64 adiv = div();
const u64 bdiv = rhs.div();
// Check overflow, generate normalized range
if (adiv != -1 && bdiv != -1 && adiv <= adiv + bdiv)
{
r = range(imin + rhs.imin, imax + rhs.imax);
}
// Carry for bitrange computation
u64 cmin = 0;
u64 cmax = 0;
const u64 amask = mask();
const u64 bmask = rhs.mask();
const u64 aones = ones();
const u64 bones = rhs.ones();
for (u32 i = 0; i < 64; i++)
{
cmin += ((amask >> i) & 1) + ((bmask >> i) & 1);
cmax += ((aones >> i) & 1) + ((bones >> i) & 1);
// Discover some constant bits
if (cmin == cmax)
{
r.bmin |= (cmin & 1) << i;
r.bmax &= ~((~cmin & 1) << i);
}
cmin >>= 1;
cmax >>= 1;
}
return r;
}
// Range AND
spec_gpr operator &(const spec_gpr& rhs) const
{
// Ignore inverted ranges (TODO)
if (imin > imax || rhs.imin > rhs.imax)
{
return approx(ones() & rhs.ones(), mask() & rhs.mask());
}
// Const (TODO: remove when unnecessary)
if (imin == imax && rhs.imin == rhs.imax)
{
return fixed(imin & rhs.imin);
}
// Swap (TODO: remove when unnecessary)
if (imin == imax || rhs.undefs() > undefs())
{
return rhs & *this;
}
// Copy and attempt to partially preserve integral range
spec_gpr r = *this;
for (u32 i = 63; ~i; i--)
{
const u64 m = 1ull << i;
if (!(rhs.mask() & m))
{
if (r.undefs() & m)
{
// undef -> 0
r.imin &= ~(m - 1);
r.imax |= (m - 1);
r.imin &= ~m;
r.imax &= ~m;
}
else if (r.ones() & m)
{
// 1 -> 0
if ((r.imin ^ r.imax) > (m - 1))
{
r.imin &= ~(m - 1);
r.imax |= (m - 1);
}
r.imin &= ~m;
r.imax &= ~m;
}
}
else if (rhs.undefs() & m)
{
// -> undef
r.imin &= ~(m - 1);
r.imax |= (m - 1);
r.imin &= ~m;
r.imax |= m;
}
}
r.bmin = ones() & rhs.ones();
r.bmax = mask() & rhs.mask();
return r;
}
// Range OR
spec_gpr operator |(const spec_gpr& rhs) const
{
// Ignore inverted ranges (TODO)
if (imin > imax || rhs.imin > rhs.imax)
{
return approx(ones() | rhs.ones(), mask() | rhs.mask());
}
// Const (TODO: remove when unnecessary)
if (imin == imax && rhs.imin == rhs.imax)
{
return fixed(imin | rhs.imin);
}
// Swap (TODO: remove when unnecessary)
if (imin == imax || rhs.undefs() > undefs())
{
return rhs | *this;
}
// Copy and attempt to partially preserve integral range
spec_gpr r = *this;
for (u32 i = 63; ~i; i--)
{
const u64 m = 1ull << i;
if (rhs.ones() & m)
{
if (r.undefs() & m)
{
// undef -> 1
r.imin &= ~(m - 1);
r.imax |= (m - 1);
r.imin |= m;
r.imax |= m;
}
else if (!(r.mask() & m))
{
// 0 -> 1
if ((r.imin ^ r.imax) > (m - 1))
{
r.imin &= ~(m - 1);
r.imax |= (m - 1);
}
r.imin |= m;
r.imax |= m;
}
}
else if (rhs.undefs() & m)
{
// -> undef
r.imin &= ~(m - 1);
r.imax |= (m - 1);
r.imin &= ~m;
r.imax |= m;
}
}
r.bmin = ones() | rhs.ones();
r.bmax = mask() | rhs.mask();
return r;
}
// Range XOR
spec_gpr operator ^(const spec_gpr& rhs)
{
return (~*this & rhs) | (*this & ~rhs);
}
// Check whether the value is in range
bool test(u64 value) const
{
if (imin <= imax)
{
if (value < imin || value > imax)
{
return false;
}
}
else
{
if (value < imin && value > imax)
{
return false;
}
}
if ((value & mask()) != value)
{
return false;
}
if ((value | ones()) != value)
{
return false;
}
return true;
}
// Constant value
static spec_gpr fixed(u64 value)
{
spec_gpr r;
r.imin = value;
r.imax = value;
r.bmin = value;
r.bmax = value;
return r;
}
// Range (tz = number of constant trailing zeros)
static spec_gpr range(u64 min, u64 max, u64 tz = 0)
{
const u64 mask = tz < 64 ? ~0ull << tz : 0ull;
spec_gpr r;
r.bmin = 0;
r.bmax = mask;
// Normalize min/max for tz (TODO)
if (min < max)
{
// Inverted constant MSB mask
const u64 mix = ~0ull >> ::cntlz64(min ^ max, true);
r.bmin |= min & ~mix;
r.bmax &= max | mix;
r.imin = (min + ~mask) & mask;
r.imax = max & mask;
verify("Impossible range" HERE), r.imin <= r.imax;
}
else
{
r.imin = min & mask;
r.imax = (max + ~mask) & mask;
verify("Impossible range" HERE), r.imin >= r.imax;
}
// Fix const values
if (r.imin == r.imax)
{
r.bmin = r.imin;
r.bmax = r.imax;
}
return r;
}
// Make from bitrange (normalize, approximate range values)
static spec_gpr approx(u64 bmin, u64 bmax)
{
spec_gpr r;
r.imin = bmin & ~(bmin ^ bmax);
r.imax = bmax | (bmin ^ bmax);
r.bmin = bmin & ~(bmin ^ bmax);
r.bmax = bmax | (bmin ^ bmax);
return r;
}
} gpr[32]{};
// Vector registers (draft)
struct spec_vec
{
u8 imin8[16]{};
u8 imax8[16]{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
u16 imin16[8]{};
u16 imax16[8]{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
u32 imin32[4]{};
u32 imax32[4]{0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu};
u64 bmin64[2]{};
u64 bmax64[2]{0xffffffffffffffffull, 0xffffffffffffffffull};
};
// Info
u32 cia;
// Analyser step
void UNK(ppu_opcode_t);
void MFVSCR(ppu_opcode_t);
void MTVSCR(ppu_opcode_t);
void VADDCUW(ppu_opcode_t);
void VADDFP(ppu_opcode_t);
void VADDSBS(ppu_opcode_t);
void VADDSHS(ppu_opcode_t);
void VADDSWS(ppu_opcode_t);
void VADDUBM(ppu_opcode_t);
void VADDUBS(ppu_opcode_t);
void VADDUHM(ppu_opcode_t);
void VADDUHS(ppu_opcode_t);
void VADDUWM(ppu_opcode_t);
void VADDUWS(ppu_opcode_t);
void VAND(ppu_opcode_t);
void VANDC(ppu_opcode_t);
void VAVGSB(ppu_opcode_t);
void VAVGSH(ppu_opcode_t);
void VAVGSW(ppu_opcode_t);
void VAVGUB(ppu_opcode_t);
void VAVGUH(ppu_opcode_t);
void VAVGUW(ppu_opcode_t);
void VCFSX(ppu_opcode_t);
void VCFUX(ppu_opcode_t);
void VCMPBFP(ppu_opcode_t);
void VCMPEQFP(ppu_opcode_t);
void VCMPEQUB(ppu_opcode_t);
void VCMPEQUH(ppu_opcode_t);
void VCMPEQUW(ppu_opcode_t);
void VCMPGEFP(ppu_opcode_t);
void VCMPGTFP(ppu_opcode_t);
void VCMPGTSB(ppu_opcode_t);
void VCMPGTSH(ppu_opcode_t);
void VCMPGTSW(ppu_opcode_t);
void VCMPGTUB(ppu_opcode_t);
void VCMPGTUH(ppu_opcode_t);
void VCMPGTUW(ppu_opcode_t);
void VCTSXS(ppu_opcode_t);
void VCTUXS(ppu_opcode_t);
void VEXPTEFP(ppu_opcode_t);
void VLOGEFP(ppu_opcode_t);
void VMADDFP(ppu_opcode_t);
void VMAXFP(ppu_opcode_t);
void VMAXSB(ppu_opcode_t);
void VMAXSH(ppu_opcode_t);
void VMAXSW(ppu_opcode_t);
void VMAXUB(ppu_opcode_t);
void VMAXUH(ppu_opcode_t);
void VMAXUW(ppu_opcode_t);
void VMHADDSHS(ppu_opcode_t);
void VMHRADDSHS(ppu_opcode_t);
void VMINFP(ppu_opcode_t);
void VMINSB(ppu_opcode_t);
void VMINSH(ppu_opcode_t);
void VMINSW(ppu_opcode_t);
void VMINUB(ppu_opcode_t);
void VMINUH(ppu_opcode_t);
void VMINUW(ppu_opcode_t);
void VMLADDUHM(ppu_opcode_t);
void VMRGHB(ppu_opcode_t);
void VMRGHH(ppu_opcode_t);
void VMRGHW(ppu_opcode_t);
void VMRGLB(ppu_opcode_t);
void VMRGLH(ppu_opcode_t);
void VMRGLW(ppu_opcode_t);
void VMSUMMBM(ppu_opcode_t);
void VMSUMSHM(ppu_opcode_t);
void VMSUMSHS(ppu_opcode_t);
void VMSUMUBM(ppu_opcode_t);
void VMSUMUHM(ppu_opcode_t);
void VMSUMUHS(ppu_opcode_t);
void VMULESB(ppu_opcode_t);
void VMULESH(ppu_opcode_t);
void VMULEUB(ppu_opcode_t);
void VMULEUH(ppu_opcode_t);
void VMULOSB(ppu_opcode_t);
void VMULOSH(ppu_opcode_t);
void VMULOUB(ppu_opcode_t);
void VMULOUH(ppu_opcode_t);
void VNMSUBFP(ppu_opcode_t);
void VNOR(ppu_opcode_t);
void VOR(ppu_opcode_t);
void VPERM(ppu_opcode_t);
void VPKPX(ppu_opcode_t);
void VPKSHSS(ppu_opcode_t);
void VPKSHUS(ppu_opcode_t);
void VPKSWSS(ppu_opcode_t);
void VPKSWUS(ppu_opcode_t);
void VPKUHUM(ppu_opcode_t);
void VPKUHUS(ppu_opcode_t);
void VPKUWUM(ppu_opcode_t);
void VPKUWUS(ppu_opcode_t);
void VREFP(ppu_opcode_t);
void VRFIM(ppu_opcode_t);
void VRFIN(ppu_opcode_t);
void VRFIP(ppu_opcode_t);
void VRFIZ(ppu_opcode_t);
void VRLB(ppu_opcode_t);
void VRLH(ppu_opcode_t);
void VRLW(ppu_opcode_t);
void VRSQRTEFP(ppu_opcode_t);
void VSEL(ppu_opcode_t);
void VSL(ppu_opcode_t);
void VSLB(ppu_opcode_t);
void VSLDOI(ppu_opcode_t);
void VSLH(ppu_opcode_t);
void VSLO(ppu_opcode_t);
void VSLW(ppu_opcode_t);
void VSPLTB(ppu_opcode_t);
void VSPLTH(ppu_opcode_t);
void VSPLTISB(ppu_opcode_t);
void VSPLTISH(ppu_opcode_t);
void VSPLTISW(ppu_opcode_t);
void VSPLTW(ppu_opcode_t);
void VSR(ppu_opcode_t);
void VSRAB(ppu_opcode_t);
void VSRAH(ppu_opcode_t);
void VSRAW(ppu_opcode_t);
void VSRB(ppu_opcode_t);
void VSRH(ppu_opcode_t);
void VSRO(ppu_opcode_t);
void VSRW(ppu_opcode_t);
void VSUBCUW(ppu_opcode_t);
void VSUBFP(ppu_opcode_t);
void VSUBSBS(ppu_opcode_t);
void VSUBSHS(ppu_opcode_t);
void VSUBSWS(ppu_opcode_t);
void VSUBUBM(ppu_opcode_t);
void VSUBUBS(ppu_opcode_t);
void VSUBUHM(ppu_opcode_t);
void VSUBUHS(ppu_opcode_t);
void VSUBUWM(ppu_opcode_t);
void VSUBUWS(ppu_opcode_t);
void VSUMSWS(ppu_opcode_t);
void VSUM2SWS(ppu_opcode_t);
void VSUM4SBS(ppu_opcode_t);
void VSUM4SHS(ppu_opcode_t);
void VSUM4UBS(ppu_opcode_t);
void VUPKHPX(ppu_opcode_t);
void VUPKHSB(ppu_opcode_t);
void VUPKHSH(ppu_opcode_t);
void VUPKLPX(ppu_opcode_t);
void VUPKLSB(ppu_opcode_t);
void VUPKLSH(ppu_opcode_t);
void VXOR(ppu_opcode_t);
void TDI(ppu_opcode_t);
void TWI(ppu_opcode_t);
void MULLI(ppu_opcode_t);
void SUBFIC(ppu_opcode_t);
void CMPLI(ppu_opcode_t);
void CMPI(ppu_opcode_t);
void ADDIC(ppu_opcode_t);
void ADDI(ppu_opcode_t);
void ADDIS(ppu_opcode_t);
void BC(ppu_opcode_t);
void SC(ppu_opcode_t);
void B(ppu_opcode_t);
void MCRF(ppu_opcode_t);
void BCLR(ppu_opcode_t);
void CRNOR(ppu_opcode_t);
void CRANDC(ppu_opcode_t);
void ISYNC(ppu_opcode_t);
void CRXOR(ppu_opcode_t);
void CRNAND(ppu_opcode_t);
void CRAND(ppu_opcode_t);
void CREQV(ppu_opcode_t);
void CRORC(ppu_opcode_t);
void CROR(ppu_opcode_t);
void BCCTR(ppu_opcode_t);
void RLWIMI(ppu_opcode_t);
void RLWINM(ppu_opcode_t);
void RLWNM(ppu_opcode_t);
void ORI(ppu_opcode_t);
void ORIS(ppu_opcode_t);
void XORI(ppu_opcode_t);
void XORIS(ppu_opcode_t);
void ANDI(ppu_opcode_t);
void ANDIS(ppu_opcode_t);
void RLDICL(ppu_opcode_t);
void RLDICR(ppu_opcode_t);
void RLDIC(ppu_opcode_t);
void RLDIMI(ppu_opcode_t);
void RLDCL(ppu_opcode_t);
void RLDCR(ppu_opcode_t);
void CMP(ppu_opcode_t);
void TW(ppu_opcode_t);
void LVSL(ppu_opcode_t);
void LVEBX(ppu_opcode_t);
void SUBFC(ppu_opcode_t);
void ADDC(ppu_opcode_t);
void MULHDU(ppu_opcode_t);
void MULHWU(ppu_opcode_t);
void MFOCRF(ppu_opcode_t);
void LWARX(ppu_opcode_t);
void LDX(ppu_opcode_t);
void LWZX(ppu_opcode_t);
void SLW(ppu_opcode_t);
void CNTLZW(ppu_opcode_t);
void SLD(ppu_opcode_t);
void AND(ppu_opcode_t);
void CMPL(ppu_opcode_t);
void LVSR(ppu_opcode_t);
void LVEHX(ppu_opcode_t);
void SUBF(ppu_opcode_t);
void LDUX(ppu_opcode_t);
void DCBST(ppu_opcode_t);
void LWZUX(ppu_opcode_t);
void CNTLZD(ppu_opcode_t);
void ANDC(ppu_opcode_t);
void TD(ppu_opcode_t);
void LVEWX(ppu_opcode_t);
void MULHD(ppu_opcode_t);
void MULHW(ppu_opcode_t);
void LDARX(ppu_opcode_t);
void DCBF(ppu_opcode_t);
void LBZX(ppu_opcode_t);
void LVX(ppu_opcode_t);
void NEG(ppu_opcode_t);
void LBZUX(ppu_opcode_t);
void NOR(ppu_opcode_t);
void STVEBX(ppu_opcode_t);
void SUBFE(ppu_opcode_t);
void ADDE(ppu_opcode_t);
void MTOCRF(ppu_opcode_t);
void STDX(ppu_opcode_t);
void STWCX(ppu_opcode_t);
void STWX(ppu_opcode_t);
void STVEHX(ppu_opcode_t);
void STDUX(ppu_opcode_t);
void STWUX(ppu_opcode_t);
void STVEWX(ppu_opcode_t);
void SUBFZE(ppu_opcode_t);
void ADDZE(ppu_opcode_t);
void STDCX(ppu_opcode_t);
void STBX(ppu_opcode_t);
void STVX(ppu_opcode_t);
void SUBFME(ppu_opcode_t);
void MULLD(ppu_opcode_t);
void ADDME(ppu_opcode_t);
void MULLW(ppu_opcode_t);
void DCBTST(ppu_opcode_t);
void STBUX(ppu_opcode_t);
void ADD(ppu_opcode_t);
void DCBT(ppu_opcode_t);
void LHZX(ppu_opcode_t);
void EQV(ppu_opcode_t);
void ECIWX(ppu_opcode_t);
void LHZUX(ppu_opcode_t);
void XOR(ppu_opcode_t);
void MFSPR(ppu_opcode_t);
void LWAX(ppu_opcode_t);
void DST(ppu_opcode_t);
void LHAX(ppu_opcode_t);
void LVXL(ppu_opcode_t);
void MFTB(ppu_opcode_t);
void LWAUX(ppu_opcode_t);
void DSTST(ppu_opcode_t);
void LHAUX(ppu_opcode_t);
void STHX(ppu_opcode_t);
void ORC(ppu_opcode_t);
void ECOWX(ppu_opcode_t);
void STHUX(ppu_opcode_t);
void OR(ppu_opcode_t);
void DIVDU(ppu_opcode_t);
void DIVWU(ppu_opcode_t);
void MTSPR(ppu_opcode_t);
void DCBI(ppu_opcode_t);
void NAND(ppu_opcode_t);
void STVXL(ppu_opcode_t);
void DIVD(ppu_opcode_t);
void DIVW(ppu_opcode_t);
void LVLX(ppu_opcode_t);
void LDBRX(ppu_opcode_t);
void LSWX(ppu_opcode_t);
void LWBRX(ppu_opcode_t);
void LFSX(ppu_opcode_t);
void SRW(ppu_opcode_t);
void SRD(ppu_opcode_t);
void LVRX(ppu_opcode_t);
void LSWI(ppu_opcode_t);
void LFSUX(ppu_opcode_t);
void SYNC(ppu_opcode_t);
void LFDX(ppu_opcode_t);
void LFDUX(ppu_opcode_t);
void STVLX(ppu_opcode_t);
void STDBRX(ppu_opcode_t);
void STSWX(ppu_opcode_t);
void STWBRX(ppu_opcode_t);
void STFSX(ppu_opcode_t);
void STVRX(ppu_opcode_t);
void STFSUX(ppu_opcode_t);
void STSWI(ppu_opcode_t);
void STFDX(ppu_opcode_t);
void STFDUX(ppu_opcode_t);
void LVLXL(ppu_opcode_t);
void LHBRX(ppu_opcode_t);
void SRAW(ppu_opcode_t);
void SRAD(ppu_opcode_t);
void LVRXL(ppu_opcode_t);
void DSS(ppu_opcode_t);
void SRAWI(ppu_opcode_t);
void SRADI(ppu_opcode_t);
void EIEIO(ppu_opcode_t);
void STVLXL(ppu_opcode_t);
void STHBRX(ppu_opcode_t);
void EXTSH(ppu_opcode_t);
void STVRXL(ppu_opcode_t);
void EXTSB(ppu_opcode_t);
void STFIWX(ppu_opcode_t);
void EXTSW(ppu_opcode_t);
void ICBI(ppu_opcode_t);
void DCBZ(ppu_opcode_t);
void LWZ(ppu_opcode_t);
void LWZU(ppu_opcode_t);
void LBZ(ppu_opcode_t);
void LBZU(ppu_opcode_t);
void STW(ppu_opcode_t);
void STWU(ppu_opcode_t);
void STB(ppu_opcode_t);
void STBU(ppu_opcode_t);
void LHZ(ppu_opcode_t);
void LHZU(ppu_opcode_t);
void LHA(ppu_opcode_t);
void LHAU(ppu_opcode_t);
void STH(ppu_opcode_t);
void STHU(ppu_opcode_t);
void LMW(ppu_opcode_t);
void STMW(ppu_opcode_t);
void LFS(ppu_opcode_t);
void LFSU(ppu_opcode_t);
void LFD(ppu_opcode_t);
void LFDU(ppu_opcode_t);
void STFS(ppu_opcode_t);
void STFSU(ppu_opcode_t);
void STFD(ppu_opcode_t);
void STFDU(ppu_opcode_t);
void LD(ppu_opcode_t);
void LDU(ppu_opcode_t);
void LWA(ppu_opcode_t);
void STD(ppu_opcode_t);
void STDU(ppu_opcode_t);
void FDIVS(ppu_opcode_t);
void FSUBS(ppu_opcode_t);
void FADDS(ppu_opcode_t);
void FSQRTS(ppu_opcode_t);
void FRES(ppu_opcode_t);
void FMULS(ppu_opcode_t);
void FMADDS(ppu_opcode_t);
void FMSUBS(ppu_opcode_t);
void FNMSUBS(ppu_opcode_t);
void FNMADDS(ppu_opcode_t);
void MTFSB1(ppu_opcode_t);
void MCRFS(ppu_opcode_t);
void MTFSB0(ppu_opcode_t);
void MTFSFI(ppu_opcode_t);
void MFFS(ppu_opcode_t);
void MTFSF(ppu_opcode_t);
void FCMPU(ppu_opcode_t);
void FRSP(ppu_opcode_t);
void FCTIW(ppu_opcode_t);
void FCTIWZ(ppu_opcode_t);
void FDIV(ppu_opcode_t);
void FSUB(ppu_opcode_t);
void FADD(ppu_opcode_t);
void FSQRT(ppu_opcode_t);
void FSEL(ppu_opcode_t);
void FMUL(ppu_opcode_t);
void FRSQRTE(ppu_opcode_t);
void FMSUB(ppu_opcode_t);
void FMADD(ppu_opcode_t);
void FNMSUB(ppu_opcode_t);
void FNMADD(ppu_opcode_t);
void FCMPO(ppu_opcode_t);
void FNEG(ppu_opcode_t);
void FMR(ppu_opcode_t);
void FNABS(ppu_opcode_t);
void FABS(ppu_opcode_t);
void FCTID(ppu_opcode_t);
void FCTIDZ(ppu_opcode_t);
void FCFID(ppu_opcode_t);
};
+7 -8
View File
@@ -7,7 +7,6 @@ extern std::string ppu_get_syscall_name(u64 code)
{
case 1: return "sys_process_getpid";
case 2: return "sys_process_wait_for_child";
case 3: return "sys_process_exit";
case 4: return "sys_process_get_status";
case 5: return "sys_process_detach_child";
case 12: return "sys_process_get_number_of_object";
@@ -16,10 +15,10 @@ extern std::string ppu_get_syscall_name(u64 code)
case 18: return "sys_process_getppid";
case 19: return "sys_process_kill";
case 21: return "_sys_process_spawn";
case 22: return "sys_process_exit";
case 22: return "_sys_process_exit";
case 23: return "sys_process_wait_for_child2";
case 25: return "sys_process_get_sdk_version";
case 26: return "_sys_process_exit";
case 26: return "_sys_process_exit2";
case 28: return "_sys_process_get_number_of_object";
case 29: return "sys_process_get_id";
case 30: return "_sys_process_get_paramsfo";
@@ -414,16 +413,16 @@ extern std::string ppu_get_syscall_name(u64 code)
case 708: return "sys_net_bnet_recvmsg";
case 709: return "sys_net_bnet_sendmsg";
case 710: return "sys_net_bnet_sendto";
case 711: return "sys_net_bnet_setsockop";
case 711: return "sys_net_bnet_setsockopt";
case 712: return "sys_net_bnet_shutdown";
case 713: return "sys_net_bnet_socket";
case 714: return "sys_net_bnet_close";
case 715: return "sys_net_bnet_poll";
case 716: return "sys_net_bnet_select";
case 717: return "sys_net_open_dump";
case 718: return "sys_net_read_dump";
case 719: return "sys_net_close_dump";
case 720: return "sys_net_write_dump";
case 717: return "_sys_net_open_dump";
case 718: return "_sys_net_read_dump";
case 719: return "_sys_net_close_dump";
case 720: return "_sys_net_write_dump";
case 721: return "sys_net_abort";
case 722: return "sys_net_infoctl";
case 723: return "sys_net_control";
+5
View File
@@ -14,6 +14,11 @@ inline void ppu_cr_set(ppu_thread& ppu, u32 field, bool le, bool gt, bool eq, bo
ppu.cr[field * 4 + 1] = gt;
ppu.cr[field * 4 + 2] = eq;
ppu.cr[field * 4 + 3] = so;
if (UNLIKELY(g_cfg.core.ppu_debug))
{
*(u32*)(vm::g_stat_addr + ppu.cia) |= *(u32*)(u8*)(ppu.cr + field * 4);
}
}
// Write comparison results to CR field
+87 -27
View File
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Utilities/VirtualMemory.h"
#include "Utilities/bin_patch.h"
#include "Crypto/sha1.h"
@@ -124,7 +124,8 @@ struct ppu_linkage_info
{
struct info
{
bool hle = false;
ppu_static_function* static_func = nullptr;
ppu_static_variable* static_var = nullptr;
u32 export_addr = 0;
std::set<u32> imports;
std::set<u32> frefss;
@@ -248,7 +249,7 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
&ppu_module_manager::sceNpTus,
&ppu_module_manager::sceNpUtil,
&ppu_module_manager::sys_io,
&ppu_module_manager::libnet,
&ppu_module_manager::sys_net,
&ppu_module_manager::sysPrxForUser,
&ppu_module_manager::sys_libc,
&ppu_module_manager::sys_lv2dbg,
@@ -315,8 +316,9 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
{
auto& flink = linkage.functions[function.first];
flink.hle = true;
flink.static_func = &function.second;
flink.export_addr = ppu_function_manager::addr + 8 * function.second.index;
function.second.export_addr = &flink.export_addr;
}
}
@@ -327,7 +329,7 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
// Allocate HLE variable
if (variable.second.size >= 4096 || variable.second.align >= 4096)
{
variable.second.var->set(vm::alloc(variable.second.size, vm::main, std::max<u32>(variable.second.align, 4096)));
variable.second.addr = vm::alloc(variable.second.size, vm::main, std::max<u32>(variable.second.align, 4096));
}
else
{
@@ -343,10 +345,15 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
alloc_addr = next;
}
variable.second.var->set(alloc_addr);
variable.second.addr = alloc_addr;
alloc_addr += variable.second.size;
}
if (variable.second.var)
{
variable.second.var->set(variable.second.addr);
}
LOG_TRACE(LOADER, "Allocated HLE variable %s.%s at 0x%x", module->name, variable.second.name, variable.second.var->addr());
// Initialize HLE variable
@@ -355,10 +362,14 @@ static void ppu_initialize_modules(const std::shared_ptr<ppu_linkage_info>& link
variable.second.init();
}
auto& vlink = linkage.variables[variable.first];
vlink.hle = true;
vlink.export_addr = variable.second.var->addr();
if ((variable.second.flags & MFF_HIDDEN) == 0)
{
auto& vlink = linkage.variables[variable.first];
vlink.static_var = &variable.second;
vlink.export_addr = variable.second.addr;
variable.second.export_addr = &vlink.export_addr;
}
}
}
}
@@ -510,7 +521,12 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
// Function linkage info
auto& flink = mlink.functions[fnid];
if (flink.export_addr && !flink.hle)
if (flink.static_func && flink.export_addr == ppu_function_manager::addr + 8 * flink.static_func->index)
{
flink.export_addr = 0;
}
if (flink.export_addr)
{
LOG_ERROR(LOADER, "Already linked function '%s' in module '%s'", ppu_get_function_name(module_name, fnid), module_name);
}
@@ -544,7 +560,6 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
{
// Set exported function
flink.export_addr = faddr;
flink.hle = false;
// Fix imports
for (const u32 addr : flink.imports)
@@ -574,7 +589,12 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
// Variable linkage info
auto& vlink = mlink.variables[vnid];
if (vlink.export_addr && !vlink.hle)
if (vlink.static_var && vlink.export_addr == vlink.static_var->addr)
{
vlink.export_addr = 0;
}
if (vlink.export_addr)
{
LOG_ERROR(LOADER, "Already linked variable '%s' in module '%s'", ppu_get_variable_name(module_name, vnid), module_name);
}
@@ -582,7 +602,6 @@ static auto ppu_load_exports(const std::shared_ptr<ppu_linkage_info>& link, u32
{
// Set exported variable
vlink.export_addr = vaddr;
vlink.hle = false;
// Fix imports
for (const auto vref : vlink.imports)
@@ -732,6 +751,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
ppu_segment _seg;
_seg.addr = addr;
_seg.size = mem_size;
_seg.filesz = file_size;
_seg.type = p_type;
_seg.flags = prog.p_flags;
prx->segs.emplace_back(_seg);
@@ -766,6 +786,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
_sec.size = size;
_sec.type = s.sh_type;
_sec.flags = s.sh_flags & 7;
_sec.filesz = 0;
prx->secs.emplace_back(_sec);
break;
}
@@ -885,7 +906,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
struct ppu_prx_library_info
{
be_t<u16> attributes;
be_t<u16> version;
u8 version[2];
char name[28];
be_t<u32> toc;
be_t<u32> exports_start;
@@ -898,6 +919,11 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
const auto& lib_info = vm::cptr<ppu_prx_library_info>(vm::cast(prx->segs[0].addr + elf.progs[0].p_paddr - elf.progs[0].p_offset, HERE));
const auto& lib_name = std::string(lib_info->name);
std::memcpy(prx->module_info_name, lib_info->name, sizeof(prx->module_info_name));
prx->module_info_version[0] = lib_info->version[0];
prx->module_info_version[1] = lib_info->version[1];
prx->module_info_attributes = lib_info->attributes;
LOG_WARNING(LOADER, "Library %s (rtoc=0x%x):", lib_name, lib_info->toc);
prx->specials = ppu_load_exports(link, lib_info->exports_start, lib_info->exports_end);
@@ -939,6 +965,23 @@ void ppu_unload_prx(const lv2_prx& prx)
pinfo->imports.erase(imp.first);
}
//for (auto& exp : prx.exports)
//{
// auto pinfo = static_cast<ppu_linkage_info::module::info*>(exp.second);
// if (pinfo->static_func)
// {
// pinfo->export_addr = ppu_function_manager::addr + 8 * pinfo->static_func->index;
// }
// else if (pinfo->static_var)
// {
// pinfo->export_addr = pinfo->static_var->addr;
// }
// else
// {
// pinfo->export_addr = 0;
// }
//}
for (auto& seg : prx.segs)
{
vm::dealloc(seg.addr, vm::main);
@@ -979,6 +1022,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
const u32 size = _seg.size = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
const u32 type = _seg.type = prog.p_type;
const u32 flag = _seg.flags = prog.p_flags;
_seg.filesz = ::narrow<u32>(prog.p_filesz, "p_filesz" HERE);
// Hash big-endian values
sha1_update(&sha, (uchar*)&prog.p_type, sizeof(prog.p_type));
@@ -1019,6 +1063,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
const u32 size = _sec.size = vm::cast(s.sh_size);
const u32 type = _sec.type = s.sh_type;
const u32 flag = _sec.flags = s.sh_flags & 7;
_sec.filesz = 0;
if (s.sh_type == 1 && addr && size)
{
@@ -1161,9 +1206,9 @@ void ppu_load_exec(const ppu_exec_object& elf)
// Get LLE module list
std::set<std::string> load_libs;
if (g_cfg.core.lib_loading == lib_loading_type::manual || g_cfg.core.lib_loading == lib_loading_type::both)
if (g_cfg.core.lib_loading == lib_loading_type::manual)
{
// Load required set of modules
// Load required set of modules (lib_loading_type::both processed in sys_prx.cpp)
load_libs = g_cfg.core.load_libraries.get_set();
}
else if (g_cfg.core.lib_loading == lib_loading_type::liblv2only)
@@ -1343,7 +1388,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
// Set path (TODO)
_main->name = "";
_main->path = vfs::get(Emu.GetPath());
_main->path = vfs::get(Emu.argv[0]);
// Analyse executable (TODO)
_main->analyse(0, static_cast<u32>(elf.header.e_entry));
@@ -1355,27 +1400,42 @@ void ppu_load_exec(const ppu_exec_object& elf)
g_ps3_sdk_version = sdk_version;
// Initialize process arguments
std::initializer_list<std::string> args = { Emu.GetPath()/*, "-emu"s*/ };
auto args = vm::ptr<u64>::make(vm::alloc(SIZE_32(u64) * (::size32(Emu.argv) + ::size32(Emu.envp) + 2), vm::main));
auto argv = args;
auto argv = vm::ptr<u64>::make(vm::alloc(SIZE_32(u64) * ::size32(args), vm::main));
auto envp = vm::ptr<u64>::make(vm::alloc(::align(SIZE_32(u64), 0x10), vm::main));
*envp = 0;
for (const auto& arg : args)
for (const auto& arg : Emu.argv)
{
const u32 arg_size = ::align(::size32(arg) + 1, 0x10);
const u32 arg_addr = vm::alloc(arg_size, vm::main);
std::memcpy(vm::base(arg_addr), arg.data(), arg_size);
*argv++ = arg_addr;
*args++ = arg_addr;
}
argv -= ::size32(args);
*args++ = 0;
auto envp = args;
for (const auto& arg : Emu.envp)
{
const u32 arg_size = ::align(::size32(arg) + 1, 0x10);
const u32 arg_addr = vm::alloc(arg_size, vm::main);
std::memcpy(vm::base(arg_addr), arg.data(), arg_size);
*args++ = arg_addr;
}
// Initialize main thread
auto ppu = idm::make_ptr<ppu_thread>("main_thread", primary_prio, primary_stacksize);
// Write initial data (exitspawn)
if (Emu.data.size())
{
std::memcpy(vm::base(ppu->stack_addr + ppu->stack_size - ::size32(Emu.data)), Emu.data.data(), Emu.data.size());
ppu->gpr[1] -= Emu.data.size();
}
ppu->cmd_push({ppu_cmd::initialize, 0});
// TODO: adjust for liblv2 loading option
@@ -1417,7 +1477,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
// Set command line arguments, run entry function
ppu->cmd_list
({
{ ppu_cmd::set_args, 8 }, u64{args.size()}, u64{argv.addr()}, u64{envp.addr()}, u64{0}, u64{ppu->id}, u64{tls_vaddr}, u64{tls_fsize}, u64{tls_vsize},
{ ppu_cmd::set_args, 8 }, u64{Emu.argv.size()}, u64{argv.addr()}, u64{envp.addr()}, u64{0}, u64{ppu->id}, u64{tls_vaddr}, u64{tls_fsize}, u64{tls_vsize},
{ ppu_cmd::set_gpr, 11 }, u64{elf.header.e_entry},
{ ppu_cmd::set_gpr, 12 }, u64{malloc_pagesize},
{ ppu_cmd::lle_call, entry },
+50 -7
View File
@@ -3,6 +3,7 @@
#include "PPUFunction.h"
#include "PPUCallback.h"
#include "ErrorCodes.h"
#include <typeinfo>
// Helper function
constexpr const char* ppu_select_name(const char* name, u32 id)
@@ -26,7 +27,7 @@ constexpr u32 ppu_generate_id(u32 id)
}
// Flags set with REG_FUNC
enum ppu_static_function_flags : u32
enum ppu_static_module_flags : u32
{
MFF_FORCED_HLE = (1 << 0), // Always call HLE function
MFF_PERFECT = (1 << 1), // Indicates complete implementation and LLE interchangeability
@@ -39,6 +40,15 @@ struct ppu_static_function
const char* name;
u32 index; // Index for ppu_function_manager
u32 flags;
const char* type;
std::vector<const char*> args; // Arg names
const u32* export_addr;
ppu_static_function& flag(ppu_static_module_flags value)
{
flags |= value;
return *this;
}
};
// HLE variable information
@@ -49,6 +59,16 @@ struct ppu_static_variable
void(*init)(); // Variable initialization function
u32 size;
u32 align;
const char* type;
u32 flags;
u32 addr;
const u32* export_addr;
ppu_static_variable& flag(ppu_static_module_flags value)
{
flags |= value;
return *this;
}
};
// HLE module information
@@ -91,10 +111,17 @@ class ppu_module_manager final
static ppu_static_variable& access_static_variable(const char* module, u32 vnid);
// Global variable for each registered function
template <typename T, T Func>
struct registered
{
static ppu_static_function* info;
};
public:
static const ppu_static_module* get_module(const std::string& name);
template<typename T, T Func>
template <typename T, T Func>
static auto& register_static_function(const char* module, const char* name, ppu_function_t func, u32 fnid)
{
auto& info = access_static_function(module, fnid);
@@ -102,11 +129,20 @@ public:
info.name = name;
info.index = ppu_function_manager::register_function<T, Func>(func);
info.flags = 0;
info.type = typeid(T).name();
registered<T, Func>::info = &info;
return info;
}
template<typename T, T* Var>
template <typename T, T Func>
static auto& find_static_function()
{
return *registered<T, Func>::info;
}
template <typename T, T* Var>
static auto& register_static_variable(const char* module, const char* name, u32 vnid)
{
static_assert(std::is_same<u32, std::decay_t<typename T::addr_type>>::value, "Static variable registration: vm::gvar<T> expected");
@@ -118,6 +154,9 @@ public:
info.init = [] {};
info.size = SIZE_32(typename T::type);
info.align = ALIGN_32(typename T::type);
info.type = typeid(T).name();
info.flags = 0;
info.addr = 0;
return info;
}
@@ -221,20 +260,24 @@ public:
static const ppu_static_module sceNpTus;
static const ppu_static_module sceNpUtil;
static const ppu_static_module sys_io;
static const ppu_static_module libnet;
static const ppu_static_module sys_net;
static const ppu_static_module sysPrxForUser;
static const ppu_static_module sys_libc;
static const ppu_static_module sys_lv2dbg;
};
template<typename T, T Func>
ppu_static_function* ppu_module_manager::registered<T, Func>::info = nullptr;
// Call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise
template<typename T, T Func, typename... Args, typename RT = std::result_of_t<T(Args...)>>
inline RT ppu_execute_function_or_callback(const char* name, ppu_thread& ppu, Args&&... args)
inline RT ppu_execute_function_or_callback(ppu_thread& ppu, Args&&... args)
{
return Func(std::forward<Args>(args)...);
vm::ps3::ptr<RT(Args...)> func = vm::cast(*ppu_module_manager::find_static_function<T, Func>().export_addr);
return func(ppu, std::forward<Args>(args)...);
}
#define CALL_FUNC(ppu, func, ...) ppu_execute_function_or_callback<decltype(&func), &func>(#func, ppu, __VA_ARGS__)
#define CALL_FUNC(ppu, func, ...) ppu_execute_function_or_callback<decltype(&func), &func>(ppu, __VA_ARGS__)
#define REG_FNID(module, nid, func) ppu_module_manager::register_static_function<decltype(&func), &func>(#module, ppu_select_name(#func, nid), BIND_FUNC(func, ppu.cia = (u32)ppu.lr & ~3), ppu_generate_id(nid))
+49 -11
View File
@@ -280,15 +280,16 @@ void ppu_thread::on_init(const std::shared_ptr<void>& _this)
if (!stack_addr)
{
// Allocate stack + gap between stacks
const_cast<u32&>(stack_addr) = vm::alloc(stack_size + 4096, vm::stack) + 4096;
if (!stack_addr)
auto new_stack_base = vm::alloc(stack_size + 4096, vm::stack);
if (!new_stack_base)
{
fmt::throw_exception("Out of stack memory (size=0x%x)" HERE, stack_size);
}
const_cast<u32&>(stack_addr) = new_stack_base + 4096;
// Make the gap inaccessible
vm::page_protect(stack_addr - 4096, 4096, 0, 0, vm::page_readable + vm::page_writable);
vm::page_protect(new_stack_base, 4096, 0, 0, vm::page_readable + vm::page_writable);
gpr[1] = ::align(stack_addr + stack_size, 0x200) - 0x200;
@@ -328,6 +329,43 @@ extern void ppu_remove_breakpoint(u32 addr)
}
}
extern bool ppu_patch(u32 addr, u32 value)
{
// TODO: check executable flag
if (vm::check_addr(addr, sizeof(u32)))
{
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm && Emu.GetStatus() != system_state::ready)
{
// TODO
return false;
}
if (!vm::check_addr(addr, sizeof(u32), vm::page_writable))
{
utils::memory_protect(vm::g_base_addr + addr, sizeof(u32), utils::protection::rw);
}
vm::write32(addr, value);
const u32 _break = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(&ppu_break));
const u32 fallback = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(&ppu_fallback));
if (ppu_ref(addr) != _break && ppu_ref(addr) != fallback)
{
ppu_ref(addr) = ppu_cache(addr);
}
if (!vm::check_addr(addr, sizeof(u32), vm::page_writable))
{
utils::memory_protect(vm::g_base_addr + addr, sizeof(u32), utils::protection::ro);
}
return true;
}
return false;
}
std::string ppu_thread::get_name() const
{
return fmt::format("PPU[0x%x] Thread (%s)", id, m_name);
@@ -1077,8 +1115,8 @@ extern void ppu_initialize(const ppu_module& info)
const auto fstart = fpos;
// Copy module information (TODO: optimize)
ppu_module part = info;
part.funcs.clear();
ppu_module part;
part.copy_part(info);
part.funcs.reserve(16000);
// Unique suffix for each module part
@@ -1163,9 +1201,9 @@ extern void ppu_initialize(const ppu_module& info)
sha1_update(&ctx, vm::ps3::_ptr<const u8>(func.addr), func.size);
}
if (info.name == "liblv2.sprx")
if (info.name == "liblv2.sprx" || info.name == "libsysmodule.sprx" || info.name == "libnet.sprx")
{
const be_t<u64> forced_upd = 1;
const be_t<u64> forced_upd = 3;
sha1_update(&ctx, reinterpret_cast<const u8*>(&forced_upd), sizeof(forced_upd));
}
@@ -1238,10 +1276,10 @@ extern void ppu_initialize(const ppu_module& info)
return;
}
if (jit_mod.vars.empty())
{
// Jit can be null if the loop doesn't ever enter.
if (jit && jit_mod.vars.empty())
{
jit->fin();
// Get and install function addresses
for (const auto& func : info.funcs)
{
+14
View File
@@ -238,6 +238,20 @@ struct ppu_gpr_cast_impl<vm::_ref_base<T, AT>, void>
}
};
template <>
struct ppu_gpr_cast_impl<vm::null_t, void>
{
static inline u64 to(const vm::null_t& value)
{
return 0;
}
static inline vm::null_t from(const u64 reg)
{
return vm::null;
}
};
template<typename To = u64, typename From>
inline To ppu_gpr_cast(const From& value)
{

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