Compare commits

..

1275 Commits

Author SHA1 Message Date
Luke Usher ec9934af2d
Merge pull request #2488 from RadWolfie/readme-update
Add minimum Windows SDK requirement or later note to the readme file
2025-04-13 18:35:50 +01:00
Luke Usher ce15f50848
Merge pull request #2490 from RadWolfie/toggle-console-mode
GUI: Add ability to choose console type
2025-04-13 18:35:10 +01:00
RadWolfie b1df891433 gui: add popup message when emulation is currently running 2025-04-13 11:21:34 -05:00
RadWolfie 5355e08b30 kernel: fix misplaced block of chihiro code to the respective location to allow forced console type by user selection on boot 2025-04-13 11:21:34 -05:00
RadWolfie 7762e883a8 gui: add selection for auto and manual console type 2025-04-13 11:21:34 -05:00
ergo720 cada16125d
Merge pull request #2489 from RadWolfie/debugger-deprecate
debugger: mark tool as deprecate
2025-04-10 22:38:44 +02:00
RadWolfie eecc1ac1f1 readme: add minimum Windows SDK requirement or later note according to #2473 pull request 2025-04-10 08:07:16 -05:00
RadWolfie 2d6696451b debugger: mark tool as deprecate 2025-04-10 07:59:30 -05:00
ergo720 dd36dd598c
Merge pull request #2484 from ergo720/update_sdl
Updated SDL submodule to version 2.30.11
2025-03-31 13:08:49 +02:00
ergo720 87634a2e27 Updated SDL submodule to version 2.30.11 2025-03-30 10:27:23 +02:00
Luke Usher 6f32d89545
Merge pull request #2474 from Margen67/build
cmake: Replace /Ob2 with /Ob3
2024-12-23 08:55:15 +00:00
Margen67 ec0c288bc4 cmake: Replace /Ob2 with /Ob3
See https://learn.microsoft.com/en-us/cpp/build/reference/ob-inline-function-expansion
2024-12-17 00:34:09 -08:00
RadWolfie 8bfbcb56fd
Merge pull request #2473 from Margen67/w11
Disable rounded corners on Windows 11
2024-12-17 01:59:01 -06:00
Margen67 8965d2443b Remove rounded corners on Windows 11 2024-12-16 23:48:10 -08:00
RadWolfie b33ed95c5b
Merge pull request #2472 from Margen67/ci2
CI: Upgrade actions
2024-12-16 22:15:06 -06:00
Margen67 8ee17b512c CI: Update actions 2024-12-16 19:39:48 -08:00
RadWolfie 50334cbc31
Merge pull request #2469 from Margen67/subhook
Replace subhook with working mirror
2024-12-13 14:52:09 -06:00
Margen67 41454b8c26 Replace subhook with working mirror 2024-12-13 12:41:38 -08:00
Luke Usher 204dcf8801
Merge pull request #2462 from RadWolfie/file-minor-fixes
File minor fixes
2024-08-25 10:21:29 +01:00
RadWolfie 77c63ceec3 kernel: fix dashupdate titles attempt delete new files
NOTE: Partition2.bin needs to be emulated in order for copy files to partition and fatx metadata.
2024-08-18 08:39:16 -05:00
RadWolfie 2cfaba893e kernel: fix Exhibition Demo discs problem for copy soundtracks onto hdd (require force santion) 2024-08-18 08:39:16 -05:00
Luke Usher 17b0cb81d4 CI: Specify minimum platform and SDK version 2024-07-08 15:19:54 +01:00
RadWolfie daa6a816ff Merge experimental chihiro branch 2024-07-05 12:19:54 -05:00
Luke Usher 6caf3ea679 chihiro: prevent JVS register updates from being missed due to long delays
This really needs a better solution, but for now, this will do.
2024-07-05 12:19:54 -05:00
Luke Usher 9a58823b70 chihiro: emulate a chihiro system when boot.id is present 2024-07-05 12:19:54 -05:00
Luke Usher 3edd8d168b chihiro: fix an issue where media board detection failed due to instant response time 2024-07-05 12:19:54 -05:00
RadWolfie f894d31332 Cleanly rebase chihiro-work on develop
Co-authored-by: Luke Usher <luke.usher@outlook.com>
Co-authored-by: wutno <aaron@installgentoo.net>
Co-authored-by: RadWolfie <RadWolfie@users.noreply.github.com>
2024-07-05 12:19:54 -05:00
RadWolfie 9241bec768 Merge ergo720 less_busy_loops branch 2024-07-05 12:19:53 -05:00
RadWolfie c50a0c5c7d Merge EmuX86 passive branch 2024-07-05 12:18:57 -05:00
Luke Usher 87bab04932 EmuX86: Let invalid memory accesses trigger a warning rather than a fatal error
This seems to resolve most regressions we have had in recent history.
2024-07-05 12:18:54 -05:00
ergo720 ad6769bbf3 Never change the thread priority on the host and the disable boost flag too
This fixes almost all the games that were broken in this branch
2024-07-05 10:58:05 -05:00
ergo720 0e63131fc3 Use a DPC for expired timers + don't execute NV2A DPCs from the timer thread to avoid the exception overhead 2024-07-05 10:58:05 -05:00
ergo720 889040c56a Fixed an issue in WaitApc where the wait block was not removed when using a zero timeout or when satisfied by a user APC + properly lock the wait block operations to avoid a race between SatisfyWait and KiTimerExpiration 2024-07-05 10:58:05 -05:00
ergo720 86542c9f2e Implemented PTIMER alarm interrupt of NV2A + fixed a bug in timer_init
This fixes DOAU showing the dirty disk error in PAL50 mode
2024-07-05 10:58:05 -05:00
ergo720 c9edbd1003 Fixed wrong nv2a clock frequency
This is accessed by DOAU via PTIMER only in PAL50 mode
2024-07-05 10:58:05 -05:00
ergo720 ebb122f2a0 Fixed a bug in KeTickCount + check all timer indices when we are late in KiClockIsr
This almost completely fixes the slowness in Panzer Dragoon Orta
2024-07-05 10:58:04 -05:00
ergo720 c158a472ff Make sure to reset WaitStatus when a new wait starts
This fixes an issue in Panzer Dragoon Orta, where KeDelayExecutionThread would return X_STATUS_TIMEOUT | X_STATUS_USER_APC
2024-07-05 10:58:04 -05:00
ergo720 6961d1c7a1 Make sure that GetNativeHandle succeeds before attempting to get the native handle
This fixes a sporadic crash in Panzer Dragoon Orta, where the title calls KeSetBasePriorityThread on a thread that has already terminated
2024-07-05 10:58:04 -05:00
ergo720 2f7cfe7e95 Fixed a bug in KiInsertTimerTable + log all objects being waited on in NtWaitForMultipleObjectsEx
This fixes a crash in Metal Slug 3
2024-07-05 10:58:04 -05:00
ergo720 46d0173673 Account for partial milliseconds in KiClockIsr
This fixes the slowness in The lord of the rings: the third era
2024-07-05 10:58:04 -05:00
ergo720 c7b028b3e7 Fixed a race condition in WaitApc + removed wrong InsertTailList for ktimers used during a timeout
This fixes almost all broken games in this branch. Still broken: PDO: 1 fps vs 10 fps, DOA3: freezes after title screen, Lord of the rings The third era: Unable to determine default Xbox backbuffer error???
2024-07-05 10:58:04 -05:00
ergo720 3d12edc77d Always create a wait object even when we satisfy the wait on the host side + fixed a bug in KiWaitTestNoYield
This fixes an occasionl freeze in Steel Battalion + the slowness in JSRF
2024-07-05 10:58:04 -05:00
ergo720 08ab4b9164 Revert to using the host to do thread suspension 2024-07-05 10:58:04 -05:00
ergo720 4fca5c7007 Hack: <= thread priority instead of >= 2024-07-05 10:58:04 -05:00
ergo720 e26f20108a Setup a KTIMER for the other functions using WaitApc too 2024-07-05 10:58:04 -05:00
ergo720 8475124e5b Restore single interrupt loop in update_non_periodic_events 2024-07-05 10:58:03 -05:00
ergo720 9b2ae106e5 Place nvnet in its own thread 2024-07-05 10:58:03 -05:00
ergo720 b3bfeca3a8 Use get_now directly in system_events instead of qpc 2024-07-05 10:58:03 -05:00
ergo720 b77a13b708 Adjust KeSystemTime when the host system time is changed by the user 2024-07-05 10:58:03 -05:00
ergo720 1b5e111ae3 Account for delays between calls to KiClockIsr
This fixes the slowness in the dashboard
2024-07-05 10:58:03 -05:00
ergo720 1504a75a46 Raise priority of system events thread 2024-07-05 10:58:03 -05:00
ergo720 87496ab873 Removed delta amount added to KeSystemTime 2024-07-05 10:58:03 -05:00
ergo720 5b37a7ec21 Fixed thread order initialization when a thread starts suspended 2024-07-05 10:58:03 -05:00
ergo720 639f42c318 Make sure to hold the DPC lock until the DPC list has been emptied
This fixes a crash in Lord of the rings: The fellowship of the ring
2024-07-05 10:58:03 -05:00
ergo720 8d92992a6b Implemented kernel unwait routines + updated/fixed KeWaitForMultipleObjects and KeWaitForSingleObject 2024-07-05 10:58:02 -05:00
ergo720 7323eed73e Only change the priority of a thread if it is being set above normal 2024-07-05 10:58:02 -05:00
ergo720 b47c1f195c Unpatch D3DDevice_BlockUntilVerticalBlank and D3DDevice_SetVerticalBlankCallback 2024-07-05 10:58:02 -05:00
ergo720 7c73bfc525 Avoid triggering multiple gpu interrupts outside the vblank 2024-07-05 10:58:02 -05:00
ergo720 1b4a3bb54f Moved position of ObfDereferenceObject in NtSuspendThread 2024-07-05 10:58:02 -05:00
ergo720 750d202fa8 Removed scaling hack in KeInterruptTime and KeTickCount + added yield in system_events routine
This fixes the stuttering in Halo 2, Metal slug 3, JSRF and restores PDO, PSO to the same state as in master
2024-07-05 10:58:02 -05:00
ergo720 e7bca5e1bf Implemented suspend/resume kernel Nt routines with the corresponding Ke routines 2024-07-05 10:58:01 -05:00
ergo720 937ab9e1c2 Fixed a bug in KeSetBasePriorityThread 2024-07-05 10:58:01 -05:00
ergo720 8006f55cf3 Merge many different periodic events in a single thread, instead of each having its own busy loop
This merges vblank, ohci's eof, pit interrupt, dsound sync and async workers, nvnet packet processing and system interrupt
2024-07-05 10:58:01 -05:00
ergo720 1828ddfd6f Merge lle and hle vblank routines in a single thread 2024-07-05 10:58:00 -05:00
ergo720 bc42cfaa6b Removed unnecessary lock in the interrupt thread 2024-07-05 10:58:00 -05:00
PatrickvL b1235b7733 Merge pull request #2458 from LukeUsher/fix-compilation-vs2022 2024-07-05 10:41:18 -05:00
Luke Usher 1615ecc976 fix the build on vs2022 17.9.1 2024-05-22 12:46:03 +01:00
Luke Usher 0007d20b03
Merge pull request #2445 from medievil1/fog-stuff
fog stuff
2024-05-22 12:42:07 +01:00
RadWolfie bfb10092c0
Merge pull request #2451 from RadWolfie/fix-hardware-model
Fix hardware model conversions + use respective hardware model based on console type
2024-02-08 12:48:46 -06:00
Luke Usher f5b4878245
Merge pull request #2452 from medievil1/my-master
fix incorrect setting in pixel shader template
2024-02-04 19:47:12 +00:00
RadWolfie 4174fbc23f review remarks 2024-02-04 13:29:40 -06:00
medievil1 0560ed6955 change clamp to saturate in shader templates
per discussions
2024-02-03 14:46:54 -05:00
medievil1 875015164c fix incorrect setting in pixel shader template
it should be normal2, not normal 3...
PS_TEXTUREMODES_DOT_RFLCT_DIFF(ts) works in conjunction with #define PS_TEXTUREMODES_DOT_RFLCT_SPEC(ts)(after) and PS_TEXTUREMODES_DOTPRODUCT(ts)(before)
dotproduct uses it's own product/normal, dot_rflct uses dotproduct and it's own, and dot_spec uses the previous 2 and it's own ... this corrects light reflection on the floor in Halo
2024-02-03 14:38:16 -05:00
medievil1 aedb5ba87b address review comment
remove PB pr sampling adjustments
2024-02-03 12:08:00 -05:00
RadWolfie e5dcdebe7f device: corrected conversions based on hardware model 2024-02-03 02:45:37 -06:00
medievil1 ad0b8340da change flow of fog table/enable
per Jack, change flow to :
if fog is disabled, avoid table code and just set fogFactor to 1
2024-01-24 00:34:47 -05:00
medievil1 7298b6c4dc address review comment
fix inadvertently not changing pixel shader pass to template c reg info
2024-01-23 21:45:15 -05:00
medievil1 b20db36e15 fix template formatting
hopefully it all matches now

Revert "fix template formatting"

This reverts commit 79aa4436ef330e8754755044ce3ebf9549c557ae.

fix template formatting

hopefully it all matches now
3rd times a charm  hopefully...lol
2024-01-21 14:52:36 -05:00
medievil1 a03d50df56 add FF fog move to Pixelshader 2024-01-20 15:14:02 -05:00
medievil1 0e25897f77 address review comments 2024-01-19 00:56:03 -05:00
medievil1 c6049b768c address review comments 2024-01-18 09:30:07 -05:00
medievil1 399baccadb fog stuff
fix no fog issue which was incorrectly passing data into iFog instead of 1 when fog was disabled

testing a move to pixel shader

adjust passthrough template

for move to pixel shader

remove printf
2024-01-18 01:29:15 -05:00
ergo720 3edc388abf
Merge pull request #2444 from RadWolfie/update-time-api
Fix RtlTimeFieldsToTime and RtlTimeToTimeFields implements
2024-01-15 15:38:03 +01:00
RadWolfie 796e8d2beb kernel: change 1000 to MSECSPERSEC 2024-01-15 05:19:57 -06:00
RadWolfie 282c5f5622 kernel: RtlTimeToTimeFields no longer need to be logged 2024-01-13 16:25:58 -06:00
RadWolfie 8e5b27d054 kernel: fix RtlTimeToTimeFields implement to match test results 2024-01-13 16:22:05 -06:00
RadWolfie b64a3b6faa kernel: fix comment typo in RtlTimeToTimeFields 2024-01-13 16:18:23 -06:00
RadWolfie d64e172c9f kernel: RtlTimeFieldsToTime no longer need to be logged 2024-01-05 01:26:08 -06:00
RadWolfie d6b96b8ea1 kernel: clean up RtlTimeFieldsToTime bad indents 2024-01-05 01:19:10 -06:00
RadWolfie 131b330a85 kernel: Change RtlTimeFieldsToTime's Time format into more readable math operation 2024-01-05 01:17:43 -06:00
RadWolfie bf6193202a kernel: split RtlTimeFieldsToTime range check into their own if statements for clear reading
Plus fixed a bug for leap year's day range
2024-01-05 01:15:15 -06:00
RadWolfie 06c28a847e Revert "Merge pull request #2441 from ergo720/time_fix"
This reverts commit 8cc9c73f58.
2024-01-05 00:33:34 -06:00
PatrickvL 8cc9c73f58
Merge pull request #2441 from ergo720/time_fix 2023-12-30 09:53:52 +01:00
ergo720 2452965580 Fixed a bug in RtlTimeFieldsToTime 2023-12-29 14:00:15 +01:00
PatrickvL eddc14e151
Merge pull request #2439 from NZJenkins/hotload_shaders 2023-12-29 11:43:42 +01:00
Luke Usher 31ff15ba1d
Merge pull request #2440 from RadWolfie/fix-xkts-issues
Fix Xbox Kernel Test Suite issues discovered
2023-12-21 15:29:44 +00:00
RadWolfie 4d9151ca26 rtl: remove unnecessary double setter in RtlInitUnicodeString 2023-12-20 09:31:35 -06:00
RadWolfie 1f1d1ac631 rtl: fix RtlCompareString and RtlCompareUnicodeString to match with kernel test suite 2023-12-17 20:50:46 -06:00
RadWolfie e5043dbc05 fix UNICODE_STRING's Buffer variable type issue 2023-12-17 20:49:10 -06:00
RadWolfie a2fb41856d kernel: fix RtlWalkFrameChain according to xbox kernel test suite failed test 2023-12-17 19:02:20 -06:00
RadWolfie b09d3ca69a kernel: update RtlAnsiStringToUnicodeString to include error log returns 2023-12-17 11:41:12 -06:00
Anthony 684d3338f2 Always copy hlsl files if they changed in the sources
Require files to be explicitly declared in CXBXR_HEADER_EMU in order to be copied
2023-11-18 11:34:05 +13:00
Anthony ae140bb6bf Copy and install hlsl files in the cxbx project 2023-11-16 23:00:18 +13:00
Anthony a5b8f15a14 reformat todo 2023-11-12 20:04:39 +13:00
Anthony 2c8a764fc7 Save a backup copy of hlsl files 2023-11-12 19:56:20 +13:00
Anthony 605271245c review comments 2023-11-11 22:19:46 +13:00
Anthony 93e36f7be3 Rename shaderhlsl to shadersources
and updateshaders to update
2023-11-11 01:08:34 +13:00
Anthony a7bc6a307d fixup remove unused variable 2023-11-11 01:08:34 +13:00
Anthony 7ad047bcea reduce crashing if the shaders are broken and get hotloaded 2023-11-11 01:08:34 +13:00
Anthony 0f21e25d7d Support hotloading pixelshaders 2023-11-11 01:08:34 +13:00
Anthony 79884bdf3d Move shader hlsl management into Shader.cpp
- g_ShaderHlsl keeps track of hlsl
- VS and PS source their hlsl from g_ShaderHlsl
2023-11-11 01:08:34 +13:00
Anthony 260e2fb7c8 Ensure filewatcher is closed if something goes wrong
and avoid creating multiple watchers
2023-11-11 01:08:34 +13:00
Anthony 4d221c3c81 tidy vertex shader loading 2023-11-11 01:08:34 +13:00
Anthony 712d3bee2f move passthrough shader to a file 2023-11-11 01:08:34 +13:00
Anthony 3cd551d827 Reload/recompile vertex shaders hlsl if they change 2023-11-11 01:08:34 +13:00
Anthony 397f33143d Rename VertexShaderSource to VertexShaderCache
because it was a weird name
2023-11-11 01:01:04 +13:00
ergo720 c7e75d7c5c
Merge pull request #2432 from Margen67/ci
CI: Upgrade checkout to v4
2023-10-21 16:19:43 +02:00
NZJenkins 4808be65c4
Slightly reduce build time (#2437) 2023-10-16 08:51:56 +02:00
Margen67 def10ff466
CI: Upgrade checkout to v4 2023-09-20 01:28:42 -07:00
Luke Usher e1ea10c4cb
Merge pull request #2428 from jackchentwkh/fix_pushbuffer_subroutine
fix COMMAND_TYPE_CALL pushbuffer command handling
2023-09-03 21:45:52 +01:00
Jack Chen 67f21d5c30 reset subr_active flag to indicate we've returned from any COMMAND_TYPE_CALL command.
NV2A used COMMAND_TYPE_JUMP_LONG to return from COMMAND_TYPE_CALL.
Otogi uses lot's of COMMAND_TYPE_CALL, this should inprove the pushbuffer handling.
2023-09-03 20:42:07 +08:00
PatrickvL 971318a89a
Merge pull request #2426 from Margen67/ci
CI: Fix output
2023-07-27 13:56:36 +02:00
Margen67 b62d39da7d CI: Fix output
set-output is deprecated: https://github.blog/changelog/2023-07-24-github-actions-update-on-save-state-and-set-output-commands/
2023-07-25 16:46:37 -07:00
Luke Usher 6c530fbf86
Merge pull request #2418 from RadWolfie/fix-reboot-non-ansii-path
kernel: fix non-ansii file path conversion for reboot process
2023-03-13 12:41:17 +00:00
RadWolfie a8f6d0496e kernel: fix non-ansii file path conversion for reboot process 2023-03-08 18:17:07 -06:00
Luke Usher 6389cb6524
Merge pull request #2417 from RadWolfie/d3d-update
Update XbSymbolDatabase fix and add LTCG patch missing
2023-03-06 14:50:23 +00:00
RadWolfie ef3439e46f d3d8: fix GTA: SA bug and add LTCG patch for D3DDevice_DrawVertices variant
Plus other variant LTCG patches that only does logging. And symbol renames.
2023-03-06 05:47:39 -06:00
ergo720 ed8a6124e4
Merge pull request #2416 from ergo720/dpc_recursion_fix
Dpc recursion fix
2023-03-02 23:32:30 +01:00
ergo720 b1bd9dd5d0
Merge pull request #2414 from RadWolfie/fix-hacked-ob-handle-return
kernel: fix hacked windows handle check to bypass special handle of current process
2023-03-02 23:04:40 +01:00
ergo720 062752e1a7 Review remarks 2023-03-02 22:53:18 +01:00
ergo720 99ab34ac82 Fixed dpc recursion bug 2023-03-02 14:59:10 +01:00
RadWolfie 8e0df988a8 kernel: fix hacked windows handle check to bypass special handle of current process 2023-03-01 17:04:42 -06:00
ergo720 58041c95b4 Clean up unused dpc event member variable 2023-03-01 22:43:42 +01:00
RadWolfie 827a3212f8
Merge pull request #2413 from ergo720/priority_thread
Fixed a bug in KeSetDisableBoostThread
2023-03-01 10:14:34 -06:00
ergo720 d0890d588d Fixed a bug in KeSetDisableBoostThread 2023-03-01 17:10:24 +01:00
Luke Usher 9e9d3f390f
Merge pull request #2412 from ergo720/priority_thread
Fix a priority bug in KeQueryBasePriorityThread and KeSetBasePriorityThread
2023-03-01 16:04:57 +00:00
ergo720 4821a72b6f Set/query the priority of the requested thread, instead of the current one in KeQueryBasePriorityThread and KeSetBasePriorityThread 2023-03-01 16:48:30 +01:00
Luke Usher bf1483ae56
Merge pull request #2411 from RadWolfie/update-xbsdb
lib: sync XbSymbolDatabase
2023-03-01 09:15:15 +00:00
RadWolfie b2f05b8b0b lib: sync XbSymbolDatabase 2023-02-27 04:37:02 -06:00
ergo720 111728f170
Merge pull request #2408 from LukeUsher/avoid-region-patching
cxbxkrnl: avoid region patching loaded titles
2023-02-10 18:35:28 +01:00
ergo720 ce05ea1397
Merge pull request #2409 from RadWolfie/fix-emulation-status
Fix false positive emulation is either still running or stopped
2023-02-10 18:17:12 +01:00
RadWolfie f4488c0270 fix false positive emulation is either still running or stopped 2023-02-10 07:16:12 -06:00
Luke Usher 65a5ad6591 cxbxkrnl: avoid region patching loaded titles
While it sounds ideal from a UX standpoint, region patching does break a number of
titles that would otherwise work.

Instead, show a warning that it may not be compatible with instructions on how to
configure region settings in eeprom.

Allow the user to attempt to run the title anyway, if the game does not do it's own
region checking, it will most likely just work regardless.
2023-02-07 22:08:31 +00:00
RadWolfie 0b695637ce
Merge pull request #2406 from LukeUsher/fix-xbe-version-reporting
xbe: fix version number formatting
2022-11-20 06:24:51 -06:00
Luke Usher fe9a706a8e xbe: fix version number formatting 2022-11-19 16:06:12 +00:00
Luke Usher 8ac5d14cd2
Merge pull request #2401 from medievil1/new-master
correct hemisphere formula
2022-10-13 14:39:59 +01:00
Luke Usher 628323218a
Merge pull request #2404 from CookiePLMonster/remove-int32x32To64
Remove Int32x32To64 from the code
2022-10-06 22:41:51 +01:00
Silent f7c09ddc4f
Remove Int32x32To64 as it's potentially harmful 2022-10-06 23:07:37 +02:00
ergo720 09e744ecc4
Merge pull request #2403 from RadWolfie/libusb-fixes
HOTFIX: Fix LibusbDevice's initialization process
2022-10-06 00:36:31 +02:00
RadWolfie a37124e2dc readme: create a link to libusb's driver installation section to find suggested driver 2022-10-05 17:09:17 -05:00
RadWolfie 5f58ae918c input: have libusb_claim_interface's return actually give err number than comparsion check for non-zero 2022-10-05 16:46:17 -05:00
RadWolfie f17b7f7fa6 input: check for error from libusb_open and report as device invalid 2022-10-05 16:40:39 -05:00
RadWolfie 4dccf6d5b9 input: don't override device's vendor id, expected to do comparsion instead 2022-10-05 06:42:56 -05:00
medievil1 6bbe6cefe8 added notes
changed a couple things around and added notes

correct hemisphere formula

correct one entry

make twointoone shorter

Per PatrickvL's suggestion and code
2022-09-25 19:32:25 -04:00
PatrickvL 547c3ae663
Merge pull request #2398 from LukeUsher/xxh3-hash 2022-09-24 07:26:34 +02:00
PatrickvL c594e34ac5
Merge pull request #2400 from jarupxx/dialog 2022-09-24 07:24:38 +02:00
jarupxx caae99952c Fixed a Folder select dialog 2022-09-24 04:51:55 +09:00
Luke Usher aeeb67dc6a hasher: use xxh3 exclusively 2022-09-14 13:51:05 +01:00
Luke Usher 4204640052
Merge pull request #2397 from medievil1/new-master
correct mod instruction
2022-09-11 18:45:16 +01:00
medievil1 3c78dd29a7 correct mod instruction 2022-09-11 13:22:29 -04:00
PatrickvL 42ff76ce0f
Merge pull request #2389 from medievil1/upsteam-master 2022-08-26 22:26:56 +02:00
PatrickvL bf931d2d81
Merge pull request #2393 from medievil1/new-master 2022-08-26 21:40:56 +02:00
medievil1 a2a4fb35a4 xdm, xdd, xmd component count fix
all 3 use 3 components but on cxbx they were using 4
discovered by NzJenkins
test case Morrowind water

cosmetic fix

:P

changed per Patrick's request

reinsert line accidentally deleted

final change, move xdot

needed one more cosmetic space change

more fornatting
2022-08-26 15:37:14 -04:00
medievil1 f570c05e95 fix up
REMOVE HACK comment
REMOVE extra white space
2022-07-17 23:58:16 -04:00
medievil1 0b76da7c00 per review remarls
moved the case to the else statement and added a log entry
2022-07-17 23:38:41 -04:00
medievil1 9ee5b45b88 typo fix 2022-07-17 10:16:27 -04:00
medievil1 ee7be21bbb fix dot_str_cube not kicking in
when a cube texture is used and dot_str_3d is the texture mode, it is suppose to be flagged by combiner for change to dot_str_cube.
2022-07-17 10:10:12 -04:00
Luke Usher 8fcc2f5e0c
Merge pull request #2387 from LukeUsher/fix-heap-corruption-at-startup-with-nvnet
Fix heap corruption in NVNetDevice::GetMacAddress
2022-07-13 09:36:31 +01:00
Luke Usher 56610cd899 Fix heap corruption in NVNetDevice::GetMacAddress
This could cause startup of CxbxR to fail for some users.
2022-07-12 09:40:27 +01:00
Luke Usher 9fab1d5bed
Merge pull request #2386 from LukeUsher/fix-multi-xbe-vfs
emufile: fix multi-xbe titles when running through xbox-iso-vfs
2022-07-11 14:22:49 +01:00
PatrickvL 0043e45531
Merge pull request #2374 from NZJenkins/vsh-op-independence
Fix vertex shader op independence
2022-07-08 22:18:50 +02:00
Luke Usher bc9cbec518
Merge pull request #2385 from ergo720/gui_xbe_crash
Fixed a crash in the gui when opening an xbe fails
2022-07-08 20:40:53 +01:00
Luke Usher 4edd3feb3e emufile: fix multi-xbe titles when running through xbox-iso-vfs
Prior to this commit, the relaunch path would become corrupted when running a game mounted with xbox-iso-vfs.
2022-07-08 20:37:32 +01:00
ergo720 0717c0166b Fixed a crash in the gui when opening an xbe fails 2022-07-08 13:38:52 +02:00
PatrickvL 16ffe3a80f
Merge pull request #2384 from LukeUsher/allow-skipping-faulty-instructions
EmuException: allow skipping of instructions that trigger unhandled exceptions
2022-07-08 13:21:15 +02:00
Luke Usher 5f3cfdeb77 address feedback 2022-07-08 11:37:48 +01:00
Luke Usher a650fd2078
Merge pull request #2375 from ergo720/libusb_update
Updated libusb submodule to include deadlock fix
2022-07-08 09:59:19 +01:00
Luke Usher cfa7be71cf
Merge pull request #2378 from ergo720/sb_fix
Fixed slowness in Steel Battalion caused by WaitApc
2022-07-08 09:58:01 +01:00
Luke Usher 4076a5b758 EmuException: allow skipping of instructions that trigger unhandled exceptions.
In many cases, this will result in more instability, however, it is useful as a debugging tool:
some games that would otherwise be working are let down by a *single* invalid read or write, and skipping
over that instruction allows the game to be played.

This can enable further research/debugging within the title.
2022-07-06 09:21:23 +01:00
ergo720 6e3635d90a Updated libusb to include deadlock fix 2022-07-05 22:25:08 +02:00
ergo720 ce55fe8627 Fixed slowness in Steel Battalion caused by WaitApc 2022-07-05 22:24:12 +02:00
Luke Usher b2f63918de
Merge pull request #2382 from jackchentwkh/vsh_cpu_2
Implement HLE D3DDevice_RunVertexStateShader()
2022-07-05 15:57:43 +01:00
Luke Usher f6274cc59f Revert "fix order of thread initialization"
This reverts commit 3a50d7e136.
2022-07-05 15:29:55 +01:00
PatrickvL 8546d7c10d EMUPATCH(D3DDevice_RunVertexStateShader):
added LOG_TEST_CASE precondition checks, replacing an assert
simplified implementation (no need for an intermediate variable)
commented some notes and future suggestions
2022-06-30 11:33:29 +02:00
jackchentwkh 4c5995af0c using memset for vertex_state_shader_v0[] init. 2022-06-26 11:00:04 +08:00
jackchentwkh c981ff23b1 Correction of v0.xyzw assignment. 2022-06-26 11:00:04 +08:00
jackchentwkh 186b5fa8ee adopt api changes of nv2a_vsh_emu_execute_track_context_writes().
using pg->vsh_constants_dirty[] again.
2022-06-26 11:00:04 +08:00
jackchentwkh ce4f4a07f0 adopt api nv2a_vsh_emu_initialize_xss_execution_state change from 3 args to 2 args.
mark all vertex constants dirty after vertex state shader execution.
2022-06-26 11:00:04 +08:00
jackchentwkh 4d110bad6e Implement RunVertexStateShader() 2022-06-26 11:00:04 +08:00
RadWolfie 6f79b035bd cmake: include nv2a_vsh_cpu libraries 2022-06-26 11:00:03 +08:00
jackchentwkh 7bc95d7a67 Add nv2a_vsh_cpu submodule 2022-06-26 11:00:03 +08:00
NZJenkins 5a454aad5c
Merge pull request #2381 from NZJenkins/cubemap-mips
Fix mipmapped cubemaps
2022-06-25 17:49:31 +12:00
Anthony 6cbb385b89 Fix mipmapped cubemaps
which had broken faces (other than the first face)
because the slice pitch calculation did not account for mipmaps.
We are iterating the mipmaps already, so just calculate the slice pitch directly
rather than trying to generalize CxbxGetPixelContainerMeasures
2022-06-22 23:57:22 +12:00
RadWolfie 31a47cde37
Merge pull request #2377 from ergo720/suspend_disable
Fix shutdown instability
2022-06-20 16:10:37 -05:00
ergo720 aba8fc8341 Fix shutdown freeze 2022-06-20 22:24:11 +02:00
Anthony 46b1f24153 Fix vertex shader op independence
Ensure the MAC op does not interfere with the input of the ILU op.
- Use a temp register to hold the input of the ILU op when necessary
- Reorganize vertex shader decoding to better reflect the data.
Decode one vsh instruction to one intermediate instruction, rather than to multiple independent instructions.
Test case:
KOTOR II (menu)
GTA III (lighting)
2022-06-18 15:24:08 +12:00
PatrickvL b43f6bbcdf
Merge pull request #2369 from RadWolfie/fix-vs-popup-newline-dialog
Fix Visual Studio's popup dialog about newline correction
2022-05-28 20:58:10 +02:00
RadWolfie 33aad02f93 fix Visual Studio's popup dialog about newline correction 2022-05-28 10:36:55 -05:00
Luke Usher 1710f01c35
Merge pull request #2364 from RadWolfie/update-subhook
Update subhook to restore support for chihiro research
2022-05-22 11:17:04 +01:00
RadWolfie f8e4f59eae update subhook to restore support for chihiro research 2022-05-21 13:53:46 -05:00
RadWolfie 4b5edbdc94
Merge pull request #2358 from RadWolfie/update-overlay
Add build, title name, and file name to overlay
2022-05-21 13:48:56 -05:00
PatrickvL 3bf2effa4d
Merge pull request #2359 from RadWolfie/fix-faux-fs-toggle
Fix faux fullscreen overlay input
2022-05-21 19:45:06 +02:00
RadWolfie 6ab30793ed review remark 2022-05-21 12:43:24 -05:00
Luke Usher 3d244b78b3
Merge pull request #2363 from NZJenkins/setmodelview
Minimal SetModelView implementation
2022-05-21 13:31:07 +01:00
Anthony 2512840968 Minimal SetModelView implementation 2022-05-21 19:24:08 +12:00
RadWolfie ecef7aec39 review remark 2022-05-16 11:40:32 -05:00
Luke Usher 95b789eb27
Merge pull request #2360 from CookiePLMonster/fix-sleep
Do not leave KeDelayExecutionThread prematurely
2022-05-16 09:43:04 +01:00
Luke Usher 5e928e508a
Merge pull request #2362 from CookiePLMonster/resource-creation-lifetime
Keep D3D resources alive during resource creation
2022-05-16 09:10:10 +01:00
Silent 39ced81d58
Keep D3D resources alive during creation to prevent them being destroyed too early
Fixes an issue where a game could tear down a resource from another
thread while it's still initializing
2022-05-15 23:11:08 +02:00
Silent b7006e2b01
Do not leave KeDelayExecutionThread prematurely
Fixes games waking up from Sleep() calls immediately
2022-05-15 14:47:39 +02:00
RadWolfie fa85d3dad4 fix faux fullscreen toggle 2022-05-10 19:07:45 -05:00
RadWolfie 05a7acf13e overlay: Add build, title name, and file name to overlay 2022-05-09 10:39:14 -05:00
RadWolfie 8b35389c71
Merge pull request #2357 from ergo720/sb_auto_cursor
Make the SBC use the cursor mouse mode by default
2022-05-08 17:50:38 -05:00
RadWolfie e8f943ebbc
Merge pull request #2356 from ergo720/fix_irql_mask
Fixed wrong irql masks
2022-05-08 17:50:18 -05:00
ergo720 87042c6bcc Make the SBC use the cursor mouse mode by default 2022-05-08 14:17:11 +02:00
ergo720 88a37ac496
Merge pull request #2353 from RadWolfie/fix-tls-data-emu
Fix tls data initialization from cxbxr's emulation threads end
2022-05-08 01:34:07 +02:00
ergo720 2168b033c6 Added comment 2022-05-07 22:30:35 +02:00
ergo720 a1cffc79f8 Fixed wrong irql masks 2022-05-07 18:56:33 +02:00
RadWolfie 1077115038
Merge pull request #2355 from RadWolfie/fix-gui-purge-regress
Fix pull request 2348 regression
2022-05-07 10:34:21 -05:00
RadWolfie 774ef7c9e3 fix pull request 2348 regression 2022-05-02 15:30:07 -05:00
RadWolfie 9973ec7b6f fix tls data initialization from cxbxr's emulation threads end 2022-05-02 09:46:14 -05:00
ergo720 5e42d181f2
Merge pull request #2348 from RadWolfie/emu-gui-purge
Purge emulation codebase from GUI project
2022-04-25 14:09:45 +02:00
RadWolfie 23488ad22b review remark 2022-04-25 04:49:22 -05:00
RadWolfie 8b0b016aec more cleanup 2022-04-14 00:14:41 -05:00
RadWolfie cd09cf8dfd remove emu codebase from gui's side 2022-04-14 00:14:41 -05:00
ergo720 374ba5ec70
Merge pull request #2345 from RadWolfie/init-thread-fix
Fix order of thread initialization
2022-04-13 15:29:31 +02:00
RadWolfie 3a50d7e136 fix order of thread initialization 2022-04-13 07:54:19 -05:00
PatrickvL 696d49820c
Merge pull request #2342 from NZJenkins/unc-xbes
Better support for UNC paths
2022-04-12 12:58:16 +02:00
Anthony 2a3656bf24 Some comments on the "mount point" 2022-04-12 19:26:31 +12:00
Anthony 469352e72a Better support for UNC paths
Fix launching demos when the title was loaded from a UNC path
e.g. MechAssault with quantum redshift demo

We use GetFinalPathNameByHandle, which returns a "root local device" path beginning with '\\?\'

For UNC paths, this looks like '\\?\UNC\bla' - but this path was not handled correctly.

Before, '\\?\' was immediately stripped from the beginning of the path,
resulting in an invalid relative path e.g 'UNC\bla' - causing errors.

Now, we don't strip anything from the path, and accept it as-is.

In some related code, we also need to use the '\' character instead of '/'
since '/' is not the path separator on Windows and is not valid to add to a path beginning with '\\?\'.

Info about paths windows paths
https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html
2022-04-12 19:11:42 +12:00
NZJenkins 72908248eb
Merge pull request #2341 from NZJenkins/jsrf-storage-spaces
Clear FILE_NO_INTERMEDIATE_BUFFERING in IoCreateFile
2022-04-07 19:32:28 +12:00
Anthony e9212c35f7 Fix annoying assert
asserting when D3DDECLTYPE_FLOAT1 was in use
2022-04-06 22:21:12 +12:00
ergo720 4b5bef273d
Merge pull request #2340 from RadWolfie/impl-thread-stack-reader
Implement Thread Stack Readers
2022-04-06 11:14:52 +02:00
RadWolfie a338a12d77 revert partial review remark 2022-04-06 03:42:35 -05:00
Anthony 88b686c27d Clear FILE_NO_INTERMEDIATE_BUFFERING in IoCreateFile
Fixes JSRF issue with loading titles from Windows Storage Spaces
2022-04-06 19:49:02 +12:00
RadWolfie b84e80663f review remark 2 2022-04-05 17:57:05 -05:00
RadWolfie 351c9a7c86 review remark 2022-04-05 17:45:36 -05:00
RadWolfie 6d395bf2ee fix alignment from tabs to spaces 2022-04-03 19:08:14 -05:00
RadWolfie 57640cad49 Implement RtlGetCallersAddress 2022-04-03 19:08:13 -05:00
RadWolfie 1d030aa41f Implement RtlCaptureStackBackTrace 2022-04-03 19:08:13 -05:00
RadWolfie c723c56e4a Implement RtlWalkFrameChain 2022-04-03 19:08:13 -05:00
ergo720 5f7b9417b0
Merge pull request #2339 from RadWolfie/improve-thread-setup
Improve Xbox Thread Setup
2022-04-04 00:54:23 +02:00
RadWolfie 877c87537e review remark 2022-04-03 17:30:08 -05:00
ergo720 9f87854040
Merge pull request #2130 from RadWolfie/update-readme
Variant Update to Readme
2022-04-01 01:37:47 +02:00
RadWolfie 38eeef7c0d add readme to informational label 2022-03-31 18:11:03 -05:00
RadWolfie 5d87ad46c6 update speical thanks section 2022-03-31 17:49:24 -05:00
RadWolfie 7b9634a3ec fix new line in markdown 2022-03-31 17:36:19 -05:00
RadWolfie 8dd54df4a8 Review remarks 2022-03-31 17:35:17 -05:00
RadWolfie c5fe198bb2 direct users from readme to official site's download page 2022-03-31 17:27:47 -05:00
RadWolfie a81ec74d06 fixup wine usage 2022-03-31 17:25:47 -05:00
RadWolfie 82427abcb8 fix hidden bug when binaries are mixed 2022-03-29 20:36:58 -05:00
RadWolfie f0a1301b64 improve xbox thread implement 2022-03-29 20:36:58 -05:00
RadWolfie d9785e7225 prepare and clean up kernel types 2022-03-29 20:36:58 -05:00
RadWolfie 067aa82cc7
Merge pull request #2337 from ergo720/mmglobaldata
Fixed wrong type for MmGlobalData kernel export
2022-03-29 08:23:22 -05:00
ergo720 5d5fc992da Fixed wrong type for MmGlobalData kernel export 2022-03-29 14:47:00 +02:00
ergo720 dc1f93b120
Merge pull request #2326 from NZJenkins/exp/dsound-buffer-streaming
DirectSoundBuffer streaming
2022-03-29 14:03:54 +02:00
RadWolfie d0b4c6abac
Merge pull request #2336 from ergo720/sdl_update
Updated SDL submodule to 2.0.20 stable version
2022-03-28 20:15:00 -05:00
ergo720 09c5eb405d Updated SDL submodule to 2.0.20 2022-03-28 18:40:39 +02:00
RadWolfie 3908a8c7b2
Merge pull request #2334 from ergo720/C++20
Updated cxbxr projects to use and build with C++20
2022-03-28 04:18:36 -05:00
ergo720 51ddb6c1d1 Dropped VS2019 builds and updated readme 2022-03-28 10:53:46 +02:00
ergo720 bfa9abbc1b Updated cxbxr projects to use and build with C++20 2022-03-22 00:52:52 +01:00
Anthony aac207c78e Fix typo 2022-03-14 17:10:26 +13:00
Anthony 49b4988953 Co-locate imgui includes 2022-03-13 21:41:13 +13:00
Anthony da27e1456b Restore Unlock logging 2022-03-12 09:57:32 +13:00
Anthony baa1cf5470 Ensure End() is called after Begin/BeginChild, regardless of return value
Note this is not required for other Begin apis
2022-03-12 09:53:22 +13:00
Anthony feb1f0383d Comment some includes 2022-03-12 09:45:23 +13:00
RadWolfie 6788bf16f3
Merge pull request #2328 from Margen67/actions
CI: Upgrade checkout+upload/download-artifact to v3+labeler to v4
2022-03-11 02:25:13 -06:00
Margen67 b1446a5f6b Other workflow improvements
autoclose:
 Use checkout v3.
pull-request:
 Use labeler v4.
2022-03-10 23:56:00 -08:00
Margen67 0a72fbf7f7 CI: Upgrade checkout+upload/download-artifact to v3 2022-03-09 13:45:50 -08:00
Anthony 4186d4ba8b Avoid expensive calls to DirectSound on buffers unless they've been played at least once 2022-03-07 21:24:35 +13:00
Anthony 4c30264136 DirectSoundBuffer visualization debug view
- Visualize play progress, play region, loop region
- Buffer streaming controls
- Scale visualization to window by RadWolfie
2022-03-07 21:24:35 +13:00
Anthony 7528d9a4e3 Change locking APIs to nops
to prevent interference DirectSoundBuffer streaming.
2022-03-07 20:33:12 +13:00
Anthony 60dbf241e8 Stream audio from Xbox DirectSoundBuffers
to handle cases where titles write to sound buffers after they are created.
Note titles do not have to lock the buffer or otherwise call any API to write to sound buffers.

Every few ms, for each sound buffer currently playing, write a chunk of sound data ahead of the current audio play cursor.

Fixes audio issues in titles including:
- NBA Live 2005 (no audio)
- Crash Tag Team Racing (audio looping incorrectly)
- Madagascar (audio looping incorrectly)
2022-03-07 20:33:11 +13:00
Anthony 852adf0d21 optimize DirectSound Buffer's StopEx function 2022-03-06 21:00:02 +13:00
Luke Usher 1e300d63ec
Merge pull request #2310 from Margen67/actions
CI: Upgrade to VS2022
2022-03-04 09:02:15 +00:00
Margen67 5b0cf41507 Update README 2022-03-04 00:26:57 -08:00
Margen67 0c8dd778d0 CI: Upgrade to VS2022
Remove windows-2016 since it's going to be removed soon;
 actions/virtual-environments#4312
Use ${GITHUB_SHA::7} for tag to prevent commit weirdness.
2022-03-03 21:48:08 -08:00
RadWolfie 25b9a2efcc
Merge pull request #2325 from LukeUsher/log-failed-patches
hle: detect when patches fail to apply
2022-03-01 17:00:42 -06:00
Luke Usher 3a59c62753
Update src/core/hle/Patches.cpp
Co-authored-by: RadWolfie <RadWolfie@users.noreply.github.com>
2022-03-01 22:41:18 +00:00
Luke Usher 884a9080b5 hle: detect when patches fail to apply 2022-03-01 20:40:56 +00:00
ergo720 f857593f77
Merge pull request #2315 from ergo720/thread_ob_handle
Updated Ps kernel functions to use Ob handles + unpatch thread XAPI functions + added APC support to kernel via Ob
2022-02-22 23:20:29 +01:00
ergo720 d3b2554b20 Use a separate array for the native handles in NtWaitForMultipleObjectsEx 2022-02-20 16:07:42 +01:00
ergo720 f174872702 Unpatch timeSetEvent and timeKillEvent + fixes a crash in chihiro games + missing audio effects in virtua cop 3 + fixes a bug in SignalObjectAndWait 2022-02-20 12:22:36 +01:00
ergo720 c6ea72dcf4 Use a condition variable to notify interrupts, fixes stuttering in the dashboard 2022-02-18 20:17:22 +01:00
ergo720 bc98e164b2 Removed CxbxKrnlTerminateThread and some unnecessary calls to TerminateProcess 2022-02-18 15:30:18 +01:00
ergo720 6867907a3c Fixed a bug in NtWaitForMultipleObjectsEx that caused the dashboard to deadlock + more review remarks 2022-02-18 12:42:56 +01:00
ergo720 7589f0a94c Avoid using std::async in WaitApc 2022-02-17 02:33:44 +01:00
RadWolfie a769e896c6 hidden bug while debugging on xbox kernel thread's issue 2022-02-16 18:20:04 +01:00
RadWolfie 44ed2ee3aa update Timer_Shutdown to reduce wait time for shutdown if threads are all xbox 2022-02-16 18:20:04 +01:00
ergo720 06f34134ff Review remarks + use PsCreateSystemThread to start all xbox threads 2022-02-16 18:20:04 +01:00
RadWolfie 6320dd5539 fix shutdown process crashed on shutdown and reboots 2022-02-16 18:20:03 +01:00
RadWolfie 8c7247abf5 reimplement suspend xbox threads so we can shutdown emulation properly 2022-02-16 18:20:02 +01:00
RadWolfie 0b90a48434 register duplicated xbox handle require duplicated handle from host 2022-02-16 18:20:01 +01:00
ergo720 e85af190d5 Properly set the ref count of ethread, fixes Amped 2022-02-16 18:20:01 +01:00
ergo720 733670c7f8 Fixed an issue with xbox handle registration 2022-02-16 18:20:01 +01:00
ergo720 79ac0c3019 Updated thread timings in ethread + null id upon thread termination 2022-02-16 18:20:00 +01:00
ergo720 ec6b16c68a Added support to Ps notification routines 2022-02-16 18:20:00 +01:00
ergo720 e9cc351bba Unpatch XSetProcessQuantumLength + moved unused xapi patched to standalone file + added code to handle xbox user APCs in SignalObjectAndWait 2022-02-16 18:19:59 +01:00
RadWolfie e208c73586 fix thread calls issue from GetNativeHandle to keep special handle return 2022-02-16 18:19:59 +01:00
RadWolfie 7e5f9a7cb7 unpatch GetExitCodeThread 2022-02-16 18:19:58 +01:00
RadWolfie b39801df11 unpatch SetThreadPriority, GetThreadPriority, SetThreadPriorityBoost 2022-02-16 18:19:58 +01:00
ergo720 a791b7609c Updated KeDelayExecutionThread, KeSetBasePriorityThread and XAPI thread functions to accept ob handles + more bug fixes 2022-02-16 18:19:58 +01:00
ergo720 b664488274 Bug fixes 2022-02-16 18:19:57 +01:00
ergo720 114be1b7c9 Added APCs support to kernel 2022-02-16 18:19:57 +01:00
ergo720 607a48e3ea Update Nt functions that accept thread handles (except for NtQueueApcThread) 2022-02-16 18:19:56 +01:00
ergo720 9082891903 Make Ps functions use Ob to create thread handles 2022-02-16 18:19:56 +01:00
Luke Usher 484a2c3f47
Merge pull request #2321 from PatrickvL/cleanup_system_selection
Cleanup system selection, so it's no longer abusing xbeType
2022-02-16 14:10:55 +00:00
PatrickvL c883034372 Cleanup system selection, so it's no longer abusing xbeType
Rename g_bIsDebug into g_bIsDevKit for consistency with system selection
Cleaned up related comments
2022-02-16 14:56:45 +01:00
Luke Usher 41d45dd88d
Merge pull request #2320 from ergo720/fix_port_func_arg
Fix incorrect type in port io kernel functions
2022-02-06 10:57:12 +00:00
Luke Usher 86022747f0
Merge pull request #2319 from RadWolfie/init-exception-manager-early
Move Crash Manager's Init at Beginning of Emulation & Fix Hidden Crash
2022-02-06 10:56:44 +00:00
ergo720 1125c1c45d Fix incorrect type in port io kernel functions 2022-02-06 11:33:58 +01:00
RadWolfie 7d116628c2 make complete set of FS instructions for offset 0x00 and 0x04 to retreive and set 2022-02-05 17:33:09 -06:00
RadWolfie f41cc02c6c disable overwrite host's stack data 2022-02-04 13:15:07 -06:00
RadWolfie da72da4d03 initialize exception manager at beginning of emulation process 2022-02-04 12:29:05 -06:00
PatrickvL db1bae2d4e
Merge pull request #2318 from GXTX/port_fixes
Fix kernel type hints for READ_PORT_BUFFER and friends
2022-02-04 08:59:19 +01:00
wutno 59fe8eb6db Fix kernel type hints for READ_PORT_BUFFER and friends 2022-02-04 02:20:27 -05:00
Luke Usher be4fb1deb6
Merge pull request #2312 from RadWolfie/fix-uem-led-status
Fix UEM and LED Status
2022-01-28 16:37:49 +00:00
RadWolfie 1e05973b81
Merge pull request #2301 from Margen67/net
Upgrade CxbxDebugger to .NET Framework 4.8
2022-01-28 10:24:08 -06:00
RadWolfie 79b3b4e803
Merge pull request #2308 from Margen67/labeler
labeler.yml: Consistently use quotation marks
2022-01-23 02:41:19 -06:00
Margen67 02b9d75b38
Update .github/labeler.yml
Co-authored-by: RadWolfie <RadWolfie@users.noreply.github.com>
2022-01-23 00:37:47 -08:00
Margen67 349f28c6cb Upgrade CxbxDebugger to .NET Framework 4.8 2022-01-19 15:59:17 -06:00
RadWolfie 4625a34eec fix LED status and emulation state 2022-01-18 13:37:05 -06:00
RadWolfie 5ac2d3e152 fix UEM screen not showing up every time 2022-01-18 13:37:04 -06:00
Luke Usher 1b10e1b9d4
Merge pull request #2298 from RadWolfie/sync-xbsdb
Sync XbSymbolDatabase + Add Missing Patch
2022-01-16 15:35:07 +00:00
Margen67 822f4f9b9a
labeler.yml: Consistently use quotation marks 2022-01-14 12:21:55 -08:00
Luke Usher c65d26a284
Merge pull request #2299 from Margen67/actions
CI.yml: Minor improvements
2022-01-14 14:07:27 +00:00
RadWolfie 54d3ee11bb add missing patch for D3DDevice_GetBackBuffer2_0__LTCG_eax1 2022-01-12 00:30:54 -06:00
RadWolfie 50b969549f sync XbSymbolDatabase 2022-01-12 00:30:54 -06:00
Luke Usher f8b449d6b1
Merge pull request #2306 from NZJenkins/sc-lighting
Fixup sampling cube textures with PROJECT2D
2022-01-10 09:15:00 +00:00
Anthony a844dffa95 Fixup sampling cube textures with PROJECT2D
Use CUBEMAP sampling instead
Fixes lighting in Splinter Cell Chaos Theory
2022-01-09 22:50:59 +13:00
Luke Usher a25e455289
Merge pull request #2305 from CookiePLMonster/adl-cpusets
Fixup Win10 CPU Sets to check the EfficiencyClass
2021-12-30 21:42:14 +00:00
Silent f41f73f6c3
Fixup Win10 CPU Sets to check the EfficiencyClass
Instead of picking the first physical core for Xbox threads,
Cxbx-R now picks the first highest performance physical core.
While at least Alder Lake lists performance cores first,
this is not guaranteed to always be the case in the future.
2021-12-30 21:36:20 +01:00
RadWolfie 283331412a
Merge pull request #2302 from ergo720/ob_fix
Allow ObIniSystem to succeed
2021-12-28 18:47:14 -06:00
ergo720 6078193fec Fixed a bug in ObOpenObjectByName 2021-12-27 16:04:57 +01:00
ergo720 922bd4e9d2 Added ObLock and ObUnlock 2021-12-27 16:04:57 +01:00
ergo720 a7cf67cd71 Allow ObIniSystem to succeed 2021-12-27 11:58:09 +01:00
Margen67 c1fb2d665b CI.yml: Minor improvements
Ignore more files.
Rename os to runs-on for consistency.
Add VS2022. (commented out due to #2300)
Remove working-directory.
Make release stat condition use single brackets;
 Same behavior, but two less characters.
2021-12-22 11:16:32 -08:00
Luke Usher 3e5272d91a
Merge pull request #2284 from NZJenkins/swap-copy
Tweak Swap behaviour to fix flickering in some titles
2021-12-22 11:03:15 +00:00
RadWolfie e77404472e
Merge pull request #2297 from ergo720/jedi_fix
Simulate correctly the USB enumeration process in XGetDevices
2021-12-12 15:40:16 -06:00
ergo720 ef5c9ad4fb Simulate correctly the USB enumeration process in XGetDevices 2021-12-12 21:59:20 +01:00
ergo720 0c28aca19c
Merge pull request #2295 from RadWolfie/libusb-rollback
Rollback libusb to v1.0.24 release tag instead of wip development
2021-12-11 02:05:02 +01:00
ergo720 7c630d6104
Merge pull request #2296 from ergo720/xbox_constants
Switched some xbox ntstatus codes to uppercase
2021-12-09 13:08:41 +01:00
ergo720 29e1dc865d Switched to uppercase for xbox ntstatuses 2021-12-04 23:09:09 +01:00
RadWolfie c9fe07ab98
Merge pull request #2294 from ergo720/lightgun
Added support for the lightgun input device
2021-11-29 12:33:23 -06:00
ergo720 0b2c0a2e33 review remarks 2021-11-29 14:45:24 +01:00
ergo720 66b83d98e4 Bug fixes 2021-11-27 23:53:54 +01:00
ergo720 caf7927445 Added lightgun laser emulation 2021-11-27 23:53:53 +01:00
ergo720 c658777645 Added lightgun support to input manager 2021-11-27 23:53:51 +01:00
ergo720 2c1f5bd430 Added lightgun support to xapi 2021-11-27 23:53:50 +01:00
ergo720 4645d42130 Added lightgun support to input gui 2021-11-27 23:53:49 +01:00
RadWolfie 41c9d7a352
Merge pull request #2292 from Fisherman166/SecureTrayEject
Implement HalEnableSecureTrayEject xbox kernel function.
2021-11-25 13:03:29 -06:00
Dartht33bagger 84ea340da1 Add TODO for implementing SMC_COMMAND_RESET_ON_EJECT in the future. 2021-11-25 09:56:08 -08:00
RadWolfie 6d08f2a99b rollback libusb to v1.0.24 release tag instead of wip development 2021-11-21 21:47:12 -06:00
Fisherman166 886bef5c8a Implement HalEnableSecureTrayEject xbox kernel function. 2021-11-13 17:15:27 -08:00
ergo720 4457d110bf
Merge pull request #2291 from RadWolfie/update-xbsymboldatabase
Update XbSymbolDatabase Module
2021-11-09 18:17:09 +01:00
RadWolfie 8e424759df update XbSymbolDatabase module 2021-11-08 11:44:51 -06:00
ergo720 f7042be933
Merge pull request #2290 from ergo720/hw_passthrough
Add support for original xbox gamepads and SBC hardware via USB passthrough with libusb
2021-11-08 11:46:59 +01:00
ergo720 7791c9dd78 Review remarks 2021-11-06 19:19:38 +01:00
ergo720 c76de904dc Added WinUSB requirement to README 2021-11-06 14:29:37 +01:00
ergo720 5a01ce5297 Fixed wrong SBC subtype + fixed off by two bytes rumble struct + removed rumble hack + switched to interrupt transfers 2021-11-06 14:29:37 +01:00
ergo720 1886819a35 Added a hack(?) to get rumble working with libusb 2021-11-06 14:29:37 +01:00
ergo720 6a9e242fad Added gui for libusb devices + bug fixes 2021-11-06 14:29:37 +01:00
ergo720 9092f7bbe6 Extended LibusbDevice class + allowed xapi to work with libusb devices 2021-11-01 17:03:40 +01:00
ergo720 006af26a6e Added libusb class + libusb log option 2021-11-01 17:03:40 +01:00
ergo720 b748c5f61a Added libusb submodule
Co-authored-by: Fred Hallock <specialfred453@gmail.com>
2021-10-31 12:39:25 +01:00
Luke Usher 94f02583ba
Merge pull request #2286 from CookiePLMonster/simplify-timers
Simplify timers
2021-10-16 16:23:57 +01:00
Luke Usher ac5289d83a
Merge pull request #2288 from ergo720/clang
Fixed some code errors detected by clang
2021-10-16 16:23:21 +01:00
ergo720 51c3f37596 Fixed non-const lvalue reference to type 'std::from_chars_result' cannot bind to a temporary of type 'std::from_chars_result' 2021-10-12 19:02:42 +02:00
ergo720 ca5a1aaa71 Fixed non-const lvalue reference to type cannot bind to a temporary of type 2021-10-12 18:44:09 +02:00
ergo720 23c72d825e Fixed cannot pass object of non-trivial type 'std::vector<char>' through variadic function; call will abort at runtime [-Wnon-pod-varargs] 2021-10-12 17:35:02 +02:00
ergo720 4f26ab927f Fixed explicit instantiation of undefined function template 'BindDefault' 2021-10-12 17:22:52 +02:00
ergo720 309975da61 Fixed subscript of pointer to incomplete type 'struct _XBE_SECTION' 2021-10-12 17:06:31 +02:00
ergo720 be56eac811 Fixed constexpr function never produces a constant expression [-Winvalid-constexpr] 2021-10-12 17:02:07 +02:00
Silent 326a5bb714
Simplify timer code to scale them without state 2021-10-09 18:15:21 +02:00
ergo720 3bdd689e03
Merge pull request #2285 from ergo720/xiso_workaround
Added workaround for dokany bug when reading files inside xisos mounted by xbox-iso-vfs
2021-10-07 23:08:54 +02:00
ergo720 9b65924898 Added workaround for dokany bug when reading files inside xisos mounted by xbox-iso-vfs 2021-10-07 22:50:16 +02:00
Anthony b863432904 Add LOG_TEST_CASE for uncommon swap flags 2021-10-07 21:38:08 +13:00
Anthony 32fa33ddab Fix MotoGP flicker
Hack to handle BYPASSCOPY
2021-10-07 00:30:20 +13:00
PatrickvL 629d6d2054
Merge pull request #2282 from ergo720/freopen_invalid_handle
Fixed invalid handle exception in freopen
2021-10-03 12:14:22 +02:00
ergo720 b52f5655e4 Added comment explaining the DETACHED_PROCESS flag 2021-10-03 12:08:47 +02:00
ergo720 35072da2ea Fixed invalid handle exception in freopen 2021-10-03 10:15:48 +02:00
Anthony b804ed1f03 Fix flicker in antialias sample
Improve X_D3DSWAP_COPY behaviour
2021-09-14 20:43:17 +12:00
Luke Usher ac68fd481c
Merge pull request #2280 from ergo720/log_fix
Fixed insufficient size of LoggedModules variable
2021-09-06 16:48:47 +01:00
ergo720 9b02cac7ad Fixed insufficient size of LoggedModules variable 2021-09-06 17:04:37 +02:00
ergo720 b405153c7e
Merge pull request #2271 from RadWolfie/cleanup-kernel-process
Some cleanup kernel process
2021-08-31 00:32:30 +02:00
RadWolfie bc6c017b7a kernel: replace __declspec(noreturn) to C++'s [[noreturn]] usage 2021-08-30 12:37:22 -05:00
RadWolfie 9bf21223f2 kernel: rename CxbxKrnlCleanup(Ex) to CxbxrKrnlAbort(Ex) 2021-08-30 12:27:03 -05:00
RadWolfie 2c46ea3d98 kernel: make CxbxrKrnlInitHacks function 2021-08-30 12:27:03 -05:00
RadWolfie cc6041d2de kernel: make CxbxrLogDumpXbeInfo function 2021-08-30 12:27:03 -05:00
RadWolfie 5e26b938fb add todo comment for ApplyMediaPatches function 2021-08-30 12:27:03 -05:00
RadWolfie f3dc44ebae kernel: move ApplyMediaPatches function 2021-08-30 12:27:03 -05:00
RadWolfie 5692f79d78 kernel: make CxbxrKrnlSetupDummyHeader function 2021-08-30 12:26:57 -05:00
RadWolfie 093c23d5bc kernel: make CxbxrKrnlPrepareXbeMap function 2021-08-30 12:26:57 -05:00
RadWolfie 249d6b2169 kernel: break down CdRom0 relative code into functions 2021-08-30 12:26:57 -05:00
RadWolfie 0e5e791a55 kernel: make CxbxrKrnlRegisterDevicePaths function 2021-08-30 12:26:57 -05:00
RadWolfie 16ea4519c8 kernel: breakdown xbe detector for system type to use 2021-08-30 12:26:57 -05:00
RadWolfie 93b5e88754 kernel: make CxbxrKrnlSyncGUI function 2021-08-30 12:26:57 -05:00
RadWolfie 08ee4a15d3 kernel: move relative console and file output into CxbxrKrnlSetupVerboseLog function 2021-08-30 12:26:57 -05:00
RadWolfie cefea8ad83 kernel: rename szFolder_CxbxReloadedData to g_DataFilePath and convert to std::string 2021-08-30 12:26:56 -05:00
RadWolfie 094256ef43 kernel: more clean up for file path setup 2021-08-30 12:26:47 -05:00
RadWolfie 8de8f411c1 kernel: move rdtsc patches relative into its own source file. 2021-08-30 12:23:50 -05:00
RadWolfie 0c2b7b4220 kernel: move relative file paths into its own header file. 2021-08-30 12:23:47 -05:00
PatrickvL a5fa40956a
Merge pull request #2278 from Shideravan/patch-1
Changing the link for the license page
2021-08-22 09:00:25 +02:00
Shideravan edffb3a128
Changing the link for the license page 2021-08-21 23:40:07 -03:00
RadWolfie 0fb2e6208d kernel: rename (G|S)etStorageLocation to (G|S)etDataLocation 2021-07-31 18:03:40 -05:00
RadWolfie e1a8391170 imgui: move fps updater functions into imgui ui class 2021-07-31 18:03:40 -05:00
RadWolfie b11cb57b0b
Merge pull request #2269 from Cxbx-Reloaded/LukeUsher-patch-1
Remove game-compatibility github link from template
2021-07-29 01:00:50 -05:00
Luke Usher 50d50288a5
Update .github/ISSUE_TEMPLATE/issue-template.md
Co-authored-by: RadWolfie <RadWolfie@users.noreply.github.com>
2021-07-28 11:49:06 +01:00
Luke Usher 9439b9f54c Remove game-compatibility github link from template 2021-07-27 09:32:35 +01:00
RadWolfie de16fe345a
Merge pull request #2268 from ergo720/create_process_error_str
Print the windows error string when CreateProcess fails to create the new emulation process
2021-07-26 12:14:01 -05:00
ergo720 5e7c6a082f Print the windows error string when CreateProcess fails to create the emulation process 2021-07-26 18:36:56 +02:00
Luke Usher a6e17bc4de
Merge pull request #2267 from NZJenkins/leave-path
Fix loading from UNC paths
2021-07-26 12:05:24 +01:00
Anthony 660e6bca1e Fix loading from UNC paths
Remove unexplained slash processing
which breaks UNC paths
2021-07-26 22:36:28 +12:00
Luke Usher b4dadb1dff
Merge pull request #2266 from ergo720/xbe_launch_error_reword
Reworded error message displayed when cxbxr fails to launch an xbe
2021-07-21 12:51:54 +01:00
ergo720 e37bb218ba Reworded error message displayed when cxbxr fails to launch an xbe 2021-07-21 13:19:28 +02:00
PatrickvL 30956c1044
Merge pull request #2261 from ergo720/emulog_cdecl
Removed stdcall from EmuLog functions
2021-07-14 15:55:50 +02:00
ergo720 cb3330a9e4 Removed stdcall from EmuLog 2021-07-14 15:38:45 +02:00
ergo720 d42e3ee271
Merge pull request #2259 from ergo720/title_short
Removed unnecessary info from the cxbxr title string
2021-07-14 12:31:40 +02:00
ergo720 cf8ff008a8 Shorten cxbxr title string 2021-07-14 10:55:45 +02:00
Luke Usher 74c8b0cde1
Merge pull request #2257 from RadWolfie/dsound-getstatus-hack-workaround
HACK: DS Stream GetStatus function workaround mimic hack.
2021-07-08 09:26:06 +01:00
RadWolfie 390466e615 dsound: GetStatus workaround mimic hack. 2021-07-05 11:10:42 -05:00
ergo720 6e68433dbd
Merge pull request #2254 from RadWolfie/cleanup-emufile
Small Clean Up Portion of EmuFile Usage
2021-07-05 11:25:01 +02:00
PatrickvL 85daa21ae2
Merge pull request #2256 from NZJenkins/cubemap-copy
Fix cubemap faces all being the same face
2021-07-02 16:42:31 +02:00
RadWolfie 533e80f171
Merge pull request #2255 from Margen67/bat
gen-msvc-project.bat: Add Visual Studio 2022
2021-06-30 14:50:35 -05:00
Anthony 755bb73b1c - Remove old TODO
- Additional comments
- Detect compressed volume texture test case
2021-06-30 21:44:28 +12:00
Margen67 8c5c80c284 gen-msvc-project.bat: Add Visual Studio 2022 2021-06-29 23:16:04 -10:00
Anthony fc430320ac simplify branch and condition 2021-06-30 20:17:07 +12:00
Anthony 516457c89c Tidy texture/mip copy code
- Rename and comment variables for clarity
- Remove unused 'dwSrcSlicePitch'
- Remove 'dwCubeFaceSize' calculations since we can get this from 'dwSlicePitch'
2021-06-30 19:56:32 +12:00
Anthony 2e27e0d4b5 Include face offset in source data offset
Fix just the first face being copied to all faces
Test case: PerPixelLighting, PerPixelLightingVS
2021-06-30 19:50:31 +12:00
RadWolfie 74138d14cc
Merge pull request #2249 from Margen67/ci
CI.yml: Remove unneeded env var
.azure-pipelines.yml: Fix exclusions
2021-06-29 20:53:18 -05:00
Margen67 56f98f9561 .azure-pipelines.yml: Fix exclusions 2021-06-29 15:37:12 -10:00
Margen67 c4016448ef CI.yml: Remove unneeded env var 2021-06-29 15:37:12 -10:00
RadWolfie edad809de0 clean up portion of EmuFile usage 2021-06-29 09:15:50 -05:00
Luke Usher 1c67c0d16d
Merge pull request #2252 from NZJenkins/update-imgui
Update imgui to the latest version
2021-06-29 12:15:44 +01:00
RadWolfie cd768c6800
Merge pull request #2246 from ergo720/mem_units
Added support for memory unit devices
2021-06-28 22:16:31 -05:00
ergo720 e6650da541 Review remarks + some code cleanup 2021-06-25 21:58:14 +02:00
Anthony 9536ba3312 Update imgui to the latest version
Fixes an issue with the imgui overlay on the Xbox dashboard
2021-06-25 23:10:40 +12:00
ergo720 efd9108279 Properly log device creation/destruction + untangle profile saving from slot connectivity 2021-06-24 13:24:35 +02:00
ergo720 3e60c31d26 Updated kernel file nt functions to support MUs + fixed bugs in xapi functions and input gui related to MUs 2021-06-24 13:24:34 +02:00
ergo720 88a786b700 Implemented MU support to xapi functions 2021-06-24 13:24:34 +02:00
ergo720 4cf90a6170 Updated xinput apis + fixed compiler errors 2021-06-24 13:24:34 +02:00
ergo720 2e9546a20a Added support to MUs to input manager 2021-06-24 13:24:33 +02:00
ergo720 9307f816ba Fixed some bugs in the mu handling of the gui + added XUnmountMU patch 2021-06-24 13:24:33 +02:00
ergo720 1d9dc0df2d Added support to mu to input gui 2021-06-24 13:24:33 +02:00
ergo720 1f404c57da Added support to mu to settings + created mu folders 2021-06-24 13:24:33 +02:00
Luke Usher 38aaf7189f
Merge pull request #2250 from ergo720/halo2_fix
Fixed a crash in Halo 2 on debug builds
2021-06-24 12:21:42 +01:00
ergo720 309db8cdae Fixed a crash in Halo 2 on debug builds 2021-06-24 13:08:06 +02:00
Luke Usher 06fadd6b74
Merge pull request #2248 from Margen67/resolution
Raise max resolution scale to 12x
2021-06-22 09:40:25 +01:00
Margen67 a69a985651 Raise max resolution scale to 12x 2021-06-21 22:14:43 -10:00
Luke Usher 05b7478d18
Merge pull request #2247 from Margen67/bat
gen-msvc-project.bat: Default to VS2019
2021-06-22 08:21:40 +01:00
Luke Usher 91a77b01f5
Merge pull request #2245 from RadWolfie/fix-release-title
Fix Release Title Default
2021-06-22 08:14:10 +01:00
Margen67 b8b08e716e
gen-msvc-project.bat: Default to VS2019 2021-06-21 16:08:40 -10:00
RadWolfie 8e384b4b8c
fix release title default to blank 2021-06-21 04:49:42 -05:00
Luke Usher 494ef0b267
Merge pull request #2243 from RadWolfie/cxbxr-chihiro-non-lle
Upstream Chihiro Non-LLE Code
2021-06-21 10:02:47 +01:00
RadWolfie 1ed65ec29a
Merge pull request #2244 from Margen67/remove_travis
CI: Remove Travis leftovers
2021-06-20 13:11:53 -05:00
Margen67 f2aaa2adea CI: Remove Travis leftovers 2021-06-20 06:21:01 -10:00
RadWolfie bc14c34efc
Merge pull request #2227 from Margen67/azure
.azure-pipelines.yml changes
2021-06-20 11:09:57 -05:00
Margen67 a1f0290039 .azure-pipelines.yml changes
Make ignored files similar to GitHub Actions.
Remove unneeded jobs/job for single job.
Use PowerShell.
Remove unneeded single quotation marks around displayName.
cmake:
 Remove unneeded generator parameter.
 Use cmake -B instead of mkdir/cd.
Artifacts:
 Check configuration variable instead of job name.
 Make artifact preparation step name more clear.
 Simplify artifact preparation.
2021-06-20 06:02:22 -10:00
RadWolfie 07992147bd
Merge pull request #2242 from Margen67/actions
CI.yml: Use gh release create
2021-06-20 10:23:57 -05:00
Margen67 1475761d5c CI.yml: Use gh release create 2021-06-20 05:17:03 -10:00
RadWolfie 4d2a59d737 add missing and sort changed values from logging config 2021-06-19 18:46:41 -05:00
RadWolfie af43500c1a move non-lle work done from chihiro to upstream 2021-06-19 18:46:41 -05:00
Luke Usher 56eede299b
Merge pull request #2241 from literalmente-game/patch-1
Typo fixes
2021-06-19 17:49:52 +01:00
literalmente-game ee9ba1cacb
Typo fixes
Fixing some typos with the "Clear Cache Partitions" error message
2021-06-19 13:34:58 -03:00
RadWolfie 1f0c3f677e
Merge pull request #2075 from Margen67/remove_travis
Delete .travis.yml
2021-06-15 18:26:20 -05:00
Margen67 0643645ddd Delete .travis.yml 2021-06-15 12:50:19 -10:00
PatrickvL 23c1dcf1c9
Merge pull request #2237 from jackchentwkh/3D_mip_map_fix
fixing 3D mip-map conversion with volume texture, fix Halo
2021-06-12 10:21:46 +02:00
ergo720 addf4b42fd
Merge pull request #2240 from ergo720/xeloadsection_bug_fix
Make XeLoadSection return status_invalid_handle when it cannot find the requested section
2021-06-11 13:05:37 +02:00
ergo720 c4d75368a5 return status_invalid_handle when it cannot find the requested section 2021-06-11 12:17:41 +02:00
Luke Usher f1e54be515
Merge pull request #2239 from ergo720/XAudioDownloadEffectsImage_from_xbe_section
Add support to load dsp images from xbe sections
2021-06-10 18:51:25 +01:00
ergo720 d847580881 Added support to load dsp images from xbe sections 2021-06-10 19:39:42 +02:00
ergo720 c7bf62ce62
Merge pull request #2238 from ergo720/XB_InitializeObjectAttributes_fix
Removed unused dwBytesRead variable and unused argument from XB_InitalizeObjectAttributes macro
2021-06-10 12:44:48 +02:00
ergo720 98a44aa47d Removed unused dwBytesRead variable and unused argument from XB_InitializeObjectAttributes macro 2021-06-10 12:22:22 +02:00
jackchentwkh f003c11260 typo fix 2021-06-10 15:35:56 +08:00
jackchentwkh 55e45e728e using correct 3D mip map dimention sizes in all 3 dimensions, and calculate correct source size.
this fix Halo, get in game.
2021-06-10 11:37:27 +08:00
Luke Usher ba9ee5fd2f
Merge pull request #2234 from jackchentwkh/DSoundBufferResizeSetSize_fix
Implement ImageDesc, fix vector iterator in DSStream packet, this fixs Otogi1, PGR2.
2021-06-08 07:16:37 +01:00
jackchentwkh fa1f4d4c50 Make sure packet iterator is validate after DSStream_Packet_Clear() calls erase().
this fixs debug builds with PGR2
2021-06-08 07:14:11 +08:00
jackchentwkh ea55dfa45d remove extra space in end of line, replace tabs with spaces. 2021-06-08 07:14:11 +08:00
jackchentwkh 6bb0234dc8 Fix DSoundBufferResizeSetSize with DSBuffer creation failure when remained hos buffer bytes is less then DSBSIZE_MIN, also correct a wrongly used argument with call to DSound3DBufferCreate. add more sanity checks. this fixs PGR2, now release build can enter the race. but debug build has different issue with vector/iterator. 2021-06-08 07:14:11 +08:00
PatrickvL 8b9b26b56e
Merge pull request #2136 from Cxbx-Reloaded/hlsl_ps
Pixel shader hlsl
2021-06-07 16:04:18 +02:00
Anthony fa0a114e0c Fix passthru not passing through all components
Previous behaviour aligned with ps_1_3 texcoord, where alpha = 1
but appears to be incorrect.
Note ps_1_4 texcrd leaves alpha undefined
Fixes Metal Arms menu clouds
2021-06-07 10:59:36 +02:00
PatrickvL a8fae55299 Fix HLSL PS bump environment mapping (most of the research done by medieval, thanks!) 2021-06-07 10:59:35 +02:00
PatrickvL c03b2ed151 Fix DolphinClassic sample, by not making fogDepth absolute (thanks NZJenkins!)
(This bug was introduced with PR #2163, based on some misleading code in xqemu, to cater for what now appear to be non-supported fog modes on NV2A.)
2021-06-07 10:59:35 +02:00
PatrickvL 061e38af6f HLSL Pixel Shader tweaks;
Fully declare stages, to avoid "error X4000: variable 'stages' used without having been completely initialized"
Add alphakill support to fixed function
Use macro-based alphakill declaration in template (same as in fixed function)
Updated comments to differentiate between texture stage and combiner stage
Rename st into ts (texture stage) where appropriate
Fixed a typo in Brdf macro (was s1, must be ts now)
Updated Reflect to use C0 (uppercase, instead of lowercase host c0)
Initialized stage to zero for use in the C0 macro, now used Reflect
Fixed type of CombinerOutputMapping to actualle be PS_COMBINEROUTPUT_OUTPUTMAPPING
Introduced and used varios PS_*_MASK defines
Added some comments on pixel shader verification and test-case discovery.
2021-06-07 10:59:35 +02:00
Anthony d46abef9a1 Redefine undefined ALPHAOP behaviour for Crash WoC
To aid debugging add a LOG_TEST_CASE , and include ALPHAARGs when ALPHAOP is disabled
2021-06-07 10:59:34 +02:00
Anthony 3da5b9f5d9 Include debug comment about how the final combiner hlsl was generated
Make hasFinalCombiner correspond to DecodedHasFinalCombiner
2021-06-07 10:59:34 +02:00
Anthony a29c2f7d62 Force VS to write to oFog.x
Default fog factor to 1 (no fog)
2021-06-07 10:59:33 +02:00
Anthony d8c18cf268 Mask flags when detecting colorarg1 + missing texture case 2021-06-07 10:59:33 +02:00
Anthony 6bf2a1f44f Reuse colorOp variable
And additional comments
2021-06-07 10:59:32 +02:00
Anthony ce7a5f6e40 Fix GTA III logos
Depending on ALPHAOP == DISABLE
2021-06-07 10:59:32 +02:00
Anthony 5aaadd026c Implement missing texture behaviour 2021-06-07 10:59:32 +02:00
Anthony 990a24292d Fix reflection equation
Improve BumpDemo
2021-06-07 10:59:31 +02:00
Anthony 85f792d2b2 Fix DOTPRODUCT3 texture op
Improves PerPixelLighting
2021-06-07 10:59:31 +02:00
Anthony 2f9558d307 Use SAMPLE_NONE instead of IsTextureSet 2021-06-07 10:59:30 +02:00
Anthony 814b040ff1 Normalize the values returned by the texture state converter 2021-06-07 10:59:30 +02:00
Anthony 657a8ef7c3 Disable lighting for point sprites 2021-06-07 10:59:30 +02:00
Anthony 5ea12636ee Passthrough fogging and generate fog factor for fixed function mode 2021-06-07 10:59:29 +02:00
Anthony 3ea3cdc1a8 Fix implicitly extern shader variable
So the hardcoded values are used,
as values were unintuitively being read from constant registers
2021-06-07 10:59:29 +02:00
Anthony 6f2460c70a Fixed function pixel shader
Placeholder shader until we are able to directly load the pixel shader program used on the Xbox
A shader is generated for each texture op and argument combination
2021-06-07 10:59:28 +02:00
Anthony 03200fdcd3 Re-enable texture stage swap hack 2021-06-07 10:59:28 +02:00
medievil1 90bdeac904 fix up fog mode (#2163)
fix up fog mode
2021-06-07 10:59:26 +02:00
Anthony 726d6ff4f3 Improve scaling of depth buffer texture coordinates
- GetZScale accepts a PixelContainer rather than a surface
- Fix accidental call to CxbxGetPixelContainerDepth instead of GetZScale
- Assume we should scale the z component for all depth buffers, not just linear ones
2021-06-07 10:58:46 +02:00
Anthony 512502ce36 Fix Azurik render issue
Remove #ifndef blocks that were driven by the opposite define than they should have been
Also provide the opposite flag as a comment, next to where the 'driver' define
2021-06-07 10:58:45 +02:00
Anthony ad1652f050 Fix array index out-of-range crash
Remove PS_REGISTER_ONE usage since its not a register, but a combination of PS_REGISTER_ZERO and an INPUT_MAPPING
2021-06-07 10:58:45 +02:00
Anthony fe6de7c621 Fix fog when xfc is undefined
* flip fog factor lerp. fog factor 1 = no fog
* ensure RC is zero initialized
2021-06-07 10:58:44 +02:00
Anthony 6373ba58bb fixup typo VXSH instead of PXSH 2021-06-07 10:58:44 +02:00
Anthony 3c96e3236b use vs_3_0 2021-06-07 10:58:43 +02:00
Anthony b565d39ffe fix abs instead of clamp 2021-06-07 10:58:43 +02:00
Anthony 7745515588 Fix front/back colour usage 2021-06-07 10:58:43 +02:00
PatrickvL 55f3c60ef2 Include Pixel Shader HLSL in output artifacts (and fixed a few typos in FixedFunction HLSL) 2021-06-07 10:58:42 +02:00
PatrickvL b5cc970d7e Corrected fixed-function formula's in final combiner 2021-06-07 10:58:42 +02:00
Anthony 7f89e72b2b fixup enable complement in final combiner
(cherry picked from commit 71df0a3a5af94f550c2ecc25a47f78e54e74ee4a)
2021-06-07 10:58:41 +02:00
Anthony e3c0b7287c fixup FC0 and FC1 constant mapping
(cherry picked from commit 45cd7f72f07a5528b83bdadb24b46a934a7bfc50)
2021-06-07 10:58:41 +02:00
Anthony cb4bbc17ee Calculate the fog factor in the vertex shader
(cherry picked from commit 3c3ede07da1f0829697cc1635058b5dc4ec610d2)
2021-06-07 10:58:41 +02:00
Anthony 3216931da6 fixup fog colour constant register
(cherry picked from commit b99e63d944d2ceb474761ae88c8c90246071f0bc)
2021-06-07 10:58:40 +02:00
Anthony 9480bea9c0 Use sampler state
(cherry picked from commit ab2064ef690179560761d29eed53fd5b756b5dc7)
2021-06-07 10:58:39 +02:00
Anthony 65734fac9d Wrap PS_INPUTMAPPING ops in brackets for consistent order of operations
(cherry picked from commit 001dca83fea387debd7e85893eb8b8631ea264fd)
2021-06-07 10:58:39 +02:00
PatrickvL 845bc7ef06 Renames, indenting, comments 2021-06-07 10:58:38 +02:00
PatrickvL af0058ad61 WIP pointsprite nuances 2021-06-07 10:58:37 +02:00
PatrickvL c6fdfc7101 Code cleanup (comments and variable renames) 2021-06-07 10:58:37 +02:00
patrickvl 4af986f058 No time to test, but here's alphakill support in PS HLSL 2021-06-07 10:58:36 +02:00
PatrickvL 29017db910 In DxbxUpdateActivePixelShader, transfer values step by step, instead of using a switch/case loop.
Also, working towards removing host SetTextureStageState calls (doesn't work yet).
2021-06-07 10:58:36 +02:00
PatrickvL 2990552230 Fixes after rebase 2021-06-07 10:58:35 +02:00
PatrickvL b72b52a4a2 RenderState mapping table review remarks (nothing functional) 2021-06-07 10:58:35 +02:00
PatrickvL 4517f36456 Unrelated to PS :
UpdateFixedFunctionVertexShaderState now derives TexCoordComponentCount from GetXboxVertexAttributeFormat, which makes it honor overrides.

This could fix corrupted textures when Fixed Function HLSL is used together with VertexStream override modes.
2021-06-07 10:58:34 +02:00
PatrickvL 609a4d3276 [WIP] Xbox register combiner to HLSL pixel shader 2021-06-07 10:58:33 +02:00
PatrickvL 1e6845c940 Generalized HLSL shader compilation 2021-06-07 10:58:32 +02:00
Luke Usher f6e54acf17
Merge pull request #2231 from NZJenkins/sleeps
SleepPrecise for more accurate sleeps
2021-06-07 09:45:56 +01:00
Luke Usher da7a917ec5
Merge pull request #2232 from NZJenkins/ff-state2
Avoid unnecessary shader constant updates
2021-06-07 08:46:57 +01:00
Anthony 7d672600bb Update dirty shader constants only
And try to minimize D3D9 calls
Constants are synced every draw, but titles may only use a few constants
so we can potentially save a lot of work
Increases performance a little (at least on certain titles like Buffy)
2021-06-06 23:15:38 +12:00
Anthony 0cb849a3f8 Avoid setting vertex shader constants more than once per draw 2021-06-06 22:49:58 +12:00
Anthony 3b1daf52ab Addd braces 2021-06-02 22:38:43 +12:00
Anthony 76eb475ed6 Move SleepPrecise to Timer 2021-06-02 22:36:40 +12:00
Anthony b66f04d811 SleepPrecise for more accurate sleeps
We can use it to reduce the amount of spin waiting which burns CPU
Try to sleep as much as we can get away with without overshooting, and then spin wait
Use it for
- VBlank timing
- Frame limiter timing
2021-06-02 21:54:02 +12:00
PatrickvL 8087b157e5
Merge pull request #2222 from ergo720/rawinput
Add controller hotplug support
2021-05-28 16:54:30 +02:00
ergo720 917bf50482
Merge pull request #2224 from Margen67/sdl2
Use official SDL2 repository
2021-05-24 16:45:12 +02:00
ergo720 f3251128e8 Fixed an issue where xinput devices were bound to the wrong xbox port under some circumstances after hotplug removal events 2021-05-24 12:11:09 +02:00
ergo720 1ed640a0d7 Add controller hotplug support 2021-05-24 12:11:08 +02:00
Margen67 55ada8d50d Use official SDL2 repository 2021-05-23 02:06:50 -10:00
ergo720 5d222c10a0
Merge pull request #2221 from jackchentwkh/ImageDescWithRebaseAddress
Keep ImageBuffer backup copy, handle ImageDesc with rebase address, Fix Otogi 1, Otogi 2, PGR2 booting.
2021-05-21 19:38:41 +02:00
ergo720 8cc4b10ce0 Added test case + fixed a macro redefinition warning 2021-05-21 19:25:22 +02:00
Luke Usher df22c8baed
Merge pull request #2210 from RadWolfie/fix-chihiro-support
Few fixes toward title mount path and prepped for chihiro work
2021-05-21 17:56:57 +01:00
ergo720 2e1ed31aaa Untabfied code and update code style 2021-05-21 13:08:57 +02:00
jackchentwkh a665cf1f8e Replace host CreateFile/GetFileSize/ReadFile/Close with xbox::NtCreateFile/NtQueryFile/NtReadFile/NtClose. Add necessary error check logic, Add logic for loading image file from xbe section in case we encounter such guest code, alghough highly unlikely. Basicaly reversed from PGR2's code. 2021-05-21 13:28:13 +08:00
jackchentwkh d49762d27e Rebase Code and State Segments in EffectMaps. fix PGR2 2021-05-19 19:20:39 +08:00
RadWolfie 8d725a689c kernel: rename tmp_buffer to p_default_mount_path 2021-05-18 16:07:56 -05:00
RadWolfie 08dd615d37 review remarks 2021-05-18 16:05:13 -05:00
RadWolfie cf3655bed1 fix g_hCurDir issue by auto-bind to D letter when symbolic link is called occur 2021-05-18 15:48:19 -05:00
RadWolfie d8eb26fbda kernel: fix chihiro support 2021-05-18 15:48:18 -05:00
RadWolfie 9eadb8d393 remove unused code 2021-05-18 15:48:18 -05:00
Luke Usher cec1b0b885
Merge pull request #2215 from NZJenkins/ivb-float4
Change IVB to an array of 4-float slots
2021-05-17 16:55:04 +01:00
PatrickvL 9d601299ad In CxbxImpl_SetVertexData4f, call CxbxSetVertexAttribute *after* detecting Register X_D3DVSDE_VERTEX, and updating it to X_D3DVSDE_POSITION, to avoid needless "Register < 0" logging, and to have current position values written to the NV2A vertex attribute value buffer. 2021-05-17 14:51:03 +02:00
Anthony b0b47ab744 Initialize vertex attribute format once 2021-05-17 19:12:54 +12:00
Anthony 867a0b1045 Fix 'NumVertexIndices' instead of 'NumVertices'
and tidy
2021-05-16 22:11:48 +12:00
Anthony 0453e451f1 Change IVB to an array of 4-float slots
Will fix Halo logo and menu text rendering (once it's visible!)
- Remove references to fixed function concepts, since slots might contain anything
e.g. don't exclude the 4th component of the slot corresponding to NORMAL in fixed function mode
- Use the IVB table directly for simplicity. Copy all table data to the vertex buffer
2021-05-16 22:11:48 +12:00
jackchentwkh a04a079f19 Adding code to allocate memory for ImageDesc and copy ImageDesc from DSP ImageBuffer.
Tested with Otogi, success.
2021-05-16 15:42:44 +08:00
PatrickvL a5f4b3b494
Merge pull request #2217 from ergo720/SetWindowText
Removed unnecessary calls to SetWindowText
2021-05-14 15:45:27 +02:00
ergo720 c769dce20e Removed unnecessary calls to SetWindowText 2021-05-14 12:01:27 +02:00
RadWolfie 2397ece059
Merge pull request #2214 from Margen67/actions
CI.yml: Use cmake -B
2021-04-30 04:52:51 -05:00
Margen67 12f2237c79
CI.yml: Use cmake -B 2021-04-29 23:32:10 -10:00
PatrickvL 8a4c7469e6
Merge pull request #2211 from RadWolfie/fix-cmake-installs
Remove extra projects we don't need at all and add SDL2 binary to be install
2021-04-30 10:32:27 +02:00
Luke Usher 7a6983478f
Merge pull request #2213 from ergo720/fatal_msg
Reworded fatal error message popup
2021-04-30 08:02:55 +01:00
ergo720 d74a9a1dfb Removed the original message, because it's already printed by EmuExceptionPrintDebugInformation 2021-04-29 19:15:09 +02:00
ergo720 2d10c1ffe2 Also print exception code and address 2021-04-29 19:15:09 +02:00
ergo720 a95636afcd Reworded fatal error message popup 2021-04-29 19:15:09 +02:00
Luke Usher dff5fb04cc
Merge pull request #2209 from CookiePLMonster/xdk-5849-stream-source
Add a new LTCG variation of D3DDevice_SetStreamSource
2021-04-29 16:02:08 +01:00
Silent 1e92046b0b
Add a new LTCG variation of D3DDevice_SetStreamSource
Found in Juiced.
2021-04-28 17:26:14 +02:00
RadWolfie 3554d8ef03 cmake: remove extra projects we don't need at all and add SDL2 binary to be install 2021-04-27 09:26:38 -05:00
PatrickvL b6d4c76b42
Merge pull request #2207 from scribam/ninja
cmake: Fix format for Ninja generator
2021-04-26 22:01:02 +02:00
scribam ea434d9cf2 cmake: Fix format for Ninja generator 2021-04-26 18:26:24 +02:00
PatrickvL 1034185a62
Merge pull request #2206 from medievil1/createdevice
check for null device
2021-04-23 23:36:53 +02:00
medievil1 cf8f2628c0 check for null device
Check to make sure device is null before creating it, avoids losing device due to unneeded recreation
2021-04-23 17:20:11 -04:00
PatrickvL dd7fbe302f
Merge pull request #2193 from RadWolfie/title-mount-path
kernel: implement title mount path
2021-04-23 22:48:59 +02:00
PatrickvL e6e0d5da9e
Merge pull request #2205 from RadWolfie/move-minor-changes
move minor changes into upstream from chihiro branch
2021-04-23 08:22:47 +02:00
RadWolfie cb2dc36e9e kernel: fix XeImageFileName bug for homebrew titles 2021-04-22 22:24:33 -05:00
RadWolfie 4778aeab1e Use string_view instead of copy whole string. 2021-04-22 22:24:33 -05:00
RadWolfie 11ac2f8058 fix host's symbolic link path to full path since kernel always use full path 2021-04-22 22:24:33 -05:00
RadWolfie 0da1273404 review remarks 2021-04-22 22:24:33 -05:00
RadWolfie 8445a02998 kernel: implement title mount path 2021-04-22 22:24:33 -05:00
Luke Usher 8f7efbe1e8 move minor changes into upstream 2021-04-22 21:55:58 -05:00
RadWolfie db545a3900
Merge pull request #2203 from scribam/add-delayimp-lib
Add delayimp lib and ignore CLion's build and project directories
2021-04-21 22:41:22 -05:00
scribam 36b83a8e52 cmake: /DELAYLOAD requires delayimp lib 2021-04-20 18:25:10 +02:00
scribam 3c74d95e17 .gitignore: Add CLion specific files 2021-04-20 18:23:04 +02:00
PatrickvL f0e99ba436
Merge pull request #2200 from RadWolfie/fix-RtlUnicodeStringToAnsiString
Fix RtlUnicodeStringToAnsiString bug
2021-04-20 10:44:41 +02:00
RadWolfie 3b43c081e4 review remarks 2021-04-19 13:18:15 -05:00
RadWolfie c809b0d01b kernel: fix RtlUnicodeStringToAnsiString 2021-04-16 12:32:26 -05:00
RadWolfie c808cf2834
Merge pull request #2197 from ergo720/eeprom_edit_scroll
Add ES_AUTOHSCROLL style to hdd and online key in the eeprom edit dialog
2021-04-13 13:14:41 -05:00
ergo720 c127a13291 Add ES_AUTOHSCROLL style to hdd and online key in the eeprom edit dialog 2021-04-13 19:39:30 +02:00
PatrickvL 68b3f0f22b
Merge pull request #2192 from ergo720/imgui_off
Set ImGui overlay to default off + fixed a bug in the overlay settings read from file
2021-04-12 12:08:22 +02:00
ergo720 59ee8326d9 Set ImGui overlay to default off + fixed a bug in the overlay settings read from file 2021-04-12 11:46:45 +02:00
PatrickvL 9e9f78ec94
Merge pull request #2188 from ergo720/remove_64mb
Removed patch menu and SaveXbe(As) options from GUI
2021-04-10 14:55:31 +02:00
PatrickvL 401337a09e
Merge pull request #2189 from ergo720/remove_old_vsbc
Removed old vsbc files
2021-04-10 14:54:49 +02:00
ergo720 91fdc1317c Removed old vsbc files 2021-04-10 13:44:02 +02:00
PatrickvL 6f81d212b3
Merge pull request #2185 from RadWolfie/fix-imgui
ImGui: couple fixes for different cause of crashes
2021-04-10 12:35:39 +02:00
ergo720 01f33a87d4 Also remove patch menu and SaveXbe(As) munus 2021-04-10 12:01:17 +02:00
ergo720 4258407b5b Removed 64MiB option in patch menu 2021-04-09 12:33:05 +02:00
RadWolfie 8d9deb8138 ImGui: couple fixes for different cause of crashes 2021-04-07 18:45:46 -05:00
PatrickvL 48814d3173
Merge pull request #2182 from ergo720/git_version_check
Detect mismatches between the cxbxr executables
2021-04-07 20:48:50 +02:00
ergo720 affae4cc0e Review remarks 2021-04-07 19:35:24 +02:00
ergo720 cb9bb62146 Add misc-batch as dependency of loader 2021-04-05 22:25:54 +02:00
ergo720 fe84236330
Merge pull request #2183 from RadWolfie/fix-imgui
HOTFIX: remove optimization due to AND bit operator does not keep in order
2021-04-05 21:51:07 +02:00
RadWolfie 49e2dc34eb HOTFIX: remove optimization due to AND bit operator does not keep in order 2021-04-05 14:22:26 -05:00
ergo720 7030e1551d Replaced StringCchCopy usage with a for loop 2021-04-05 18:37:02 +02:00
ergo720 a8405c967e Removed reserved variables in EmuShared 2021-04-05 18:29:32 +02:00
ergo720 1e0c75c3bd Detect mismatch between cxbxr modules 2021-04-05 18:28:20 +02:00
PatrickvL 52c88d7462
Merge pull request #2174 from RadWolfie/add-imgui
Add Basic ImGui Support
2021-04-04 21:08:09 +02:00
RadWolfie 781b7b8618 found a hidden bug during review remark, not relative to the pr 2021-04-03 14:39:36 -05:00
RadWolfie 3ba0ff084d review remarks 2021-04-03 14:39:36 -05:00
RadWolfie 000dd6c0a5 ImGui: register functions for individual release purpose and combine them into central call purpose 2021-04-03 14:35:31 -05:00
RadWolfie 74df117284 ImGui: fix crash on early terminate emulation 2021-04-03 14:35:31 -05:00
RadWolfie c6d1ec4924 kernel: mark as fallthrough permit to avoid warning message appear 2021-04-03 14:35:30 -05:00
RadWolfie 0875de0727 ImGui: move generic vertex cache into ImGui's video class. 2021-04-03 14:35:30 -05:00
RadWolfie e052a681be D3D8: move INDEX16 to xbox's D3D8 types header file 2021-04-03 14:35:30 -05:00
RadWolfie c403d6d129 input: fix incorrect getter/setter when should be using boolean method than long 2021-04-03 14:35:30 -05:00
RadWolfie 9885859916 ImGui: make functional imgui integration along with basic features 2021-04-03 14:35:30 -05:00
RadWolfie 23681729a5 input: fix bugged ShowCursor when redundant call occur with same value 2021-04-03 14:35:30 -05:00
RadWolfie 5c4e6945dc input: remove unnecessary pointer since const exists in parameter. 2021-04-03 14:35:30 -05:00
RadWolfie 327490a8ed input: fix general settings to use simplified getter/setter. 2021-04-03 14:35:30 -05:00
Silent 4985d9ca7e ImGui: More detailed vertex cache statistics 2021-04-03 14:35:29 -05:00
Silent f68c706b1e ImGui: Improve style a bit, start hidden 2021-04-03 14:35:29 -05:00
Silent 55f1228c66 ImGui: Quick set-up 2021-04-03 14:35:29 -05:00
Silent 611966f34e ImGui: Disabled some useless Win32 functions 2021-04-03 14:35:29 -05:00
RadWolfie a57aeed9f0 Add Dear ImGui library 2021-04-03 14:35:29 -05:00
ergo720 5995641a8f
Merge pull request #2178 from RadWolfie/kernel-fixes
Minor kernel fixes
2021-04-03 19:21:40 +02:00
Luke Usher a53f3604fd
Merge pull request #2181 from NZJenkins/stencil-convert
Convert STENCILFAIL
2021-04-03 17:14:39 +01:00
Anthony d0e525cd99 Convert STENCILFAIL
Improves shadows in DoA3
2021-04-04 02:30:36 +13:00
RadWolfie db6dd7110e fix xbox::RtlInitAnsiString when used inside cxbxr 2021-04-02 10:14:44 -05:00
RadWolfie 45e4e18415 fix crash with xbox kernel test suite for IoCreateSymbolicLink/IoDeleteSymbolicLink tests 2021-04-02 10:14:44 -05:00
RadWolfie 58f1c0959c kernel: check for CXBX_KERNEL_REWORK_ENABLED macro switch to investigate what need to work on 2021-04-02 10:14:44 -05:00
RadWolfie f3aaea3bc2
Merge pull request #2179 from Margen67/actions
ci: Use ubuntu-latest for release
2021-03-31 14:50:10 -05:00
Margen67 d66c50ad26
ci: Use ubuntu-latest for release
See https://github.com/actions/virtual-environments/issues/1430
2021-03-31 05:11:50 -10:00
RadWolfie 3d95e0223b kernel: add notes 2021-03-30 14:48:48 -05:00
RadWolfie 8a750fb4f2 kernel: add warning message 2021-03-29 19:33:24 -05:00
RadWolfie 3ff7869331 kernel: move emulated symbolic link object into ObOpenObjectByName patch 2021-03-29 19:33:24 -05:00
RadWolfie 98805bd0c5 minor fixes 2021-03-29 19:28:09 -05:00
PatrickvL 6cfad6f212
Merge pull request #2172 from CookiePLMonster/cpu-sets
Use Win10 CPU Sets API where supported
2021-03-27 09:52:39 +01:00
PatrickvL 6d187f1015
Merge pull request #2176 from ergo720/xinputpoll
Implemented XInputPoll
2021-03-27 09:50:24 +01:00
ergo720 2b6f452f18 Addressed review remark 2021-03-27 00:10:10 +01:00
ergo720 c30a2e058a Implemented input auto-poll behaviour 2021-03-24 23:00:50 +01:00
Silent 39c938f990
Use Win10 CPU Sets API where supported
Using CPU Sets instead of thread affinity allows to ensure
that the entire physical core is reserved ONLY for the game code,
so even the worker threads and third party libraries inside the process
cannot run code on it.

For Windows 7 and 8.1, the existing thread affinity approach is retained.
2021-03-24 19:25:25 +01:00
Luke Usher 187f4a8162
Merge pull request #2171 from ergo720/free_thread_resources
Free thread resources upon termination
2021-03-24 06:13:22 +00:00
ergo720 d929e81f1f Free thread resources upon termination 2021-03-23 19:14:32 +01:00
RadWolfie 2d63e89208
Merge pull request #2170 from ergo720/format_partition
Added option to clear the cache partitions from the GUI
2021-03-22 14:51:58 -05:00
ergo720 721d83eaf1 Addressed review remarks 2021-03-22 19:41:06 +01:00
ergo720 7518f8375a Added option to clear the cache partitions from the GUI 2021-03-22 18:23:04 +01:00
Luke Usher efda454399
Merge pull request #2168 from NZJenkins/upscale-all
Upscale rendertargets and depth surfaces consistently
2021-03-20 10:24:26 +00:00
Anthony 4938b13bc5 Upscale rendertargets and depth surfaces consistently
Rather than just upscaling the backbuffer
Allows high resolution rendering in some games that rendered to textures
Fixes Amped shadows when upscaling, due to SetRenderTarget failure (probably mixing scaled and unscaled RT & Depth)
2021-03-20 12:17:37 +13:00
Luke Usher d9b994c357
Merge pull request #2164 from CookiePLMonster/vertex-cache-improvements
Vertex buffer cache improvements
2021-03-18 13:48:27 +00:00
Luke Usher 8c754be62a
Merge pull request #2165 from NZJenkins/fix-fse
Fix crash in fullscreen mode
2021-03-18 13:45:26 +00:00
Anthony 9d18a16370 Fix crash in fullscreen mode
Set a backbuffer format, since UNKNOWN is only accepted in windowed mode
2021-03-18 21:44:27 +13:00
Silent dd5196f3ca
Reduce the amount of state in CxbxVertexBufferConverter
Also removes some legacy code in XbVertexBuffer
2021-03-17 18:46:20 +01:00
Silent 977fdd360c
Use a compound key in the vertex cache to reduce false cache evictions
Now same data viewed with different vertex elements can coexist
in the cache instead of evicting elements continuously
2021-03-17 18:24:57 +01:00
Silent 609614f735
Const-qualify ComputeHash
Needed for an upcoming commit
2021-03-16 23:55:45 +01:00
PatrickvL 6db6256e45
Merge pull request #2157 from NZJenkins/tidy-mip-code
Tidy mip code and work around DXT crash with small textures
2021-03-13 08:24:07 +01:00
Anthony 4f91ca6838 fixup 2021-03-13 19:55:38 +13:00
Anthony 9c6e2656af Hoist blocksize out of the loop 2021-03-13 16:39:59 +13:00
Anthony d382722d38 co-locate compressed texture handling 2021-03-13 16:38:02 +13:00
Luke Usher 61e7e30e29
Merge pull request #2152 from ergo720/ignore_kbmo_opt
Added option to allow kb/mo input when the rendering window is unfocused
2021-03-12 11:29:18 +00:00
Anthony a414ee20b9 fixup style 2021-03-11 23:56:11 +13:00
Anthony b3768ba5ec Avoid crash by not attempting to convert compressed textures (which currently isn't supported) 2021-03-11 20:37:38 +13:00
Anthony 6332b9beaf Try to clarify the mip handling code
- Keep track of the mip width and height in pixels, without any regard for the texture format.
We need to know this to properly convert compressed textures (not that we convert them properly!)
The minimum mip width/height for compressed textures is 1 pixel, not 4 pixels.
- For compressed textures, bottom out the row pitch at the minimum block data size
2021-03-11 20:37:38 +13:00
ergo720 3ac793eb6e Added option to allow kb/mo input when the rendering window is unfocused 2021-03-10 20:06:18 +01:00
PatrickvL 72acea23b2
Merge pull request #2151 from NZJenkins/fix-backbuffer-format
Use the backbuffer format requested by the title
2021-03-10 18:11:03 +01:00
Anthony 55d81a3bfb fixup texture conversion warning 2021-03-10 20:14:48 +13:00
Anthony 0c8ae3f3e2 Always convert D3DFMT_A8 to ARGB
In D3D8, the RGB values appear to be undefined, and the Xbox uses 1.
Whereas in D3D9, the RGB values are 0
2021-03-09 19:49:12 +13:00
Anthony 3c393227be - Remove code that aligns the host backbuffer with the xbox backbuffer
- Remove code related to setting the backbuffer format
2021-03-09 19:49:12 +13:00
PatrickvL e4ef9c1985
Merge pull request #2156 from CookiePLMonster/format-improve
Further improve partition path functions
2021-03-07 18:11:43 +01:00
Silent 6abf4f0c66
Further improve partition path functions
* Close a possible edge case of "\\Partition" being present in the path
* Close a possible edge case of an invalid path being shorter than the string "\\Partition"
* Allow for partition formatting to work fine when EmuDisk has been relocated
2021-03-07 13:30:22 +01:00
Luke Usher 0217200a4c
Merge pull request #2155 from CookiePLMonster/fix-partition-formatting
Fix partition formatting
2021-03-06 20:22:17 +00:00
Silent f04c518d15
Modernize CxbxGetPartitionNumberFromHandle and CxbxGetPartitionDataPathFromHandle
Now consistently uses Unicode and supports long paths
2021-03-06 19:13:43 +01:00
Silent 35cd99a844
CxbxFormatPartitionByHandle: Use non-throwing std::filesystem functions 2021-03-06 18:37:10 +01:00
Silent 487ad3fa19
CxbxFormatPartitionByHandle: Do not recurse into subdirectories
Fixes a crash while formatting partitions occurring when
attempting to recurse into now-deleted subdirectories.
2021-03-06 18:28:10 +01:00
PatrickvL fb4ca717e4
Merge pull request #2154 from CookiePLMonster/section-unload-fixup
Fix XeUnloadSection errorerously zeroing memory
2021-03-05 23:03:08 +01:00
Silent 9ea0051d92
Xbe: Read section headers and library versions in one go 2021-03-05 22:56:10 +01:00
Silent 6d1e095a41
Fix XeUnloadSection errorerously zeroing memory
Makes Apex/Racing Evoluzione reach menus
2021-03-05 22:56:10 +01:00
NZJenkins 84cd4e3ba4
Merge pull request #2153 from NZJenkins/fixup-symbolcache
Measure the string length to get the correct size the string should be
2021-03-06 00:39:09 +13:00
Anthony 15d5397037 Measure the string length to get the correct size the string should be
Fix accidental use of string constructor with length, that causes null bytes to be included in the string
2021-03-06 00:07:32 +13:00
Luke Usher 23c8d37731
Merge pull request #2141 from RadWolfie/hide-sensitive-info
Hide Sensitive Fields from EEPROM gui
2021-03-03 10:39:32 +00:00
Luke Usher f32a2e7d19
Merge pull request #2150 from ergo720/arcade_ctrl
Add support for the arcade joystick device to the input gui
2021-03-03 10:38:22 +00:00
ergo720 5bfc595414 Add support for the arcade joystick device to the input gui 2021-03-02 22:20:26 +01:00
Luke Usher 018a8061ad
Merge pull request #2116 from RadWolfie/action-pr-labeler
Add Pull Request Labeler Support
2021-03-02 15:19:31 +00:00
Luke Usher 65959ec439
Merge pull request #2131 from RadWolfie/fix-linguist-stats
Fix Linguist Stats
2021-03-02 15:18:28 +00:00
PatrickvL e6d9c6de15
Merge pull request #2149 from NZJenkins/half-pixel-offset
Add D3D9 half-pixel offset
2021-03-01 08:11:24 +01:00
Anthony 72492527e5 Add D3D9 half-pixel offset
Fixes UI rendering issues especially text
2021-02-28 23:50:45 +13:00
RadWolfie 4361c7c6c9 add labeler workflow 2021-02-27 16:04:07 +00:00
RadWolfie 7f86dc80ae add labeler.yml file for prep pull request usage 2021-02-27 16:04:07 +00:00
PatrickvL 97b90fcfd7
Merge pull request #2147 from RadWolfie/tree-clean-up
Minor Clean up in Repo Directories
2021-02-27 09:19:27 +01:00
PatrickvL 807f95cae2
Merge pull request #2148 from NZJenkins/kong-title
Handle game title strings that aren't null terminated
2021-02-27 09:15:48 +01:00
Anthony a60c6aa701 - Adjust string format so we don't write more than 40 chars
- Align comment
2021-02-27 21:09:55 +13:00
Anthony 63e1e0d339 Handle game title strings that aren't null terminated
Fixes instability in King Kong since its title name uses all 40 characters
* Rename wszTitleName to wsTitleName
* Pass length to std::string constructor
* Ensure null termination when copying to m_szAsciiTitle
2021-02-27 20:21:59 +13:00
RadWolfie 00fa639a11 Move XADPCM.h file into audio folder 2021-02-27 02:38:47 +00:00
RadWolfie e30217f2ac Somehow CxbxLoader folder wasn't deleted in the rebased process 2021-02-27 02:38:47 +00:00
RadWolfie 6c70627ad2 Move and rename EmuNVNet files into its own network folder 2021-02-27 02:38:47 +00:00
PatrickvL 8f848f8dda
Merge pull request #2146 from NZJenkins/handle-handling
Implement IsEmuHandle by keeping a lookup of EmuHandle objects
2021-02-27 01:09:49 +01:00
Anthony de20deaa8a Detect when NtQuerySymbolicLinkObject is called without an EmuHandle 2021-02-26 20:59:06 +13:00
Anthony 16c449ddc7 Drop Handle <-> EmuHandle conversion step 2021-02-25 22:48:00 +13:00
Anthony f818e43fc7 - use read/write locking via shared_mutex
- lock in IsEmuHandle
2021-02-25 22:02:41 +13:00
Anthony 7c51e2e34b Use lock_guard instead of explicit lock/unlock 2021-02-25 21:38:24 +13:00
Anthony 3dd4ca7349 Implement IsEmuHandle by keeping a lookup of EmuHandle objects
Fixes a crash in Amped on loading a map after having exited one
Amped requests an invalid handle 0xFDFDFDFD
IsEmuHandle return a false positive and we'd crash trying to call NtClose()
2021-02-25 21:10:55 +13:00
RadWolfie e68d277929 hide sensitive fields from EEPROM gui 2021-02-20 17:11:40 +00:00
RadWolfie c36da13798
Merge pull request #2140 from ergo720/mem_alloc_drop
Removed redundant allocation functions in VMManager
2021-02-20 10:22:02 -06:00
ergo720 1b2308f3e1 Removed redundant allocate functions 2021-02-20 00:46:56 +01:00
RadWolfie 86788a558e
Merge pull request #2135 from ergo720/mouse_wnd_pos
Add support for mouse input as cursor position relative to the rendering window
2021-02-19 17:38:09 -06:00
ergo720 559230a02a Add tooltip to buttons in input gui 2021-02-19 20:37:24 +01:00
ergo720 240dc03dd5 Add support for mouse input as cursor position relative to the rendering window 2021-02-11 17:31:22 +01:00
ergo720 bf6d8b804f
Merge pull request #2134 from ergo720/sb_ctrl
Add Steel Battalion controller support to input gui
2021-02-11 15:03:39 +01:00
ergo720 07b4738e97 Review remarks 2021-02-09 12:36:14 +01:00
ergo720 cd362b6383 Avoid a crash when changing the device type at runtime in the input gui 2021-02-09 12:33:00 +01:00
ergo720 f750b2e4f2 Fixed some tab/space issues and comments 2021-02-09 12:33:00 +01:00
ergo720 9c1c61f191 Deleted XapiCxbxr.h 2021-02-08 22:37:29 +01:00
ergo720 769444f91c Deleted old vsbc project 2021-02-08 22:37:29 +01:00
ergo720 6a54aa5573 Add Steel battalion controller support to input gui 2021-02-08 22:37:29 +01:00
LanHikariDS 689e3ca93c Very belated rebase, as well as progress on the UI and Git resolutions 2021-02-08 22:37:29 +01:00
Luke Usher 4f2404867e
Merge pull request #2133 from NZJenkins/msaa_fixes
Fix some AA scale issues
2021-02-08 20:50:35 +00:00
Anthony d9a2e7a715 CxbxUpdateHostTextureScaling accounts for multisampling
Fixes Max Payne 2 bullet time
which uses MSAA and the backbuffer as a texture
2021-02-08 03:51:13 +13:00
Anthony d7c9e78195 GetScreenScaleFactors ignores multisample scale when using Xbox the fixed function pipeline. 2021-02-08 03:51:13 +13:00
RadWolfie 59d635821a
Update .gitattributes 2021-02-05 04:58:02 -06:00
RadWolfie 2bb2e5c3d4
fix linguist stats 2021-02-05 04:45:30 -06:00
ergo720 d26e028125
Merge pull request #2129 from RadWolfie/update-readme
Update Prerequisites Section
2021-02-02 13:46:18 +01:00
RadWolfie 4056974209
review remark 2021-02-02 06:31:42 -06:00
RadWolfie 87196b8231
remove extra line 2021-02-02 05:16:01 -06:00
RadWolfie 463277c5d8
add notice + fix header 2021-02-02 05:14:48 -06:00
RadWolfie 6166a6ee85
update prerequisites section 2021-02-02 04:59:05 -06:00
Margen67 049a070a10
ci: Improvements (#2021)
Simplify ignored paths.
Opt out of PowerShell telemetry.
Delete Wine VS2017 removal comment.
Make checkout fetch-depth 0.
Capitalize CMake.
upload-artifact:
 Update to v2.
 Simplify path. (/** isn't needed)
 if-no-files-found: error.
release:
 Switch to ubuntu-20.04.
 Prettify if condition.
 Use download-artifact v2;
  This allows all artifacts to be downloaded.
 Iterate through artifacts instead of manually naming/hard coding them.
 Switch to create-release v1;
  This tag is the latest version.
 Use hub release instead of upload-release-asset.
2021-02-01 16:55:55 -06:00
Luke Usher f390c79bdf
Merge pull request #2014 from NZJenkins/experiment/fixedfunc3
HLSL fixed function implementation
2021-01-31 09:27:19 +00:00
PatrickvL ad7328d963
Merge pull request #2127 from LukeUsher/shader-model-tweaks
vs: use model 2.a primarily, with 3.0 fallback
2021-01-30 10:34:53 +01:00
Luke Usher 3abddb5983 vs: use model 2.a primarily, with 3.0 fallback 2021-01-29 20:31:46 +00:00
RadWolfie 2331816a99 review remarks 2021-01-28 10:30:31 +00:00
Anthony b6db19e353 Add hlsl files to install 2021-01-28 19:24:09 +13:00
Anthony 24b38ae3b3 Point sprite fixes
* Implement Min and Max
* Account for upscaling
2021-01-27 22:48:06 +13:00
Anthony 5441dbff1c Fix LocalViewer again, and move it to where it's used 2021-01-27 22:48:06 +13:00
Anthony 8a5c9a6445 Consolidate lighting calculations 2021-01-27 22:48:06 +13:00
Anthony c722d80503 Get view transform from transform state 2021-01-27 22:48:05 +13:00
Anthony 54e0c08ef1 Let MultiplyTransform call SetTransform
Detect if it didn't
2021-01-27 22:48:05 +13:00
Anthony c77582524d Fix incorrect toViewer vector when LocalViewer is enabled 2021-01-27 22:48:05 +13:00
PatrickvL 134dd70117 Optimize away SpecularEnable and PointScaleEnable, by resetting the related variables on CPU.
This shaves off almost 50 vertex shader instructions (down to 705 with this).
2021-01-27 22:48:05 +13:00
PatrickvL bd76d67c78 Indentation fixes & add a 'const' prefix to all single-assigned variables, and 'static' for all literal assignments. 2021-01-27 22:48:05 +13:00
PatrickvL 39e91ffec6 Fixed Function HLSL : Optimized ColorVertex handling in DoMaterial, by removing it's check froM HLSL, and replace that by CPU replacing all MaterialSource's with D3DMCS_MATERIAL when X_D3DRS_COLORVERTEX is disabled. This shaves off 13 vertex shader instructions. 2021-01-27 22:48:05 +13:00
PatrickvL 0245cc6ee8 Optimized vertex blending by only recalculating the required world/view matrices, and a simplified HLSL implementation 2021-01-27 22:48:05 +13:00
PatrickvL 8200cd8e43 Fixed Function : Extract method D3D8TransformState::RecalculateDependentMatrices, called via two getters using a dirty boolean, preventing needless recalculations. 2021-01-27 22:48:05 +13:00
PatrickvL 8b8d1e0d39 Fixed Function : Fixed CXBX_ALL_TEXCOORD_INPUTS build, avoid ambiguous symbol redeclaration 2021-01-27 22:48:05 +13:00
Anthony 43be445c37 Copy constants regardless of dirty state 2021-01-27 22:48:05 +13:00
Anthony Miles b4685c1dc2 Initialize all registers for fixed function mode 2021-01-27 22:48:05 +13:00
Anthony Miles f98d040a65 Enable fixed function vertex shader
- Various bits of glue code
- Toggle Shader/D3D9 with F2
- Replace vertex shader mode flags with enum
2021-01-27 22:48:05 +13:00
Anthony 5720444c6b Fix normal transformations
- Keep track of transforms set by the title
- Transform normals by the inverse transpose of the position transform
- X_D3DTRANSFORMSTATETYPE enum
2021-01-27 22:48:05 +13:00
Anthony Miles 3bfad0327f Xbox fixed function vertex shader (not yet enabled)
The shader should behave similarly to D3D9's fixed function pipeline
But supports Xbox extensions and helps to move off D3D9
Co-authored with PatrickVL
2021-01-27 22:48:05 +13:00
Anthony Miles 99a96e675d Add FixedFunctionState to keep track of D3D fixed function lights 2021-01-27 22:48:05 +13:00
Anthony Miles ddc62ad00e Extract HLSL compilation to a method 2021-01-27 22:48:05 +13:00
ergo720 f44f35f6fa
Merge pull request #2076 from RadWolfie/add-cmake-install
Implement CMake Install Support
2021-01-26 13:48:36 +01:00
PatrickvL fe398a4562
Merge pull request #2126 from NZJenkins/fix-wm-paint
Ensure WM_PAINT is handled correctly
2021-01-26 09:52:09 +01:00
Anthony 20549fec19 Ensure WM_PAINT is handled correctly
Otherwise, Windows will send WM_PAINT messages non-stop and burn CPU doing nothing
This fixes an odd behaviour where moving the mouse over the window could increase FPS
2021-01-26 20:08:58 +13:00
Luke Usher ae43ded58b
Merge pull request #2125 from Cxbx-Reloaded/revert-2109-fix-vsh-initialize
Revert "Initialize vertex shader outputs to vertex shader attribute values"
2021-01-21 09:45:30 +00:00
NZJenkins 515df2b533
Revert "Initialize vertex shader outputs to vertex shader attribute values" 2021-01-21 21:59:51 +13:00
PatrickvL 8c1ee7d755
Merge pull request #2124 from Cxbx-Reloaded/revert-2122-high-perf-graphics-ldr
Revert "Export high performance graphics hints in cxbxr-ldr.exe"
2021-01-20 09:56:21 +01:00
PatrickvL b3f1e610ba
Merge pull request #2123 from NZJenkins/optimize-cnk2
Reduce the amount of work done per draw
2021-01-20 09:55:25 +01:00
RadWolfie 7e838ff677 workflow: update azure-pipelines.yml to use CMake's install method 2021-01-19 23:23:56 +00:00
RadWolfie 8d741e66d3 workflow: update appveyor.yml to use CMake's install method 2021-01-19 23:23:56 +00:00
RadWolfie e39a9a0420 workflow: update GitHub Action CI yml to use CMake's install method 2021-01-19 23:23:56 +00:00
RadWolfie ab01047450 cmake: add CMake install method 2021-01-19 23:23:56 +00:00
RadWolfie 6f62ec001b update submodules' fixes 2021-01-19 23:23:56 +00:00
Anthony d7f0957cba Note why LOG_TEST_CASE is where it is 2021-01-19 01:47:02 +13:00
RadWolfie dab91c1913
remove broken source file path originally in pull request 2021-01-18 05:42:38 -06:00
Anthony ce369a6259 PR cleanup
* Create index cache size variable
* Use std::optional
* Make PreviousStates a class variable
* Remove double-cast
* Use LOG_TEST_CASE in VertexShaderSource
Also move LOG_TEST_CASE to CxbxKrnl.h since it's unuseable from Logging.h
2021-01-19 00:32:56 +13:00
Luke Usher 29719e8fc1
Revert "Export high performance graphics hints in cxbxr-ldr.exe" 2021-01-17 22:03:42 +00:00
Anthony 27dbf03743 Only parse a vertex shader if we can't find it in the cache
Try to clean up and rationalize some things along the way
* GetVshFunctionSize lets us hash an Xbox vsh function, so we can check the cache before trying to parse it
* Consider that the vertex shader header won't be passed to the shader parsing code anymore:
  Combine header/headerless paths in EmuParseVertexShader
  Drop Header information from IntermediateVertexShader as it's no longer used
  Remove EmuGetShaderInfo which looked at the header
* Make XboxVertexShaderDecoder static method in a namespace
2021-01-17 20:26:44 +13:00
Anthony 301205051b Increase vertex buffer cache size
Improves performance in Crash Nitro Kart, which did more draws per frame than the cache size.
2021-01-17 20:25:48 +13:00
Anthony 363d91faff Expand the index cache to a generous size
This seems to slightly increase performance in Crash Nitro Kart
which can do ~4000 draws per frame
2021-01-17 20:25:48 +13:00
Anthony 8eeb061a42 Avoid setting texture states to the same value they already are
This improves performance in Crash Nitro Kart
2021-01-17 20:25:48 +13:00
ergo720 59534bdbcc
Merge pull request #2120 from RadWolfie/relocate-controller-dialogs
Relocate controller dialogs into its own folder
2021-01-14 15:40:53 +01:00
PatrickvL 70088b3697
Merge pull request #2122 from CookiePLMonster/high-perf-graphics-ldr
Export high performance graphics hints in cxbxr-ldr.exe
2021-01-12 22:41:32 +01:00
Silent 0bfc4c4479
Export high performance graphics hints in cxbxr-ldr 2021-01-12 21:39:22 +01:00
RadWolfie e7f2e88784
Merge pull request #2121 from Cxbx-Reloaded/LukeUsher-update-compatibility-link
Update Readme.md: Link to Compatibility website
2021-01-12 10:19:24 -06:00
Luke Usher ffee8ace55
Update Readme.md: Link to Compatibility website 2021-01-12 15:39:45 +00:00
RadWolfie 4d84e71363 relocate controller dialogs into its own folder 2021-01-12 14:24:03 +00:00
Luke Usher e0f41fe6f7
Merge pull request #2117 from NZJenkins/clear-fix
Ensure the xbox viewport is applied when Clear is called
2021-01-11 08:11:00 +00:00
PatrickvL aa3c09c430
Merge pull request #2118 from CookiePLMonster/load-vertex-shader-ltcg
Split D3DDevice_LoadVertexShader_0 into two OOVPAs
2021-01-10 16:17:19 +01:00
Silent 55932e5493
Split D3DDevice_LoadVertexShader_0 into two OOVPAs
XDK-5849 version of this LTCG function passes arguments in EAX and EDX
2021-01-10 15:48:05 +01:00
Anthony 38a0f82980 Ensure the xbox viewport is applied when Clear is called
This fixes an issue introduced in 46ec7516fa
The xbox viewport was applied in UpdateNativeD3DResources instead of the SetViewport patch, so wouldn't be applied until a Draw call.
Crash Tag Team Racing graphics would be blacked out whenever the rear view mirror appeared on the screen.
2021-01-11 00:06:15 +13:00
PatrickvL 875f97b5dd
Merge pull request #2112 from x1nixmzeng/fix-ro-launch
Fixed booting games from write-protected drives
2021-01-03 17:57:12 +01:00
x1nixmzeng 9e05b3342d Log a fatal message if registering a host device fails 2021-01-02 00:20:32 +00:00
x1nixmzeng dfe9a19b0d Fixed path registration on write protected drives 2021-01-01 15:52:49 +00:00
PatrickvL 4ff30fff20
Merge pull request #2071 from RadWolfie/dsound-status-debug
Add Basic DSound Stats to Log Output
2020-12-31 08:41:50 +01:00
Margen67 d82e0ad07a
Add warning to untested CIs (#2072)
* Add warning to untested CIs
2020-12-26 18:08:04 -06:00
PatrickvL 9f5b4e0e11
Merge pull request #2110 from CookiePLMonster/debug-console-removal
Remove debug console
2020-12-25 21:49:42 +01:00
Silent f6d210461d
Remove debug console 2020-12-25 19:08:52 +01:00
PatrickvL a1dfa3d6fe
Merge pull request #2109 from NZJenkins/fix-vsh-initialize
Initialize vertex shader outputs to vertex shader attribute values
2020-12-22 13:12:47 +01:00
PatrickvL 8fe6092f0f
Merge pull request #2108 from CookiePLMonster/ltcg-patches-refactor
Complete refactor of D3D8 LTCG patches calling conventions
2020-12-22 13:12:05 +01:00
Silent 626e84763e
Tidy up final LTCG patches 2020-12-22 12:35:43 +01:00
Silent f0531c5d09
Tidy up Swap, SetTransform, SetStreamSource and SetVertexShader patches 2020-12-22 12:35:43 +01:00
Silent 77579a6113
Tidy up SetShaderConstantMode and SetTexture patches 2020-12-22 12:35:42 +01:00
Silent c9a7911d15
Tidy up SetIndices, EndVisibilityTest, LoadVertexShader, SelectVertexShader patches 2020-12-22 12:35:42 +01:00
Silent f553265c03
Tidy up D3DDevice_SetVertexDataXX patches 2020-12-22 12:35:41 +01:00
Silent c67e925011
Add LTCG_PROLOGUE and LTCG_MACROS and adapt CreateDevice patches to use it 2020-12-22 12:35:29 +01:00
Luke Usher ef30044a93
Merge pull request #2107 from Margen67/typo
Fix typos
2020-12-22 11:12:49 +00:00
Luke Usher 9635ba9d39
Merge pull request #2105 from Margen67/shallow_submodules
.gitmodules: Fix URLs, make some submodules shallow
2020-12-22 11:12:31 +00:00
Luke Usher c89e1ba079
Merge pull request #2104 from CookiePLMonster/d3d9ex
Move to Direct3D 9Ex
2020-12-22 11:11:11 +00:00
Margen67 afbf1fd723
Update .gitmodules
Co-authored-by: RadWolfie <RadWolfie@users.noreply.github.com>
2020-12-20 06:31:24 -08:00
Margen67 c2dc6a44f1
Update src/gui/WinMain.cpp
Co-authored-by: RadWolfie <RadWolfie@users.noreply.github.com>
2020-12-20 06:31:04 -08:00
Margen67 456fd3e30a Fix typos, remove whitespace
Convert tabs to spaces.
Make links https where applicable.
2020-12-19 10:33:14 -08:00
Anthony deb597dd59 Initialize vertex shader outputs to vertex shader attribute values 2020-12-20 00:20:39 +13:00
Margen67 8ab6b91fe5 .gitmodules: Fix URLs, make some submodules shallow 2020-12-19 02:42:13 -08:00
Silent 89f72d8ff0
Move to D3D9Ex
For a full list of improvements see:
https://docs.microsoft.com/en-us/windows/win32/direct3darticles/direct3d-9ex-improvements

For us the most important aspect is no more device loss,
which never existed on Xbox. This allows exclusive fullscreen
to work properly, in the future might also potentially allow for
resizing the backbuffer at runtime.
2020-12-15 18:17:04 +01:00
x1nixmzeng 357948a457
Update cs_x86 submodule (#2074)
* Update cs_x86 submodule

* Remove cstool target as this is no longer added by cs_x86
2020-12-11 20:11:38 -06:00
PatrickvL 2d3977b220
Merge pull request #2070 from RadWolfie/cmake-fix
Fix Missing ResCxbx.h File from the List
2020-12-11 08:02:14 +01:00
RadWolfie 6c3c033158 fixup: use EmuFlags instead of Xb_Flags for receive real time update 2020-12-10 21:39:38 -06:00
RadWolfie b5788e85ca dsound: add stats to log output 2020-12-10 20:02:12 -06:00
RadWolfie afc4c0b561 cmake: fix missing ResCxbx.h file for listing 2020-12-10 18:30:17 -06:00
Luke Usher 2f74af168d
Merge pull request #2069 from RadWolfie/wine-env
Update Wine Usage
2020-12-10 11:38:35 +00:00
RadWolfie 1ceb0b424f wine: suppress admin privilege popup warning in wine environment 2020-12-10 05:23:01 -06:00
RadWolfie e42c39e9ba common: move wine check into its own file 2020-12-10 04:32:06 -06:00
PatrickvL fe0c2db158
Merge pull request #2067 from RadWolfie/dsound-fixes
Fix Audio Overall Volume Not Included From Input Sets of Volume
2020-12-09 23:50:35 +01:00
RadWolfie a02efe0466 dsound: fix overall mixbin volume than only input volume(s) 2020-12-09 16:17:40 -06:00
RadWolfie 0356b40735 dsound: add X_DSVOICEPROPS to log for further troubleshooting 2020-12-09 15:08:29 -06:00
PatrickvL efee57a10c
Merge pull request #2039 from RadWolfie/dsound-fixes
Another Round of DSound's Stream fixes
2020-12-09 20:53:10 +01:00
PatrickvL 4d4f6dd681
Merge pull request #2059 from CookiePLMonster/d3d-create-fixes
Refactor D3D device creation
2020-12-09 16:46:42 +01:00
Luke Usher 10ba282305
Merge pull request #2060 from ergo720/ff_fix
Fix incorrect flags in NtDuplicateObject
2020-12-08 16:52:12 +00:00
ergo720 f5ed14d276 Address review remark 2020-12-07 21:49:25 +01:00
ergo720 b86e64f36a Fix incorrect flags in NtDuplicateObject 2020-12-07 21:10:01 +01:00
Silent 2691f44970
Remove EmuCreateDeviceProxy and refactor D3D device creation
Greatly streamlines the code and most importantly,
ensures that CreateDevice and Release() are called on the window message
thread, just as it is required.

See:
https://docs.microsoft.com/en-us/windows/win32/direct3d9/multithreading-issues
2020-12-04 22:23:59 +01:00
Silent 5a8cfaf7f9
Add RunOnWndMsgThread to run arbitrary code on the window message thread 2020-12-04 20:48:36 +01:00
Silent 7902c12738
Don't use g_bRenderWindowActive for synchronization 2020-12-04 20:31:32 +01:00
RadWolfie e2fcedd1b7 dsound: fix status return when envelope is complete 2020-12-03 21:13:22 -06:00
RadWolfie 07c3f3b0fa dsound: fix async flush 2020-12-03 21:13:21 -06:00
RadWolfie f872bb5f8a dsound: replace size to empty function 2020-12-03 21:13:21 -06:00
RadWolfie 50d21d8127 dsound: don't process flush if there's no packets 2020-12-03 21:13:20 -06:00
RadWolfie 3a506df754 dsound: Add stream's flushex flag type to extend verbose output 2020-12-03 21:13:20 -06:00
RadWolfie 5031f1aa65 dsound: remove unused cxbxr flag from log 2020-12-03 21:13:19 -06:00
RadWolfie 3209bf7be5 dsound: fix pause flags as enums instead 2020-12-03 21:13:19 -06:00
RadWolfie ee9612e263 dsound: fix stream class to match hardware with latest sampling log 2020-12-03 21:13:18 -06:00
PatrickvL 471f3894cc
Merge pull request #2058 from RadWolfie/input-list-fix
Change listing to target specific type than default order
2020-12-03 08:30:07 +01:00
RadWolfie 93a3a3b35c input: change listing to target specific type than default order 2020-12-03 00:06:14 -06:00
PatrickvL 3a7b233199
Merge pull request #2052 from LukeUsher/remove-3925-hacks
remove 3925 fog/alpha hacks
2020-11-29 17:59:35 +01:00
Luke Usher 764304c0ca
Merge pull request #2055 from CookiePLMonster/fix-completion-callback
Preserve original IO status block and context for ApcRoutine
2020-11-29 14:07:22 +00:00
Silent 0411f27c65
Preserve original IO status block and context for ApcRoutine
Fixes cases where guest's APC routine/completion callback
does not receive the original IO status block variable,
but it assumed it did (it's allowed as per WinAPI docs).

Fixes Project Gotham Racing deadlocking after intro movies
2020-11-29 11:51:18 +01:00
PatrickvL 8415397067
Merge pull request #2053 from LukeUsher/improve-texturestate-mappings
rework texturestate mapping to be more sane + fix unmapped get
2020-11-28 20:12:48 +01:00
Luke Usher a99d3f923a
Update TextureStates.cpp 2020-11-28 18:13:41 +00:00
Luke Usher 6c0bb86336 rework texturestate mapping to be more sane + fix unmapped get 2020-11-28 17:39:22 +00:00
Luke Usher 6915ccb027 remove 3925 fog/alpha hacks 2020-11-28 14:29:05 +00:00
Luke Usher 8c986c2480
Merge pull request #2040 from NZJenkins/z_fixes
Z fixes
2020-11-28 13:40:07 +00:00
PatrickvL 47795babfd
Merge pull request #2050 from CookiePLMonster/current-ps-fix
Modernize DxbxUpdateActivePixelShader
2020-11-28 09:14:46 +01:00
Silent 64672ddb4b
Modernize DxbxUpdateActivePixelShader
Fixes redundant constant setting, leaking pixel shader handle
and generally tidies up the code
2020-11-28 00:39:01 +01:00
Luke Usher 362c93801f
Merge pull request #2048 from CookiePLMonster/vertex-stream-cache-optimization
Optimize vertex stream cache for partial buffer access
2020-11-27 07:56:15 +00:00
PatrickvL 246d1fa3fe
Merge pull request #2049 from LukeUsher/renderstate-table-4034
update renderstate table with 4034 findings
2020-11-26 22:09:23 +01:00
Silent 2480582b0c
Optimize vertex stream cache for partial buffer access
Drastically reduces the amount of copied and converted data in cases
where any of the following apply:
* BaseVertexIndex is not 0
* LowIndex is not 0
* dwStartVertex is not 0

Also potentially fixes an issue where data past an indexed
vertex buffer was hashed and converted, leading to
potential false positives on dirty checks, maybe more.
2020-11-26 21:20:15 +01:00
Luke Usher 2324b798ab
Update XbConvert.cpp 2020-11-26 19:48:14 +00:00
Luke Usher 1aac347af9 update renderstate table with 4034 findings 2020-11-26 19:02:44 +00:00
PatrickvL d748d3d4f2 Removed needless externs 2020-11-26 00:44:08 +01:00
PatrickvL 698719d5ad Moved g_RenderUpscaleFactor declaration to Direct3D9.cpp (the only file where it's used).
Introduced g_RenderTargetUpscaleFactor and update it in CxbxImpl_SetRenderTarget.
Where possible, incorporate g_RenderTargetUpscaleFactor once in X and Y scaling factors.
2020-11-25 22:08:04 +01:00
Anthony d1596da695 Resolve the rendertarget upscale factor once 2020-11-25 22:08:04 +01:00
Anthony 7268219f5e Fix rendering to a non-upscaled rendertarget when upscaling is enabled
Test case: JSRF character select with upscaling
Rename RenderScaleFactor to RenderUpscaleFactor
2020-11-25 22:08:04 +01:00
Anthony 95b97b0502 - Calculate Z matching D3D9 docs (combined with Xbox depth scaling)
- Normalize Z from either (0, 1) or (0, zbuffer depth)
2020-11-25 22:07:03 +01:00
PatrickvL b2ca28198e
Merge pull request #2044 from LukeUsher/create-surface-as-texture
d3d: wrap surfaces in textures
2020-11-25 22:05:09 +01:00
PatrickvL eca9c330c5
Merge pull request #2045 from CookiePLMonster/palette-fixes
Palette fixes
2020-11-25 21:35:04 +01:00
PatrickvL beac314243 Processed review remarks 2020-11-25 21:33:46 +01:00
Silent 7af503b90c
Do not try to resolve the palettized texture if there is no palette bound
Fixes a crash in DRIV3R
2020-11-25 20:39:03 +01:00
Luke Usher ec6987d17f
Merge pull request #2041 from Blackbird88/master
Added "Silent (CookiePLMonster)"
2020-11-25 07:49:37 +00:00
Silent 4d8c4fbb68
Fix D3DDevice_SetPalette and D3DDevice_SetPalette_4 not calling to guest code
Fixes memory leaks in SetPalette functions, as they are now able
to reference count and destroy palette resources.
Also fixes a very poor SetPalette_4 LTCG function
2020-11-24 20:04:53 +01:00
Luke Usher e0b62dde9d d3d: experimental creation of surfaces as textures 2020-11-24 17:06:53 +00:00
Silent 36e6349de5
Fix a wrong NestedCallCounter in D3DDevice_SetRenderTarget_0 2020-11-24 18:04:49 +01:00
Blackbird88 8c3d1bcdfa
Added "Silent (CookiePLMonster)" 2020-11-24 13:07:40 +01:00
RadWolfie 55da0a278b
Merge pull request #2038 from RadWolfie/loader-fix
Fix free up address range's system allocated
2020-11-22 02:26:09 -06:00
RadWolfie e424d05252 fix couple variable types usage 2020-11-22 01:50:57 -06:00
RadWolfie a08145b0c2 loader: fix input for what system need to be free up reserve address ranges 2020-11-22 01:40:42 -06:00
Luke Usher 21c27b416f
Merge pull request #2032 from RadWolfie/dsound-fixes
Fix CDirectSoundStream_GetStatus for difference output over time
2020-11-21 12:37:45 +00:00
Luke Usher 9d714c4488
Merge pull request #2033 from NZJenkins/viewport_fixes2
Improve viewport calculations
2020-11-21 12:37:19 +00:00
Luke Usher 9ebdef8502
Merge pull request #2037 from ergo720/fix_loader_wine
Allow cxbxr to work again with wine under Linux
2020-11-21 12:36:47 +00:00
Anthony 46ec7516fa Improve viewport calculations and 2D rendering
- SetViewport tracks the Xbox viewport values instead of setting the viewport,
so we can calculate what we need from them
- Rework GetViewportOffsetAndScale and scaling methods
- Vertex shader programs do not depend on D3D9 viewport to transform verts
- Account for backbuffer scale
- Add some D3DSWAP flags and LOG_TEST_CASE for unhandled usage
2020-11-21 23:41:16 +13:00
ergo720 c566836f42 Allow the cxbxr to work again with wine under Linux 2020-11-20 18:59:48 +01:00
Luke Usher 6350abaaf7
Merge pull request #2036 from CookiePLMonster/release-skip-removal
Remove hacks skipping guest resource removal if they are bound
2020-11-18 10:12:29 +00:00
Silent 43eefa8041
Improve the D3D_DestroyResource__LTCG patch
EDI register is unlikely to be trashed, but use a naked function anyway
Added logging, same as the non-LTCG DestroyResource
2020-11-17 20:44:26 +01:00
Silent 74333af9c0
Remove hacks skipping guest resource removal if they are bound
Fixes games running out of guest memory:
- Outrun 2
- Monster Garage
- probably many more

Removes "Skipping Release of..." test cases
2020-11-17 20:33:34 +01:00
Luke Usher dc5f56222e
Merge pull request #2034 from CookiePLMonster/vertex-stream-offsets
Take vertex stream offset into the account when caching VBs
2020-11-16 23:07:32 +00:00
Silent 6892591084
Take vertex stream offset into the account when caching VBs
Fixes exploding vertices in TOCA Race Driver.
2020-11-16 23:52:18 +01:00
RadWolfie 1c2c02f47b dsound: fix CDirectSoundStream_GetStatus for difference output over time 2020-11-15 16:38:03 -06:00
PatrickvL 7e0f8f4b30
Merge pull request #2031 from CookiePLMonster/xdk-3911-ltcg-fixes
Misc fixes after the vertex declaration changes
2020-11-15 22:20:51 +01:00
Silent 770d062014
Fix a merge error in CxbxImpl_SetViewPort 2020-11-15 22:03:43 +01:00
Silent 67c31c650b
Const qualify a few parameters in XbVertexShader.cpp functions
No functional change, just preventing future me from a typo I made.
Const-qualifying those parameters would have prevented it.
2020-11-15 22:03:43 +01:00
Silent dab1da6caf
Fix X_VERTEXSHADER_FLAG_PROGRAM flag for XDK-3948
In this XDK X_VERTEXSHADER_FLAG_PROGRAM appears to have a value of 4,
not 16. Adjusted the code accordingly and added test cases to verify
that assumption.
2020-11-15 22:03:43 +01:00
Silent c3568f6ea3
Fix D3DDevice_SetVertexShader_0 not calling a trampoline
Fixes NASCAR Heat 2002 rendering (again)
2020-11-15 20:28:24 +01:00
Luke Usher 213dd2f86f
Merge pull request #1894 from PatrickvL/vertex_declaration_refactoring
Vertex declaration refactoring
2020-11-14 14:04:58 +00:00
Luke Usher 3f4f141cf1
Merge pull request #2030 from RadWolfie/update-env-method
Action: Fix CI Release Job
2020-11-13 12:08:12 +00:00
RadWolfie a6353f7554 action: fix CI release job 2020-11-13 02:21:30 -06:00
Luke Usher 498cf39664
Merge pull request #2029 from RadWolfie/update-env-method
Action: Replace Deprecated Method to New Method for Set Environment
2020-11-12 08:57:54 +00:00
RadWolfie 2759d9bb8c action: replace deprecated method to new method for set environment 2020-11-11 12:33:27 -06:00
PatrickvL c3993c6abb
Merge pull request #2028 from CookiePLMonster/subhook-update
Update subhook
2020-11-11 00:12:19 +01:00
Silent 50164a5a67
Update subhook 2020-11-10 23:39:02 +01:00
patrickvl 561f76c067 Fixes after rebase
Write our viewport constants after copying dirty constants from PGRAPH
Fixes geometry flickering in some titles
Miscellaneous cleanup (renaming, indentation, function inlining)
Start stream offset from slot offset rather than vertex stride
Vertex declaration debug logging
Xbox clamps fog in pixel shader (not vertex shader)
Fix typos
Introduce HostStreamNumber, to use Xbox stream index on host
Pass HostStreamNumber to Activate
Let CountActiveD3DStreams return an actual count
Call ConvertStream with a regular counter instead of pretended stream index
For clarity in ConvertStream, discern between XboxStreamNumber and HostStreamNumber (even though they're the same value)
Don't check CxbxVertexDeclarationNeedsPatching in GetNbrStreams
Remove now unused CxbxVertexDeclarationNeedsPatching
Rename IndexOfStream into StreamIndex
Remove unused DeclPosition
Rename CurrentStreamNumber into XboxStreamIndex
Reduce size of VertexElements array to X_VSH_MAX_ATTRIBUTES (16)
Rename StreamNumber into XboxStreamNumber
Set XboxStreamIndex only once
Assert VertexStreams won't be accessed outside it's size
Assert VertexElements won't be accessed outside it's size
For AUTONORMAL, set UsageIndex to 0 instead of (according to docs) incorrect 1
Derive NeedPatching from XboxVertexElementByteSize, instead of setting it alongside
Set dummy vertex buffers using HostStreamNumber argument name
Clamp output fog in vertex shader HLSL.

Also, cleanup passthrough HLSL to write outputs identical to vertex shader template HLSL
Turns out, the scale and offset we send to the Xbox passthrough program, should just be identity, regardless resolution or scale.

This seems to fix sub-pixel differences, noticeable when F7-toggling passthrough mode between our dedicated HLSL vs the Xbox program.
Let F7 toggle passthrough based rendering between an Xbox (-derived) shader or our dedicated HLSL shader. Also fixed the index of the -96 and -95 (scale and offset) passthrough constants. F7-toggling, you can see a slight sub-pixel difference between the two modes, probably related to how scale and offset are calculated and used differently between the two approaches. With this, we can postpone the decision on how we should handle passthrough mode.
Fixup use render target width rather than backbuffer width
Multiply instead of divide in ReverseScreenspaceTransform
Don't scale Z in passthrough
test case GTA III sprites
Scale viewport X and Y as well as height.
Fixes cases where X and Y are nonzero e.g. DoA3 character select
Tidy and simplify GetViewPortOffsetAndScale a bit
Refactor passthrough HLSL to call reverseScreenspaceTransform, which not only uses offset and scale constants, but is now also configurable to handle RHW transformed positions.

This takes us one step closer to merging passthrough HLSL with our generic vertex shader HLSL
- IVB passes the position register in full (FLOAT4 instead of FLOAT3)
Fixes samples that pack 2d coords and texcoord into position
- Remove POSITIONT semantic, as we don't expect it in our shaders or pass it to the fixed function pipeline
scaley
rhw
Don't scale texcoords by default. Not all texcoords are used for texture fetches
LoadVertexShader_4 avoids trashing EAX parameter
Apply g_RenderScaleFactor to passthrough constants.

Also renamed ViewPort into HostViewPort. Added Comments, fixed typo's, marked unused code.
Extract D3DDevice_SetViewPort into CxbxImpl_SetViewPort

Also fix build
Extract D3DDevice_SetRenderTarget into CxbxImpl_SetRenderTarget, and call that from Direct3D_CreateDevice_End
Split off CxbxUpdateHostTextureScaling()
Typos
Separate setting host textures from texture coord scaling
Call UpdateHostTextures before state apply calls
Fix build
Prepare for more accurate calculation of passthrough constants zero and one (not functional yet).

Plus some cleanup
While at it, implement the conversion of remaining TextureStageStates in a similar way as TextureCoordinateIndex (mentioning known values explicitly in code, LOG_TEST_CASE or EmuLog for unsupported/unexpected input values).
Fix TSS_TCI conversion (and some typos, and reordering of code)
Map texture coordinate indices in fixed function mode only

(cherry picked from commit 32878cac2fc3682ac057af4f74f495d994fa13b8)
- Revert to scaling coordinates for linear textures
- Use texture state to map from stages to texcoord indices
- Add Get method to XboxTextureState

(cherry picked from commit 39dd0144851e49ea2452506293dca5e1f532ac97)
Fix XDK Ripple sample regression in CxbxSetVertexShaderPassthroughProgram, by not setting our own calculations in constant zero and one (and instead rely on Xbox code setting those through pushbuffer commands)
Remove texture normalization from vertex buffer conversion.
Instead, apply the texture scale factor in our vertex shader HLSL
This removed yet another reason for buffer patching, simplifying code more and speeding up rendering a little.

The Ripple XDK sample regressed because of this (or an earlier commit?), which might (or might not) be related to vertex explosions seen in some games.

(That, or it has something to do with the use of non-standard registers for passing in texture coordinates - in any case, a fix for this will probably improve a few games as well).
Set vertex shader constants based on pgraph (and write then to there as well)
Set constant zero and one for passthrough programs
For this, introduce and call CxbxImpl_SetScreenSpaceOffset
Renamed all host update functions to : CxbxUpdateHost...
As it turns out, texture normalization only applies to pre-transformed (X_D3DFVF_XYZRHW) vertex declarations (not just FVF based declarations)!

So, replace final use of VshHandleIsFVF (allowing removal of it's declaration) with GetXboxVertexAttributeFormat(), and update CxbxVertexBufferConverter::ConvertStream to use the Xbox AttributeFormat (instead of decoding FVF's).
With this, there's also no more use for DxbxFVF_GetNumberOfTextureCoordinates nor DxbxFVFToVertexSizeInBytes, so these are now removed as well.

I verified this still renders all XDK samples identically, but some games might improve due to this (especially if they have separate sets of texture-coordinates in a single stream). There's a low chance for regressions.
Remove our final SetFVF call on host, by composing an Xbox vertex attribute format according to the registers that have been written to in CxbxImpl_SetVertexData4f

This also allowed to clean up the code that copies data from g_InlineVertexBuffer_Table to g_InlineVertexBuffer_pData (a pass that we might even be able to skip?)
Extract the code from our D3DDevice_Begin patch towards CxbxImpl_Begin
Rename EmuFlushIVB into CxbxImpl_End
With this, all use of g_InlineVertexBuffer* symbols is limited to XbVertexBuffer.cpp
So, remove all extern declarations on g_InlineVertexBuffer* symbols.

Remove implementation and calls to HLE_write_NV2A_vertex_attribute_slot,
because CxbxSetVertexAttribute already does that with less overhead,
which is already called in CxbxImpl_SetVertexData4f.
Some comments on how we might handle vertex shader constants later on
Disable two LOG_TEST_CASE's
Simplify CxbxSetVertexAttribute
Extract CxbxImpl_SetVertexData4f from our D3DDevice_SetVertexData4f patch
Move the implementation to XbVertexBuffer.cpp
There, extract the part about setting default register values towards a separate function, called CxbxSetVertexAttribute
In CxbxImpl_SetVertexData4f, read starting values for all attributes
For this, refactored HLE_read_NV2A_vertex_attribute_slot into HLE_get_NV2A_vertex_attribute_value_pointer
Convert it's float pointer result to required data type per g_InlineVertexBuffer_Table field.
Use the same function in CxbxSetVertexAttribute to write default attribute values
In CxbxImpl_SetVertexShader, call CxbxSetVertexAttribute to set default values for attributes missing from vertex shader
Remove duplicate reset of g_Xbox_VertexShader_FunctionSlots_StartAddress
Remove bNeedRHWReset remnants
Don't set fixed function mode when we don't know what to do
Fixes Amped menu graphics
Make sure we process stream elements in order of offset
Use clamped reciprocal for defined behavour with rcp(0)
Remove FVF vertex buffer fixups
Reset vertex shader address when setting the passthrough program
Revert "Postpone calling EmuParseVshFunction until after shader cache miss, this should speed up rendering a little"

This reverts commit a4b647e6fe365ca414815afcf813431e7080546d.

Reason : EmuParseVshFunction sets the size needed for ComputeHash, so we can't avoid it!
Silence compiler warning
Reset g_Xbox_VertexShader_FunctionSlots_StartAddress to zero for passthrough mode

Also prepared storing g_Xbox_VertexShader_Ptr (See CXBX_USE_GLOBAL_VERTEXSHADER_POINTER).
Postpone calling EmuParseVshFunction until after shader cache miss, this should speed up rendering a little
Avoid calling trampoline when not assigned
Write binary Xbox shader to our slots for passthrough shaders
Use a version-dependent getter for shader tokens
Make sure EmuParseVshFunction never goes out of bounds (by putting a FLD_FINAL at slot 136 in CxbxSetVertexShaderSlots)
Document vertex shader flags and set more of them in XboxVertexShaderFromFVF
Oops
Took some stuff from NZJenkins dca881d61f
Postpone host update of vertex declaration and shader towards draw-time.
Introduce new fixed-function status boolean
Conversion of FVF to internal vertex shader INCLUDING texture Dimensions.
Avoid treating internal vertex shader as older version
Some more cleanup

Status of this is, that some XDK samples lack geometry, not sure if this is the result of this commit or a prior one. NZJenkins has a branch that shares history with this one, that does show geometry, so perhaps we should mix & match the best parts of these two branches, and continue with the result?!?
Call UpdateViewPortOffsetAndScaleConstants only from CxbxUpdateNativeD3DResources (and after CxbxTransferVertexShaderConstants)
Extracted code into CxbxTransferVertexShaderConstants function, using new (renamed) HLE_read_NV2A_vertex_constant_float4_ptr function
Introduce HLE_read_NV2A_vertex_program_slot and HLE_read_NV2A_vertex_constant_slot functions
Fix missing nv2a registers
Differentiate between two versions of X_D3DVertexShader
In HLE_write_NV2A_vertex_attribute_slot assert failure in pgraph_handle_method()
Call HLE_init_pgraph_plugins() from a better suitable place (EmuD3DInit)
Processed code review comments : Fixed a few typo's, document SetVertexShaderInput test-cases, rename inaccurate symbol names, add more comments, add LOG_TEST_CASE("Limiting FVF to 4 textures")
Start using GetXboxVertexStreamInput everywhere g_Xbox_SetStreamSource was accessed
Removed CreateVertexShader patch and implementation
Cache VertexDeclarations based on hash of their contents
Store FVF based VertexAttributeFormat in global variable
GetXboxVertexAttributeFormat returns a pointer now
A lot of cleanup (like IsValidCurrentShader and VshHandleIsValidShader are no longer needed)
Fix post-processing of elements for D3DDECLMETHOD_CROSSUV (normal tesselation)
Move and rename global variables.

Also, partly picked conversion of tesselation-declarations.
Reorder and comment vertex-shader related types
Removed now-obsolete CxbxVertexShader struct, instead use CxbxVertexDeclaration and renamed all references to that.
Start using GetXboxVertexAttributes, which calls the new (temporary) XboxFVFToXboxVertexAttributeFormat function for FVF vertex shader handles)

Also removed the now-obsolete SetCxbxVertexShaderHandle() and SetCxbxVertexDeclaration() functions
Introduce GetXboxVertexShader and GetXboxVertexAttributes getters (both not yet used)
In D3DDevice_SwitchTexture use a switch statement instead of an array plus for-loop
Implement our patch on SetVertexShaderInput and introduce GetXboxVertexStreamInput, a getter that honors this g_Xbox_SetStreamSource override (not yet used)
Disabled patches on D3DDevice_GetVertexShaderInput and D3DDevice_SetVertexShaderInputDirect.
Call trampoline in D3DDevice_SetVertexShaderInput (and add a LOG_TEST_CASE)
Disabled patch on D3DDevice_SelectVertexShaderDirect (since all it does, is forward to D3DDevice_SelectVertexShader, which we DO patch)
Call trampoline in D3DDevice_SetVertexShader
CxbxImpl_LoadVertexShader must not skip first program DWORD
Explicit padding in X_VERTEXSHADERINPUT to avoid potential alignment issue
Make Xb2PCRegisterType more compact, and let it support D3DDECLUSAGE_POSITIONT
WIP
Introduce CxbxFVFToXboxVertexAttributeFormat, a function that converts an Xbox FVF handle to the Xbox Vertex attribute format struct. This, so that in a next step we can convert the Xbox Vertex attribute format struct to a CxbxVertexDeclaration (or maybe just straight to a host declaration)
Implement CxbxImpl_LoadVertexShader much closer to reality
Define X_D3DVertexShader.Flags values
CxbxImpl_SelectVertexShader : Only store Handle when it's non-NULL (which must always be a VertexShader, so LOG_TEST_CASE when not)
Use CxbxSetVertexShaderSlots tooling function to reduce duplicate code
2020-11-02 21:39:40 +01:00
PatrickvL 97bf1d9169
Merge pull request #2022 from CookiePLMonster/mm3-fixes
Miscellaneous Direct3D LTCG fixes
2020-11-02 18:36:08 +01:00
Silent 2875342b5c
Fix a resource leak in D3DDevice_Swap 2020-11-02 17:52:56 +01:00
Silent 65d5abc813
Implement D3DDevice_DeleteVertexShader_0
Test case now can be removed, as it existed only due
to no known games using this function.
2020-11-02 17:52:56 +01:00
Silent feef6ffb3d
Refactor LTCG versions of Direct3D_CreateDevice
* Make Direct3D_CreateDevice_4 naked to remove
   the risk of trashing parameters
* Split Direct3D_CreateDevice_16 into two separate functions
   with different calling convention
2020-11-02 17:52:55 +01:00
Silent cbe534cb54
Patch D3D_CommonSetRenderTarget 2020-11-02 17:52:55 +01:00
Silent 62af56b67a
Fix D3DDevice_SetPixelShader_0 corrupting the stack 2020-11-02 17:52:54 +01:00
Silent 8b7f4a5027
Patch D3DDevice_SetRenderTarget_0 and factorize implementations
CreateDevice would try to call an inexistant guest trampoline,
but in fact we only needed to call the host implementation
2020-10-31 14:44:13 +01:00
Luke Usher 38242d48f9
Merge pull request #2015 from CookiePLMonster/affinity-fix
Fix affinity for EmuCreateDeviceProxy thread
2020-10-28 16:59:52 +00:00
Silent 16efb84eb9
Fix affinity for EmuCreateDeviceProxy thread 2020-10-28 17:47:34 +01:00
Luke Usher 5fe769b906
Merge pull request #2002 from PatrickvL/ps_const_simplfy
Simplfy pixel shader constant handling;
2020-10-28 13:40:57 +00:00
PatrickvL 44f0aee5d4
Merge pull request #2012 from CookiePLMonster/interlocked-lockcounts
Interlocked lockcounts
2020-10-28 11:20:11 +01:00
PatrickvL b8bb054402 Revert unintentional subhook change 2020-10-27 18:23:00 +01:00
patrickvl c09a90e459 Remap host pixel shader constant indexes, so that all constants can be set using just one call to SetPixelShaderConstantsF
Also, added more notes and code on the PSDef.PSTextureMode field (which lies outside of the render state pixel shader range), and skip the values of the final combiner constants when checking for uniqueness of pixel shader definitions.
2020-10-27 18:22:59 +01:00
patrickvl eae97f3f07 Optimize setting host pixel shader constants, by collecting all values and set them using a single call.
Also remove one more unused variable
2020-10-27 18:22:59 +01:00
patrickvl 337946db25 Simplfy pixel shader constant handling;
Since we've ported over to Direct3D 9, and we're using pixel shader version 1.4, we've got more than enough constants available to remove the need for constant packing.

Also, there was a left-over patch on SetPixelShaderConstant which must no longer be applied, since nowadays we read constant values straight from their corresponding render state slots.
This also implies we no longer need to declare the final combiner constants as part of the shader assembly, because these 2 are also read from their corresponding xbox render state slots, and thus can be transferred to host on each update.

This will likely improve the output of pixel shaders which stay otherwise unchanged but rely on changing constant values.
2020-10-27 18:22:58 +01:00
RadWolfie f8593e692d
Merge pull request #1993 from CookiePLMonster/dsound-improvements-alt
DSound improvements (alternative volume heuristics)
2020-10-26 17:29:31 -05:00
Silent dd0e331528
Thread safety fixes for ERWLOCK 2020-10-26 20:55:24 +01:00
Silent 4323e401d8
Thread safety fixes for RtlCriticalSection 2020-10-26 20:51:19 +01:00
Luke Usher 1c465409c2
Merge pull request #2011 from CookiePLMonster/transform-patches-recursive
Guard against nested SetTransform/MultiplyTransform calls
2020-10-26 18:01:11 +00:00
Silent 4dd9aaeed7
Guard against nested SetTransform/MultiplyTransform calls
In the case of 25 to Life, MultiplyTransform calls SetTransform
which corrupted the host's internal state. Introduce a guard variable
to ensure we call to host only once per the patch chain and keep
the internal state pristine
2020-10-26 18:54:39 +01:00
Silent acff986fe1
Add NestedPatchCounter 2020-10-26 18:50:54 +01:00
Luke Usher 3b82af621d
Merge pull request #2007 from CookiePLMonster/burnout-patches
Changes to D3D patches
2020-10-25 19:07:50 +00:00
Silent e81c9fecb8
Unpatch D3DDevice_GetTransform and call to guest in SetTransform and MultiplyTransform
Fixes (not yet visible) rendering in Burnout 3, possibly because to it
having an unpatched LTCG-specific GetTransform or reading from
the D3D state directly.
2020-10-25 18:53:34 +01:00
Silent 5592f81c02
Implement D3D_BlockOnTime_4 2020-10-25 18:52:20 +01:00
Luke Usher 9a773ef7ac
Merge pull request #2003 from CookiePLMonster/fix-apu-timer
Fix APU timer ticking at wrong frequency
2020-10-25 01:41:56 +01:00
Silent d5adbb2ab3
Refactor APU, TSC and ACPI timers to use shared code 2020-10-24 23:53:15 +02:00
PatrickvL 23a3bc4b78
Merge pull request #2005 from CookiePLMonster/fix-vs-precision
Improve reverse screenspace transformation precision
2020-10-24 23:21:48 +02:00
Silent 709a3508ee
Pre-divide reverse scale in reverseScreenspaceTransform
This should improve numerical stability of the reverse transformation
when D24 depth is used by the game, as this caused viewport.z
to be very large (0xFFFFFF).
2020-10-24 23:18:59 +02:00
Silent 9b2c1ba2ce
Submit viewport scale and offset in one batch 2020-10-24 22:36:56 +02:00
Silent 0f88b77bfe
Fix APU timer ticking at wrong frequency 2020-10-24 13:09:37 +02:00
Luke Usher 724a1ca684
Merge pull request #2001 from PatrickvL/fix_ps_sum_reg
Pixel shader fix XFC SUM
2020-10-23 09:10:23 +01:00
patrickvl a412c80b24 Fix how our current pixel shader conversion calculates the final combiner special purpose register 'sum' : it was accidentally multiplying instead of adding it's arguments! 2020-10-23 01:05:24 +02:00
Luke Usher 1ee123900b
Merge pull request #1982 from ergo720/InlineVertexBuffer_as_vector
Use std::vector for g_InlineVertexBuffer_Table instead of realloc
2020-10-21 08:38:02 +01:00
Luke Usher 4e6068f6b4
Merge pull request #1998 from CookiePLMonster/thread-creation-delay
Simplify thread creation logic, remove hardcoded delays and tighten affinity changes
2020-10-21 08:36:10 +01:00
PatrickvL 7938142faf
Merge pull request #2000 from CookiePLMonster/copyrects-fallback
Add a fallback to CopyRects for cases which StretchRect can't handle
2020-10-21 01:04:09 +02:00
ergo720 a4d1807b4c Use std::fill and std::copy where possible 2020-10-20 21:26:43 +02:00
ergo720 47ea099a92 Use std::vector for g_InlineVertexBuffer_Table instead of realloc 2020-10-20 21:26:43 +02:00
Silent ea98d4bdea
Add a fallback to CopyRects for cases which StretchRect can't handle
Fixes menus in World Racing 2 because CopyRects tries to copy
a texture to texture.
2020-10-20 19:40:46 +02:00
Silent b7b2c24fdb
Start child threads suspended and finalize their initialization before resuming
* Closes a possible race condition where a child thread uses
ThreadHandle or dwThreadId AND starts before _beginthreadex even returns
* Allows to remove hardcoded sleeps "slowing down" parent thread
execution in favour of more reliable affinity mask changes on the child thread

Test case: The Warriors and its race condition on event creation
(child thread waits on the event parent thread creates AFTER spawning
the child thread)
2020-10-19 23:59:22 +02:00
Silent b04980a150
Remove hStartedEvent
It doesn't seem to be useful anymore (does not protect any thread-unsafe
initialization), and it was encouraging the OS scheduler to keep executing
the child thread before returning the parent thread from PsCreateSystemThreadEx

Test case: The Warriors and its race condition on event creation
(child thread waits on the event parent thread creates AFTER spawning
the child thread)
2020-10-19 21:49:46 +02:00
Silent 6f27d335f7
Change ThreadId parameter type to PWORD
Purely cosmetic change, does not change any functionality.
2020-10-19 21:27:16 +02:00
PatrickvL 8588230ee1
Merge pull request #1997 from LukeUsher/fix-shenmue-bios-read
emux86: fix bad bios rom mapping
2020-10-18 17:22:50 +02:00
PatrickvL b07ca858d5
Merge pull request #1999 from CookiePLMonster/pixel-combiner-fixes
Pixel combiner fixes
2020-10-18 16:49:12 +02:00
Silent 2d33a1bb6b
Implement better Blue-to-Alpha
Fixes pixel shaders decoding BINK videos (together with the previous commits).
Cleaned up a few TODOs.
2020-10-18 16:46:57 +02:00
Silent cc98adb38c
Fix SimplifyLRP remapping to wrong intermediate registers 2020-10-18 15:49:17 +02:00
Luke Usher 03d864c465 emux86: update flash read function with a better explaination 2020-10-17 22:37:01 +01:00
Luke Usher 4665bd0c3f emux86: fix bad bios rom mapping
Prevents a crash in Shenmue II
2020-10-17 16:05:17 +01:00
Luke Usher 6a70a08c59
Merge pull request #1996 from CookiePLMonster/viewport-clear-improvements
SetViewport & Clear improvements
2020-10-17 16:04:51 +01:00
Silent 21092a5d38
Support multiple rects in Clear 2020-10-17 14:15:53 +02:00
Anthony Miles 4b85f0949a
Scale viewport X and Y as well as height.
Fixes cases where X and Y are nonzero e.g. DoA3 character select
2020-10-17 14:06:29 +02:00
Silent fa10dcfd29
Refactor SetMixBinVolumes
* Clears the code up
* Picks the buffer volume from the maximum speaker volume
2020-10-17 12:40:57 +02:00
RadWolfie d9ec4342d7
Merge pull request #1995 from CookiePLMonster/dsound-improvements-split
Dsound improvements (split)
2020-10-17 05:37:41 -05:00
Silent 6d2e598c8c
IDirectSoundBuffer_SetBufferData: Fix 0 byte buffers not stoppping audio
NASCAR Heat 2002 (and probably plenty of other titles) submit
an empty buffer to stop audio. Handling this properly fixes
issues with audio samples lingering throughout the session.
2020-10-17 12:33:44 +02:00
Silent 3dcf1e67e0
Fix a copypaste typo in GetFormat_4034_lower and change its signature
Allows GetFormat() to be used more cleanly
2020-10-17 12:31:26 +02:00
Luke Usher 8d8ebd76f7
Merge pull request #1994 from CookiePLMonster/resource-cache-fixup
Treat identical X_D3DResource objects with a different address as one
2020-10-17 11:31:23 +01:00
Silent 0f7ce3b527
Treat identical X_D3DResource objects with a different address as one
This fixes issues where resource objects got relocated in memory or
reused without having been released properly first.

Fixes black cars in NASCAR Heat 2002
2020-10-17 12:24:49 +02:00
Luke Usher 8ae094d730
Merge pull request #1986 from x1nixmzeng/debugger-multi-xbe
Update cxbx-debugger to support switching XBEs during emulation
2020-10-15 08:08:49 +01:00
RadWolfie 7a59d775f9
Merge pull request #1992 from medievil1/Typo-fix-for-IDirectSoundBuffer_SetMinDistance
Typo fix for IDirectSoundBuffer_SetMinDistance patch
2020-10-15 02:03:03 -05:00
medievil1 a7a69f5108 Update DirectSound.hpp 2020-10-15 02:26:10 -04:00
Luke Usher 28d031d9f9
Merge pull request #1990 from ergo720/rdtsc_25_to_life
Avoid false rdtsc negative in 25 to life
2020-10-14 22:33:59 +01:00
ergo720 b34165d63b Avoid false rdtsc negative in 25 to life 2020-10-14 23:17:24 +02:00
Luke Usher 8a87fd8376
Merge pull request #1978 from CookiePLMonster/msaa-improvements
MSAA improvements basing on xdk-3911 behaviour
2020-10-14 21:49:47 +01:00
Luke Usher 9b5fe396ca
Merge pull request #1989 from ergo720/rdtsc_odd_world_stanger_wrath
Fix crash in Stranger's Wrath caused by false rdtsc positives
2020-10-14 20:51:43 +01:00
ergo720 621960258d Fix crash in Stranger's Wrath caused by false rdtsc positives 2020-10-14 21:34:24 +02:00
Luke Usher efe42f4eba
Merge pull request #1985 from CookiePLMonster/fix-rdtsc-overflow
Make RDTSC and ACPI timers stateful to fix overflows
2020-10-13 19:16:29 +01:00
x1nixmzeng df1ead013a Adjust default window size as per feedback 2020-10-12 19:48:21 +01:00
Silent f42009a27e
Implement MSAA scaling to be closer to Xbox
Now scales clears, and applies scaling based on a bound render target.
X/Y scale masks now also match the xbox runtime (at least xdk-3911)
2020-10-12 20:25:14 +02:00
Silent 190ef8c3d5
Implement X_D3DRS_MULTISAMPLETYPE 2020-10-12 20:14:58 +02:00
Silent 0d1a8e3afd
Make RDTSC and ACPI timers stateful to fix overflows
Stateless RDTSC and ACPI timers were ticking relative
to the host QPC and multiplied to nanoseconds.
This resulted in values so huge they would overflow since
20-30 minutes.

Introducing state allows to multiply to nanoseconds only over
a delta value, which should be reasonably small in almost call cases.
2020-10-12 18:26:29 +02:00
Luke Usher 7767250624
Merge pull request #1987 from ergo720/mem_page_usage_fix
Memory manager fixes
2020-10-12 08:46:08 +01:00
Luke Usher 756ad91cbe
Merge pull request #1976 from CookiePLMonster/set-texture-ltcg
Add several D3D8LTCG function variations for xdk-3911
2020-10-12 08:41:01 +01:00
ergo720 dd5a029ee6 Restore correctly the pfn database during reboots when using the debug layout 2020-10-11 23:33:43 +02:00
x1nixmzeng 4c8c00fecd Various UI improvements after move to MDI 2020-10-11 22:19:49 +01:00
x1nixmzeng dce84c4b7e Fix crash unwinding callstack with addresses outside of IntPtr range 2020-10-11 22:11:18 +01:00
ergo720 cd918389a4 Restore correct page usage upon xbe reboot 2020-10-11 21:29:49 +02:00
ergo720 0a3dd68191 Use UnknownType page usage for the pfn pages 2020-10-11 19:38:08 +02:00
x1nixmzeng d7c6648162 Revive stack frame selection and other minor fixes 2020-10-11 18:28:19 +01:00
x1nixmzeng 0b31f3ad95 Suppress missing debugger exception 2020-10-11 17:37:58 +01:00
x1nixmzeng 3241ba8fef Fix exception ranges used by debugger 2020-10-11 17:36:52 +01:00
RadWolfie 216b5c274e
Merge pull request #1983 from CookiePLMonster/mixbin-improvements
Improvements to old style (mask based) mixbin
2020-10-11 09:27:58 -05:00
Silent 2d649c969f
Improve mixbin handling for Revision 1 mixbin
Added an union combining both a pointer to new mixbins
and a mixbin mask, and a function to convert to the new format.
This allows to initialize mixbins for Revision 1 XDKs too.

Implements IDirectSoundBuffer_SetMixBinVolumes_12 and
CDirectSoundStream_SetMixBinVolumes_12.
2020-10-11 15:43:38 +02:00
RadWolfie 24c4e3d0a7
Merge pull request #1970 from LukeUsher/optional-maintain-aspect-ratio
Allow users to disable aspect ratio correction
2020-10-11 07:07:59 -05:00
x1nixmzeng cf594cda97 Rename child MDI form 2020-10-11 12:25:58 +01:00
x1nixmzeng dced533dd8 Add new error code definition 2020-10-11 12:17:22 +01:00
x1nixmzeng e01b863fd2 Support for different debug sessions using MDI child forms 2020-10-11 12:16:22 +01:00
x1nixmzeng 96155736e5 Update debugger types and thread report handling 2020-10-11 12:14:42 +01:00
x1nixmzeng 3a740d7933 Report relaunching with another Xbe to the debugger 2020-10-11 12:13:03 +01:00
RadWolfie 1887f3ac29
Merge pull request #1984 from CookiePLMonster/fix-setbufferdata-deadlock
IDirectSoundBuffer_SetBufferData: Stop the sound before waiting for finish
2020-10-11 06:12:51 -05:00
Silent a4c4719a19
IDirectSoundBuffer_SetBufferData: Stop the sound before waiting for it to end 2020-10-11 12:20:44 +02:00
Silent ad6438f936
Fix issues related to volume getting/setting
Not adding headroom to volume in HybridDirectSoundBuffer_SetMixBinVolumes_8
caused the sound to be attenuated by the headroom value every time
it was updated.
2020-10-11 00:21:46 +02:00
Luke Usher a380927fba
Merge pull request #1981 from CookiePLMonster/fix-ivb-zeroing
Actually zero g_InlineVertexBuffer_Table[0]
2020-10-09 21:22:41 +01:00
Silent fd490e9929
Actually zero g_InlineVertexBuffer_Table[0]
Operator= invoked default constructors where available,
and a default constructor for D3DXVECTOR4 does nothing.
memset/memcpy zeroes and copies the entire structure for real.
2020-10-09 22:15:15 +02:00
Silent ec8c930ebc
Update XbSymbolDatabase submodule
Add a signature for D3DDevice_DrawIndexedVertices for xdk-3911 LTCG
2020-10-09 17:39:25 +02:00
Luke Usher 2c72faad81
Merge pull request #1977 from CookiePLMonster/new-rdtsc-pattern
Add a new rdtsc pattern based on NASCAR Heat 2002 logs
2020-10-08 22:03:02 +01:00
Luke Usher 4271a857cc settings: better if statements for settings versioning 2020-10-08 13:43:36 +01:00
Luke Usher a0ae63d030 settings: use if statements rather than switch/case 2020-10-08 09:20:54 +01:00
Silent 665dc37877
Implemented D3DDevice_SetVertexShader_0
LTCG version of D3DDevice_SetVertexShader which passes
Handle in EBX
2020-10-07 19:11:02 +02:00
Silent 13d79192c8
Implemented D3DDevice_DrawVerticesUP_12
LTCG version of D3DDevice_DrawVerticesUP which passes
pVertexStreamZeroData in EBX
2020-10-07 18:56:29 +02:00
Silent ad3c042df2
Add a new rdtsc pattern based on NASCAR Heat 2002 logs
New pattern detects the following:

rdtsc
mov address, eax
2020-10-06 21:30:58 +02:00
Silent 05bae29ec3
Add a proper D3DDevice_SetStreamSource for xdk-391 LTCG
The signature was correct, but it was redirecting to a wrong
version of SetStreamSource. The correct version passes the first
argument in EDX.
2020-10-06 21:04:06 +02:00
Silent 556a65f1dc
Fix wrong D3DDevice_SetVertexShaderConstant_8 implementation
The assumption that one of the parameters has to be taken from EDX
was correct, but the function was not implemented properly
2020-10-06 19:22:02 +02:00
Silent 3fdfa89812
Implement LTCG D3DDevice::SetTexture for xdk-3911
Test case: NASCAR Heat 2002
2020-10-06 19:22:02 +02:00
Silent 24fa7dc935
D3DDevice_SetTexture_4: Fix Xbox implementation call 2020-10-06 18:50:39 +02:00
ergo720 13bd79f930
Use fixed width types for xbox types + restructured kernel header files (#1969)
* VOID -> void_xt

* CHAR, CCHAR -> char_xt, cchar_xt

* UCHAR -> uchar_xt

* BYTE, BOOLEAN -> byte_xt, boolean_xt

* Fix bogus intellisense errors in the kernel headers

* SHORT, CSHORT, USHORT -> short_xt, cshort_xt, ushort_xt

* LONG -> long_xt

* WORD, DWORD -> word_xt, dword_xt

* HRESULT -> hresult_xt

* ULONG -> ulong_xt

* SIZE_T, ACCESS_MASK, PHYSICAL_ADDRESS -> size_xt, access_mask_xt, physical_address_xt

* UINT, INT -> uint_xt, int_xt

* LONG_PTR, ULONG_PTR, INT_PTR -> long_ptr_xt, ulong_ptr_xt, int_ptr_xt

* LONGLONG, ULONGLONG -> longlong_xt, ulonglong_xt

* WCHAR, QUAD, BOOL, FLOAT -> wchar_xt, quad_xt, bool_xt, float_xt

* Updated types in xonline.h + reverted some type changes + moved kernel header files in cxbxr source tree

* Use char16_t instead of wchar_t for wchar_xt xbox type

* Fixed macro redefinition warnings from ntstatus macros in types.h
  Fixed macro redefinition warnings from NT_SUCCESS and FIELD_OFFSET
  Fixed macro redefinition warnings from the REG_ macros used by the eeprom

* NTSTATUS -> ntstatus_xt
2020-10-06 05:33:16 -05:00
Luke Usher 8a1e4b1beb
Merge pull request #1974 from RadWolfie/symbolscan-fix
Fix Symbol Scan's Kernel Thunk Bug
2020-10-06 10:11:50 +01:00
Luke Usher f8e0b73e23
Merge pull request #1975 from CookiePLMonster/CC-005-rdtsc-false-positive
Add an rdtsc false positive check for Group S Challenge [CC-005] [1.05]
2020-10-06 10:11:06 +01:00
Silent 0a46366c22
Add an rdtsc false positive check for Group S Challenge [CC-005] [1.05] 2020-10-05 21:45:59 +02:00
RadWolfie 746a7e6450 hle: move MapThunkTable after EmuHLEIntercept plus fix hidden xbeType bug to use directly xbe type than system type. 2020-10-05 11:24:22 -05:00
RadWolfie 200c614d21 hle: fix a crash if move before MapThunkTable call 2020-10-05 11:24:22 -05:00
RadWolfie 31fd0600b6 hle: let EmuLog handler handle debug messages 2020-10-05 11:08:59 -05:00
Luke Usher a852c3ef9d
Merge pull request #1972 from CookiePLMonster/fix-thread-id
PsCreateSystemThreadEx: Fill dwThreadId immediately after creating the thread
2020-10-05 07:22:13 +01:00
Silent bd759e5858
PsCreateSystemThreadEx: Fill dwThreadId immediately after creating the thread 2020-10-04 23:47:10 +02:00
Luke Usher 550df54b77 indenting tweaks 2020-10-01 11:58:48 +01:00
Luke Usher da4e1a3aec indenting tweaks 2020-10-01 11:53:49 +01:00
Luke Usher 42dc0c0fc9 update settings version 2020-10-01 11:40:04 +01:00
Luke Usher ecc6669158 Allow users to disable aspect ratio correction
This replaces the unused 'Hardware YUV overlay' option in the video settings.
2020-10-01 08:57:57 +01:00
RadWolfie ea7007090c
Merge pull request #1968 from x1nixmzeng/fix-debugger-launch
Fix for starting with debugger
2020-09-25 19:23:05 -05:00
x1nixmzeng 6c56bcfcf3 Fix for missing embedded resources in designer 2020-09-25 23:49:12 +01:00
x1nixmzeng 2c16a3f1b6 Fixed the launch argument processing done by the debugger 2020-09-25 20:41:28 +01:00
Luke Usher 44f1e0937c
Merge pull request #1967 from RadWolfie/cleanup-includes
Remove unnecessary includes since they are handled from CMake end
2020-09-25 12:30:36 +01:00
RadWolfie 5af26d23f5 cmake: fix includes for libtommath and libtomcrypt 2020-09-25 05:20:27 -05:00
RadWolfie c48484c135 cmake: remove unnecessary includes since they are handled 2020-09-25 04:34:25 -05:00
Luke Usher e34c990ff4
Merge pull request #1966 from RadWolfie/move-to-submodule
Move xxHash to Submodule
2020-09-25 10:14:57 +01:00
RadWolfie 5aad40ce9d move xxHash to submodule 2020-09-25 03:38:29 -05:00
Luke Usher abe0c827d3
Merge pull request #1965 from RadWolfie/update-submodule
Update XbSymbolDatabase Submodule
2020-09-25 07:15:55 +01:00
RadWolfie eaeb521bd9 update XbSymbolDatabase submodule 2020-09-24 14:10:24 -05:00
RadWolfie abb50d6f99
Merge pull request #1964 from ergo720/mouse_input
Re-enable Mouse Support
2020-09-24 05:16:11 -05:00
ergo720 cc032120bf Renamed subclass procedure + moved option synchronization code 2020-09-24 11:42:23 +02:00
ergo720 cb2bd277cd Hide the mouse cursor when hovering on the rendering window 2020-09-23 12:02:00 +02:00
ergo720 fc888cac2d Addressed review remarks 2020-09-21 15:12:12 +02:00
ergo720 dd24225477 Ignore K/M input when the cursor is outside of the rendering window 2020-09-20 22:58:04 +02:00
ergo720 4c47d5a6d9 Store ClipCursor flag in EmuShared 2020-09-20 17:57:16 +02:00
ergo720 01382d7e1d Lock the mouse cursor to the rendering window when the user presses F3 key 2020-09-20 14:58:11 +02:00
ergo720 cd11b34415 Restored optional fields in the resource file for clang 2020-09-20 11:14:16 +02:00
ergo720 6ecd89cd27 Fixed a crash happening when the settings file doesn't exist 2020-09-20 00:59:20 +02:00
ergo720 6afcd6a3f3 Removed IsDetectable(), it's no longer necessary 2020-09-19 20:33:59 +02:00
ergo720 92b6a9800d Fix an issue with sdl input binding 2020-09-19 20:27:01 +02:00
ergo720 d091a0ee8f Make binding the mouse in the input gui a bit easier 2020-09-19 14:20:09 +02:00
ergo720 6e265244cf Allow mouse options to be changed at runtime 2020-09-19 12:37:55 +02:00
ergo720 1ea6c5485e Added mouse support to input gui 2020-09-17 15:16:45 +02:00
ergo720 fa6387a545
Merge pull request #1955 from RadWolfie/fix-dsound-namespace
Fix Xbox DSound Namespace
2020-09-08 13:40:58 +02:00
RadWolfie e3b1cffd3a dsound: remove todo comment 2020-09-08 04:53:29 -05:00
RadWolfie 0b32d66e37 dsound: move HybridDirectSoundBuffer_SetMixBins to original location 2020-09-08 04:53:29 -05:00
RadWolfie 4cd89d77b8 dsound: remove extra parameter from HybridDirectSoundBuffer_SetMixBins 2020-09-08 04:53:29 -05:00
RadWolfie e6f875b7a7 dsound: updated to use without depend on windows' dsound header file for xbox usage 2020-09-08 04:53:29 -05:00
RadWolfie e7be2435c2 xbox: add missing xbox types for dsound 2020-09-08 04:53:25 -05:00
Luke Usher 6111fc9fdb
Merge pull request #1957 from NZJenkins/res_scaling
CopyRects accounts for host resource scaling
2020-09-02 13:44:26 +01:00
Anthony Miles 5272b1de12 Reduce aliasing in CopyRects 2020-09-02 23:29:47 +12:00
Anthony Miles fc655cdca5 CopyRects accounts for host resource scaling
Fixes Crash Tag Team Racing resolution scaling issue
2020-09-02 23:05:23 +12:00
Luke Usher ee6a61c364
d3d: apply aspect ratio correction to the backbuffer (#1956)
* d3d: apply aspect ratio correction to the backbuffer

* d3d: optimise aspect ratio correction + allow run-time aspect change (eg: dashboard)

* d3d: fix typo

* d3d: fix borders on aspect ratio change + apply aspect ratio correction to FMV

* d3d: fix indenting in SetAspectRatioScale

* d3d: add comment to explain clear
2020-09-02 04:45:04 -05:00
ergo720 79391fc55a
Merge pull request #1952 from RadWolfie/update-readme
Miscellaneous Update to Readme
2020-08-28 23:08:19 +02:00
RadWolfie 2720c5b430 readme: fix grammars 2020-08-28 15:49:25 -05:00
RadWolfie a501e9a4a4 readme: update bug report section 2020-08-28 15:49:25 -05:00
RadWolfie eb90237285
Merge pull request #1944 from LukeUsher/better-eeprom-defaults
eeprom: cleanup eeprom generation + generate hdd key
2020-08-27 16:21:26 -05:00
Luke Usher 96e2b593a6 eeprom: cleanup eeprom generation + generate hdd key
# Conflicts:
#	src/common/EmuEEPROM.cpp
2020-08-27 10:08:00 +01:00
RadWolfie e1f587a629 readme: update to focus only on push events than include pull requests 2020-08-25 02:12:22 -05:00
ergo720 b304e538c6
Introduce xbox namespace + deduplicate xbox types (#1942)
* Introduced new xbox namespace + moved inside it xbox pointer/address types

* Replaced xboxkrnl namespace with xbox namespace

* Moved kernel types from xboxkrnl.h to xbox_types.h

* Replaced XTL namespace with xbox namespace

* Fix a conflict with the VOID macro imported by Windows.h

* Fixed misalignment issues + renamed xtl_prefix
2020-08-24 13:29:48 -05:00
Luke Usher 8919d9981c
Merge pull request #1948 from RadWolfie/fix-dsound-str-patches
HOTFIX: Fix dsound string patches typos
2020-08-23 19:46:36 +01:00
RadWolfie f9084d9b2e hotfix: fix dsound string patches typos 2020-08-23 12:55:49 -05:00
ergo720 615b702cde
Merge pull request #1947 from RadWolfie/fix-pr-1945-normalize
HOTFIX: PR 1945 Normalize
2020-08-23 19:11:49 +02:00
RadWolfie b10d242b80 fix pr 1945 normalize 2020-08-23 11:52:04 -05:00
Luke Usher ffe3b95323
Merge pull request #1946 from RadWolfie/line-ending-renormalize
Setup Force Source Files to LF Line Ending and Renormalize
2020-08-23 14:58:19 +01:00
Luke Usher 967f53ad6f
Merge pull request #1945 from LukeUsher/d3d-dont-create-invalid-buffers
d3d: don't attempt to create 0 sized vertex buffers
2020-08-23 14:49:39 +01:00
RadWolfie 3550fa4ed1 setup force source files to lf line ending and renormalize 2020-08-22 20:17:07 -05:00
Luke Usher d961d4e7e7 d3d: don't attempt to create 0 sized vertex buffers 2020-08-21 20:13:23 +01:00
PatrickvL cdb3b13756
Merge pull request #1943 from LukeUsher/fix-iocreatefile
krnl: IoCreateFile should return INVALID_HANDLE_VALUE on failure
2020-08-21 16:54:39 +02:00
Luke Usher dd36bce933 krnl: IoCreateFile should return INVALID_HANDLE_VALUE on failure 2020-08-21 15:05:01 +01:00
Luke Usher 7bfd8bed46
Merge pull request #1941 from RadWolfie/use-steady-clock
Fix couple chrono usage due to variety of systems may behave differently
2020-08-21 14:49:10 +01:00
Luke Usher 4c384ef322
Merge pull request #1940 from RadWolfie/cmake-note
CMake: add note reason of cannot direct include nv2a source files in compilers
2020-08-21 14:48:30 +01:00
RadWolfie 8861b845d7 chrono: replace duration_cast to duration 2020-08-20 15:51:12 -05:00
RadWolfie e0f6d75cd0 chrono: use steady_clock than high_resolution_clock 2020-08-20 14:50:02 -05:00
RadWolfie 35227da440 cmake: add note reason of cannot direct include nv2a source files in compilers 2020-08-19 18:41:03 -05:00
Luke Usher 4b735c58cc
Merge pull request #1938 from ergo720/xbox_types
Use xboxkrnl namespace inside xboxkrnl header file
2020-08-18 16:50:33 +01:00
ergo720 f46bcd6875 Use xboxkrnl namespace inside xboxkrnl header file 2020-08-18 17:02:19 +02:00
Luke Usher 2695d91496
Merge pull request #1913 from RadWolfie/improve-compiler-support
Improve SEH/VEH support for compilers
2020-08-18 14:55:08 +01:00
RadWolfie d51743a132
Merge pull request #1934 from LukeUsher/avoid-debug-overflow
kernel: avoid potential buffer overflow on DbgPrint
2020-08-17 12:12:10 -05:00
Luke Usher b0ebc8b332 kernel: avoid potential buffer overflow on DbgPrint 2020-08-17 17:21:10 +01:00
RadWolfie fb4b988eb7
Merge pull request #1935 from LukeUsher/hle-disable-raise-exception
hle: Disable RaiseException patch, let the kernel handle it.
2020-08-16 17:31:04 -05:00
Luke Usher de92e5048b hle: Disable RaiseException patch, let the kernel handle it. 2020-08-15 20:43:16 +01:00
Luke Usher 71dc7e988e
Merge pull request #1932 from RadWolfie/migrate-customs-in-one-batch
Migrate Customs in One Batch
2020-08-15 20:38:09 +01:00
RadWolfie f911980a37 move glew32.dll copy to batch script 2020-07-30 15:57:22 -05:00
RadWolfie d184035103 fix git versioning whenever git is updated 2020-07-30 15:13:58 -05:00
Luke Usher 4d06712489
Merge pull request #1929 from RadWolfie/dsound-debug-outputs
Add Argument Results Verbose
2020-07-18 10:12:06 +01:00
PatrickvL d95249cab2
Merge pull request #1928 from ergo720/autoclose_action_invalid
Update issue template + add action to automatically close issues not following the template
2020-06-30 09:48:15 +02:00
ergo720 250b2f5157 Removed edited as action triggering event 2020-06-29 22:57:48 +02:00
RadWolfie e1c53ac304 add verbose arg output for DSound's main class 2020-06-29 14:26:29 -05:00
RadWolfie c06817d8fa add verbose arg output for DSound's stream class 2020-06-29 14:26:24 -05:00
RadWolfie a6a95072a9 add verbose arg output for DSound's buffer class 2020-06-29 14:26:20 -05:00
RadWolfie 54005aad18 extend logging support for verbose args result 2020-06-29 14:26:09 -05:00
ergo720 8eb5384ad9 Add GH action to automatically close issues not following the template 2020-06-28 10:32:07 +02:00
RadWolfie d5af8461be
Merge pull request #1925 from ergo720/sha_popup
Show a popup when xbe sections are corrupted + print section corruption status on xbe dumps as well
2020-06-23 18:38:17 -05:00
ergo720 9a5aa06e7f Removed unnecessary boolean variable 2020-06-23 23:20:22 +02:00
ergo720 9e90a2df50 Show a popup when xbe sections are corrupted 2020-06-23 22:24:52 +02:00
PatrickvL ed57ca9788
Merge pull request #1921 from RadWolfie/improve-popup-handler
Improve Popup Handler
2020-06-20 15:37:39 +02:00
RadWolfie 0d38f6cfad add Enable wording in GUI test case popup checkbox 2020-06-20 05:10:59 -05:00
RadWolfie 6de2d464c4 fix disabled code to sync with new change. 2020-06-20 04:44:50 -05:00
RadWolfie 222f266cd1 fix fixed buffer size to dynamic size compatible 2020-06-20 04:44:50 -05:00
RadWolfie e2d1b4de30 add comment to LOG_TEST_CASE macro 2020-06-20 04:44:50 -05:00
RadWolfie 997f4bd928 replace unnecessary logOnly check to continue 2020-06-20 04:44:50 -05:00
RadWolfie 4da39275b4 rename CxbxMessageBox to PopupPlatformHandler 2020-06-20 04:44:50 -05:00
RadWolfie 2c73d8b736 use assert since we expect format string not to be null pointer 2020-06-20 04:44:50 -05:00
RadWolfie 4043ac1b01 rewording APIs for review remarks 2020-06-20 03:40:54 -05:00
PatrickvL cf87eaef06
Merge pull request #1923 from ergo720/xinput_dll
Load the most appropriate xinput dll based on the Windows version
2020-06-19 09:15:02 +02:00
ergo720 91241dbd08 Addressed PR review remarks 2020-06-18 18:32:11 +02:00
ergo720 bbe3cc1f47 Load the most appropriate xinput dll based on the Windows version 2020-06-18 14:59:46 +02:00
PatrickvL 66bccac3cf
Merge pull request #1922 from RadWolfie/update-create-release-action
Update Create Release Action v1.1.1
2020-06-18 13:34:07 +02:00
RadWolfie f503902267 update create release action 2020-06-18 05:26:07 -05:00
RadWolfie 7f4da40f21 make use of const in parameters 2020-06-13 17:55:12 -05:00
RadWolfie 93962a9de4 fix typos 2020-06-13 17:55:12 -05:00
RadWolfie d881695cf4 update LOG_TEST_CASE to always have test case output to log 2020-06-13 17:27:00 -05:00
RadWolfie 9f593237fe add voids whenever not using return values 2020-06-13 16:41:48 -05:00
RadWolfie 5bc4eee10b transfer GUI popups to CxbxPopupMsg variant 2020-06-11 12:54:31 -05:00
RadWolfie ce3626eb9d replace CxbxShowError to CxbxPopupMsg prefix to include in log record 2020-06-11 12:54:31 -05:00
RadWolfie 458b332e8e always log popup message to log even when set to hidden 2020-06-11 12:38:28 -05:00
RadWolfie 77d469ddb5 suppress popups while in exclusive fullscreen mode 2020-06-11 12:38:28 -05:00
RadWolfie c0f2d60a3f fix compiler warning to use enum class instead of enum 2020-06-11 12:38:28 -05:00
RadWolfie dbae5dbb79 move popup message to logging file 2020-06-11 12:38:28 -05:00
RadWolfie 9bee8ea17b add testcase popup option 2020-06-11 12:38:27 -05:00
Luke Usher f1d09aff15
Merge pull request #1917 from Fisherman166/HalReadSMCTrayState
Rewrite HalReadSMCTrayState to match original kernel implementation.
2020-06-08 15:22:32 +01:00
RadWolfie b8d87ecdc3 add note 2020-06-07 23:27:08 -05:00
RadWolfie 3e7ac34987 pcap delay load module require SEH 2020-06-07 23:27:08 -05:00
RadWolfie a216c3d90e rename bOverrideException to bOverrideEmuException 2020-06-07 23:27:08 -05:00
RadWolfie b5358508d6 update Windows' SEH, fix overflow exception, and non-Windows platform support 2020-06-07 23:27:08 -05:00
RadWolfie 64f69f78ae add exception manager 2020-06-07 22:38:01 -05:00
PatrickvL d3544f7b5f
Merge pull request #1918 from Fisherman166/FsSetCacheSize
Update FscSetCacheSize to match original kernel
2020-06-07 18:51:45 +02:00
Fisherman166 a981607e51 Add g_ prefix to FscCacheEvent. 2020-06-07 09:40:55 -07:00
PatrickvL 0afcf04c06
Merge pull request #1915 from Fisherman166/KeReleaseSemaphore
Implement KeReleaseSemaphore
2020-06-07 08:10:40 +02:00
PatrickvL ca0b978cf9
Merge pull request #1916 from RadWolfie/dsound-misc-fixes
Couple DirectSound Fixes
2020-06-07 08:04:45 +02:00
RadWolfie e166b97cd7 check for 3D audio to use mono channel by default instead of stereo 2020-06-07 00:45:05 -05:00
Fisherman166 326f645b8f Initialize FscCacheEvent at emulation start to match the real kernel implementation. 2020-06-06 16:09:01 -07:00
Fisherman166 6d8d692b7c Implement FscSetCacheSize matching original kernel implementation. 2020-06-06 13:34:40 -07:00
Fisherman166 857b8f933e Rewrite HalReadSMCTrayState to match original kernel implementation. Keeps the TRAY_OPEN hack for the time being. 2020-06-06 13:27:54 -07:00
RadWolfie 503ce9b825 fix applications using IDirectSoundBuffer_Lock incorrectly 2020-06-05 20:23:52 -05:00
Fisherman166 db1429a4b9 Implement KeReleaseSemaphore based on kernel reverse engineering. Needs KiWaitTest to be implemented to be fully functional. 2020-06-04 21:26:01 -07:00
PatrickvL ab6b4786bd
Merge pull request #1914 from NZJenkins/reserved_constants_flag
Treat X_D3DSCM_NORESERVEDCONSTANTS as a flag
2020-06-02 14:27:02 +02:00
Anthony Miles 201ab08043 Treat X_D3DSCM_NORESERVEDCONSTANTS as a flag 2020-06-03 00:10:34 +12:00
Luke Usher e5af2b1754
Merge pull request #1911 from Fisherman166/ReadWriteLock
Implement ExReadWriteLock Kernel functions
2020-05-29 11:18:20 +01:00
Fisherman166 52f18bca28 Add size offsets for the KSEMAPHORE and ERWLOCK structs. 2020-05-28 09:13:19 -07:00
Fisherman166 49e68a1ecc Refactor ExReleaseReadWriteLock. 2020-05-28 09:10:51 -07:00
Fisherman166 b72be80b88 Refactor ExAcquireReadWriteLockShared to remove duplicate code. 2020-05-26 09:20:15 -07:00
Fisherman166 a679073ec6 Implement ExReleaseReadWriteLock. 2020-05-25 16:20:02 -07:00
Fisherman166 6f5a1f2c46 Implement ExAcquireReadWriteLockShared. 2020-05-25 16:20:01 -07:00
Fisherman166 f375bbf6ba Add offset comments to _ERWLOCK and _KSEMAPHORE structs. 2020-05-25 16:20:01 -07:00
Fisherman166 a2e623180a Implement ExAcquireReadWriteLockExclusive. 2020-05-25 16:20:01 -07:00
PatrickvL d1580cd19d
Merge pull request #1901 from RadWolfie/wwe-raw-2-fixup
Partial Implement of Xbox DSound's Class Structure
2020-05-18 11:10:22 +02:00
RadWolfie ba8adc04f4 add todo comment 2020-05-15 04:01:06 -05:00
RadWolfie 772e6ed18e add PatrickvL comments 2020-05-14 19:12:37 -05:00
RadWolfie 9871b25fa8 move audio converter helper 2020-05-14 19:09:19 -05:00
RadWolfie 95e8642970 fix placeholder reference counter 2020-05-14 18:46:16 -05:00
RadWolfie 97abbd0a7c replace virtual functions to VMT comments 2020-05-14 18:43:44 -05:00
RadWolfie ada86a42b5 create gc for EmuDirectSoundBuffer destructor 2020-05-14 18:38:05 -05:00
RadWolfie fad467196a add test case comment 2020-05-14 17:13:37 -05:00
RadWolfie 0c5117dc06 reword union data for better readability 2020-05-14 17:13:37 -05:00
RadWolfie 06af046c13 also another fixup for pitch type 2020-05-14 17:13:37 -05:00
RadWolfie ce0e35b052 oops, volume is signed integer 2020-05-14 17:13:37 -05:00
RadWolfie 8b780f2d5c remove Xb_Volume member from host's structure 2020-05-14 17:13:37 -05:00
RadWolfie ee4856a06d add comments 2020-05-14 17:13:37 -05:00
RadWolfie 72401c44d4 use typedef function pointers for better readability and remove redundant 2020-05-14 17:13:37 -05:00
RadWolfie e91d1bf23c finally clean up redundant codes 2020-05-14 17:13:37 -05:00
RadWolfie 04dce78f53 forward xbox audio format to internal voice class 2020-05-14 17:13:37 -05:00
RadWolfie 18a22cd934 fix spacing 2020-05-14 17:13:37 -05:00
RadWolfie ab142abd69 forward headroom setter to voice 2020-05-14 17:13:37 -05:00
RadWolfie d7d1d781d8 implement hybrid buffer for partial internal exposure 2020-05-14 17:13:36 -05:00
RadWolfie dab7a608c2 oops 2020-05-14 17:13:36 -05:00
PatrickvL 935fab7b9c
Merge pull request #1906 from RadWolfie/add-setting-asserts
Add Settings Structure Assert Checks
2020-05-14 17:52:48 +02:00
RadWolfie 9f8e617890 fix allowAdminPrivilege not align with other boolean members 2020-05-14 05:02:11 -05:00
RadWolfie b281861e49 forgot to update history for loader project 2020-05-14 05:02:11 -05:00
RadWolfie bd93e2288d enforce verify shared memory structures are align properly 2020-05-14 05:02:11 -05:00
PatrickvL 34f8d30219
Merge pull request #1905 from RadWolfie/separate-admin-priv-vs-invalid-sig
Separate Invalid Xbe Signature popup from Admin Privilege Config Bypass
2020-05-14 09:58:31 +02:00
RadWolfie fcdab48d00 separate invalid xbe sig popup from admin priv config 2020-05-13 16:29:02 -05:00
PatrickvL ba980d249d
Merge pull request #1904 from RadWolfie/mute-config-reword
Invert GUI's audio mute config
2020-05-13 22:51:13 +02:00
RadWolfie d756012ea3 invert GUI's mute config 2020-05-13 15:05:28 -05:00
RadWolfie 0f853f3665
Merge pull request #1892 from LukeUsher/multisampling-experiment
Implement support for Xbox MSAA, reducing 'jaggies'
2020-05-08 06:14:49 -05:00
patrickvl 6d9dfb2dde Change zero input into a comment instead of LOG_TEST_CASE everyone into madness 2020-05-08 12:13:55 +02:00
patrickvl ba2d18d17f Prevent invalid g_Xbox_MultiSampleType values using a setter
This avoids zero-dectection later on
Some tooling functions to top it off.
2020-05-08 12:05:29 +02:00
Luke Usher fec845f6f8 Cleaner fix to the above 2020-05-08 10:00:46 +01:00
Luke Usher 85c0f608e2 Another minor fix 2020-05-08 09:52:54 +01:00
Luke Usher 23104c8280 Fix an issue where rendering broke when MultiSampleType = 0 2020-05-08 09:40:20 +01:00
Luke Usher e499d3ad07 fix an issue where offset was not used 2020-05-08 09:28:20 +01:00
Luke Usher b0bcc2fd9b Add LOG_TEST_CASE as per request 2020-05-08 09:04:58 +01:00
Luke Usher 543756d712 Amendments 2020-05-08 08:49:13 +01:00
Luke Usher 97012d649f
Merge pull request #1891 from Serentty/patch-2
One more Wine-related edit
2020-05-07 22:56:27 +01:00
Luke Usher 86bb8cad97 Implement support for Xbox MSAA, reducing 'jaggies'
Also fixes offset models in GTA3 and potentially others
2020-05-07 22:51:30 +01:00
Serentty 82c61be866
One more Wine-related edit
Somehow I missed the very first line of the readme, which also makes it sound Windows-exclusive, in my last PR. Sorry for the spam.
2020-05-07 16:52:51 -04:00
PatrickvL 8667d22196
Merge pull request #1890 from Serentty/patch-1
Mention Wine support more prominently in the readme
2020-05-07 22:44:43 +02:00
PatrickvL 555f240319
Merge pull request #1888 from LukeUsher/cleanup-createdevice
Cleanup EmuCreateDeviceProxy & Clarify 'Automatic' option
2020-05-07 22:42:57 +02:00
Serentty 2ab2965f3a
Mention Wine support more prominently in the readme
Right now the first mention of Wine is down next to the download link, and no mention is made of it under the system requirements. Given that compatibility with Wine has been a goal for this project in the past (in terms of bugfixes that fixed issues that only emerged when using it), I thought it would be a good idea to show that this use case is indeed considered by the developers. As a Linux user myself, this kind of thing would be more likely to consider using Cxbx after glancing at the repository.
2020-05-07 16:40:21 -04:00
PatrickvL f3d7ae61c2
Merge pull request #1889 from LukeUsher/fix-rendertarget-test-case
Fix an issue where with CreateDevice LOG_TEST_CASE
2020-05-07 22:32:16 +02:00
Luke Usher e17d872356 Fix an issue where the 'Xbox CreateDevice did not call SetRenderTarget' test case would be incorrectly flagged if no depth stencil was provided 2020-05-07 20:51:45 +01:00
Luke Usher db640d5b6f
Merge pull request #1881 from NZJenkins/improve_slots
Improve shader slot emulation
2020-05-07 14:03:35 +01:00
Luke Usher a32b10aa79 oops: fix typo 2020-05-07 13:54:47 +01:00
Luke Usher f98023bbb8 Cleanup EmuCreateDeviceProxy & Clarify 'Automatic' option 2020-05-07 13:45:39 +01:00
PatrickvL 5a1b8b55e5
Merge pull request #1887 from LukeUsher/fix-compilation-newer-vs
fix compilation on new installs of vs2019
2020-05-07 14:06:13 +02:00
Luke Usher 0aa92e826a fix compilation on new installs of vs2019 2020-05-07 12:40:01 +01:00
Anthony Miles ada56843ad Check for shader handles without shader functions 2020-05-04 22:22:13 +12:00
Anthony Miles 7370a29367 Tidy shader creation and handle property assignment 2020-05-04 21:42:59 +12:00
Anthony Miles 176dc9a38c Ensure shader has been created before setting it in SetVertexShader 2020-05-04 20:49:03 +12:00
patrickvl 79102c6ef8 Don't free what hasn't been allocated.
Don't activate declaration when a shader is merely created
Use X_VSH_MAX_ATTRIBUTES instead of 16
Rename SetCxbxVertexShader into RegisterCxbxVertexShader
2020-05-04 10:18:00 +02:00
patrickvl 9ab91550ae Rename SetCxbxVertexShaderHandleDeclaration into SetCxbxVertexDeclaration and give it just the Declaration.
Also fixed a compiler warning
2020-05-04 10:05:41 +02:00
Anthony Miles 1087b3e645 - Reset shader when shader slots are overwritten
- Keep track of the shader slot address
2020-05-04 18:55:51 +12:00
patrickvl e60d11959c Add a reminder to g_VertexShaderSource 2020-05-01 10:12:40 +02:00
patrickvl 7d53eaae73 Disabled patches on D3DDevice_GetVertexShaderDeclaration and D3DDevice_GetVertexShaderFunction (all they do is read data from their input arguments, which we don't alter anymore, so these two getters can just as well be left unpatched) 2020-04-30 15:44:24 +02:00
patrickvl 6a8534a22e Move D3DDevice_LoadVertexShaderProgram implementation to XbVertexShader.cpp 2020-04-30 15:34:22 +02:00
patrickvl 00e85b8af8 Move D3DDevice_CreateVertexShader implementation to XbVertexShader.cpp 2020-04-30 15:27:30 +02:00
patrickvl 932398547e Move SetCxbxVertexShader to XbVertexShader.cpp 2020-04-30 15:13:39 +02:00
patrickvl ab6bb98758 Move D3DDevice_DeleteVertexShader implementation to XbVertexShader.cpp 2020-04-30 14:53:10 +02:00
patrickvl 311e1037a6 Move D3DDevice_SelectVertexShader implementation to XbVertexShader.cpp 2020-04-30 14:49:10 +02:00
patrickvl ddc5d14c52 Move g_VertexShaderSource macro towards VertexShaderSource.cpp (in preparation for the next commit, that's going to use it) 2020-04-30 14:48:04 +02:00
patrickvl e94be42c40 Fix compile warning on not-supported LOG_TEST_CASE macro argument
Fix compile warning on implicit type cast
2020-04-30 14:39:02 +02:00
patrickvl 7bab062ff5 Move D3DDevice_SetVertexShaderConstant implementation to XbVertexShader.cpp 2020-04-30 14:36:59 +02:00
patrickvl 5a222185a3 Move D3DDevice_SetVertexShader implementation to XbVertexShader.cpp 2020-04-30 14:28:32 +02:00
patrickvl ea5f494a8e Move DEBUG_D3DRESULT macro towards XbD3D8Logging.h (in preparation for the next commit, that's going to use it) 2020-04-30 14:27:17 +02:00
patrickvl cc7e1a4069 Fix compile warning on not-supported LOG_TEST_CASE macro arguments 2020-04-30 14:21:13 +02:00
patrickvl 3db98e4e90 Move implementation of D3DDevice_LoadVertexShader towards XbVertexShader.cpp 2020-04-30 13:58:27 +02:00
patrickvl 848f4eeee3 Hide vertex slots behind GetCxbxVertexShaderSlotPtr (which also logs out of range test cases) 2020-04-29 19:08:15 +02:00
patrickvl c1b58dafb9 Remove everything related to no-longer-set HostFVF variable 2020-04-29 15:14:27 +02:00
Luke Usher f296636643
Merge pull request #1879 from Margen67/actions
ci: Update release if condition
2020-04-27 08:07:04 +01:00
Margen67 47b53211f9 ci: Update release if condition 2020-04-27 00:04:50 -07:00
Anthony Miles a2b5d2c466 Improve shader slot emulation 2020-04-27 11:18:16 +12:00
Anthony Miles eaa095e8a2 - Rename VertexShaderInfo to VertexDeclaration
- Move declaration related fields to CxbxVertexShader.Declaration
2020-04-26 22:01:22 +12:00
PatrickvL 57a8dc6f3b
Merge pull request #1877 from Margen67/typofix
setup.bat: Fix typos, add -j to build
2020-04-25 21:40:36 +02:00
Margen67 1a2df9cd13
setup.bat: Fix typos, add -j to build 2020-04-20 11:16:52 -07:00
PatrickvL e6b2ed88af
Merge pull request #1872 from Cxbx-Reloaded/cmake_loader_reloaded
Near absolute memory control
2020-04-20 09:50:50 +02:00
RadWolfie c27da955ab replace placeholder to working emulate_system variable set 2020-04-17 14:54:01 +02:00
PatrickvL 10b7d06be8
Merge pull request #1871 from RadWolfie/enable-loader-ui
LOADER: Enable Loader's UI and Set to Default
2020-04-15 09:02:26 +02:00
RadWolfie a554f1cbba enable Loader's UI toggleable and set enable by default 2020-04-14 20:27:16 -05:00
ergo720 653252d1f3 Create two independent file mappings for a chihiro system 2020-04-14 20:24:19 -05:00
RadWolfie 0623d4f485 add SEGABOOT_EP_XOR and update GetXbeType to use named value 2020-04-14 20:24:19 -05:00
RadWolfie d2f104f251 change KB/MB to KiB/MiB 2020-04-14 20:24:19 -05:00
RadWolfie 1a1019b85c replace hardcode 384 to blocks_reserved_t plus add comments 2020-04-14 20:24:19 -05:00
RadWolfie 897bc182f8 use enum class for XbeType to resolve warnings 2020-04-14 20:24:19 -05:00
RadWolfie 55f84cd67e move functions into their own locations 2020-04-14 20:24:19 -05:00
RadWolfie 35319dc724 convert defines to inline constexpr 2020-04-14 20:24:19 -05:00
RadWolfie 57905bab69 replace hardcode addresses to defined values 2020-04-14 20:24:19 -05:00
RadWolfie 32001136ae replace hardcode addresses to macro for AddressRanges files 2020-04-14 20:24:18 -05:00
RadWolfie 2ead1e0fe0 move address ranges into AddressRanges header file 2020-04-14 20:24:18 -05:00
RadWolfie 7bfd1c795b move GetLastErrorString and FreeLastErrorString to loader source file 2020-04-14 20:24:18 -05:00
RadWolfie 04840af6d3 remove old todo comment 2020-04-14 20:24:18 -05:00
RadWolfie 9e1077fe9f declare ARRAY_SIZE once and use C++11 feature 2020-04-14 20:24:18 -05:00
RadWolfie af3858c0d8 add todo comments 2020-04-14 20:24:18 -05:00
RadWolfie fbe4987569 add verbose debug; won't work with loader project 2020-04-14 20:24:18 -05:00
RadWolfie fb7398d7c9 Get maximum reserve memory ranges from host.
Plus more fixup to manage reliable memory design on loader launch and emulator.
2020-04-14 20:24:18 -05:00
RadWolfie 37b230fbfe scrap win32 draft gui 2020-04-14 20:24:18 -05:00
RadWolfie 8a33562dc8 fix standalone persisted memory support 2020-04-14 20:24:18 -05:00
RadWolfie b20a970b1d fix shared memory reboot loss 2020-04-14 20:24:18 -05:00
RadWolfie 7fca148bc6 implement toggle loader project in GUI 2020-04-14 20:24:18 -05:00
RadWolfie 380d93c03e yet another re-fix... 2020-04-14 20:24:18 -05:00
RadWolfie 0f38209e4b use std map pairs instead of string for cli usage
Plus enable individual memory shared settings and lock data file path hash whenever in used.
2020-04-14 20:24:18 -05:00
ergo720 11c046e0aa Suppress warning 4200 (alternative method) 2020-04-14 20:24:18 -05:00
ergo720 446b7efc29 Fix memory manager crashing upon second reboot 2020-04-14 20:24:18 -05:00
ergo720 f1255cb89b Allow the memory manager to work again with the non-loader approach 2020-04-14 20:24:18 -05:00
PatrickvL 79a3a8d9a6 Extracted functions for MapPersistedMemory and UnmapPersistedMemory 2020-04-14 20:24:18 -05:00
RadWolfie 1485d9c82b Add note about memory range option at launch should not occur at all. 2020-04-14 20:24:18 -05:00
RadWolfie 95d2406937 fix compile build to able call CxbxKrnlMain in cxbx.exe
Plus some fixes to able launch from cxbx.exe's emulation to verify the work is good or not.
2020-04-14 20:24:18 -05:00
ergo720 52f0d6f03b Updated memory functions to work with the loader 2020-04-14 20:24:18 -05:00
patrickvl a8e8f0c071 Loader : Update build script to include new binaries in artifact 2020-04-14 20:24:17 -05:00
PatrickvL c4f9821c6a Loader : Fix typos and avoid Microsoft compiler specific types 2020-04-14 20:24:17 -05:00
PatrickvL affc999d70 Loader : Use CxbxMessageBox (a wrapper for Windows' MessageBox API) wherever possible, to avoid repeating the TEXT("Cxbx-Reloaded") caption everywhere, and a different argument-order allowing default argument values and thus more compact code. 2020-04-14 20:24:17 -05:00
patrickvl f283dff3b6 Loader : Deduplicate code via new CreateSettings() 2020-04-14 20:24:17 -05:00
PatrickvL 254e666bfe Loader : Shared implementation for termining guiProcessID (and "2nd GUI" mode?!) 2020-04-14 20:24:17 -05:00
patrickvl 170b971a8e Loader : Deduplicate code via new CreateSettings() 2020-04-14 20:24:17 -05:00
patrickvl 890a5ffd2f Loader : Merge LaunchEmulation() into CxbxKrnlMain() 2020-04-14 20:24:17 -05:00
patrickvl 37f5a751a1 Loader : Moved HandleFirstLaunch() and LaunchEmulation() towards shared source file (CxbxKrnl.cpp), and call it from our DLL's Emulate() function. 2020-04-14 20:24:17 -05:00
PatrickvL daffa99825 Refactorings preparing actual emulation start for DLL (just need to move two functions to a shared file) 2020-04-14 20:24:17 -05:00
PatrickvL cd62ac9cc1 Shared implementation of VerifyBaseAddr() 2020-04-14 20:24:17 -05:00
PatrickvL 3be54d4569 Rely on CxbxKrnl.h for CXBX_BASE_ADDR (avoiding a duplicate declaration) 2020-04-14 20:24:17 -05:00
PatrickvL c537539c6e Extracted VerifyWow64() function, so that the Cxbx and CxbxLoader projects share the same implementation.
For this, renamed LoaderTooling.cpp to AddressRanges.cpp, which better aligns with AddressRanges.h anyway.
2020-04-14 20:24:17 -05:00
PatrickvL bf115fe7ab Complete Emulation DLL project by adding all Cxbx source files (except GUI-related stuff). Entire solution builds again with this.
Next steps :
- Actually getting the emulation DLL to work
- Complete CxbxGUI project by adding all Cxbx GUI-related source files
2020-04-14 20:24:17 -05:00
PatrickvL c42aff2307 Loader : Collect actually reserved ranges during range-verification (in the emulation DLL, not during reservation in the loader) 2020-04-14 20:24:17 -05:00
patrickvl 39a9bd451f Log initialization failure in the loader 2020-04-14 20:24:17 -05:00
patrickvl 747ec875aa Use EXIT_SUCCESS for forced termination, EXIT_FAILURE for all other exit-reasons. 2020-04-14 20:24:17 -05:00
patrickvl 41c2de8e5d Pass along the selected system configuration flag to the emulation DLL and use it to verify the address ranges.
Note, that even though verification passes, a few blocks in optional ranges do fail. It's probably wise to build up a list of those, so that the memory managers can keep this into account.
2020-04-14 20:24:17 -05:00
PatrickvL 93c8514700 Loader : Initial drop of a separate *empty* GUI project (probably won't compile either) 2020-04-14 20:24:17 -05:00
PatrickvL b2b0813db4 Loader : Added emulation DLL, working towards this stub compiling, moved loader project to subfolder 2020-04-14 20:24:17 -05:00
PatrickvL 9f19b26161 Loader : Log errors to console output. Also added a few comments 2020-04-14 20:24:16 -05:00
PatrickvL 4e1062905d Loader : Correct the PageTable range to fit all possible entries 2020-04-14 20:24:16 -05:00
PatrickvL e333152bd1 Loader : We won't emulate Alpha kits, and all other hardware revisions lack the physical hardware lines for USB1 ports, so this can go. 2020-04-14 20:24:16 -05:00
PatrickvL 032eee144f Reduce clutter in Loader by splitting up functionality in task-specific source files 2020-04-14 20:24:16 -05:00
patrickvl 420d689d82 Cleaned up of the loader project, added environment checks and documented it somewhat. 2020-04-14 20:24:16 -05:00
patrickvl 2295a10e77 Configurable system configuration by matching command line flags against memory-range flags - a quite flexible solution if I may say ;) 2020-04-14 20:24:16 -05:00
patrickvl 0532fa7c58 Loader coding style 2020-04-14 20:24:16 -05:00
patrickvl da10d3602f Extended reserved memory ranges with DevKitMemory and SystemMemory (both partially fail) 2020-04-14 20:24:16 -05:00
patrickvl 34072e9fd9 Random stuff, taken from my old Loader branch 2020-04-14 20:24:16 -05:00
patrickvl 208ce0e35c Added minimal CxbxLoader project 2020-04-14 20:24:16 -05:00
PatrickvL ca6423b484 Reviving my more-than-a-year-old Loader branch, by copying over various things (nothing functional yet) 2020-04-14 20:24:16 -05:00
PatrickvL 2a23634c77
Merge pull request #1870 from Cxbx-Reloaded/develop
Move develop Branch into master Branch
2020-04-14 12:23:31 +02:00
RadWolfie 52cdb4e984
Merge pull request #1869 from Margen67/readme-fix
Remove Azure badge
2020-04-13 19:25:24 -05:00
Margen67 525a2fb330
Remove Azure badge 2020-04-13 17:22:06 -07:00
377 changed files with 77078 additions and 65485 deletions

View File

@ -8,7 +8,6 @@ skip_commits:
- .github/*
- .github/*/*
- .azure-pipelines.yml
- .travis.yml
- CONTRIBUTORS
- COPYING
- README.md
@ -16,7 +15,10 @@ skip_commits:
- setup.bat
init:
- ps: Update-AppveyorBuild -Version "$env:appveyor_repo_commit"
- ps: |-
echo "This CI isn't tested against master, and therefore, isn't guaranteed to work. Pull requests are welcome."
echo "If it doesn't work and you'd rather not fix it, it's recommended to use GitHub Actions CI instead."
Update-AppveyorBuild -Version "$env:appveyor_repo_commit"
image: # If this is modified, please also update the build script
- Visual Studio 2019
@ -38,9 +40,7 @@ build_script:
on_success:
- ps: |-
If ($env:configuration -eq 'Release') {
cd bin\$env:configuration
7z u "$env:configuration.zip" ..\..\..\COPYING ..\..\..\README.md
7z u "$env:configuration.zip" Cxbx.exe glew32.dll subhook.dll SDL2.dll
7z u "$env:configuration.zip" cxbxr-debugger.exe capstone.dll cs_x86.dll
cmake --install . --config $env:configuration --prefix artifacts
7z a "$env:configuration.zip" ./artifacts/bin/*
Get-ChildItem .\*.zip | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
}

View File

@ -3,18 +3,13 @@ trigger:
include:
- '*'
paths:
exclude:
- doc/*
- doc/*/*
- .github/*
- .github/*/*
- .appveyor.yml
- .travis.yml
- CONTRIBUTORS
- COPYING
- README.md
- gen-msvc-project.bat
- setup.bat
exclude: # Azure Pipelines doesn't support recursive wildcards, see
- '.github/*' # https://developercommunity.visualstudio.com/t/support-wildcards-in-trigger-path-filters-1/366363
- '.github/*/*'
- '*.bat'
- '.appveyor.yml'
- 'doc/*/*'
- 'doc/*'
pr:
branches:
@ -22,61 +17,44 @@ pr:
- '*'
paths:
exclude:
- doc/*
- doc/*/*
- .github/*
- .github/*/*
- .appveyor.yml
- .travis.yml
- CONTRIBUTORS
- COPYING
- README.md
- gen-msvc-project.bat
- setup.bat
- '.github/*'
- '.github/*/*'
- '*.bat'
- '.appveyor.yml'
- 'doc/*/*'
- 'doc/*'
jobs:
- job:
pool:
vmImage: windows-latest
strategy:
matrix:
Release:
configuration: Release
Debug:
configuration: Debug
pool:
vmImage: windows-latest
strategy:
matrix:
Release:
configuration: Release
Debug:
configuration: Debug
steps:
- checkout: self
submodules: recursive
steps:
- pwsh: |
echo "This CI isn't tested against master, and therefore, isn't guaranteed to work. Pull requests are welcome."
echo "If it doesn't work and you'd rather not fix it, it's recommended to use GitHub Actions CI instead."
displayName: Third-Party CI Warning
- script: |
mkdir build
cd build
cmake .. -G "Visual Studio 16 2019" -A Win32
displayName: 'Before build'
- checkout: self
submodules: recursive
- script: cmake --build . --config %configuration%
workingDirectory: build
displayName: 'Build'
- pwsh: cmake -B build -A Win32
displayName: Before build
- task: CopyFiles@2
displayName: 'Copy files to $(Build.ArtifactStagingDirectory)'
condition: and(succeeded(), eq(variables['Agent.JobName'], 'Release'))
inputs:
Contents: |
COPYING
README.md
build\bin\$(configuration)\Cxbx.exe
build\bin\$(configuration)\glew32.dll
build\bin\$(configuration)\subhook.dll
build\bin\$(configuration)\SDL2.dll
build\bin\$(configuration)\cxbxr-debugger.exe
build\bin\$(configuration)\capstone.dll
build\bin\$(configuration)\cx_x86.dll
TargetFolder: '$(Build.ArtifactStagingDirectory)'
flattenFolders: true
- pwsh: cmake --build . --config $env:configuration
workingDirectory: build
displayName: Build
- publish: $(Build.ArtifactStagingDirectory)
artifact: $(configuration)
condition: and(succeeded(), eq(variables['Agent.JobName'], 'Release'))
displayName: Publish artifact(s)
- pwsh: cmake --install . --config $env:configuration --prefix $(Build.ArtifactStagingDirectory)
workingDirectory: build
condition: and(succeeded(), eq(variables['configuration'], 'Release'))
displayName: Prepare artifacts
- publish: $(Build.ArtifactStagingDirectory)
artifact: $(configuration)
condition: and(succeeded(), eq(variables['configuration'], 'Release'))
displayName: Publish artifacts

23
.gitattributes vendored
View File

@ -1,11 +1,3 @@
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
@ -18,5 +10,16 @@
*.rtf diff=astextplain
*.RTF diff=astextplain
[Cc][Mm]ake[Ll]ists.txt text=lf
*.bat text=lf
* text=auto
[Cc][Mm]ake[Ll]ists.txt text eol=lf
*.bat text eol=lf
*.c text eol=lf
*.h text eol=lf
*.cpp text eol=lf
*.hpp text eol=lf
*.unused-patches text eol=lf
*.rc text eol=lf
# All module imports are vendor, remove them from linguist stats chart for accurate stats.
import/* linguist-vendored

View File

@ -8,7 +8,38 @@ assignees: ''
---
<!--
Questions can be asked on Discord: https://discord.gg/26Xjx23
If this is an issue specifically related to one game, please report it at https://github.com/Cxbx-Reloaded/game-compatibility
Any emulation/general issues like crashes when a controller is connected, or regressions across several titles can be reported here.
ISSUES NOT UTILIZING THE TEMPLATE BELOW WILL BE CLOSED!
-->
<!--
Please read https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/blob/master/README.md and https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/wiki/Frequently-Asked-Questions-(FAQ) before opening an issue.
Remember, the GitHub Issue Tracker is not the place to ask for support. You must use our forum on Discord https://discord.gg/26Xjx23 for that.
Compatibility Reports should be submitted at the website: https://cxbx-reloaded.co.uk
Otherwise, for any other emulation/general issues like crashes when a controller is connected, or regressions across several titles, feel free to report your issue here.
-->
## Quick summary
<!--
Please briefly describe what is not working correctly.
-->
## Details
<!--
Please describe the problem as accurately as possible.
-->
### System Configuration:
<!--
Please provide your system configuration
-->
* OS
* CPU
* GPU
* etc.
### Additional Information (if any):
<!--
Anything else you deem to be important
-->

111
.github/labeler.yml vendored Normal file
View File

@ -0,0 +1,111 @@
# Labels are in alphabetical order.
cmake:
- changed-files:
- any-glob-to-any-file:
- 'CMake*'
- '**/CMakeLists.txt'
- '**/*.cmake'
cpu-emulation:
- changed-files:
- any-glob-to-any-file:
- 'src/devices/x86/**'
deployment:
- changed-files:
- any-glob-to-any-file:
- '*.yml'
- '.github/workflows/CI.yml'
file-system:
- changed-files:
- any-glob-to-any-file:
- 'src/core/kernel/support/EmuFile*'
graphics:
- changed-files:
- any-glob-to-any-file:
- 'src/core/hle/D3D8/**'
- 'src/core/hle/XGRAPHIC/**'
- 'src/devices/video/**'
- 'src/gui/*Video*'
HLE:
- changed-files:
- any-glob-to-any-file:
- 'src/core/hle/**'
- 'src/core/kernel/**'
informational:
- changed-files:
- any-glob-to-any-file:
- '**/*Logging*'
- '**/*Logging*/**'
- '**/README.md'
input:
- changed-files:
- any-glob-to-any-file:
- 'src/common/input/**'
- 'src/core/hle/XAPI/input/**'
- 'src/devices/usb/**'
- 'src/gui/controllers/**'
- 'src/gui/*Input*'
kernel:
- changed-files:
- any-glob-to-any-file:
- 'src/core/kernel/**'
LLE:
- changed-files:
- any-glob-to-any-file:
- 'src/devices/**'
memory:
- changed-files:
- any-glob-to-any-file:
- 'src/core/kernel/memory-manager/**'
networking:
- changed-files:
- any-glob-to-any-file:
- 'src/core/hle/XONLINE/**'
- 'src/devices/network/**'
- 'src/gui/*Network*'
sound:
- changed-files:
- any-glob-to-any-file:
- 'src/common/audio/**'
- 'src/core/hle/DSOUND/**'
- 'src/core/hle/XACTENG/**'
- 'src/devices/audio/**'
- 'src/gui/*Audio*'
modules:
- changed-files:
- any-glob-to-any-file:
- 'import/**'
threading:
- changed-files:
- any-glob-to-any-file:
- 'src/core/kernel/support/EmuFS*'
timing:
- changed-files:
- any-glob-to-any-file:
- 'src/common/Timer*'
user interface:
- changed-files:
- any-glob-to-any-file:
- 'src/core/common/imgui/*'
- 'src/gui/**'
xbdm:
- changed-files:
- any-glob-to-any-file:
- 'src/common/xbdm/**'

View File

@ -3,117 +3,79 @@ name: GitHub CI
on:
push:
paths-ignore:
- '.github/CONTRIBUTING.md'
- '.github/FUNDING.md'
- '.github/ISSUE_TEMPLATE/*'
- 'doc/*'
- 'doc/*/*'
- '.appveyor.yml'
- '.azure-pipelines.yml'
- '.travis.yml'
- 'gen-msvc-project.bat'
- 'setup.bat'
- '.gitattributes'
- '.github/*'
- '.github/*_TEMPLATE/**'
- '.gitignore'
- '*.bat'
- '*.yml'
- 'doc/**'
pull_request:
paths-ignore:
- '.github/CONTRIBUTING.md'
- '.github/FUNDING.md'
- '.github/ISSUE_TEMPLATE/*'
- 'doc/*'
- 'doc/*/*'
- '.appveyor.yml'
- '.azure-pipelines.yml'
- '.travis.yml'
- 'gen-msvc-project.bat'
- 'setup.bat'
- '.gitattributes'
- '.github/*'
- '.github/*_TEMPLATE/**'
- '.gitignore'
- '*.bat'
- '*.yml'
- 'doc/**'
jobs:
build-windows:
runs-on: ${{ matrix.os }}
name: Build (Windows, ${{ matrix.configuration }}, VS${{ matrix.vsver }}) # runner.os doesn't work here
runs-on: windows-${{ matrix.vsver }}
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
strategy:
fail-fast: false
matrix:
configuration: [Release, Debug]
vsver: [VS2019, VS2017]
include:
- vsver: VS2019
os: windows-latest
- vsver: VS2017 # TODO: Remove VS2017 once WINE supports VS2019 runtimes;
os: windows-2016 # https://github.com/actions/virtual-environments/issues/68#issuecomment-602652021
vsver: [2019]
winver: [7]
sdkver: [10.0.22621.0]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Generate cmake files
run: |
mkdir build && cd build
cmake .. -A Win32
- name: Generate CMake files
run: cmake -B build -A Win32,version=${{ matrix.sdkver }} -DCMAKE_SYSTEM_VERSION=${{ matrix.winver }} -DBUILD_CXBXR_DEBUGGER=ON
- name: Build
working-directory: build
run: cmake --build . --config ${{ matrix.configuration }} -j $env:NUMBER_OF_PROCESSORS
run: cmake --build build --config ${{ matrix.configuration }} -j $env:NUMBER_OF_PROCESSORS
- name: Prepare artifacts
if: matrix.configuration == 'Release'
run: |
robocopy . artifacts COPYING README.md /r:0 /w:0
robocopy build\bin\${{ matrix.configuration }} artifacts `
Cxbx.exe glew32.dll subhook.dll SDL2.dll `
cxbxr-debugger.exe capstone.dll cs_x86.dll /r:0 /w:0
If ($LastExitCode -le 7) { $LastExitCode = 0 }
- uses: actions/upload-artifact@v1
run: cmake --install build --config ${{ matrix.configuration }} --prefix artifacts
- uses: actions/upload-artifact@v4
if: matrix.configuration == 'Release'
with:
name: CxbxReloaded-${{ matrix.configuration }}-${{ matrix.vsver }}
path: artifacts
name: CxbxReloaded-${{ matrix.configuration }}-VS${{ matrix.vsver }}
path: artifacts/bin
if-no-files-found: error
release:
if: | # TODO: Remove develop once rebased
if: |
github.event.action != 'pull_request' &&
(github.ref == 'refs/heads/develop' ||
github.ref == 'refs/heads/master') &&
github.ref == 'refs/heads/master' &&
github.repository == 'Cxbx-Reloaded/Cxbx-Reloaded'
needs: build-windows
env:
artifact_1: CxbxReloaded-Release-VS2019
artifact_2: CxbxReloaded-Release-VS2017
runs-on: windows-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download artifacts (1)
uses: actions/download-artifact@v1
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: ${{ env.artifact_1 }}
- name: Download artifacts (2)
uses: actions/download-artifact@v1
with:
name: ${{ env.artifact_2 }}
- name: Prepare artifacts for release
run: | # download-artifact doesn't download a zip, so rezip it
echo "::set-env name=short_commit_sha::$(git rev-parse --short HEAD)"
7z a -mx1 "$env:artifact_1.zip" ".\$env:artifact_1\*"
7z a -mx1 "$env:artifact_2.zip" ".\$env:artifact_2\*"
path: artifacts
- name: Re-zip artifacts
id: zip
run: |
for artifact in artifacts/*; do
7z a ${artifact}.zip "./${artifact}/*"
if [ $(stat -c %s ${artifact}.zip) -le 100000 ]; then
echo "Error: Archive ${artifact}.zip too small!"
exit 1
fi
done
echo "tag_name=CI-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: CI-${{ env.short_commit_sha }}
release_name: CI-${{ env.short_commit_sha }}
prerelease: true
- name: Upload Release Asset (1)
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ env.artifact_1 }}.zip
asset_name: ${{ env.artifact_1 }}.zip
asset_content_type: application/zip
- name: Upload Release Asset (2)
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ env.artifact_2 }}.zip
asset_name: ${{ env.artifact_2 }}.zip
asset_content_type: application/zip
run: gh release create ${{ steps.zip.outputs.tag_name }} artifacts/*.zip -p --target $GITHUB_SHA --title '${{ steps.zip.outputs.tag_name }}'

16
.github/workflows/autoclose.yml vendored Normal file
View File

@ -0,0 +1,16 @@
on:
issues:
types: opened
jobs:
auto_close_issues:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Automatically close issues that don't follow the issue template
uses: ergo720/auto-close-issues@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-close-message: "@${issue.user.login}: your issue has been automatically closed because it does not follow the issue template." # optional property
closed-issues-label: "invalid" # optional property

13
.github/workflows/pull-request.yml vendored Normal file
View File

@ -0,0 +1,13 @@
name: Pull Request Manager
on: pull_request_target
jobs:
pr_manager:
runs-on: ubuntu-latest
steps:
- name: Labeler
uses: actions/labeler@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
sync-labels: true

4
.gitignore vendored
View File

@ -2,6 +2,10 @@
[Bb]uild/
[Bb]uild-*/
# CLion
.idea/
cmake-build-*/
# Visual Studio Cache
.vs/

40
.gitmodules vendored
View File

@ -1,23 +1,49 @@
[submodule "import/subhook"]
path = import/subhook
url = https://github.com/Zeex/subhook.git
url = https://github.com/Cxbx-Reloaded/subhook.git
shallow = true
[submodule "import/cs_x86"]
path = import/cs_x86
url = https://github.com/x1nixmzeng/cs_x86
url = https://github.com/x1nixmzeng/cs_x86.git
[submodule "import/XbSymbolDatabase"]
path = import/XbSymbolDatabase
url = https://github.com/Cxbx-Reloaded/XbSymbolDatabase
url = https://github.com/Cxbx-Reloaded/XbSymbolDatabase.git
[submodule "import/simpleini"]
path = import/simpleini
url = https://github.com/brofield/simpleini
url = https://github.com/brofield/simpleini.git
shallow = true
[submodule "import/libtommath"]
path = import/libtommath
url = https://github.com/libtom/libtommath
url = https://github.com/libtom/libtommath.git
branch = master
shallow = true
[submodule "import/libtomcrypt"]
path = import/libtomcrypt
url = https://github.com/libtom/libtomcrypt
url = https://github.com/libtom/libtomcrypt.git
branch = master
shallow = true
[submodule "import/xxHash"]
path = import/xxHash
url = https://github.com/Cyan4973/xxHash.git
branch = release
shallow = true
[submodule "import/imgui"]
path = import/imgui
url = https://github.com/ocornut/imgui.git
shadow = true
[submodule "import/SDL2"]
path = import/SDL2
url = https://github.com/SDL-mirror/SDL
url = https://github.com/libsdl-org/SDL
shallow = true
[submodule "import/libusb"]
path = import/libusb
url = https://github.com/Cxbx-Reloaded/libusb
branch = deadlock_fix
shallow = true
[submodule "import/nv2a_vsh_cpu"]
path = import/nv2a_vsh_cpu
url = https://github.com/abaire/nv2a_vsh_cpu.git
[submodule "import/mio"]
path = import/mio
url = https://github.com/mandreyel/mio.git
shadow = true

View File

@ -1,20 +0,0 @@
language: cpp
matrix:
include:
- os: windows
env: configuration=Debug
- os: windows
env: configuration=Release
before_script:
- if [ $TRAVIS_OS_NAME == 'windows' ]; then
mkdir build;
cd build;
cmake .. -G "Visual Studio 15 2017" -A Win32;
fi
script:
- if [ $TRAVIS_OS_NAME == 'windows' ]; then
cmake --build . --config $configuration;
fi

View File

@ -13,48 +13,36 @@ endif()
set(SUBHOOK_TESTS OFF)
set(SUBHOOK_INSTALL OFF)
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/subhook")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/subhook" EXCLUDE_FROM_ALL)
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/XbSymbolDatabase")
# Not require since only include a header file
#add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/simpleini")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/SDL2")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/SDL2" EXCLUDE_FROM_ALL)
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/cs_x86")
endif()
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/mio" EXCLUDE_FROM_ALL)
# Cxbx-Reloaded projects
set(CXBXR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR})
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/libtom")
find_package(Git)
if(Git_FOUND)
message("Git found: ${GIT_EXECUTABLE}")
execute_process(
COMMAND git describe --always --tags --first-parent
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE _GIT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message("Git version: " ${_GIT_VERSION})
else()
set(_GIT_VERSION "unknown")
endif()
# Appears to update whenever define has changed.
configure_file(
"${CXBXR_ROOT_DIR}/src/version.h.in" "${CXBXR_ROOT_DIR}/src/version.h" @ONLY
NEWLINE_STYLE LF
add_custom_target(misc-batch
${CMAKE_COMMAND} -DTargetRunTimeDir=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>
-P ${CXBXR_ROOT_DIR}/projects/misc/batch.cmake
WORKING_DIRECTORY ${CXBXR_ROOT_DIR}
)
#add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/vsbc")
# Custom CMake projects since some import libraries doesn't have it.
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/libtom")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/imgui")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/libusb")
set(nv2a_vsh_cpu_UNIT_TEST OFF)
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/import/nv2a_vsh_cpu" EXCLUDE_FROM_ALL)
# Split the files into group for which project is likely
# going to be used for both header and source files.
@ -66,39 +54,52 @@ configure_file(
# Common (GUI and Emulator)
file (GLOB CXBXR_HEADER_COMMON
"${CXBXR_ROOT_DIR}/src/common/AddressRanges.h"
"${CXBXR_ROOT_DIR}/src/common/crypto/EmuDes.h"
"${CXBXR_ROOT_DIR}/src/common/crypto/EmuRsa.h"
"${CXBXR_ROOT_DIR}/src/common/crypto/EmuSha.h"
"${CXBXR_ROOT_DIR}/src/common/crypto/LibRc4.h"
"${CXBXR_ROOT_DIR}/src/common/CxbxDebugger.h"
"${CXBXR_ROOT_DIR}/src/common/cxbxr.hpp"
"${CXBXR_ROOT_DIR}/src/common/EmuEEPROM.h"
"${CXBXR_ROOT_DIR}/src/common/Error.h"
"${CXBXR_ROOT_DIR}/src/common/FilePaths.hpp"
"${CXBXR_ROOT_DIR}/src/common/input/DInputKeyboardCodes.h"
"${CXBXR_ROOT_DIR}/src/common/input/DInputKeyboardMouse.h"
"${CXBXR_ROOT_DIR}/src/common/input/layout_xbox_controller.h"
"${CXBXR_ROOT_DIR}/src/common/input/layout_xbox_device.h"
"${CXBXR_ROOT_DIR}/src/common/input/LibusbDevice.h"
"${CXBXR_ROOT_DIR}/src/common/input/InputDevice.h"
"${CXBXR_ROOT_DIR}/src/common/input/InputManager.h"
"${CXBXR_ROOT_DIR}/src/common/input/SdlJoystick.h"
"${CXBXR_ROOT_DIR}/src/common/input/XInputPad.h"
"${CXBXR_ROOT_DIR}/src/common/input/RawDevice.h"
"${CXBXR_ROOT_DIR}/src/common/IPCHybrid.hpp"
"${CXBXR_ROOT_DIR}/src/common/Logging.h"
"${CXBXR_ROOT_DIR}/src/common/ReservedMemory.h"
"${CXBXR_ROOT_DIR}/src/common/Settings.hpp"
"${CXBXR_ROOT_DIR}/src/common/Timer.h"
"${CXBXR_ROOT_DIR}/src/common/util/cliConfig.hpp"
"${CXBXR_ROOT_DIR}/src/common/util/cliConverter.hpp"
"${CXBXR_ROOT_DIR}/src/common/util/CPUID.h"
"${CXBXR_ROOT_DIR}/src/common/util/crc32c.h"
"${CXBXR_ROOT_DIR}/src/common/util/CxbxUtil.h"
"${CXBXR_ROOT_DIR}/src/common/util/std_extend.hpp"
"${CXBXR_ROOT_DIR}/src/common/util/strConverter.hpp"
"${CXBXR_ROOT_DIR}/src/common/win32/AlignPosfix1.h"
"${CXBXR_ROOT_DIR}/src/common/win32/AlignPrefix1.h"
"${CXBXR_ROOT_DIR}/src/common/win32/EmuShared.h"
"${CXBXR_ROOT_DIR}/src/common/win32/Mutex.h"
"${CXBXR_ROOT_DIR}/src/common/win32/Threads.h"
"${CXBXR_ROOT_DIR}/src/common/win32/Util.h"
"${CXBXR_ROOT_DIR}/src/common/win32/WineEnv.h"
"${CXBXR_ROOT_DIR}/src/common/xbdm/CxbxXbdm.h"
"${CXBXR_ROOT_DIR}/src/common/xbe/Xbe.h"
"${CXBXR_ROOT_DIR}/src/common/xbe/XbePrinter.h"
"${CXBXR_ROOT_DIR}/src/common/xbox/Logging.hpp"
"${CXBXR_ROOT_DIR}/src/common/xbox/Types.hpp"
"${CXBXR_ROOT_DIR}/src/common/xbox_types.h"
"${CXBXR_ROOT_DIR}/src/common/xdvdfs-tools/buffered_io.h"
"${CXBXR_ROOT_DIR}/src/common/xdvdfs-tools/xdvdfs.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbConvert.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbD3D8Types.h"
"${CXBXR_ROOT_DIR}/src/core/hle/XAPI/Xapi.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlLogging.h"
"${CXBXR_ROOT_DIR}/src/Cxbx.h"
"${CXBXR_ROOT_DIR}/src/CxbxVersion.h"
"${CXBXR_ROOT_DIR}/src/version.h"
@ -109,33 +110,55 @@ file (GLOB CXBXR_HEADER_GUIv1
"${CXBXR_ROOT_DIR}/src/common/input/Button.h"
"${CXBXR_ROOT_DIR}/src/common/input/EmuDevice.h"
"${CXBXR_ROOT_DIR}/src/common/input/InputWindow.h"
"${CXBXR_ROOT_DIR}/src/gui/DbgConsole.h"
"${CXBXR_ROOT_DIR}/src/gui/input/DlgDukeControllerConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/input/DlgLibusbControllerConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/input/DlgLightgunConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/input/DlgSBControllerConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/DlgAbout.h"
"${CXBXR_ROOT_DIR}/src/gui/DlgAudioConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/DlgInputConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/DlgDukeControllerConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/DlgEepromConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/DlgLoggingConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/DlgNetworkConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/DlgVideoConfig.h"
"${CXBXR_ROOT_DIR}/src/gui/ResCxbx.h"
"${CXBXR_ROOT_DIR}/src/gui/Wnd.h"
"${CXBXR_ROOT_DIR}/src/gui/WndMain.h"
)
# Emulator (module)
file (GLOB CXBXR_HEADER_EMU_IMPORT
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_dx9.h"
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_opengl3.h"
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_win32.h"
)
file (GLOB CXBXR_HEADER_EMU
"${CXBXR_ROOT_DIR}/src/common/audio/converter.hpp"
"${CXBXR_ROOT_DIR}/src/common/audio/XADPCM.h"
"${CXBXR_ROOT_DIR}/src/common/Timer.h"
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/glextensions.h"
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen.h"
"${CXBXR_ROOT_DIR}/src/common/XADPCM.h"
"${CXBXR_ROOT_DIR}/src/common/win32/Threads.h"
"${CXBXR_ROOT_DIR}/src/core/common/imgui/audio.hpp"
"${CXBXR_ROOT_DIR}/src/core/common/imgui/ui.hpp"
"${CXBXR_ROOT_DIR}/src/core/common/imgui/settings.h"
"${CXBXR_ROOT_DIR}/src/core/common/imgui/video.hpp"
"${CXBXR_ROOT_DIR}/src/core/common/video/RenderBase.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/CxbxPixelShaderTemplate.hlsl"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderPassthrough.hlsl"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Direct3D9.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsli"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/FixedFunctionVertexShader.hlsl"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/FixedFunctionVertexShaderState.hlsli"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/PixelShader.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Shader.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShader.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShaderSource.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShaderCache.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/WalkIndexBuffer.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/FixedFunctionState.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/ResourceTracker.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbConvert.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbD3D8Logging.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbD3D8Types.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbPixelShader.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbPushBuffer.h"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbState.h"
@ -147,21 +170,22 @@ file (GLOB CXBXR_HEADER_EMU
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DirectSoundLogging.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundFuncs.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundLogging.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundTypes.h"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalStruct.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/Intercept.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/Patches.hpp"
"${CXBXR_ROOT_DIR}/src/core/hle/XACTENG/XactEng.h"
"${CXBXR_ROOT_DIR}/src/core/hle/XAPI/Xapi.h"
"${CXBXR_ROOT_DIR}/src/core/hle/XAPI/XapiCxbxr.h"
"${CXBXR_ROOT_DIR}/src/core/hle/XGRAPHIC/XGraphic.h"
"${CXBXR_ROOT_DIR}/src/core/hle/XONLINE/XOnline.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/common/strings.hpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlAvModes.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlKe.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlKi.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlLogging.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlPs.hpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/init/CxbxKrnl.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/init/KrnlPatches.hpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/memory-manager/PhysicalMemory.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/memory-manager/PoolManager.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/memory-manager/VMManager.h"
@ -169,9 +193,11 @@ file (GLOB CXBXR_HEADER_EMU
"${CXBXR_ROOT_DIR}/src/core/kernel/support/EmuFile.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/support/EmuFS.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/support/EmuNtDll.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/support/NativeHandle.h"
"${CXBXR_ROOT_DIR}/src/core/kernel/support/PatchRdtsc.hpp"
"${CXBXR_ROOT_DIR}/src/devices/ADM1032Device.h"
"${CXBXR_ROOT_DIR}/src/devices/EEPROMDevice.h"
"${CXBXR_ROOT_DIR}/src/devices/EmuNVNet.h"
"${CXBXR_ROOT_DIR}/src/devices/network/NVNetDevice.h"
"${CXBXR_ROOT_DIR}/src/devices/LED.h"
"${CXBXR_ROOT_DIR}/src/devices/MCPXDevice.h"
"${CXBXR_ROOT_DIR}/src/devices/PCIBus.h"
@ -200,38 +226,55 @@ file (GLOB CXBXR_HEADER_EMU
"${CXBXR_ROOT_DIR}/src/devices/Xbox.h"
)
# filter hlsl files into its own list
# excluding hlsli file(s)
set(CXBXR_HEADER_HLSL ${CXBXR_HEADER_EMU})
list(FILTER CXBXR_HEADER_HLSL INCLUDE REGEX ".*\\.hlsl$")
# Common (GUI and Emulator)
file (GLOB CXBXR_SOURCE_COMMON
"${CXBXR_ROOT_DIR}/src/common/AddressRanges.cpp"
"${CXBXR_ROOT_DIR}/src/common/crypto/EmuDes.cpp"
"${CXBXR_ROOT_DIR}/src/common/crypto/EmuRsa.cpp"
"${CXBXR_ROOT_DIR}/src/common/crypto/EmuSha.cpp"
"${CXBXR_ROOT_DIR}/src/common/crypto/LibRc4.cpp"
"${CXBXR_ROOT_DIR}/src/common/CxbxDebugger.cpp"
"${CXBXR_ROOT_DIR}/src/common/cxbxr.cpp"
"${CXBXR_ROOT_DIR}/src/common/EmuEEPROM.cpp"
"${CXBXR_ROOT_DIR}/src/common/Error.cpp"
"${CXBXR_ROOT_DIR}/src/common/FilePaths.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/DInputKeyboardMouse.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/InputDevice.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/InputManager.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/LibusbDevice.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/SdlJoystick.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/XInputPad.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/RawDevice.cpp"
"${CXBXR_ROOT_DIR}/src/common/Logging.cpp"
"${CXBXR_ROOT_DIR}/src/common/Settings.cpp"
"${CXBXR_ROOT_DIR}/src/common/Timer.cpp"
"${CXBXR_ROOT_DIR}/src/common/util/crc32c.cpp"
"${CXBXR_ROOT_DIR}/src/common/util/cliConfig.cpp"
"${CXBXR_ROOT_DIR}/src/common/util/cliConverter.cpp"
"${CXBXR_ROOT_DIR}/src/common/util/CxbxUtil.cpp"
"${CXBXR_ROOT_DIR}/src/common/util/hasher.cpp"
"${CXBXR_ROOT_DIR}/src/common/win32/EmuShared.cpp"
"${CXBXR_ROOT_DIR}/src/common/win32/InlineFunc.cpp"
"${CXBXR_ROOT_DIR}/src/common/win32/IPCWindows.cpp"
"${CXBXR_ROOT_DIR}/src/common/win32/Mutex.cpp"
"${CXBXR_ROOT_DIR}/src/common/win32/Threads.cpp"
"${CXBXR_ROOT_DIR}/src/common/win32/Util.cpp"
"${CXBXR_ROOT_DIR}/src/common/win32/WineEnv.cpp"
"${CXBXR_ROOT_DIR}/src/common/xbdm/CxbxXbdm.cpp"
"${CXBXR_ROOT_DIR}/src/common/xbe/Xbe.cpp"
"${CXBXR_ROOT_DIR}/src/common/xbe/XbePrinter.cpp"
"${CXBXR_ROOT_DIR}/src/common/xbox/Logging.cpp"
"${CXBXR_ROOT_DIR}/src/common/xbox/Types.cpp"
"${CXBXR_ROOT_DIR}/src/common/xdvdfs-tools/buffered_io.cpp"
"${CXBXR_ROOT_DIR}/src/common/xdvdfs-tools/xdvdfs.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbConvert.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/XAPI/Xapi.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlLogging.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlXbox.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlXc.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlXe.cpp"
"${CXBXR_ROOT_DIR}/src/CxbxVersion.cpp"
"${CXBXR_ROOT_DIR}/src/gui/DbgConsole.cpp"
"${CXBXR_ROOT_DIR}/src/HighPerformanceGraphicsEnabler.c"
)
@ -240,10 +283,13 @@ file (GLOB CXBXR_SOURCE_GUIv1
"${CXBXR_ROOT_DIR}/src/common/input/Button.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/EmuDevice.cpp"
"${CXBXR_ROOT_DIR}/src/common/input/InputWindow.cpp"
"${CXBXR_ROOT_DIR}/src/gui/input/DlgDukeControllerConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/input/DlgLibusbControllerConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/input/DlgLightgunConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/input/DlgSBControllerConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/DlgAbout.cpp"
"${CXBXR_ROOT_DIR}/src/gui/DlgAudioConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/DlgInputConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/DlgDukeControllerConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/DlgEepromConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/DlgLoggingConfig.cpp"
"${CXBXR_ROOT_DIR}/src/gui/DlgNetworkConfig.cpp"
@ -258,20 +304,33 @@ file (GLOB CXBXR_SOURCE_GUIv1
file (GLOB CXBXR_KRNL_CPP
"${CXBXR_ROOT_DIR}/src/core/kernel/init/CxbxKrnl.cpp"
)
file (GLOB CXBXR_SOURCE_EMU_IMPORT
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_dx9.cpp"
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_opengl3.cpp"
"${CXBXR_ROOT_DIR}/import/imgui/backends/imgui_impl_win32.cpp"
)
file (GLOB CXBXR_SOURCE_EMU
"${CXBXR_KRNL_CPP}"
"${CXBXR_ROOT_DIR}/HighPerformanceGraphicsEnabler.c"
"${CXBXR_ROOT_DIR}/src/common/Timer.cpp"
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/glextensions.cpp"
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen_common.cpp"
"${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen_wgl.cpp"
"${CXBXR_ROOT_DIR}/src/common/VerifyAddressRanges.cpp"
"${CXBXR_ROOT_DIR}/src/common/win32/Threads.cpp"
"${CXBXR_ROOT_DIR}/src/core/common/imgui/audio.cpp"
"${CXBXR_ROOT_DIR}/src/core/common/imgui/ui.cpp"
"${CXBXR_ROOT_DIR}/src/core/common/imgui/video.cpp"
"${CXBXR_ROOT_DIR}/src/core/common/video/RenderBase.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/PixelShader.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/RenderStates.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/Shader.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/TextureStates.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShader.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShaderSource.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/VertexShaderCache.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/Direct3D9/WalkIndexBuffer.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/FixedFunctionState.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/ResourceTracker.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbConvert.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbD3D8Logging.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbPixelShader.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/D3D8/XbPushBuffer.cpp"
@ -286,10 +345,12 @@ file (GLOB CXBXR_SOURCE_EMU
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundLogging.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalStruct.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/Intercept.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/JVS/JVS.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/Patches.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/XACTENG/XactEng.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/XAPI/Xapi.cpp"
"${CXBXR_ROOT_DIR}/src/core/hle/XGRAPHIC/XGraphic.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnl.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlAv.cpp"
@ -301,16 +362,12 @@ file (GLOB CXBXR_SOURCE_EMU
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlKd.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlKe.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlKi.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlLogging.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlMm.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlNt.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlOb.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlPhy.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlPs.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlRtl.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlXbox.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlXc.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/EmuKrnlXe.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/exports/KernelThunk.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/memory-manager/PhysicalMemory.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/memory-manager/PoolManager.cpp"
@ -319,9 +376,13 @@ file (GLOB CXBXR_SOURCE_EMU
"${CXBXR_ROOT_DIR}/src/core/kernel/support/EmuFile.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/support/EmuFS.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/support/EmuNtDll.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/support/NativeHandle.cpp"
"${CXBXR_ROOT_DIR}/src/core/kernel/support/PatchRdtsc.cpp"
"${CXBXR_ROOT_DIR}/src/devices/ADM1032Device.cpp"
"${CXBXR_ROOT_DIR}/src/devices/Chihiro/JvsIO.cpp"
"${CXBXR_ROOT_DIR}/src/devices/Chihiro/MediaBoard.cpp"
"${CXBXR_ROOT_DIR}/src/devices/EEPROMDevice.cpp"
"${CXBXR_ROOT_DIR}/src/devices/EmuNVNet.cpp"
"${CXBXR_ROOT_DIR}/src/devices/network/NVNetDevice.cpp"
"${CXBXR_ROOT_DIR}/src/devices/MCPXDevice.cpp"
"${CXBXR_ROOT_DIR}/src/devices/PCIBus.cpp"
"${CXBXR_ROOT_DIR}/src/devices/PCIDevice.cpp"
@ -332,6 +393,8 @@ file (GLOB CXBXR_SOURCE_EMU
"${CXBXR_ROOT_DIR}/src/devices/usb/OHCI.cpp"
"${CXBXR_ROOT_DIR}/src/devices/usb/USBDevice.cpp"
"${CXBXR_ROOT_DIR}/src/devices/usb/XidGamepad.cpp"
#NOTE: These files are direct includes inside nv2a.cpp file. If we comment them out, we will have compile errors.
#"${CXBXR_ROOT_DIR}/src/devices/video/EmuNV2A_DEBUG.cpp"
#"${CXBXR_ROOT_DIR}/src/devices/video/EmuNV2A_PBUS.cpp"
#"${CXBXR_ROOT_DIR}/src/devices/video/EmuNV2A_PCOUNTER.cpp"
@ -353,6 +416,7 @@ file (GLOB CXBXR_SOURCE_EMU
#"${CXBXR_ROOT_DIR}/src/devices/video/EmuNV2A_PVIDEO.cpp"
#"${CXBXR_ROOT_DIR}/src/devices/video/EmuNV2A_PVPE.cpp"
#"${CXBXR_ROOT_DIR}/src/devices/video/EmuNV2A_USER.cpp"
"${CXBXR_ROOT_DIR}/src/devices/video/nv2a.cpp"
"${CXBXR_ROOT_DIR}/src/devices/video/nv2a_debug.cpp"
"${CXBXR_ROOT_DIR}/src/devices/video/nv2a_psh.cpp"
@ -362,39 +426,84 @@ file (GLOB CXBXR_SOURCE_EMU
"${CXBXR_ROOT_DIR}/src/devices/video/swizzle.cpp"
"${CXBXR_ROOT_DIR}/src/devices/x86/EmuX86.cpp"
"${CXBXR_ROOT_DIR}/src/devices/Xbox.cpp"
# Temporary usage for need ReserveAddressRanges func with cxbx.exe's emulation.
"${CXBXR_ROOT_DIR}/src/common/ReserveAddressRanges.cpp"
)
option(BUILD_CXBXR_DEBUGGER "Build cxbxr-debugger tool (with cheat table support)")
if(BUILD_CXBXR_DEBUGGER)
message(DEPRECATION "The Cxbxr-Debugger tool will eventually be removed from the upstream branch.")
endif()
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/cxbx")
# Issues with compile (the same with develop branch) and
# for some reason did not put the files into virtual folder?
# Might need to put the list in the source folder for workaround fix.
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])")
#add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/debugger")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/src/CxbxDebugger")
endif()
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/cxbxr-ldr")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/cxbxr-emu")
set(cxbxr_INSTALL_files "COPYING" "README.md")
# Cxbx-Reloaded project with third-party libraries
set_target_properties(cxbx cxbxr-ldr cxbxr-emu misc-batch SDL2 subhook libXbSymbolDatabase libtommath libtomcrypt imgui libusb
PROPERTIES FOLDER Cxbx-Reloaded
)
set_target_properties(nv2a_vsh_emulator nv2a_vsh_disassembler nv2a_vsh_cpu
PROPERTIES FOLDER Cxbx-Reloaded/nv2a_vsh
)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# Configure startup project
set_property(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" PROPERTY VS_STARTUP_PROJECT cxbx)
endif()
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])")
# Refuse to exclude due to install is not set to optional
#set_target_properties(cstool
# PROPERTIES EXCLUDE_FROM_ALL TRUE
#)
set_target_properties(Tests_cs_x86
PROPERTIES EXCLUDE_FROM_ALL TRUE
)
# Check if generator is Visual Studio then enable Cxbxr-Debugger project.
# Since C# is currently supported with Visual Studio for now.
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])" AND BUILD_CXBXR_DEBUGGER)
# Issues with compile (the same with develop branch) and
# for some reason did not put the files into virtual folder?
# Might need to put the list in the source folder for workaround fix.
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/src/CxbxDebugger")
# Cxbx-Debugger project with third-party libraries
set_target_properties(cxbxr-debugger cs_x86 Tests_cs_x86 capstone-shared cstool
PROPERTIES FOLDER Cxbx-Reloaded/debugger
)
set_target_properties(Tests_cs_x86
PROPERTIES EXCLUDE_FROM_ALL TRUE
)
# Cxbx-Debugger project with third-party libraries
set_target_properties(cxbxr-debugger cs_x86 Tests_cs_x86 capstone-shared
PROPERTIES FOLDER Cxbx-Reloaded/debugger
)
endif()
# Cxbx-Reloaded project with third-party libraries
set_target_properties(cxbx subhook XbSymbolDatabase libtommath libtomcrypt
PROPERTIES FOLDER Cxbx-Reloaded
install(FILES ${cxbxr_INSTALL_files}
DESTINATION bin
)
# Copy HLSL files to the output directory, which are loaded at runtime
set(CXBXR_HLSL_FILES ${CXBXR_HEADER_EMU})
list(FILTER CXBXR_HLSL_FILES INCLUDE REGEX ".*/src/core/hle/D3D8/Direct3D9/[^/]+\.hlsli?")
add_custom_command(
TARGET misc-batch POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/hlsl
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CXBXR_HLSL_FILES} "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/hlsl"
# These files can be edited.
# Create backup copies for convenience of restoring original shader behaviour.
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/hlsl/backup
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CXBXR_HLSL_FILES} "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/hlsl/backup"
)
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/hlsl DESTINATION bin)
set(cxbxr_GLEW_DLL "${CMAKE_SOURCE_DIR}/import/glew-2.0.0/bin/Release/Win32/glew32.dll")
install(PROGRAMS ${cxbxr_GLEW_DLL}
DESTINATION bin
)
install(PROGRAMS $<TARGET_FILE_DIR:cxbx>/${CMAKE_SHARED_LIBRARY_PREFIX}subhook${CMAKE_SHARED_LIBRARY_SUFFIX}
DESTINATION bin
)
install(PROGRAMS $<TARGET_FILE_DIR:cxbx>/${CMAKE_SHARED_LIBRARY_PREFIX}SDL2${CMAKE_SHARED_LIBRARY_SUFFIX}
DESTINATION bin
)

View File

@ -7,7 +7,7 @@ Cxbx was initiated by Caustik. Dxbx was initiated by shadowtj.
The following contributors are grouped per project and listed in alphabetical order,
based on sources like https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/graphs/contributors ,
http://www.caustik.com/cxbx/about.htm , http://emulation.gametechwiki.com/index.php/Cxbx ,
http://www.caustik.com/cxbx/about.htm , https://emulation.gametechwiki.com/index.php/Cxbx ,
and https://github.com/PatrickvL/Dxbx/graphs/contributors .
@ -34,7 +34,7 @@ Ernegien (Mike Davis)
ergo720
faha223 (Fred Hallock)
Fisherman166
gandalfthewhite19890404
gandalfthewhite19890404
gellis713
ggKismet
GXTX (wutno)
@ -46,14 +46,15 @@ JayFoxRox (Jannik Vogel)
literalmente-game
Luca1991 (Luca D'Amico) [Luca91]
LukeUsher (Luke Usher) [SoullessSentinel]
Margen67
Margen67
NZJenkins
PatrickvL (Patrick van Logchem)
phire (Scott Mansell)
RadWolfie
revel8n
Silent (CookiePLMonster)
StrikerX3 (Ivan Roberto de Oliveira)
TotalCaesar659
TotalCaesar659
Voxel9 (Voxel)
x1nixmzeng
@ -61,7 +62,7 @@ x1nixmzeng
Cxbx-Reloaded Supporters:
Cedric Wilson
Cisco Martinez
Cisco Martinez
Cody Dale Barton
Elijah Chondropoulos
Jacob Kelly
@ -72,7 +73,7 @@ Kenneth Edmonds
Kyle Lenhardt
Manny Calavera
Mark Knasiak
Marko V.
Marko V.
Matt Coady
Roman Guivan
Taylor Stock

View File

@ -1,45 +1,57 @@
# Cxbx-Reloaded - Original Xbox Emulator
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](https://img.shields.io/badge/License-GPL%20v2-blue.svg)
[![GitHub Actions](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/workflows/GitHub%20CI/badge.svg)](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/actions?query=workflow%3A%22GitHub+CI%22)
[![Azure](https://Cxbx-Reloaded.visualstudio.com/Cxbx-Reloaded/_apis/build/status/Cxbx-Reloaded.Cxbx-Reloaded?branchName=develop)](https://Cxbx-Reloaded.visualstudio.com/Cxbx-Reloaded/_build/latest?definitionId=7&branchName=develop)
[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/blob/master/COPYING)
[![GitHub Actions](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/workflows/GitHub%20CI/badge.svg?event=push)](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/actions?query=event%3Apush+workflow%3A%22GitHub+CI%22)
[![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?logo=discord)](https://discord.gg/26Xjx23)
Cxbx-Reloaded is an emulator for running Microsoft Xbox (and eventually, Chihiro) games on Microsoft Windows.
Cxbx-Reloaded is an emulator for running Microsoft Xbox (and eventually, Chihiro) games on Microsoft Windows and Wine.
## System Requirements
### Minimum
* OS: Windows 7+ x64. 32-bit is not supported.
* OS: Windows 7+ x64, or x86-64 Linux with Wine. 32-bit is not supported.
* MacOS with Wine is known not to work, and BSD-based systems are untested.
* Also note that Wine is relatively unstable, and it might break compatibility with Cxbx-Reloaded at any time without warning.
* GPU: Direct3D 9.0c with Pixel Shader Model 2.x, and Vertex Shader Model 3.0.
### Prerequisites
* [32-bit (x86) Visual C++ 2019 Redistributable](https://aka.ms/vs/16/release/vc_redist.x86.exe)
## Prerequisites
### Windows
* [32-bit (x86) Visual C++ 2022 Redistributable](https://aka.ms/vs/17/release/vc_redist.x86.exe)
* [Npcap *(used for network emulation)*](https://nmap.org/npcap/#download)
* Make sure to enable winpcap compatibility mode!
* Make sure to enable winpcap compatibility mode.
* [WinUSB compliant driver](https://github.com/libusb/libusb/wiki/Windows#Driver_Installation)
* *Optional, only needed for USB pass-through of original Xbox and Steel Battalion controllers.*
### Wine
**Please use the latest stable release version of Wine. If it does not work for you, then roll back to Wine 7.0 which is the last known working version.**<br/>
**There also exists this known [issue](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/issues/2314) which currently prevents savings in some games with the most recent Wine 6.8 and later versions.**
* Winetricks
* `vcrun2019`
* Requires the latest winetricks script.
* `d3dcompiler_47`
* This may be subject to change.
* Winpcap is built-in, no installation is required.
## Automated Builds
Cxbx-Reloaded doesn't currently have stable builds, but you can obtain pre-release builds from the Releases tab, or the links below:
Cxbx-Reloaded doesn't currently have stable builds, but you can obtain pre-release builds from our official website's download page, or the links below:
* **[Release Builds](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/releases)**
* **WINE users will need to use `CxbxReloaded-Release-VS2017.zip` for it to run correctly.**
* **[Release Builds](https://cxbx-reloaded.co.uk/download)**
* *[Full build history](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/actions?query=workflow%3A%22GitHub+CI%22)*
## Compatibility
Cxbx-Reloaded has a [compatibility list](https://github.com/Cxbx-Reloaded/game-compatibility#cxbx-reloaded-game-compatibility-project).
Cxbx-Reloaded has a [compatibility list](https://cxbx-reloaded.co.uk/compatibility).
If you have something to report on a title, please create or update the issue for it there.
Please read the [Readme file](https://github.com/Cxbx-Reloaded/game-compatibility/blob/master/README.md) first!
If you would like to submit compatibility reports, please request permission in our Discord server.
## Bug Reports
Game or software specific issues can be reported in the [compatibility list](https://github.com/Cxbx-Reloaded/game-compatibility#cxbx-reloaded-game-compatibility-project).
Game or software specific issues can be reported in the [compatibility website](https://cxbx-reloaded.co.uk/compatibility).
For emulation issues that are not specific to any single piece of software, a bug report can be submitted at [the Cxbx-Reloaded issue tracker](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/issues).
Make sure bug reports contain:
<!--Make sure to follow the issue template and that it contains:
* The build tested with, error message displayed (if any)
* Screenshots
* Xbe dump (created via `Edit > Dump Xbe Info To > File`)
* Kernel Debug log (created when running a game with `View > Debug Output (Kernel) > File` selected).
* **You can copy and paste any popup messages. However, please keep it clean by pasting and trimming down to only the message itself.**
* Screenshots
* Optional unless there are graphic bugs for reference.
**Failure to follow the template will auto close your ticket.**-->
## Additional information
Cxbx-Reloaded has a [wiki](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/wiki) containing various subjects and background information.
@ -51,19 +63,18 @@ We welcome contributions, large and small.
If you want to do some coding, be sure to read the [Developer notes](https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/wiki/Developer-notes).
**IMPORTANT: Pull-Requests containing code derived from XQEMU will _not_ be approved until an agreement is reached to make work mutually beneficial. this includes updates to existing XQEMU derived code. We should not/will not become a hostile fork.**
**IMPORTANT: Pull-Requests containing code derived from XQEMU will _not_ be approved until an agreement is reached to make work mutually beneficial. This includes updates to existing XQEMU derived code. We should not/will not become a hostile fork.**
Please contact us before you start working on something, so we can make sure your work is going to be accepted once finished.
### Main Prerequisites
1. [Git for Windows](https://git-scm.com)
2. [CMake](https://cmake.org)
* Some IDEs already have CMake support, so this is optional.
* Some IDEs already have CMake support, this is optional.
### Fetching the code
1. Run the following command in the command line:
`git clone --recurse-submodules https://github.com/Cxbx-Reloaded/Cxbx-Reloaded.git`
<br>`git clone --recurse-submodules https://github.com/Cxbx-Reloaded/Cxbx-Reloaded.git`
* Please note the `--recurse-submodules` parameter. This is required to fetch submodules.
* If Cxbx-Reloaded was checked out without submodules, they can be updated/fetched with the following command:
@ -72,12 +83,13 @@ Please contact us before you start working on something, so we can make sure you
### Compiling
#### Windows
**NOTE:** Don't open `CMakeLists.txt` from Visual Studio, as it won't generate files in the `build` directory.
Don't open `CMakeLists.txt` from Visual Studio, as it won't generate files in the `build` directory.
##### Prerequisites
1. [Visual Studio](https://visualstudio.microsoft.com/downloads/) 2017 or later
1. [Visual Studio](https://visualstudio.microsoft.com/downloads/) 2022
* C++ and C# desktop development
* Windows Universal CRT SDK
* Windows 11 SDK (10.0.22621.0) or later
* C++ CMake tools for Windows
* *Optional if CMake is installed*
* [Microsoft Child Process Debugging Power Tool](https://marketplace.visualstudio.com/items?itemName=vsdbgplat.MicrosoftChildProcessDebuggingPowerTool)
@ -85,11 +97,11 @@ Please contact us before you start working on something, so we can make sure you
##### Generate Visual Studio files
1. If you don't have CMake installed, open `___ Native Tools Command Prompt for VS 20##`.
2. `cd` to the Cxbx-Reloaded directory.
3. Run these commands.
1. `mkdir build & cd build`
2. `cmake .. -G "Visual Studio 16 2019" -A Win32`
* Visual Studio 2019 16.1 or later has CMake 3.14 bundled, and is required for the Visual Studio 2019 generator.
* Use `cmake .. -G "Visual Studio 15 2017" -A Win32` for Visual Studio 2017.
3. Run the following command: `cmake -B build -G "Visual Studio 17 2022" -A Win32` \
**NOTES**:
* VS2022 17.0 or later is required.
* To build the Cxbx-Reloaded Debugger tool, add the variable `-DBUILD_CXBXR_DEBUGGER=ON` to the above command.
* _This debugger tool is deprecated and will be eventually removed, please use the Visual Studio debugger instead._
4. Open `Cxbx-Reloaded.sln` from the `build` directory.
5. Select the Release configuration, then click Build.
* Debug builds are **significantly slower, and only for developers**.
@ -104,3 +116,5 @@ You can support [Luke Usher](https://github.com/LukeUsher), initiator of Cxbx-Re
* All contributors to the original Cxbx and [Dxbx](https://github.com/PatrickvL/Dxbx) projects. Without them Cxbx-Reloaded would not exist at all.
* [XQEMU](https://github.com/xqemu/xqemu) - While the majority of Cxbx-R is our own work (Kernel, HLE, etc), the NV2A LLE and NVNet implementation are primarily the work of the XQEMU developers.
* [XboxDev](https://github.com/xboxdev) - Providing Xbox hardware research & useful tooling.
* [XbSymbolDatabase](https://github.com/Cxbx-Reloaded/XbSymbolDatabase) - Providing support to detect symbols across XDK builds from reverse engineered retail titles.
* [Xbox Kernel Test Suite](https://github.com/Cxbx-Reloaded/xbox_kernel_test_suite) - Making accurate tests on hardware to compare against cxbxr's kernel implementation.

View File

@ -47,6 +47,9 @@ GOTO :helpInfo
)
:: Check second arg (Visual Studio version)
IF "%2"=="2022" (
SET msvc_compiler=Visual Studio 17 2022
)
IF "%2"=="2019" (
SET msvc_compiler=Visual Studio 16 2019
)
@ -54,7 +57,7 @@ IF "%2"=="2017" (
SET msvc_compiler=Visual Studio 15 2017
)
IF "%2"=="" (
SET msvc_compiler=Visual Studio 15 2017
SET msvc_compiler=Visual Studio 16 2019
)
IF NOT DEFINED msvc_compiler (
GOTO :helpInfo
@ -100,8 +103,9 @@ ECHO - ARM
ECHO - ARM64
ECHO ---
ECHO arg2
ECHO - 2017
ECHO - 2022
ECHO - 2019
ECHO - 2017
PAUSE
GOTO :end

2
import/SDL2 vendored

@ -1 +1 @@
Subproject commit c7b8b49ef8691ac85ad18298468f7e4a616290ed
Subproject commit fa24d868ac2f8fd558e4e914c9863411245db8fd

@ -1 +1 @@
Subproject commit 0f2794cac610fad4f1955241ef43e6254fd11205
Subproject commit 774111351210e6f340246d6fb32741b09708f381

2
import/cs_x86 vendored

@ -1 +1 @@
Subproject commit 7c491b6ef7e49c7f35dcdd39f99f1f5943e48e9e
Subproject commit f8a95b7afa963c90b01a9e7cd758346f95c90f50

1
import/imgui vendored Submodule

@ -0,0 +1 @@
Subproject commit 8ced41570e4692b0d556503683ae45f92416f5f1

1
import/libusb vendored Submodule

@ -0,0 +1 @@
Subproject commit cf178f1fac38426990425cc034f7d4b8c9e1e388

1
import/mio vendored Submodule

@ -0,0 +1 @@
Subproject commit 3f86a95c0784d73ce6815237ec33ed25f233b643

1
import/nv2a_vsh_cpu vendored Submodule

@ -0,0 +1 @@
Subproject commit ead0af5dee49e408c005151393f8a7dbcd27026c

2
import/subhook vendored

@ -1 +1 @@
Subproject commit 29cb47ea7674b36cf2b742c11cf2568add1f47fc
Subproject commit 83d4e1ebef3588fae48b69a7352cc21801cb70bc

1
import/xxHash vendored Submodule

@ -0,0 +1 @@
Subproject commit 94e5f23e736f2bb67ebdf90727353e65344f9fc0

View File

@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.12)
project(cxbx)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
# Suppress extra stuff from generated solution
set(CMAKE_SUPPRESS_REGENERATION true)
@ -12,16 +12,13 @@ include_directories(
"${CXBXR_ROOT_DIR}/src/common"
"${CXBXR_ROOT_DIR}/src/common/Win32"
"${CXBXR_ROOT_DIR}/import/OpenXDK/include"
"${CXBXR_ROOT_DIR}/import/DirectX9/include"
"${CXBXR_ROOT_DIR}/import/distorm/include"
"${CXBXR_ROOT_DIR}/import/glew-2.0.0/include"
"${CXBXR_ROOT_DIR}/import/subhook"
"${CXBXR_ROOT_DIR}/import/DirectX9/include"
"${CXBXR_ROOT_DIR}/import/XbSymbolDatabase"
"${CXBXR_ROOT_DIR}/import/libusb/libusb"
"${CXBXR_ROOT_DIR}/import/simpleini"
"${CXBXR_ROOT_DIR}/import/libtommath"
"${CXBXR_ROOT_DIR}/import/libtomcrypt/src/headers"
"${CXBXR_ROOT_DIR}/import/winpcap/Include"
"${CXBXR_ROOT_DIR}/import/SDL2/include"
"${CXBXR_ROOT_DIR}/import/xxHash"
)
link_directories(
@ -45,8 +42,11 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
LTC_NO_PRNGS
LTC_NO_MISC
LTC_NO_PROTOTYPES
# Enable Chihiro work
CHIHIRO_WORK
)
# Reference: https://docs.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-alphabetically
add_compile_options(
# Catch synchronous (C++) exceptions only
@ -68,28 +68,31 @@ XXH_INLINE_ALL
)
file (GLOB RESOURCES
"${CXBXR_ROOT_DIR}/CONTRIBUTORS"
"${CXBXR_ROOT_DIR}/COPYING"
"${CXBXR_ROOT_DIR}/README.md"
"${CXBXR_ROOT_DIR}/resource/.editorconfig"
"${CXBXR_ROOT_DIR}/resource/Cxbx.rc"
"${CXBXR_ROOT_DIR}/resource/Cxbx-R.ico"
"${CXBXR_ROOT_DIR}/resource/Logo.bmp"
"${CXBXR_ROOT_DIR}/resource/Logo-License-CC4.bmp"
"${CXBXR_ROOT_DIR}/src/gui/resource/.editorconfig"
"${CXBXR_ROOT_DIR}/src/gui/resource/Cxbx.rc"
"${CXBXR_ROOT_DIR}/src/gui/resource/Cxbx-R.ico"
"${CXBXR_ROOT_DIR}/src/gui/resource/Logo.bmp"
"${CXBXR_ROOT_DIR}/src/gui/resource/Logo-License-CC4.bmp"
"${CXBXR_ROOT_DIR}/src/gui/resource/ResCxbx.h"
"${CXBXR_ROOT_DIR}/src/.editorconfig"
)
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES
${CXBXR_HEADER_GUIv1}
${CXBXR_HEADER_COMMON}
${CXBXR_HEADER_EMU}
)
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES
source_group(TREE ${CXBXR_ROOT_DIR}/import PREFIX import FILES
${CXBXR_SOURCE_EMU_IMPORT}
)
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES
${CXBXR_SOURCE_GUIv1}
${CXBXR_SOURCE_COMMON}
${CXBXR_SOURCE_EMU}
)
source_group(TREE ${CXBXR_ROOT_DIR} FILES ${RESOURCES})
@ -97,10 +100,8 @@ source_group(TREE ${CXBXR_ROOT_DIR} FILES ${RESOURCES})
add_executable(cxbx WIN32 ${RESOURCES}
${CXBXR_HEADER_GUIv1}
${CXBXR_HEADER_COMMON}
${CXBXR_HEADER_EMU}
${CXBXR_SOURCE_GUIv1}
${CXBXR_SOURCE_COMMON}
${CXBXR_SOURCE_EMU}
${CXBXR_GIT_VERSION_H}
)
@ -110,25 +111,17 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# Reference: https://docs.microsoft.com/en-us/cpp/build/reference/linker-options
set_target_properties(cxbx PROPERTIES
LINK_FLAGS "
/INCREMENTAL:NO
/LARGEADDRESSAWARE
/FIXED
/SAFESEH:NO
/DYNAMICBASE:NO
/BASE:0x10000
/STACK:65536,65536
/NODEFAULTLIB:libcmt
/DELAYLOAD:wpcap.dll
/NODEFAULTLIB:libcmt \
"
LINK_FLAGS_RELEASE "
/LTCG
/DEBUG
/LTCG \
/DEBUG \
"
)
# Reference: https://docs.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-alphabetically
# /Zi = create a PDB file without affecting optimization
# /Ob2 = Controls inline expansion of functions.
# /Ob3 = Controls inline expansion of functions.
# /Oi = Generate intrinsic functions
# /Ot = In favor of using fast code than small code
# /GL = Whole program optimization
@ -137,19 +130,19 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# /Qpar = Enable automatic parallelize loops in the code
# Set optimization options for release build
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}
/Zi
/Ob2
/Oi
/Ot
/GL
/GS-
/Gy
/Qpar
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} \
/Zi \
/Ob3 \
/Oi \
/Ot \
/GL \
\
/GS- \
/Gy \
/Qpar \
"
)
# disable optimization for CxbxKrnl.cpp file
set_source_files_properties(
${CXBXR_KRNL_CPP} PROPERTIES COMPILE_FLAGS "/Od /GL-"
@ -157,10 +150,11 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
endif()
# Windows libraries
set(WINS_LIB
set(WINS_LIB
legacy_stdio_definitions
d3d9
d3dcompiler
delayimp
dinput8
dxguid
odbc32
@ -176,25 +170,36 @@ set(WINS_LIB
comctl32
XINPUT9_1_0
Iphlpapi
wpcap
Dwmapi
)
target_link_libraries(cxbx
PUBLIC XbSymbolDatabase
PUBLIC libXbSymbolDatabase
subhook
libtomcrypt
SDL2
imgui
libusb
mio::mio_min_winapi
${WINS_LIB}
)
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])")
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
)
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])" AND BUILD_CXBXR_DEBUGGER)
add_dependencies(cxbx cxbxr-debugger)
endif()
set(CXBXR_GLEW_DLL "${CXBXR_ROOT_DIR}/import/glew-2.0.0/bin/Release/Win32/glew32.dll")
add_dependencies(cxbx cxbxr-ldr cxbxr-emu misc-batch)
# Copy glew32.dll to build type's folder after build.
add_custom_command(TARGET cxbx POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${CXBXR_GLEW_DLL} $<TARGET_FILE_DIR:cxbx>
# Try to stop cmake from building hlsl files
# Which are all currently loaded at runtime only
set_source_files_properties(
${CXBXR_HEADER_HLSL}
PROPERTIES
HEADER_FILE_ONLY TRUE
VS_TOOL_OVERRIDE "None"
)

View File

@ -0,0 +1,196 @@
cmake_minimum_required (VERSION 3.12)
project(cxbxr-emu)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)
# Suppress extra stuff from generated solution
set(CMAKE_SUPPRESS_REGENERATION true)
# Force exclude default libraries being included
#set(CMAKE_CXX_STANDARD_LIBRARIES "")
include_directories(
"${CXBXR_ROOT_DIR}/src"
"${CXBXR_ROOT_DIR}/src/common"
"${CXBXR_ROOT_DIR}/src/common/Win32"
"${CXBXR_ROOT_DIR}/import/OpenXDK/include"
"${CXBXR_ROOT_DIR}/import/DirectX9/include"
"${CXBXR_ROOT_DIR}/import/distorm/include"
"${CXBXR_ROOT_DIR}/import/glew-2.0.0/include"
"${CXBXR_ROOT_DIR}/import/libusb/libusb"
"${CXBXR_ROOT_DIR}/import/simpleini"
"${CXBXR_ROOT_DIR}/import/winpcap/Include"
"${CXBXR_ROOT_DIR}/import/xxHash"
)
link_directories(
"${CXBXR_ROOT_DIR}/import/distorm/lib/Win32"
"${CXBXR_ROOT_DIR}/import/glew-2.0.0/lib/Release/Win32"
"${CXBXR_ROOT_DIR}/import/DirectX9/lib"
"${CXBXR_ROOT_DIR}/import/winpcap/Lib"
)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_compile_definitions(
_CRT_SECURE_NO_WARNINGS
# Windows 7 minimum requirement
_WIN32_WINNT=0x0601
LTM_DESC
USE_LTM
LTC_NO_TEST
LTC_NO_CIPHERS
LTC_NO_HASHES
LTC_NO_MACS
LTC_NO_PRNGS
LTC_NO_MISC
LTC_NO_PROTOTYPES
# Use inline XXHash version
XXH_INLINE_ALL
# Enable Chihiro work
CHIHIRO_WORK
)
add_compile_options(
/EHs
/MP
/GF
/arch:SSE2
)
endif()
add_compile_definitions(
NOMINMAX
CXBXR_EMU
CXBXR_EMU_EXPORTS
)
file (GLOB RESOURCES
"${CXBXR_ROOT_DIR}/CONTRIBUTORS"
"${CXBXR_ROOT_DIR}/COPYING"
"${CXBXR_ROOT_DIR}/README.md"
)
source_group(TREE ${CXBXR_ROOT_DIR}/import PREFIX import FILES
${CXBXR_HEADER_EMU_IMPORT}
)
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES
${CXBXR_HEADER_GUIv1}
${CXBXR_HEADER_COMMON}
${CXBXR_HEADER_EMU}
"${CXBXR_ROOT_DIR}/src/emulator/targetver.h"
)
source_group(TREE ${CXBXR_ROOT_DIR}/import PREFIX import FILES
${CXBXR_SOURCE_EMU_IMPORT}
)
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES
${CXBXR_SOURCE_GUIv1}
${CXBXR_SOURCE_COMMON}
${CXBXR_SOURCE_EMU}
"${CXBXR_ROOT_DIR}/src/emulator/cxbxr-emu.cpp"
"${CXBXR_ROOT_DIR}/src/emulator/dllmain.cpp"
)
source_group(TREE ${CXBXR_ROOT_DIR} FILES ${RESOURCES})
add_library(cxbxr-emu SHARED ${RESOURCES}
${CXBXR_HEADER_COMMON}
${CXBXR_HEADER_EMU_IMPORT}
${CXBXR_HEADER_EMU}
"${CXBXR_ROOT_DIR}/src/emulator/targetver.h"
${CXBXR_SOURCE_COMMON}
${CXBXR_SOURCE_EMU_IMPORT}
${CXBXR_SOURCE_EMU}
${CXBXR_GIT_VERSION_H}
"${CXBXR_ROOT_DIR}/src/emulator/cxbxr-emu.cpp"
"${CXBXR_ROOT_DIR}/src/emulator/dllmain.cpp"
)
# Link and compile flags
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set_target_properties(cxbxr-emu PROPERTIES
LINK_FLAGS "
/INCREMENTAL:NO \
/LARGEADDRESSAWARE \
/SAFESEH:NO \
/STACK:65536,65536 \
/NODEFAULTLIB:libcmt \
/DELAYLOAD:wpcap.dll \
"
LINK_FLAGS_RELEASE "
/LTCG \
/DEBUG \
"
)
# Set optimization options for release build
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} \
/Zi \
/Ob3 \
/Oi \
/Ot \
/GL \
\
/GS- \
/Gy \
/Qpar \
"
)
endif()
# Windows libraries
set(WINS_LIB
legacy_stdio_definitions
d3d9
d3dcompiler
delayimp
dinput8
dxguid
odbc32
odbccp32
Shlwapi
dxerr9
ws2_32
dsound
winmm
ddraw
d3dx9
dbghelp
comctl32
XINPUT9_1_0
Iphlpapi
wpcap
)
target_link_libraries(cxbxr-emu
PUBLIC libXbSymbolDatabase
subhook
libtomcrypt
SDL2
imgui
libusb
nv2a_vsh_emulator
mio::mio_min_winapi
${WINS_LIB}
)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
)
add_dependencies(cxbxr-emu cxbxr-ldr misc-batch)
# Try to stop cmake from building hlsl files
# Which are all currently loaded at runtime only
set_source_files_properties(
${CXBXR_HEADER_HLSL}
PROPERTIES
HEADER_FILE_ONLY TRUE
VS_TOOL_OVERRIDE "None"
)

View File

@ -0,0 +1,75 @@
cmake_minimum_required (VERSION 3.12)
project(cxbxr-ldr)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)
# Suppress extra stuff from generated solution
set(CMAKE_SUPPRESS_REGENERATION true)
# Force exclude default libraries being included
set(CMAKE_CXX_STANDARD_LIBRARIES "")
# Force set BasicRunTimeChecks to default
STRING (REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_compile_definitions(
_CRT_SECURE_NO_WARNINGS
)
add_compile_options(
/sdl-
)
endif()
file (GLOB HEADERS
"${CXBXR_ROOT_DIR}/src/common/AddressRanges.h"
"${CXBXR_ROOT_DIR}/src/common/ReserveAddressRanges.h"
"${CXBXR_ROOT_DIR}/src/CxbxVersion.h"
"${CXBXR_ROOT_DIR}/src/version.h"
)
file (GLOB SOURCES
"${CXBXR_ROOT_DIR}/src/common/AddressRanges.cpp"
"${CXBXR_ROOT_DIR}/src/common/ReserveAddressRanges.cpp"
"${CXBXR_ROOT_DIR}/src/CxbxVersion.cpp"
"${CXBXR_ROOT_DIR}/src/loader/cxbxr-ldr.cpp"
)
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES ${HEADERS})
source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES ${SOURCES})
add_executable(cxbxr-ldr ${HEADERS} ${SOURCES})
# Link and compile flags
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set_target_properties(cxbxr-ldr PROPERTIES
LINK_FLAGS "
/LARGEADDRESSAWARE \
/FIXED \
/DYNAMICBASE:NO \
/BASE:0x10000 \
/STACK:65536,65536 \
/NODEFAULTLIB \
/ENTRY:rawMain \
"
)
# Set optimization options for release build
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} \
/Oi \
"
)
endif()
target_link_libraries(cxbxr-ldr
PUBLIC kernel32.lib
)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
)
add_dependencies(cxbxr-ldr misc-batch)

View File

@ -0,0 +1,42 @@
cmake_minimum_required (VERSION 3.8)
project(imgui LANGUAGES CXX)
# Since imgui doesn't have CMake, we'll make an interface project here.
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_compile_definitions(
_CRT_SECURE_NO_WARNINGS
_CRT_NONSTDC_NO_DEPRECATE
)
endif()
# Add any defines from imconfig.h file in here without need to edit import file directly.
add_compile_definitions(
IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
)
file (GLOB HEADERS
"${CXBXR_ROOT_DIR}/import/imgui/imconfig.h"
"${CXBXR_ROOT_DIR}/import/imgui/imgui.h"
"${CXBXR_ROOT_DIR}/import/imgui/imgui_internal.h"
"${CXBXR_ROOT_DIR}/import/imgui/imstb_rectpack.h"
"${CXBXR_ROOT_DIR}/import/imgui/imstb_textedit.h"
"${CXBXR_ROOT_DIR}/import/imgui/imstb_truetype.h"
)
file (GLOB SOURCES
"${CXBXR_ROOT_DIR}/import/imgui/imgui.cpp"
"${CXBXR_ROOT_DIR}/import/imgui/imgui_draw.cpp"
"${CXBXR_ROOT_DIR}/import/imgui/imgui_tables.cpp"
"${CXBXR_ROOT_DIR}/import/imgui/imgui_widgets.cpp"
)
source_group(TREE ${CXBXR_ROOT_DIR}/import/imgui PREFIX header FILES ${HEADERS})
source_group(TREE ${CXBXR_ROOT_DIR}/import/imgui PREFIX source FILES ${SOURCES})
add_library(${PROJECT_NAME} ${HEADERS} ${SOURCES})
target_include_directories(${PROJECT_NAME}
PUBLIC "${CXBXR_ROOT_DIR}/import/imgui"
)

View File

@ -17,11 +17,6 @@ add_compile_definitions(
LTC_NO_PROTOTYPES
)
include_directories(
"${CXBXR_ROOT_DIR}/import/libtommath"
"${CXBXR_ROOT_DIR}/import/libtomcrypt/src/headers"
)
file (GLOB HEADERS
"${CXBXR_ROOT_DIR}/import/libtomcrypt/src/headers/tomcrypt.h"
"${CXBXR_ROOT_DIR}/import/libtomcrypt/src/headers/tomcrypt_argchk.h"
@ -462,6 +457,10 @@ add_library(libtomcrypt ${HEADERS} ${SOURCES})
target_compile_definitions(libtomcrypt PUBLIC LTM_DESC=1)
target_include_directories(libtomcrypt
PUBLIC "${CXBXR_ROOT_DIR}/import/libtomcrypt/src/headers"
)
target_link_libraries(libtomcrypt
PUBLIC libtommath

View File

@ -11,11 +11,6 @@ if ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
)
endif()
include_directories(
"${CXBXR_ROOT_DIR}/import/libtommath"
)
file (GLOB HEADERS
"${CXBXR_ROOT_DIR}/import/libtommath/tommath.h"
"${CXBXR_ROOT_DIR}/import/libtommath/tommath_class.h"
@ -170,3 +165,7 @@ source_group(TREE ${CXBXR_ROOT_DIR}/import/libtommath PREFIX header FILES ${HEAD
source_group(TREE ${CXBXR_ROOT_DIR}/import/libtommath PREFIX source FILES ${SOURCES})
add_library(libtommath ${HEADERS} ${SOURCES})
target_include_directories(libtommath
PUBLIC "${CXBXR_ROOT_DIR}/import/libtommath"
)

View File

@ -0,0 +1,51 @@
cmake_minimum_required (VERSION 3.8)
project(libusb LANGUAGES CXX)
# Since libusb doesn't have CMake, we'll make an interface project here.
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_compile_definitions(
_CRT_SECURE_NO_WARNINGS
_CRT_NONSTDC_NO_DEPRECATE
)
endif()
include_directories(
"${CXBXR_ROOT_DIR}/import/libusb/msvc"
"${CXBXR_ROOT_DIR}/import/libusb/libusb")
file (GLOB HEADERS
"${CXBXR_ROOT_DIR}/import/libusb/libusb/libusb.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/libusbi.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/version.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/version_nano.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/msvc/config.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/events_windows.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/threads_windows.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/windows_common.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/windows_usbdk.h"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/windows_winusb.h"
)
file (GLOB SOURCES
"${CXBXR_ROOT_DIR}/import/libusb/libusb/core.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/descriptor.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/hotplug.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/io.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/strerror.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/sync.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/events_windows.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/threads_windows.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/windows_common.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/windows_usbdk.c"
"${CXBXR_ROOT_DIR}/import/libusb/libusb/os/windows_winusb.c"
)
source_group(TREE ${CXBXR_ROOT_DIR}/import/libusb/libusb PREFIX header FILES ${HEADERS})
source_group(TREE ${CXBXR_ROOT_DIR}/import/libusb/libusb PREFIX source FILES ${SOURCES})
add_library(${PROJECT_NAME} ${HEADERS} ${SOURCES})
target_include_directories(${PROJECT_NAME}
PUBLIC "${CXBXR_ROOT_DIR}/import/libusb"
)

29
projects/misc/batch.cmake Normal file
View File

@ -0,0 +1,29 @@
find_package(Git)
if(Git_FOUND)
message("Git found: ${GIT_EXECUTABLE}")
execute_process(
COMMAND git describe --always --tags --first-parent --dirty
OUTPUT_VARIABLE _GIT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message("Git version: " ${_GIT_VERSION})
else()
set(_GIT_VERSION "unknown")
endif()
# Appears to update whenever define has changed.
configure_file(
"${CMAKE_SOURCE_DIR}/src/version.h.in" "${CMAKE_SOURCE_DIR}/src/version.h" @ONLY
NEWLINE_STYLE LF
)
message("Runtime Build Directory: ${TargetRunTimeDir}")
# Copy glew32.dll to build type's folder.
set(CXBXR_GLEW_DLL "${CMAKE_SOURCE_DIR}/import/glew-2.0.0/bin/Release/Win32/glew32.dll")
file(COPY ${CXBXR_GLEW_DLL} DESTINATION ${TargetRunTimeDir})

View File

@ -1,40 +0,0 @@
cmake_minimum_required (VERSION 3.8)
project(vsbc)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
# Suppress extra stuff from generated solution
set(CMAKE_SUPPRESS_REGENERATION true)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_compile_definitions(_CRT_SECURE_NO_WARNINGS
)
endif()
add_compile_definitions(CXBXVSBC_EXPORTS
)
file (GLOB HEADERS
"${CXBXR_ROOT_DIR}/src/vsbc/CxbxVSBC.h"
"${CXBXR_ROOT_DIR}/src/vsbc/DlgVirtualSBCFeedback.h"
"${CXBXR_ROOT_DIR}/src/vsbc/stdafx.h"
"${CXBXR_ROOT_DIR}/src/vsbc/targetver.h"
)
file (GLOB SOURCES
"${CXBXR_ROOT_DIR}/src/vsbc/CxbxVSBC.cpp"
"${CXBXR_ROOT_DIR}/src/vsbc/DlgVirtualSBCFeedback.cpp"
"${CXBXR_ROOT_DIR}/src/vsbc/dllmain.cpp"
"${CXBXR_ROOT_DIR}/src/vsbc/stdafx.cpp"
)
source_group(TREE ${CXBXR_ROOT_DIR}/src/vsbc PREFIX header FILES ${HEADERS})
source_group(TREE ${CXBXR_ROOT_DIR}/src/vsbc PREFIX source FILES ${SOURCES})
add_library(vsbc SHARED ${HEADERS} ${SOURCES})
set_target_properties(vsbc PROPERTIES
OUTPUT_NAME CxbxVSBC
)

View File

@ -1,26 +1,26 @@
@echo off
REM CXbx-Reloaded setup script
REM
REM Depends on git, cmake and Visual Studio being installed.
echo Pulling lastest version from git...
REM git clone --recurse-submodules https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/
git pull --recurse-submodules
REM echo Synchronizing submodules...
REM git submodule update --init --recursive
echo Initializing most recent Visual Studio build environment...
@call "%VS140COMNTOOLS%vsvars32.bat"
echo Generating solution...
mkdir build
cd build
REM cmake .. -G "Visual Studio 16 2019" -A Win32
cmake .. -A Win32
echo Building solution...
cmake --build .
echo Done! Enjoy using Cxbx-Reloaded!
@echo off
REM Cxbx-Reloaded setup script
REM
REM Depends on git, cmake and Visual Studio being installed.
echo Pulling latest version from git...
REM git clone --recurse-submodules https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/
git pull --recurse-submodules
REM echo Synchronizing submodules...
REM git submodule update --init --recursive
echo Initializing most recent Visual Studio build environment...
@call "%VS140COMNTOOLS%vsvars32.bat"
echo Generating solution...
mkdir build
cd build
REM cmake .. -G "Visual Studio 16 2019" -A Win32
cmake .. -A Win32
echo Building solution...
cmake --build . -j %NUMBER_OF_PROCESSORS%
echo Done! Enjoy using Cxbx-Reloaded!

View File

@ -3,5 +3,5 @@ root = true
[*]
indent_size = 4
trim_trailing_whitespace = true
end_of_line = crlf
end_of_line = lf
insert_final_newline = true

View File

@ -27,14 +27,7 @@
#include <cstdint>
/*! xbaddr is the type of a physical address */
typedef uint32_t xbaddr;
/*! xbnullptr is the type of null pointer address*/
#define xbnullptr nullptr
/*! xbnull is the type of null address or value*/
#define xbnull 0
#define FUNC_EXPORTS __pragma(comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__))
#ifdef _DEBUG
/*! define this to track memory allocations */
@ -68,18 +61,14 @@ enum DebugMode { DM_NONE, DM_CONSOLE, DM_FILE };
/*! debugger enable state */
enum DebuggerState { debuggerOff, debuggerOn };
/*! type of Xbe */
enum XbeType { xtRetail, xtDebug, xtChihiro };
extern XbeType g_XbeType;
/*! indicates emulation of an Chihiro (arcade, instead of Xbox console) executable */
/*! indicates emulation of a Chihiro system */
extern bool g_bIsChihiro;
/*! indicates emulation of a Debug xbe executable */
extern bool g_bIsDebug;
/*! indicates emulation of a DevKit system */
/* Note: Our DevKit emulation lacks the kernel debugging interface and virtual dvd-rom emulator card, so this is actually a Debug Kit */
extern bool g_bIsDevKit;
/*! indicates emulation of a Retail xbe executable*/
/*! indicates emulation of a Retail system */
extern bool g_bIsRetail;
/*! indicates ability to save on exit (needed for settings reset) */
@ -95,6 +84,4 @@ extern volatile bool g_bPrintfOn;
#define CxbxSetThreadName(Name)
#endif
#include <filesystem>
#endif

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
<supportedRuntime version="v4.8" sku=".NETFramework,Version=v4.8"/>
</startup>
</configuration>

View File

@ -13,6 +13,12 @@ add_compile_options(
/langversion:6
)
# First, we must define .NET Framework version before include cs_x86's projects.
# Which then will pass down version we want unified.
set(DOTNET_TARGET_FRAMEWORK_VERSION "v4.8")
add_subdirectory("${CXBXR_ROOT_DIR}/import/cs_x86" "${CMAKE_BINARY_DIR}/import/cs_x86")
set(CXBXR_DEBUGGER_SRC_DIR "${CXBXR_ROOT_DIR}/src/CxbxDebugger")
file (GLOB SOURCES
@ -37,16 +43,15 @@ file (GLOB SOURCES
"${CXBXR_DEBUGGER_SRC_DIR}/DebugOutputManager.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/FileEventManager.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/FileWatchManager.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Form1.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Form1.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Form1.resx"
"${CXBXR_DEBUGGER_SRC_DIR}/IDebugWindow.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerInstance.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerInstance.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerInstance.resx"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerMain.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerMain.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerMain.resx"
"${CXBXR_DEBUGGER_SRC_DIR}/PatchManager.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Program.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/AssemblyInfo.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/Resources.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/Resources.resx"
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/Settings.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/Settings.settings"
"${CXBXR_DEBUGGER_SRC_DIR}/Resources/BreakpointDisable_16x_24.bmp"
"${CXBXR_DEBUGGER_SRC_DIR}/Resources/BreakpointEnable_16x_24.bmp"
"${CXBXR_DEBUGGER_SRC_DIR}/Resources/Pause_16x_24.bmp"
@ -92,10 +97,8 @@ file (GLOB SOURCES
"${CXBXR_DEBUGGER_SRC_DIR}/Win32/Windows/NativeMethods.cs"
)
csharp_set_windows_forms_properties(
"${CXBXR_DEBUGGER_SRC_DIR}/Form1.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Form1.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Form1.resx"
file (GLOB PROPERTIES
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/Settings.settings"
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/AssemblyInfo.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/Resources.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/Resources.resx"
@ -103,7 +106,22 @@ csharp_set_windows_forms_properties(
"${CXBXR_DEBUGGER_SRC_DIR}/Properties/Settings.settings"
)
set_source_files_properties("${CXBXR_DEBUGGER_SRC_DIR}/Form1.cs"
csharp_set_windows_forms_properties(
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerInstance.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerInstance.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerInstance.resx"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerMain.Designer.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerMain.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerMain.resx"
)
csharp_set_designer_cs_properties(
${PROPERTIES}
)
set_source_files_properties(
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerInstance.cs"
"${CXBXR_DEBUGGER_SRC_DIR}/CxbxDebuggerMain.cs"
VS_CSHARP_SubType "Form"
)
@ -113,18 +131,21 @@ set_source_files_properties("${CXBXR_DEBUGGER_SRC_DIR}/RicherTextBox.cs"
source_group(TREE ${CXBXR_ROOT_DIR} FILES ${SOURCES})
add_executable(cxbxr-debugger WIN32 ${SOURCES} #Test WIN32 like cxbx does if doesn't need compile option set
add_executable(cxbxr-debugger WIN32 ${SOURCES} ${PROPERTIES} #Test WIN32 like cxbx does if doesn't need compile option set
)
set_target_properties(cxbxr-debugger PROPERTIES
set_target_properties(cxbxr-debugger PROPERTIES
VS_DOTNET_REFERENCES
"Microsoft.CSharp;System;System.Core;System.Data;System.Data.DataSetExtensions;System.Deployment;System.Drawing;System.Windows;System.Windows.Forms;System.Xml;System.Xml.Linq;System.Net.Http"
VS_GLOBAL_ApplicationIcon "${CXBXR_ROOT_DIR}/resource/Cxbx-R.ico"
VS_GLOBAL_ApplicationIcon "${CXBXR_ROOT_DIR}/src/gui/resource/Cxbx-R.ico"
VS_GLOBAL_ROOTNAMESPACE "CxbxDebugger"
DOTNET_TARGET_FRAMEWORK_VERSION ${DOTNET_TARGET_FRAMEWORK_VERSION}
)
set_property(TARGET cxbxr-debugger PROPERTY DOTNET_TARGET_FRAMEWORK_VERSION "v4.5")
target_link_libraries(cxbxr-debugger cs_x86)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
)

View File

@ -1,6 +1,6 @@
namespace CxbxDebugger
{
partial class Form1
partial class CxbxDebuggerInstance
{
/// <summary>
/// Required designer variable.
@ -28,22 +28,21 @@
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CxbxDebuggerInstance));
this.lbConsole = new System.Windows.Forms.ListBox();
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.btnStart = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.btnSuspend = new System.Windows.Forms.ToolStripButton();
this.btnResume = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel();
this.cbThreads = new System.Windows.Forms.ToolStripComboBox();
this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel();
this.cbFrames = new System.Windows.Forms.ToolStripComboBox();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.statusBar = new System.Windows.Forms.StatusStrip();
this.lblStatus = new System.Windows.Forms.ToolStripStatusLabel();
this.tabContainer = new System.Windows.Forms.TabControl();
this.tabSummary = new System.Windows.Forms.TabPage();
this.linkLabel3 = new System.Windows.Forms.LinkLabel();
this.linkLabel2 = new System.Windows.Forms.LinkLabel();
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
this.label9 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.tabDisassembly = new System.Windows.Forms.TabPage();
this.splitContainer2 = new System.Windows.Forms.SplitContainer();
this.btnToMemory = new System.Windows.Forms.Button();
@ -52,7 +51,6 @@
this.btnGo = new System.Windows.Forms.Button();
this.label6 = new System.Windows.Forms.Label();
this.cbDisAddr = new System.Windows.Forms.ComboBox();
this.txDisassembly = new CxbxDebugger.RicherTextBox();
this.tabBreakpoints = new System.Windows.Forms.TabPage();
this.splitContainer3 = new System.Windows.Forms.SplitContainer();
this.groupBox4 = new System.Windows.Forms.GroupBox();
@ -112,10 +110,11 @@
this.lbDebug = new System.Windows.Forms.ListBox();
this.diagSaveMemory = new System.Windows.Forms.SaveFileDialog();
this.diagBrowseCT = new System.Windows.Forms.OpenFileDialog();
this.txDisassembly = new CxbxDebugger.RicherTextBox();
this.toolStrip1.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.statusBar.SuspendLayout();
this.tabContainer.SuspendLayout();
this.tabSummary.SuspendLayout();
this.tabDisassembly.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
this.splitContainer2.Panel1.SuspendLayout();
@ -158,73 +157,33 @@
//
this.lbConsole.Dock = System.Windows.Forms.DockStyle.Fill;
this.lbConsole.FormattingEnabled = true;
this.lbConsole.Location = new System.Drawing.Point(3, 231);
this.lbConsole.Location = new System.Drawing.Point(3, 271);
this.lbConsole.Name = "lbConsole";
this.lbConsole.ScrollAlwaysVisible = true;
this.lbConsole.Size = new System.Drawing.Size(728, 51);
this.lbConsole.Size = new System.Drawing.Size(728, 62);
this.lbConsole.TabIndex = 2;
//
// toolStrip1
//
this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.toolStrip1.ImageScalingSize = new System.Drawing.Size(24, 24);
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.btnStart,
this.toolStripSeparator1,
this.btnSuspend,
this.btnResume,
this.toolStripSeparator2,
this.toolStripLabel1,
this.cbThreads,
this.toolStripLabel2,
this.cbFrames});
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Padding = new System.Windows.Forms.Padding(0, 0, 2, 0);
this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
this.toolStrip1.Size = new System.Drawing.Size(734, 25);
this.toolStrip1.TabIndex = 7;
this.toolStrip1.Text = "toolStrip1";
//
// btnStart
//
this.btnStart.Image = global::CxbxDebugger.Properties.Resources.run;
this.btnStart.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(51, 22);
this.btnStart.Text = "Start";
this.btnStart.Click += new System.EventHandler(this.toolStripButton1_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
//
// btnSuspend
//
this.btnSuspend.Image = global::CxbxDebugger.Properties.Resources.pause;
this.btnSuspend.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnSuspend.Name = "btnSuspend";
this.btnSuspend.Size = new System.Drawing.Size(72, 22);
this.btnSuspend.Text = "Suspend";
this.btnSuspend.Click += new System.EventHandler(this.toolStripButton2_Click);
//
// btnResume
//
this.btnResume.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.btnResume.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnResume.Name = "btnResume";
this.btnResume.Size = new System.Drawing.Size(53, 22);
this.btnResume.Text = "Resume";
this.btnResume.Click += new System.EventHandler(this.toolStripButton3_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
//
// toolStripLabel1
//
this.toolStripLabel1.Name = "toolStripLabel1";
this.toolStripLabel1.Size = new System.Drawing.Size(47, 22);
this.toolStripLabel1.Size = new System.Drawing.Size(46, 22);
this.toolStripLabel1.Text = "Thread:";
//
// cbThreads
@ -244,45 +203,28 @@
//
this.cbFrames.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbFrames.Name = "cbFrames";
this.cbFrames.Size = new System.Drawing.Size(200, 25);
this.cbFrames.Size = new System.Drawing.Size(135, 25);
this.cbFrames.SelectedIndexChanged += new System.EventHandler(this.cbFrames_SelectedIndexChanged);
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 1;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Controls.Add(this.statusBar, 0, 2);
this.tableLayoutPanel3.Controls.Add(this.tabContainer, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.lbConsole, 0, 1);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 25);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 3;
this.tableLayoutPanel3.RowCount = 2;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 80F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(734, 306);
this.tableLayoutPanel3.Size = new System.Drawing.Size(734, 336);
this.tableLayoutPanel3.TabIndex = 9;
//
// statusBar
//
this.statusBar.Dock = System.Windows.Forms.DockStyle.Fill;
this.statusBar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.lblStatus});
this.statusBar.Location = new System.Drawing.Point(0, 285);
this.statusBar.Name = "statusBar";
this.statusBar.Size = new System.Drawing.Size(734, 21);
this.statusBar.TabIndex = 10;
this.statusBar.Text = "statusStrip1";
//
// lblStatus
//
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(39, 16);
this.lblStatus.Text = "Ready";
//
// tabContainer
//
this.tabContainer.Controls.Add(this.tabSummary);
this.tabContainer.Controls.Add(this.tabDisassembly);
this.tabContainer.Controls.Add(this.tabBreakpoints);
this.tabContainer.Controls.Add(this.tabWatch);
@ -294,16 +236,82 @@
this.tabContainer.Multiline = true;
this.tabContainer.Name = "tabContainer";
this.tabContainer.SelectedIndex = 0;
this.tabContainer.Size = new System.Drawing.Size(728, 222);
this.tabContainer.Size = new System.Drawing.Size(728, 262);
this.tabContainer.TabIndex = 3;
//
// tabSummary
//
this.tabSummary.Controls.Add(this.linkLabel3);
this.tabSummary.Controls.Add(this.linkLabel2);
this.tabSummary.Controls.Add(this.linkLabel1);
this.tabSummary.Controls.Add(this.label9);
this.tabSummary.Controls.Add(this.label7);
this.tabSummary.Location = new System.Drawing.Point(4, 22);
this.tabSummary.Name = "tabSummary";
this.tabSummary.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabSummary.Size = new System.Drawing.Size(654, 318);
this.tabSummary.TabIndex = 6;
this.tabSummary.Text = "Summary";
this.tabSummary.UseVisualStyleBackColor = true;
//
// linkLabel3
//
this.linkLabel3.AutoSize = true;
this.linkLabel3.Location = new System.Drawing.Point(11, 112);
this.linkLabel3.Name = "linkLabel3";
this.linkLabel3.Size = new System.Drawing.Size(89, 13);
this.linkLabel3.TabIndex = 5;
this.linkLabel3.TabStop = true;
this.linkLabel3.Text = "View disassembly";
this.linkLabel3.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel3_LinkClicked);
//
// linkLabel2
//
this.linkLabel2.AutoSize = true;
this.linkLabel2.Location = new System.Drawing.Point(11, 85);
this.linkLabel2.Name = "linkLabel2";
this.linkLabel2.Size = new System.Drawing.Size(69, 13);
this.linkLabel2.TabIndex = 4;
this.linkLabel2.TabStop = true;
this.linkLabel2.Text = "View memory";
this.linkLabel2.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel2_LinkClicked);
//
// linkLabel1
//
this.linkLabel1.AutoSize = true;
this.linkLabel1.Location = new System.Drawing.Point(11, 60);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(95, 13);
this.linkLabel1.TabIndex = 3;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "View file resources";
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
//
// label9
//
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(9, 35);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(268, 13);
this.label9.TabIndex = 1;
this.label9.Text = "To get started, select Debug->Start from the main menu";
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(11, 6);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(155, 13);
this.label7.TabIndex = 0;
this.label7.Text = "Welcome to the cxbx-debugger";
//
// tabDisassembly
//
this.tabDisassembly.Controls.Add(this.splitContainer2);
this.tabDisassembly.Location = new System.Drawing.Point(4, 22);
this.tabDisassembly.Name = "tabDisassembly";
this.tabDisassembly.Padding = new System.Windows.Forms.Padding(3);
this.tabDisassembly.Size = new System.Drawing.Size(720, 196);
this.tabDisassembly.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabDisassembly.Size = new System.Drawing.Size(654, 318);
this.tabDisassembly.TabIndex = 0;
this.tabDisassembly.Text = "Disassembly";
this.tabDisassembly.UseVisualStyleBackColor = true;
@ -329,14 +337,14 @@
// splitContainer2.Panel2
//
this.splitContainer2.Panel2.Controls.Add(this.txDisassembly);
this.splitContainer2.Size = new System.Drawing.Size(714, 190);
this.splitContainer2.Size = new System.Drawing.Size(648, 312);
this.splitContainer2.SplitterDistance = 34;
this.splitContainer2.TabIndex = 2;
//
// btnToMemory
//
this.btnToMemory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnToMemory.Location = new System.Drawing.Point(452, 3);
this.btnToMemory.Location = new System.Drawing.Point(386, 3);
this.btnToMemory.Name = "btnToMemory";
this.btnToMemory.Size = new System.Drawing.Size(119, 23);
this.btnToMemory.TabIndex = 4;
@ -347,7 +355,7 @@
// btnNext
//
this.btnNext.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnNext.Location = new System.Drawing.Point(647, 3);
this.btnNext.Location = new System.Drawing.Point(581, 3);
this.btnNext.Name = "btnNext";
this.btnNext.Size = new System.Drawing.Size(64, 23);
this.btnNext.TabIndex = 3;
@ -358,7 +366,7 @@
// btnPrev
//
this.btnPrev.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnPrev.Location = new System.Drawing.Point(577, 3);
this.btnPrev.Location = new System.Drawing.Point(512, 3);
this.btnPrev.Name = "btnPrev";
this.btnPrev.Size = new System.Drawing.Size(64, 23);
this.btnPrev.TabIndex = 2;
@ -369,7 +377,7 @@
// btnGo
//
this.btnGo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnGo.Location = new System.Drawing.Point(327, 3);
this.btnGo.Location = new System.Drawing.Point(261, 3);
this.btnGo.Name = "btnGo";
this.btnGo.Size = new System.Drawing.Size(119, 23);
this.btnGo.TabIndex = 1;
@ -393,33 +401,18 @@
this.cbDisAddr.FormattingEnabled = true;
this.cbDisAddr.Location = new System.Drawing.Point(132, 5);
this.cbDisAddr.Name = "cbDisAddr";
this.cbDisAddr.Size = new System.Drawing.Size(189, 21);
this.cbDisAddr.Size = new System.Drawing.Size(124, 21);
this.cbDisAddr.TabIndex = 0;
this.cbDisAddr.SelectedIndexChanged += new System.EventHandler(this.cbDisAddr_SelectedIndexChanged);
this.cbDisAddr.KeyDown += new System.Windows.Forms.KeyEventHandler(this.comboBox1_KeyDown);
//
// txDisassembly
//
this.txDisassembly.BackColor = System.Drawing.SystemColors.Window;
this.txDisassembly.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.txDisassembly.Cursor = System.Windows.Forms.Cursors.Default;
this.txDisassembly.Dock = System.Windows.Forms.DockStyle.Fill;
this.txDisassembly.Font = new System.Drawing.Font("Lucida Console", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txDisassembly.Location = new System.Drawing.Point(0, 0);
this.txDisassembly.Name = "txDisassembly";
this.txDisassembly.ReadOnly = true;
this.txDisassembly.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical;
this.txDisassembly.Size = new System.Drawing.Size(714, 152);
this.txDisassembly.TabIndex = 1;
this.txDisassembly.Text = "";
//
// tabBreakpoints
//
this.tabBreakpoints.Controls.Add(this.splitContainer3);
this.tabBreakpoints.Location = new System.Drawing.Point(4, 22);
this.tabBreakpoints.Name = "tabBreakpoints";
this.tabBreakpoints.Padding = new System.Windows.Forms.Padding(3);
this.tabBreakpoints.Size = new System.Drawing.Size(720, 196);
this.tabBreakpoints.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabBreakpoints.Size = new System.Drawing.Size(654, 318);
this.tabBreakpoints.TabIndex = 1;
this.tabBreakpoints.Text = "Breakpoints";
this.tabBreakpoints.UseVisualStyleBackColor = true;
@ -438,8 +431,8 @@
// splitContainer3.Panel2
//
this.splitContainer3.Panel2.Controls.Add(this.clbBreakpoints);
this.splitContainer3.Size = new System.Drawing.Size(714, 190);
this.splitContainer3.SplitterDistance = 237;
this.splitContainer3.Size = new System.Drawing.Size(648, 312);
this.splitContainer3.SplitterDistance = 214;
this.splitContainer3.TabIndex = 5;
//
// groupBox4
@ -451,7 +444,7 @@
this.groupBox4.Controls.Add(this.cbBreakpointCxbx);
this.groupBox4.Location = new System.Drawing.Point(2, 112);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(233, 75);
this.groupBox4.Size = new System.Drawing.Size(210, 196);
this.groupBox4.TabIndex = 5;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "Interrupts";
@ -489,7 +482,7 @@
this.groupBox1.Controls.Add(this.tbFilter);
this.groupBox1.Location = new System.Drawing.Point(0, 0);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(234, 106);
this.groupBox1.Size = new System.Drawing.Size(211, 106);
this.groupBox1.TabIndex = 4;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "File Watch";
@ -502,7 +495,7 @@
this.cbAction.FormattingEnabled = true;
this.cbAction.Location = new System.Drawing.Point(89, 45);
this.cbAction.Name = "cbAction";
this.cbAction.Size = new System.Drawing.Size(139, 21);
this.cbAction.Size = new System.Drawing.Size(115, 21);
this.cbAction.TabIndex = 6;
//
// label5
@ -529,7 +522,7 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.btnAddFileBp.Location = new System.Drawing.Point(89, 72);
this.btnAddFileBp.Name = "btnAddFileBp";
this.btnAddFileBp.Size = new System.Drawing.Size(139, 23);
this.btnAddFileBp.Size = new System.Drawing.Size(115, 23);
this.btnAddFileBp.TabIndex = 4;
this.btnAddFileBp.Text = "Add";
this.btnAddFileBp.UseVisualStyleBackColor = true;
@ -541,7 +534,7 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.tbFilter.Location = new System.Drawing.Point(89, 19);
this.tbFilter.Name = "tbFilter";
this.tbFilter.Size = new System.Drawing.Size(139, 20);
this.tbFilter.Size = new System.Drawing.Size(115, 20);
this.tbFilter.TabIndex = 2;
//
// clbBreakpoints
@ -550,7 +543,7 @@
this.clbBreakpoints.FormattingEnabled = true;
this.clbBreakpoints.Location = new System.Drawing.Point(0, 0);
this.clbBreakpoints.Name = "clbBreakpoints";
this.clbBreakpoints.Size = new System.Drawing.Size(473, 190);
this.clbBreakpoints.Size = new System.Drawing.Size(430, 312);
this.clbBreakpoints.TabIndex = 0;
this.clbBreakpoints.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.clbBreakpoints_ItemCheck);
this.clbBreakpoints.KeyDown += new System.Windows.Forms.KeyEventHandler(this.clbBreakpoints_KeyDown);
@ -560,8 +553,8 @@
this.tabWatch.Controls.Add(this.splitContainer1);
this.tabWatch.Location = new System.Drawing.Point(4, 22);
this.tabWatch.Name = "tabWatch";
this.tabWatch.Padding = new System.Windows.Forms.Padding(3);
this.tabWatch.Size = new System.Drawing.Size(720, 196);
this.tabWatch.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabWatch.Size = new System.Drawing.Size(654, 318);
this.tabWatch.TabIndex = 2;
this.tabWatch.Text = "File Watcher";
this.tabWatch.UseVisualStyleBackColor = true;
@ -579,8 +572,8 @@
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.lbOpenedFiles);
this.splitContainer1.Size = new System.Drawing.Size(714, 190);
this.splitContainer1.SplitterDistance = 501;
this.splitContainer1.Size = new System.Drawing.Size(648, 312);
this.splitContainer1.SplitterDistance = 453;
this.splitContainer1.TabIndex = 3;
//
// lvFileDetails
@ -595,7 +588,7 @@
this.lvFileDetails.Location = new System.Drawing.Point(0, 0);
this.lvFileDetails.MultiSelect = false;
this.lvFileDetails.Name = "lvFileDetails";
this.lvFileDetails.Size = new System.Drawing.Size(501, 190);
this.lvFileDetails.Size = new System.Drawing.Size(453, 312);
this.lvFileDetails.TabIndex = 2;
this.lvFileDetails.UseCompatibleStateImageBehavior = false;
this.lvFileDetails.View = System.Windows.Forms.View.Details;
@ -621,7 +614,7 @@
this.lbOpenedFiles.FormattingEnabled = true;
this.lbOpenedFiles.Location = new System.Drawing.Point(0, 0);
this.lbOpenedFiles.Name = "lbOpenedFiles";
this.lbOpenedFiles.Size = new System.Drawing.Size(209, 190);
this.lbOpenedFiles.Size = new System.Drawing.Size(191, 312);
this.lbOpenedFiles.TabIndex = 0;
//
// tabMemory
@ -629,8 +622,8 @@
this.tabMemory.Controls.Add(this.splitContainer4);
this.tabMemory.Location = new System.Drawing.Point(4, 22);
this.tabMemory.Name = "tabMemory";
this.tabMemory.Padding = new System.Windows.Forms.Padding(3);
this.tabMemory.Size = new System.Drawing.Size(720, 196);
this.tabMemory.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabMemory.Size = new System.Drawing.Size(720, 236);
this.tabMemory.TabIndex = 4;
this.tabMemory.Text = "Memory Viewer";
this.tabMemory.UseVisualStyleBackColor = true;
@ -648,8 +641,8 @@
// splitContainer4.Panel2
//
this.splitContainer4.Panel2.Controls.Add(this.groupBox2);
this.splitContainer4.Size = new System.Drawing.Size(714, 190);
this.splitContainer4.SplitterDistance = 376;
this.splitContainer4.Size = new System.Drawing.Size(714, 230);
this.splitContainer4.SplitterDistance = 375;
this.splitContainer4.TabIndex = 7;
//
// txMemoryDump
@ -663,7 +656,7 @@
this.txMemoryDump.Name = "txMemoryDump";
this.txMemoryDump.ReadOnly = true;
this.txMemoryDump.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txMemoryDump.Size = new System.Drawing.Size(376, 190);
this.txMemoryDump.Size = new System.Drawing.Size(375, 230);
this.txMemoryDump.TabIndex = 0;
//
// groupBox2
@ -681,7 +674,7 @@
this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox2.Location = new System.Drawing.Point(0, 0);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(334, 190);
this.groupBox2.Size = new System.Drawing.Size(335, 230);
this.groupBox2.TabIndex = 8;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "View or Dump Memory";
@ -690,9 +683,9 @@
//
this.textBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox2.Location = new System.Drawing.Point(213, 129);
this.textBox2.Location = new System.Drawing.Point(183, 129);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(115, 20);
this.textBox2.Size = new System.Drawing.Size(146, 20);
this.textBox2.TabIndex = 10;
//
// label8
@ -706,13 +699,11 @@
//
// cbDataFormat
//
this.cbDataFormat.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.cbDataFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbDataFormat.FormattingEnabled = true;
this.cbDataFormat.Location = new System.Drawing.Point(88, 130);
this.cbDataFormat.Name = "cbDataFormat";
this.cbDataFormat.Size = new System.Drawing.Size(119, 21);
this.cbDataFormat.Size = new System.Drawing.Size(89, 21);
this.cbDataFormat.TabIndex = 8;
this.cbDataFormat.SelectionChangeCommitted += new System.EventHandler(this.cbDataFormat_SelectionChangeCommitted);
//
@ -722,7 +713,7 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.btnAddWatch.Location = new System.Drawing.Point(88, 157);
this.btnAddWatch.Name = "btnAddWatch";
this.btnAddWatch.Size = new System.Drawing.Size(240, 23);
this.btnAddWatch.Size = new System.Drawing.Size(241, 23);
this.btnAddWatch.TabIndex = 7;
this.btnAddWatch.Text = "Add to Editor...";
this.btnAddWatch.UseVisualStyleBackColor = true;
@ -743,7 +734,7 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.btnDumpMemory.Location = new System.Drawing.Point(88, 100);
this.btnDumpMemory.Name = "btnDumpMemory";
this.btnDumpMemory.Size = new System.Drawing.Size(240, 23);
this.btnDumpMemory.Size = new System.Drawing.Size(241, 23);
this.btnDumpMemory.TabIndex = 6;
this.btnDumpMemory.Text = "Dump Memory to File...";
this.btnDumpMemory.UseVisualStyleBackColor = true;
@ -755,7 +746,7 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.txAddress.Location = new System.Drawing.Point(88, 18);
this.txAddress.Name = "txAddress";
this.txAddress.Size = new System.Drawing.Size(240, 20);
this.txAddress.Size = new System.Drawing.Size(241, 20);
this.txAddress.TabIndex = 1;
//
// label2
@ -773,7 +764,7 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.btnReadMemory.Location = new System.Drawing.Point(88, 71);
this.btnReadMemory.Name = "btnReadMemory";
this.btnReadMemory.Size = new System.Drawing.Size(240, 23);
this.btnReadMemory.Size = new System.Drawing.Size(241, 23);
this.btnReadMemory.TabIndex = 2;
this.btnReadMemory.Text = "Read Memory";
this.btnReadMemory.UseVisualStyleBackColor = true;
@ -785,7 +776,7 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.txSize.Location = new System.Drawing.Point(88, 45);
this.txSize.Name = "txSize";
this.txSize.Size = new System.Drawing.Size(240, 20);
this.txSize.Size = new System.Drawing.Size(241, 20);
this.txSize.TabIndex = 3;
this.txSize.Text = "32";
//
@ -794,8 +785,8 @@
this.tabTweaks.Controls.Add(this.tabCEContainer);
this.tabTweaks.Location = new System.Drawing.Point(4, 22);
this.tabTweaks.Name = "tabTweaks";
this.tabTweaks.Padding = new System.Windows.Forms.Padding(3);
this.tabTweaks.Size = new System.Drawing.Size(720, 196);
this.tabTweaks.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabTweaks.Size = new System.Drawing.Size(654, 318);
this.tabTweaks.TabIndex = 5;
this.tabTweaks.Text = "Memory Editor";
this.tabTweaks.UseVisualStyleBackColor = true;
@ -808,7 +799,7 @@
this.tabCEContainer.Location = new System.Drawing.Point(3, 3);
this.tabCEContainer.Name = "tabCEContainer";
this.tabCEContainer.SelectedIndex = 0;
this.tabCEContainer.Size = new System.Drawing.Size(714, 190);
this.tabCEContainer.Size = new System.Drawing.Size(648, 312);
this.tabCEContainer.TabIndex = 5;
//
// tabSubData
@ -816,8 +807,8 @@
this.tabSubData.Controls.Add(this.splitContainer6);
this.tabSubData.Location = new System.Drawing.Point(4, 22);
this.tabSubData.Name = "tabSubData";
this.tabSubData.Padding = new System.Windows.Forms.Padding(3);
this.tabSubData.Size = new System.Drawing.Size(706, 164);
this.tabSubData.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabSubData.Size = new System.Drawing.Size(640, 286);
this.tabSubData.TabIndex = 0;
this.tabSubData.Text = "Edit Data";
this.tabSubData.UseVisualStyleBackColor = true;
@ -839,8 +830,8 @@
// splitContainer6.Panel2
//
this.splitContainer6.Panel2.Controls.Add(this.lvCEMemory);
this.splitContainer6.Size = new System.Drawing.Size(700, 158);
this.splitContainer6.SplitterDistance = 34;
this.splitContainer6.Size = new System.Drawing.Size(634, 280);
this.splitContainer6.SplitterDistance = 57;
this.splitContainer6.TabIndex = 2;
//
// btnRefresh
@ -866,7 +857,7 @@
// btnApply
//
this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnApply.Location = new System.Drawing.Point(574, 3);
this.btnApply.Location = new System.Drawing.Point(508, 3);
this.btnApply.Name = "btnApply";
this.btnApply.Size = new System.Drawing.Size(123, 23);
this.btnApply.TabIndex = 4;
@ -880,7 +871,7 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.txNewValue.Location = new System.Drawing.Point(261, 5);
this.txNewValue.Name = "txNewValue";
this.txNewValue.Size = new System.Drawing.Size(307, 20);
this.txNewValue.Size = new System.Drawing.Size(240, 20);
this.txNewValue.TabIndex = 2;
//
// lvCEMemory
@ -896,7 +887,7 @@
this.lvCEMemory.Location = new System.Drawing.Point(0, 0);
this.lvCEMemory.MultiSelect = false;
this.lvCEMemory.Name = "lvCEMemory";
this.lvCEMemory.Size = new System.Drawing.Size(700, 120);
this.lvCEMemory.Size = new System.Drawing.Size(634, 219);
this.lvCEMemory.TabIndex = 1;
this.lvCEMemory.UseCompatibleStateImageBehavior = false;
this.lvCEMemory.View = System.Windows.Forms.View.Details;
@ -926,8 +917,8 @@
this.tabSubAssembly.Controls.Add(this.lvCEAssembly);
this.tabSubAssembly.Location = new System.Drawing.Point(4, 22);
this.tabSubAssembly.Name = "tabSubAssembly";
this.tabSubAssembly.Padding = new System.Windows.Forms.Padding(3);
this.tabSubAssembly.Size = new System.Drawing.Size(706, 164);
this.tabSubAssembly.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabSubAssembly.Size = new System.Drawing.Size(640, 286);
this.tabSubAssembly.TabIndex = 1;
this.tabSubAssembly.Text = "Edit Assembly";
this.tabSubAssembly.UseVisualStyleBackColor = true;
@ -945,7 +936,7 @@
this.lvCEAssembly.Location = new System.Drawing.Point(3, 3);
this.lvCEAssembly.MultiSelect = false;
this.lvCEAssembly.Name = "lvCEAssembly";
this.lvCEAssembly.Size = new System.Drawing.Size(700, 158);
this.lvCEAssembly.Size = new System.Drawing.Size(635, 280);
this.lvCEAssembly.TabIndex = 4;
this.lvCEAssembly.UseCompatibleStateImageBehavior = false;
this.lvCEAssembly.View = System.Windows.Forms.View.Details;
@ -975,8 +966,8 @@
this.tabOutput.Controls.Add(this.splitContainer5);
this.tabOutput.Location = new System.Drawing.Point(4, 22);
this.tabOutput.Name = "tabOutput";
this.tabOutput.Padding = new System.Windows.Forms.Padding(3);
this.tabOutput.Size = new System.Drawing.Size(720, 196);
this.tabOutput.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabOutput.Size = new System.Drawing.Size(654, 318);
this.tabOutput.TabIndex = 3;
this.tabOutput.Text = "Debug Output";
this.tabOutput.UseVisualStyleBackColor = true;
@ -998,7 +989,7 @@
// splitContainer5.Panel2
//
this.splitContainer5.Panel2.Controls.Add(this.lbDebug);
this.splitContainer5.Size = new System.Drawing.Size(714, 190);
this.splitContainer5.Size = new System.Drawing.Size(648, 312);
this.splitContainer5.SplitterDistance = 26;
this.splitContainer5.TabIndex = 6;
//
@ -1009,7 +1000,7 @@
this.txFilter.Enabled = false;
this.txFilter.Location = new System.Drawing.Point(41, 3);
this.txFilter.Name = "txFilter";
this.txFilter.Size = new System.Drawing.Size(670, 20);
this.txFilter.Size = new System.Drawing.Size(604, 20);
this.txFilter.TabIndex = 4;
//
// label3
@ -1029,7 +1020,7 @@
this.lbDebug.Location = new System.Drawing.Point(0, 0);
this.lbDebug.Name = "lbDebug";
this.lbDebug.ScrollAlwaysVisible = true;
this.lbDebug.Size = new System.Drawing.Size(714, 160);
this.lbDebug.Size = new System.Drawing.Size(648, 282);
this.lbDebug.TabIndex = 3;
//
// diagSaveMemory
@ -1042,24 +1033,40 @@
this.diagBrowseCT.Filter = "Cheat Engine Tables (*.CT)|*.ct";
this.diagBrowseCT.Title = "Load cheat table";
//
// Form1
// txDisassembly
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(734, 331);
this.txDisassembly.BackColor = System.Drawing.SystemColors.Window;
this.txDisassembly.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.txDisassembly.Cursor = System.Windows.Forms.Cursors.Default;
this.txDisassembly.Dock = System.Windows.Forms.DockStyle.Fill;
this.txDisassembly.Font = new System.Drawing.Font("Lucida Console", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txDisassembly.Location = new System.Drawing.Point(0, 0);
this.txDisassembly.Name = "txDisassembly";
this.txDisassembly.ReadOnly = true;
this.txDisassembly.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical;
this.txDisassembly.Size = new System.Drawing.Size(648, 274);
this.txDisassembly.TabIndex = 1;
this.txDisassembly.Text = "";
//
// CxbxDebuggerInstance
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size(734, 361);
this.ControlBox = false;
this.Controls.Add(this.tableLayoutPanel3);
this.Controls.Add(this.toolStrip1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "Form1";
this.Text = "Cxbx-Reloaded Debugger";
this.MinimizeBox = false;
this.Name = "CxbxDebuggerInstance";
this.Text = "unnamed instance";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
this.statusBar.ResumeLayout(false);
this.statusBar.PerformLayout();
this.tabContainer.ResumeLayout(false);
this.tabSummary.ResumeLayout(false);
this.tabSummary.PerformLayout();
this.tabDisassembly.ResumeLayout(false);
this.splitContainer2.Panel1.ResumeLayout(false);
this.splitContainer2.Panel1.PerformLayout();
@ -1111,11 +1118,6 @@
#endregion
private System.Windows.Forms.ListBox lbConsole;
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.ToolStripButton btnStart;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripButton btnSuspend;
private System.Windows.Forms.ToolStripButton btnResume;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripComboBox cbThreads;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.TabControl tabContainer;
@ -1135,8 +1137,6 @@
private System.Windows.Forms.TextBox txAddress;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox tbFilter;
private System.Windows.Forms.StatusStrip statusBar;
private System.Windows.Forms.ToolStripStatusLabel lblStatus;
private RicherTextBox txDisassembly;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
@ -1192,6 +1192,11 @@
private System.Windows.Forms.Button btnLoadCT;
private System.Windows.Forms.Button btnRefresh;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.TabPage tabSummary;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.LinkLabel linkLabel3;
private System.Windows.Forms.LinkLabel linkLabel2;
private System.Windows.Forms.LinkLabel linkLabel1;
}
}

View File

@ -8,15 +8,15 @@ using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using cs_x86;
using System.Runtime.InteropServices;
namespace CxbxDebugger
{
public partial class Form1 : Form
public partial class CxbxDebuggerInstance : Form, IDebugWindow
{
Thread DebuggerWorkerThread;
Debugger DebuggerInst;
string[] CachedArgs;
string CachedTitle = "";
string[] StartupArgs;
bool SuspendedOnBp = false;
DebuggerFormEvents DebugEvents;
@ -29,33 +29,45 @@ namespace CxbxDebugger
DebugOutputManager debugStrMan;
PatchManager patchMan;
IDebugContainerWindow DebugContainer
{
get
{
return MdiParent as IDebugContainerWindow;
}
}
DebugStateInfo StateInfo = new DebugStateInfo();
private void SetDebugState(DebugState State, string Detail = "")
{
DebugContainer.ReportStatus(this, State, Detail);
StateInfo.State = State;
StateInfo.Detail = Detail;
}
List<DebuggerMessages.FileOpened> FileHandles = new List<DebuggerMessages.FileOpened>();
public Form1()
public CxbxDebuggerInstance(Form Owner, string[] args)
{
InitializeComponent();
// TODO: Cleanup arg handling
string[] args = Environment.GetCommandLineArgs();
MdiParent = Owner;
#if !DEBUG
// Arguments are expected before the Form is created
if (args.Length < 2)
{
throw new Exception("Incorrect usage");
}
#endif
var items = new List<string>(args.Length - 1);
for (int i = 1; i < args.Length; ++i)
{
items.Add(args[i]);
}
CachedArgs = items.ToArray();
StartupArgs = args;
DebugEvents = new DebuggerFormEvents(this);
SetDebugProcessActive(false);
SetDebugState(DebugState.Unknown);
txDisassembly.InlineLinkClicked += OnDisassemblyNavigation;
@ -77,6 +89,8 @@ namespace CxbxDebugger
fileWatchMan = new FileWatchManager(clbBreakpoints);
debugStrMan = new DebugOutputManager(lbDebug);
patchMan = new PatchManager();
CreateDebuggerOnce();
}
private void OnDisassemblyNavigation(object sender, InlineLinkClickedEventArgs e)
@ -86,38 +100,85 @@ namespace CxbxDebugger
ShowDisassemblyAt(e.Link);
}
private void StartDebugging()
private void CreateDebuggerOnce()
{
bool Create = false;
if (DebuggerWorkerThread == null)
{
// First launch
Create = true;
}
else if (DebuggerWorkerThread.ThreadState == ThreadState.Stopped)
{
// Further launches
Create = true;
}
if (Create)
if (DebuggerInst == null)
{
// Create debugger instance
DebuggerInst = new Debugger(CachedArgs);
DebuggerInst = new Debugger(StartupArgs);
DebuggerInst.RegisterEventInterfaces(DebugEvents);
DebuggerInst.RegisterEventInterfaces(patchMan);
var TargetXbeName = ValidateXbeTargetName(DebuggerInst.TargetPath);
var TargetXbeValid = true;
if (string.IsNullOrEmpty(TargetXbeName))
{
TargetXbeName = "<unknown>";
TargetXbeValid = false;
}
if (InvokeRequired)
{
// Set form title based on this new process
Invoke(new MethodInvoker(delegate ()
{
Text = TargetXbeName;
}));
}
else
{
Text = TargetXbeName;
}
if (TargetXbeValid)
{
SetDebugState(DebugState.Idle, $"{TargetXbeName} is waiting to start");
}
}
}
private string ValidateXbeTargetName(string XbePath)
{
var XbeName = Path.GetFileName(XbePath);
if (File.Exists(XbePath))
{
return XbeName;
}
// Cxbx CLI will pass through the path as a list of parameters, "dir;name"
if (XbeName.StartsWith(";"))
{
var CleanedXbePath = XbePath.Remove(XbePath.Length - XbeName.Length, 1);
if (File.Exists(CleanedXbePath))
{
return XbeName.Substring(1);
}
}
return null;
}
private void StartDebugging()
{
if (GetSessionState() == SessionState.Inactive)
{
// Setup new debugger thread
DebuggerWorkerThread = new Thread(x =>
{
CreateDebuggerOnce();
if (DebuggerInst.Launch())
{
DebuggerInst.RunThreaded();
}
});
DebuggerWorkerThread.Name = "CxbxDebugger";
var ProcessName = Path.GetFileName(DebuggerInst.TargetPath);
DebuggerWorkerThread.Name = $"DebuggerFor_{ProcessName}";
DebuggerWorkerThread.Start();
}
}
@ -146,7 +207,7 @@ namespace CxbxDebugger
if (IsMainThread)
PrefixStr = "> ";
string DisplayStr = string.Format("{0}[{1}] ", PrefixStr, (uint)Thread.Handle);
var DisplayStr = $"{PrefixStr}[{(uint)Thread.Handle}]";
// Resolve thread name
@ -206,7 +267,7 @@ namespace CxbxDebugger
private void DebugLog(string Message)
{
string MessageStamped = string.Format("[{0}] {1}", DateTime.Now.ToLongTimeString(), Message);
var MessageStamped = $"[{DateTime.Now.ToLongTimeString()}] {Message}";
if (InvokeRequired)
{
@ -235,11 +296,11 @@ namespace CxbxDebugger
{
case FileEventType.Read:
case FileEventType.Write:
string text = string.Format("{0} bytes", Event.Length.ToString());
string text = $"{Event.Length} bytes";
if (Event.Offset != uint.MaxValue)
{
text += string.Format(" from offset {0}", Event.Offset);
text += $" from offset {Event.Offset}";
}
lvi.SubItems.Add(text);
@ -280,7 +341,7 @@ namespace CxbxDebugger
{
Invoke(new MethodInvoker(delegate ()
{
Suspend("file open");
Suspend(DebugState.Breakpoint, "Hit file event");
}));
}
}
@ -290,12 +351,10 @@ namespace CxbxDebugger
{
Invoke(new MethodInvoker(delegate ()
{
CachedTitle = Title;
Text = string.Format("{0} - Cxbx-Reloaded Debugger", CachedTitle);
DebugContainer.ReportGameTitle(Title);
// This is done too late - modules are already loaded
//LoadCheatTable(string.Format("{0}.ct", CachedTitle));
//LoadCheatTable($"{Title}.ct");
}));
}
@ -329,7 +388,7 @@ namespace CxbxDebugger
else
{
string module_name = Path.GetFileName(Module.Path);
Suspend(string.Format("Breakpoint hit in {0} at 0x{1:x}", module_name, Address));
Suspend(DebugState.Breakpoint, string.Format("Breakpoint hit in {0} at 0x{1:x}", module_name, Address));
// Forces a refresh at the breakpoint address (not the callstack trace)
DumpDisassembly(Address);
@ -344,35 +403,21 @@ namespace CxbxDebugger
{
Invoke(new MethodInvoker(delegate ()
{
// Disable when active
btnStart.Enabled = !Active;
// Enable when active
btnSuspend.Enabled = Active;
btnResume.Enabled = Active;
lblStatus.Text = (Active ? "Running" : "Inactive");
SetDebugState(Active ? DebugState.Running : DebugState.Terminated);
}));
}
else
{
// Disable when active
btnStart.Enabled = !Active;
// Enable when active
btnSuspend.Enabled = Active;
btnResume.Enabled = Active;
lblStatus.Text = (Active ? "Running" : "Inactive");
SetDebugState(Active ? DebugState.Running : DebugState.Terminated);
}
}
private void btnClearLog_Click(object sender, EventArgs e)
{
lbConsole.Items.Clear();
//lbConsole.Items.Clear();
}
class DebuggerFormEvents : IDebuggerGeneralEvents,
class DebuggerFormEvents : IDebuggerSessionEvents,
IDebuggerProcessEvents,
IDebuggerModuleEvents,
IDebuggerThreadEvents,
@ -380,9 +425,12 @@ namespace CxbxDebugger
IDebuggerExceptionEvents,
IDebuggerFileEvents
{
Form1 frm;
CxbxDebuggerInstance frm;
public DebuggerFormEvents(Form1 main)
public DebuggerFormEvents(CxbxDebuggerInstance main)
{
frm = main;
}
@ -397,8 +445,8 @@ namespace CxbxDebugger
{
int remainingThreads = Process.Threads.Count;
frm.DebugLog(string.Format("Process exited {0} ({1})", Process.ProcessID, NtStatus.PrettyPrint(ExitCode)));
frm.DebugLog(string.Format("{0} child thread(s) remain open", remainingThreads));
frm.DebugLog($"Process exited {Process.ProcessID} ({NtStatus.PrettyPrint(ExitCode)})");
frm.DebugLog($"{remainingThreads} child thread(s) remain open");
frm.DebugModules.Clear();
@ -426,36 +474,70 @@ namespace CxbxDebugger
public void OnDebugTitleLoaded(string Title)
{
frm.DebugLog(string.Format("Loaded title \"{0}\"", Title));
frm.DebugLog($"Loaded title \"{Title}\"");
frm.DebugTitle(Title);
}
// https://stackoverflow.com/a/749653
public static string[] CommandLineToArgs(string commandLine)
{
int argc;
var argv = VsChromium.Core.Win32.Processes.NativeMethods.CommandLineToArgvW(commandLine, out argc);
if (argv == IntPtr.Zero)
throw new System.ComponentModel.Win32Exception();
try
{
var args = new string[argc];
for (var i = 0; i < args.Length; i++)
{
var p = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
args[i] = Marshal.PtrToStringUni(p);
}
return args;
}
finally
{
Marshal.FreeHGlobal(argv);
}
}
public void OnDebugTargetChanged(string CommandLine)
{
frm.DebugLog($"New debug session started - {CommandLine}");
frm.Invoke(new MethodInvoker(delegate ()
{
frm.DebugContainer.AddDebugSession(CommandLineToArgs(CommandLine), true);
}));
}
public void OnThreadCreate(DebuggerThread Thread)
{
frm.DebugLog(string.Format("Thread created {0}", Thread.ThreadID));
frm.DebugLog($"Thread created {Thread.ThreadID}");
frm.DebugThreads.Add(Thread);
}
public void OnThreadExit(DebuggerThread Thread, uint ExitCode)
{
frm.DebugLog(string.Format("Thread exited {0} ({1})", Thread.ThreadID, NtStatus.PrettyPrint(ExitCode)));
frm.DebugLog($"Thread exited {Thread.ThreadID} ({NtStatus.PrettyPrint(ExitCode)})");
frm.DebugThreads.Remove(Thread);
}
public void OnThreadNamed(DebuggerThread Thread)
{
frm.DebugLog(string.Format("Thread {0} named {1}", Thread.ThreadID, Thread.DebugName));
frm.DebugLog($"Thread {Thread.ThreadID} named {Thread.DebugName}");
}
public void OnModuleLoaded(DebuggerModule Module)
{
frm.DebugLog(string.Format("Loaded module \"{0}\"", Module.Path));
frm.DebugLog($"Loaded module \"{Module.Path}\"");
frm.DebugModules.Add(Module);
}
public void OnModuleUnloaded(DebuggerModule Module)
{
frm.DebugLog(string.Format("Unloaded module \"{0}\"", Module.Path));
frm.DebugLog($"Unloaded module \"{Module.Path}\"");
frm.DebugModules.Remove(Module);
}
@ -475,7 +557,7 @@ namespace CxbxDebugger
}
// TODO Include GetLastError string
string ExceptionMessage = string.Format("Access violation thrown at 0x{0:X8} ({1})", Address, ProcessName);
var ExceptionMessage = string.Format("Access violation thrown at 0x{0:X8} ({1})", Address, ProcessName);
ExceptionMessage += string.Format("\n\nException code {0:X8}", Code);
@ -505,13 +587,13 @@ namespace CxbxDebugger
if (Info.Succeeded)
{
frm.FileHandles.Add(Info);
frm.DebugLog(string.Format("Opened file: \"{0}\"", Info.FileName));
frm.DebugLog($"Opened file: \"{Info.FileName}\"");
frm.DebugFileEvent(FileEvents.Opened(Info.FileName));
}
else
{
frm.DebugLog(string.Format("Opened file FAILED: \"{0}\"", Info.FileName));
frm.DebugLog($"Opened file FAILED: \"{Info.FileName}\"");
frm.DebugFileEvent(FileEvents.OpenedFailed(Info.FileName));
}
@ -522,7 +604,7 @@ namespace CxbxDebugger
var Found = frm.FileHandles.Find(FileInfo => FileInfo.Handle == Info.Handle);
if (Found != null)
{
frm.DebugLog(string.Format("Reading {0} byte(s) from: {1}", Info.Length, Found.FileName));
frm.DebugLog($"Reading {Info.Length} byte(s) from: {Found.FileName}");
frm.DebugFileEvent(FileEvents.Read(Found.FileName, Info.Length, Info.Offset));
}
}
@ -532,7 +614,7 @@ namespace CxbxDebugger
var Found = frm.FileHandles.Find(FileInfo => FileInfo.Handle == Info.Handle);
if (Found != null)
{
frm.DebugLog(string.Format("Writing {0} byte(s) to: {1}", Info.Length, Found.FileName));
frm.DebugLog($"Writing {Info.Length} byte(s) to: {Found.FileName}");
frm.DebugFileEvent(FileEvents.Write(Found.FileName, Info.Length, Info.Offset));
}
}
@ -546,17 +628,12 @@ namespace CxbxDebugger
frm.DebugFileEvent(FileEvents.Closed(Found.FileName));
frm.DebugLog(string.Format("Closed file: \"{0}\"", Found.FileName));
frm.DebugLog($"Closed file: \"{Found.FileName}\"");
}
}
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
StartDebugging();
}
private void Suspend(string Reason)
private void Suspend(DebugState State, string Detail)
{
if (DebuggerInst != null)
{
@ -572,7 +649,7 @@ namespace CxbxDebugger
PopulateThreadList(cbThreads, null);
}
lblStatus.Text = string.Format("Suspended ({0})", Reason);
SetDebugState(State, Detail);
cbThreads.Enabled = true;
cbFrames.Enabled = true;
@ -593,22 +670,12 @@ namespace CxbxDebugger
}
}
lblStatus.Text = "Running";
SetDebugState(DebugState.Running);
cbThreads.Enabled = false;
cbFrames.Enabled = false;
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
Suspend("manually triggered");
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
Resume();
}
struct CallstackInfo
{
public uint InstructionPointer;
@ -741,8 +808,8 @@ namespace CxbxDebugger
{
if (EP != 0)
{
string LinkName = string.Format("{0} +{1:x}", Name, Address - EP);
string Link = string.Format("0x{0:x8}", Address);
var LinkName = string.Format("{0} +{1:x}", Name, Address - EP);
var Link = string.Format("0x{0:x8}", Address);
tb.InsertLink(LinkName, Link);
}
@ -833,9 +900,6 @@ namespace CxbxDebugger
private void btnDumpMemory_Click(object sender, EventArgs e)
{
if (DebuggerInst == null)
return;
if (diagSaveMemory.ShowDialog() == DialogResult.OK)
{
byte[] data = ReadMemory();
@ -855,7 +919,7 @@ namespace CxbxDebugger
int Index = cbThreads.SelectedIndex;
if (Index == -1)
return;
CallstackDump.Clear();
cbFrames.Items.Clear();
@ -974,17 +1038,6 @@ namespace CxbxDebugger
fileWatchMan.SetEnabled(e.Index, e.NewValue == CheckState.Checked);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.F5)
{
StartDebugging();
return true;
}
return false;
}
private void HandleDisasmGo()
{
uint addr = 0;
@ -1045,7 +1098,7 @@ namespace CxbxDebugger
{
var li = lvCEMemory.Items.Add(string.Format("{0} 0x{1:x}", DataPatch.Module, DataPatch.Offset));
li.SubItems.Add(DataPatch.Name);
li.SubItems.Add(string.Format("{0} byte(s)", DataPatch.Patched.Length));
li.SubItems.Add($"{DataPatch.Patched.Length} byte(s)");
if (MainProcess != null)
{
li.SubItems.Add(patchMan.Read(MainProcess, DataPatch));
@ -1104,7 +1157,7 @@ namespace CxbxDebugger
if (File.Exists(filename))
{
DebugLog(string.Format("Attempting to load \"{0}\"", filename));
DebugLog($"Attempting to load \"{filename}\"");
CheatEngine.CheatTable ct_data = CheatEngine.CheatTableReader.FromFile(filename);
if (ct_data != null)
@ -1141,8 +1194,8 @@ namespace CxbxDebugger
patchMan.Assembly.Add(DataPatch);
}
DebugLog(string.Format("Loaded {0} auto-assembler entries", ct_data.CodeEntires.Count));
DebugLog(string.Format("Loaded {0} cheat entries", ct_data.CheatEntries.Count));
DebugLog($"Loaded {ct_data.CodeEntires.Count} auto-assembler entries");
DebugLog($"Loaded {ct_data.CheatEntries.Count} cheat entries");
RefreshPatches();
}
@ -1151,7 +1204,7 @@ namespace CxbxDebugger
private void button5_Click(object sender, EventArgs e)
{
PatchType PatchType = (PatchType)cbDataFormat.SelectedIndex;
var PatchType = (PatchType)cbDataFormat.SelectedIndex;
int PatchSize = PatchManager.PatchTypeLength(PatchType);
if (PatchSize == 0)
@ -1169,7 +1222,7 @@ namespace CxbxDebugger
Patch DataPatch = new Patch();
DataPatch.DisplayAs = PatchType;
DataPatch.Name = string.Format("Patched {0}", PatchType);
DataPatch.Name = $"Patched {PatchType}";
DataPatch.Module = "";
DataPatch.Offset = addr;
@ -1234,5 +1287,60 @@ namespace CxbxDebugger
}
}
}
public SessionState GetSessionState()
{
if (DebuggerWorkerThread == null)
{
return SessionState.Inactive;
}
else if (DebuggerWorkerThread.ThreadState == ThreadState.Stopped)
{
return SessionState.Ended;
}
return SessionState.Running;
}
public void StartSession()
{
if (GetSessionState() == SessionState.Inactive)
{
StartDebugging();
}
}
public void SuspendSession()
{
if (GetSessionState() == SessionState.Running)
{
Suspend(DebugState.Suspended, "By user");
}
}
public void ResumeSession()
{
Resume();
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
tabContainer.SelectedTab = tabWatch;
}
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
tabContainer.SelectedTab = tabMemory;
}
private void linkLabel3_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
tabContainer.SelectedTab = tabDisassembly;
}
public DebugStateInfo GetDebugStateInfo()
{
return StateInfo;
}
}
}

View File

@ -118,16 +118,13 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="statusBar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>122, 17</value>
<value>534, 17</value>
</metadata>
<metadata name="diagSaveMemory.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>238, 17</value>
<value>153, 17</value>
</metadata>
<metadata name="diagBrowseCT.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>384, 17</value>
<value>357, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">

View File

@ -0,0 +1,201 @@
namespace CxbxDebugger
{
partial class CxbxDebuggerMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CxbxDebuggerMain));
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileMenu = new System.Windows.Forms.ToolStripMenuItem();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.debugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.miStartDebugging = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.miSuspend = new System.Windows.Forms.ToolStripMenuItem();
this.miResume = new System.Windows.Forms.ToolStripMenuItem();
this.windowsMenu = new System.Windows.Forms.ToolStripMenuItem();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.lblStatusDeprecate = new System.Windows.Forms.ToolStripStatusLabel();
this.lblStatus = new System.Windows.Forms.ToolStripStatusLabel();
this.menuStrip.SuspendLayout();
this.statusStrip1.SuspendLayout();
this.SuspendLayout();
//
// menuStrip
//
this.menuStrip.ImageScalingSize = new System.Drawing.Size(24, 24);
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileMenu,
this.debugToolStripMenuItem,
this.windowsMenu});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.MdiWindowListItem = this.windowsMenu;
this.menuStrip.Name = "menuStrip";
this.menuStrip.Padding = new System.Windows.Forms.Padding(4, 1, 0, 1);
this.menuStrip.Size = new System.Drawing.Size(734, 24);
this.menuStrip.TabIndex = 0;
this.menuStrip.Text = "MenuStrip";
//
// fileMenu
//
this.fileMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.exitToolStripMenuItem});
this.fileMenu.ImageTransparentColor = System.Drawing.SystemColors.ActiveBorder;
this.fileMenu.Name = "fileMenu";
this.fileMenu.Size = new System.Drawing.Size(37, 22);
this.fileMenu.Text = "&File";
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.ShortcutKeyDisplayString = "Alt+F4";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
this.exitToolStripMenuItem.Text = "E&xit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.ExitToolsStripMenuItem_Click);
//
// debugToolStripMenuItem
//
this.debugToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.miStartDebugging,
this.toolStripMenuItem1,
this.miSuspend,
this.miResume});
this.debugToolStripMenuItem.Name = "debugToolStripMenuItem";
this.debugToolStripMenuItem.Size = new System.Drawing.Size(54, 22);
this.debugToolStripMenuItem.Text = "Debug";
//
// miStartDebugging
//
this.miStartDebugging.Image = global::CxbxDebugger.Properties.Resources.run;
this.miStartDebugging.ImageTransparentColor = System.Drawing.Color.Magenta;
this.miStartDebugging.Name = "miStartDebugging";
this.miStartDebugging.ShortcutKeyDisplayString = "F5";
this.miStartDebugging.Size = new System.Drawing.Size(117, 22);
this.miStartDebugging.Text = "&Start";
this.miStartDebugging.Click += new System.EventHandler(this.startDebuggingToolStripMenuItem_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(114, 6);
//
// miSuspend
//
this.miSuspend.Image = global::CxbxDebugger.Properties.Resources.pause;
this.miSuspend.ImageTransparentColor = System.Drawing.Color.Magenta;
this.miSuspend.Name = "miSuspend";
this.miSuspend.Size = new System.Drawing.Size(117, 22);
this.miSuspend.Text = "&Break";
this.miSuspend.Click += new System.EventHandler(this.suspendToolStripMenuItem_Click);
//
// miResume
//
this.miResume.Image = global::CxbxDebugger.Properties.Resources.run;
this.miResume.ImageTransparentColor = System.Drawing.Color.Magenta;
this.miResume.Name = "miResume";
this.miResume.Size = new System.Drawing.Size(117, 22);
this.miResume.Text = "&Resume";
this.miResume.Click += new System.EventHandler(this.resumeToolStripMenuItem_Click);
//
// windowsMenu
//
this.windowsMenu.Name = "windowsMenu";
this.windowsMenu.Size = new System.Drawing.Size(68, 22);
this.windowsMenu.Text = "&Windows";
//
// statusStrip1
//
this.statusStrip1.ImageScalingSize = new System.Drawing.Size(24, 24);
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.lblStatusDeprecate,
this.lblStatus});
this.statusStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
this.statusStrip1.Location = new System.Drawing.Point(0, 339);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 9, 0);
this.statusStrip1.Size = new System.Drawing.Size(734, 61);
this.statusStrip1.TabIndex = 2;
this.statusStrip1.Text = "statusStrip1";
//
// lblStatusDeprecate
//
this.lblStatusDeprecate.BackColor = System.Drawing.Color.Yellow;
this.lblStatusDeprecate.Name = "lblStatusDeprecate";
this.lblStatusDeprecate.Size = new System.Drawing.Size(723, 15);
this.lblStatusDeprecate.Spring = true;
this.lblStatusDeprecate.Text = "WARNING: cxbxr-debugger will eventually be removed from upstream branch.";
this.lblStatusDeprecate.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lblStatus
//
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(723, 15);
this.lblStatus.Text = "Ready";
//
// CxbxDebuggerMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size(734, 361);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.menuStrip);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.IsMdiContainer = true;
this.MainMenuStrip = this.menuStrip;
this.Name = "CxbxDebuggerMain";
this.Text = "cxbx-debugger";
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileMenu;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem windowsMenu;
private System.Windows.Forms.ToolTip toolTip;
private System.Windows.Forms.ToolStripMenuItem debugToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem miStartDebugging;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem miSuspend;
private System.Windows.Forms.ToolStripMenuItem miResume;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripStatusLabel lblStatusDeprecate;
private System.Windows.Forms.ToolStripStatusLabel lblStatus;
}
}

View File

@ -0,0 +1,156 @@
// Written by x1nixmzeng for the Cxbx-Reloaded project
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CxbxDebugger
{
public partial class CxbxDebuggerMain : Form, IDebugContainerWindow
{
public CxbxDebuggerMain(string[] args)
{
InitializeComponent();
var StartupArgs = new string[args.Length - 1];
Array.Copy(args, 1, StartupArgs, 0, args.Length - 1);
// Setup session without initially running the game
AddDebugSession(StartupArgs, false);
#if FALSE
AddDebugSession(new string[] { }, false);
#endif
}
private void ExitToolsStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void startDebuggingToolStripMenuItem_Click(object sender, EventArgs e)
{
if (ActiveMdiChild is IDebugWindow)
{
(ActiveMdiChild as IDebugWindow).StartSession();
}
}
private void suspendToolStripMenuItem_Click(object sender, EventArgs e)
{
if (ActiveMdiChild is IDebugWindow)
{
(ActiveMdiChild as IDebugWindow).SuspendSession();
}
}
private void resumeToolStripMenuItem_Click(object sender, EventArgs e)
{
if (ActiveMdiChild is IDebugWindow)
{
(ActiveMdiChild as IDebugWindow).ResumeSession();
}
}
public void AddDebugSession(string[] Arguments, bool StartAutomatically)
{
var SessionWindow = CreateNewSessionWindow(Arguments);
if (StartAutomatically)
{
SessionWindow.StartSession();
}
}
public void ReportGameTitle(string GameTitle)
{
Text = $"cxbx-debugger ({GameTitle})";
}
private IDebugWindow CreateNewSessionWindow(string[] Arguments)
{
var childForm = new CxbxDebuggerInstance(this, Arguments);
childForm.WindowState = FormWindowState.Maximized;
childForm.TextChanged += (sender, e) => { OnSessionWindowRenamed(sender as Form); };
childForm.Activated += (sender, e) => { OnSessionWindowActivated(sender as IDebugWindow); };
childForm.Show();
return childForm;
}
private void OnSessionWindowActivated(IDebugWindow child)
{
var state = child.GetDebugStateInfo();
RefreshStatusText(state);
}
private void OnSessionWindowRenamed(Form form)
{
// https://stackoverflow.com/questions/1347734/mdi-window-list-not-updating-child-title-bar-texts
ActivateMdiChild(null);
ActivateMdiChild(form);
}
public void ReportStatus(IDebugWindow Window, DebugState State, string Detail)
{
if (Window == ActiveMdiChild)
{
RefreshStatusText(new DebugStateInfo() { State = State, Detail = Detail });
}
}
private void RefreshStatusText(DebugStateInfo stateInfo)
{
var stateString = "";
var canSuspend = false;
var canResume = false;
var canRun = false;
switch (stateInfo.State)
{
case DebugState.Unknown:
stateString = "No valid Xbe was loaded. Invalid session.";
break;
case DebugState.Idle:
stateString = "Ready";
canRun = true;
break;
case DebugState.Suspended:
stateString = "Suspended";
canResume = true;
break;
case DebugState.Running:
stateString = "Running";
canSuspend = true;
break;
case DebugState.Terminated:
stateString = "Terminated";
//canRun = true; // Uncomment to allow restarted sessions
break;
}
if (!string.IsNullOrEmpty(stateInfo.Detail))
{
stateString += $" - {stateInfo.Detail}";
}
miStartDebugging.Enabled = canRun;
miSuspend.Enabled = canSuspend;
miResume.Enabled = canResume;
lblStatus.Text = stateString;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@ using WinDebug = VsChromium.Core.Win32.Debugging;
using System.Runtime.InteropServices;
using WinLowLevel = LowLevelDesign.Win32.Windows.NativeMethods;
using System.Threading;
using System.Threading.Tasks;
namespace CxbxDebugger
{
@ -32,13 +33,18 @@ namespace CxbxDebugger
string[] args = new string[] { };
string Target = "";
public string TargetPath
{
get { return Target; }
}
RunState State = RunState.NotLaunched;
DebuggerMessages.DebuggerInit InitParams = new DebuggerMessages.DebuggerInit();
DebuggerInstance DebugInstance;
List<IDebuggerGeneralEvents> GeneralEvents = new List<IDebuggerGeneralEvents>();
List<IDebuggerSessionEvents> SessionEvents = new List<IDebuggerSessionEvents>();
List<IDebuggerProcessEvents> ProcessEvents = new List<IDebuggerProcessEvents>();
List<IDebuggerThreadEvents> ThreadEvents = new List<IDebuggerThreadEvents>();
List<IDebuggerModuleEvents> ModuleEvents = new List<IDebuggerModuleEvents>();
@ -71,30 +77,29 @@ namespace CxbxDebugger
Init();
}
public Debugger(string[] x_args)
public Debugger(string[] launchArgs)
{
Init();
if (x_args == null)
return;
// Copy all arguments
args = x_args;
// Keep quotes for any strings that may contain spaces
int scratch;
for (int i = 0; i < args.Length; ++i)
// Copy XBE path without the quotes
var loadArg = Array.FindIndex(launchArgs, x => x == "/load");
if (loadArg != -1)
{
if (int.TryParse(args[i], out scratch) == false)
{
args[i] = string.Format("\"{0}\"", args[i]);
}
Target = launchArgs[loadArg + 1].Trim(new char[] { '"' });
}
// Copy XBE path without the quotes
if(x_args.Length > 2)
args = new string[launchArgs.Length];
for (int i = 0; i < launchArgs.Length; ++i)
{
Target = x_args[2].Trim(new char[] { '"' });
var arg = launchArgs[i];
if (arg.Contains(" "))
{
arg = string.Format($"\"{arg}\"");
}
args[i] = arg;
}
}
@ -104,7 +109,7 @@ namespace CxbxDebugger
bpStall.Set();
// Remove all events
GeneralEvents.Clear();
SessionEvents.Clear();
ProcessEvents.Clear();
ThreadEvents.Clear();
ModuleEvents.Clear();
@ -173,14 +178,19 @@ namespace CxbxDebugger
if (CanLaunch() == false)
throw new Exception("Unable to launch in this state");
if (args.Length == 0)
return false;
var DebugCreationFlags =
WinProcesses.ProcessCreationFlags.DEBUG_ONLY_THIS_PROCESS |
WinProcesses.ProcessCreationFlags.CREATE_NEW_CONSOLE;
var launchArgs = new StringBuilder(string.Join(" ", args));
bool bRet = WinProcesses.NativeMethods.CreateProcess
(
null,
new StringBuilder(string.Join(" ", args)),
launchArgs,
null,
null,
false,
@ -196,11 +206,15 @@ namespace CxbxDebugger
// Store so they can be marshalled and closed correctly
hProcess = new WinProcesses.SafeProcessHandle(stProcessInfo.hProcess);
hThread = new WinProcesses.SafeThreadHandle(stProcessInfo.hThread);
bContinue = true;
State = RunState.Running;
}
else
{
throw new Exception($"Failed to launch loader '{launchArgs}'");
}
return bRet;
}
@ -308,10 +322,7 @@ namespace CxbxDebugger
Thread.StartAddress = DebugInfo.lpStartAddress;
Thread.ThreadBase = DebugInfo.lpThreadLocalBase;
foreach (IDebuggerThreadEvents Event in ThreadEvents )
{
Event.OnThreadCreate(Thread);
}
Parallel.ForEach(ThreadEvents, Event => Event.OnThreadCreate(Thread));
}
private void HandleExitThread(WinDebug.DEBUG_EVENT DebugEvent)
@ -328,10 +339,7 @@ namespace CxbxDebugger
{
uint ExitCode = DebugInfo.dwExitCode;
foreach (IDebuggerThreadEvents Event in ThreadEvents)
{
Event.OnThreadExit(TargetThread, ExitCode);
}
Parallel.ForEach(ThreadEvents, Event => Event.OnThreadExit(TargetThread, ExitCode));
}
}
@ -364,26 +372,17 @@ namespace CxbxDebugger
DebugInstance = new DebuggerInstance(Process);
RegisterEventInterfaces(DebugInstance);
foreach (IDebuggerProcessEvents Event in ProcessEvents)
{
Event.OnProcessCreate(Process);
}
Parallel.ForEach(ProcessEvents, Event => Event.OnProcessCreate(Process));
foreach (IDebuggerThreadEvents Event in ThreadEvents)
{
Event.OnThreadCreate(MainThread);
}
Parallel.ForEach(ThreadEvents, Event => Event.OnThreadCreate(MainThread));
var XboxModule = new DebuggerModule();
XboxModule.Path = Target;
XboxModule.ImageBase = DebugInfo.lpBaseOfImage;
XboxModule.Core = true;
foreach (IDebuggerModuleEvents Event in ModuleEvents)
{
Event.OnModuleLoaded(XboxModule);
}
Parallel.ForEach(ModuleEvents, Event => Event.OnModuleLoaded(XboxModule));
}
private void HandleExitProcess(WinDebug.DEBUG_EVENT DebugEvent)
@ -400,10 +399,7 @@ namespace CxbxDebugger
if (TargetProcess != null)
{
foreach (IDebuggerProcessEvents Event in ProcessEvents)
{
Event.OnProcessExit(TargetProcess, ExitCode);
}
Parallel.ForEach(ProcessEvents, Event => Event.OnProcessExit(TargetProcess, ExitCode));
}
}
@ -421,10 +417,7 @@ namespace CxbxDebugger
Module.Path = ResolveProcessPath(DebugInfo.hFile);
Module.ImageBase = DebugInfo.lpBaseOfDll;
foreach (IDebuggerModuleEvents Event in ModuleEvents)
{
Event.OnModuleLoaded(Module);
}
Parallel.ForEach(ModuleEvents, Event => Event.OnModuleLoaded(Module));
}
private void HandleUnloadDll(WinDebug.DEBUG_EVENT DebugEvent)
@ -440,10 +433,7 @@ namespace CxbxDebugger
if (TargetModule != null)
{
foreach (IDebuggerModuleEvents Event in ModuleEvents)
{
Event.OnModuleUnloaded(TargetModule);
}
Parallel.ForEach(ModuleEvents, Event => Event.OnModuleUnloaded(TargetModule));
}
}
@ -453,10 +443,7 @@ namespace CxbxDebugger
string debugString = ReadProcessString(DebugInfo.lpDebugStringData, DebugInfo.nDebugStringLength, DebugInfo.fUnicode == 1);
foreach(IDebuggerOutputEvents Event in OutputEvents)
{
Event.OnDebugOutput(debugString);
}
Parallel.ForEach(OutputEvents, Event => Event.OnDebugOutput(debugString));
}
private void HandleException(WinDebug.DEBUG_EVENT DebugEvent)
@ -477,12 +464,28 @@ namespace CxbxDebugger
}
break;
case ExceptionCode.PrivilegedInstruction:
{
// Seeing this frequently called in Win10
ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_EXCEPTION_NOT_HANDLED;
}
break;
case ExceptionCode.StatusHandleNotClosable:
{
// Seeing this frequently called in Win10
ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_EXCEPTION_NOT_HANDLED;
}
break;
case (ExceptionCode)DebuggerMessages.ReportType.OVERRIDE_EXCEPTION:
{
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Query = DebuggerMessages.GetExceptionHandledQuery(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Query = DebuggerMessages.GetExceptionHandledQuery(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
bool Handled = false;
foreach (IDebuggerExceptionEvents Event in ExceptionEvents)
@ -501,7 +504,7 @@ namespace CxbxDebugger
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetHLECacheReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Report = DebuggerMessages.GetHLECacheReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
SetupHLECacheProvider(Report.FileName);
}
}
@ -512,7 +515,7 @@ namespace CxbxDebugger
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetKernelPatchReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Report = DebuggerMessages.GetKernelPatchReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
KernelSymbolProvider.AddKernelSymbolFromMessage(Report);
}
@ -524,12 +527,9 @@ namespace CxbxDebugger
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetFileOpenedReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Report = DebuggerMessages.GetFileOpenedReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
foreach (IDebuggerFileEvents Event in FileEvents)
{
Event.OnFileOpened(Report);
}
Parallel.ForEach(FileEvents, Event => Event.OnFileOpened(Report));
}
}
break;
@ -539,12 +539,9 @@ namespace CxbxDebugger
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetFileReadReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Report = DebuggerMessages.GetFileReadReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
foreach (IDebuggerFileEvents Event in FileEvents)
{
Event.OnFileRead(Report);
}
Parallel.ForEach(FileEvents, Event => Event.OnFileRead(Report));
}
}
break;
@ -554,12 +551,9 @@ namespace CxbxDebugger
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetFileWriteReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Report = DebuggerMessages.GetFileWriteReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
foreach (IDebuggerFileEvents Event in FileEvents)
{
Event.OnFileWrite(Report);
}
Parallel.ForEach(FileEvents, Event => Event.OnFileWrite(Report));
}
}
break;
@ -569,13 +563,10 @@ namespace CxbxDebugger
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetFileClosedReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Report = DebuggerMessages.GetFileClosedReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
if (Report != null)
{
foreach (IDebuggerFileEvents Event in FileEvents)
{
Event.OnFileClosed(Report);
}
Parallel.ForEach(FileEvents, Event => Event.OnFileClosed(Report));
}
}
}
@ -586,14 +577,23 @@ namespace CxbxDebugger
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetDebuggerInitReport(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Report = DebuggerMessages.GetDebuggerInitReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
InitParams = Report;
foreach (IDebuggerGeneralEvents Event in GeneralEvents)
{
Event.OnDebugTitleLoaded(InitParams.Title);
}
Parallel.ForEach(SessionEvents, Event => Event.OnDebugTitleLoaded(InitParams.Title));
}
}
break;
case (ExceptionCode)DebuggerMessages.ReportType.DEBUGGER_NEW_TARGET:
{
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetDebuggerNewTargetReport(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
Parallel.ForEach(SessionEvents, Event => Event.OnDebugTargetChanged(Report.CommandLine));
}
}
break;
@ -603,7 +603,7 @@ namespace CxbxDebugger
var Thread = DebugInstance.MainProcess.FindThread((uint)DebugEvent.dwThreadId);
if (Thread != null)
{
var Report = DebuggerMessages.GetMSVCThreadName(Thread, DebugInfo.ExceptionRecord.ExceptionInformation);
var Report = DebuggerMessages.GetMSVCThreadName(Thread, new DebuggerMessages.DataProcessor(DebugInfo.ExceptionRecord.ExceptionInformation));
if(Report != null)
{
// Resolve the ThreadId of an invalid ID to the current thread name
@ -618,10 +618,7 @@ namespace CxbxDebugger
// Update the resolved thread name
ResolvedThread.DebugName = Report.Name;
foreach (IDebuggerThreadEvents Event in ThreadEvents)
{
Event.OnThreadNamed(Thread);
}
Parallel.ForEach(ThreadEvents, Event => Event.OnThreadNamed(Thread));
}
}
}
@ -639,10 +636,7 @@ namespace CxbxDebugger
bpStall.Reset();
foreach (IDebuggerExceptionEvents Event in ExceptionEvents)
{
Event.OnBreakpoint(Thread, BpAddr, BpCode, FirstChance);
}
Parallel.ForEach(ExceptionEvents, Event => Event.OnBreakpoint(Thread, BpAddr, BpCode, FirstChance));
bpStall.WaitOne();
}
@ -669,10 +663,7 @@ namespace CxbxDebugger
WinDebug.DEBUG_EVENT DbgEvt = new WinDebug.DEBUG_EVENT();
ContinueStatus = WinDebug.CONTINUE_STATUS.DBG_CONTINUE;
foreach (IDebuggerGeneralEvents Event in GeneralEvents)
{
Event.OnDebugStart();
}
Parallel.ForEach(SessionEvents, Event => Event.OnDebugStart());
// Loop until told to stop
while (bContinue == true)
@ -729,10 +720,7 @@ namespace CxbxDebugger
State = RunState.Ended;
foreach (IDebuggerGeneralEvents Event in GeneralEvents)
{
Event.OnDebugEnd();
}
Parallel.ForEach(SessionEvents, Event => Event.OnDebugEnd());
}
public DebuggerSymbol ResolveSymbol(uint Address)
@ -752,8 +740,8 @@ namespace CxbxDebugger
public void RegisterEventInterfaces(object EventClass)
{
IDebuggerGeneralEvents GeneralListener = EventClass as IDebuggerGeneralEvents;
if(GeneralListener != null ) GeneralEvents.Add(GeneralListener);
IDebuggerSessionEvents SessionListener = EventClass as IDebuggerSessionEvents;
if(SessionListener != null ) SessionEvents.Add(SessionListener);
IDebuggerProcessEvents ProcessListener = EventClass as IDebuggerProcessEvents;
if (ProcessListener != null) ProcessEvents.Add(ProcessListener);

View File

@ -5,11 +5,12 @@ using System;
namespace CxbxDebugger
{
public interface IDebuggerGeneralEvents
public interface IDebuggerSessionEvents
{
void OnDebugStart();
void OnDebugEnd();
void OnDebugTitleLoaded(string Title);
void OnDebugTargetChanged(string CommandLine);
}
public interface IDebuggerProcessEvents

View File

@ -9,15 +9,20 @@ namespace CxbxDebugger
{
public enum ReportType : uint
{
HLECACHE_FILE = 0x00deed00,
KERNEL_PATCH = 0x00deed01,
FILE_OPENED = 0x00deed02,
FILE_READ = 0x00deed03,
FILE_CLOSED = 0x00deed04,
DEBUGGER_INIT = 0x00deed05,
FILE_WRITE = 0x00deed06,
HLECACHE_FILE = 0x1000,
OVERRIDE_EXCEPTION = 0x00ceed01,
KERNEL_PATCH = 0x2000,
FILE_OPENED = 0x3000,
FILE_READ = 0x3001,
FILE_WRITE = 0x3002,
FILE_CLOSED = 0x3003,
DEBUGGER_INIT = 0x4000,
DEBUGGER_NEW_TARGET = 0x4001,
OVERRIDE_EXCEPTION = 0x5000,
// Exception code from https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
MS_VC_EXCEPTION = 0x406D1388,
@ -29,22 +34,38 @@ namespace CxbxDebugger
WCHAR,
};
public class DataProcessor
{
uint[] SourceData;
uint SourceIndex;
public DataProcessor(uint[] Data)
{
SourceData = Data;
SourceIndex = 0;
}
public uint Pop()
{
return SourceData[SourceIndex++];
}
}
public class HLECache
{
public string FileName { get; set; }
}
public static HLECache GetHLECacheReport(DebuggerThread Context, uint[] Data)
public static HLECache GetHLECacheReport(DebuggerThread Context, DataProcessor Data)
{
HLECache Report = new HLECache();
StringType Type = (StringType)Data[0];
var Type = (StringType)Data.Pop();
if (Type != StringType.CHAR)
throw new Exception("GetHLECacheReport expects a string message");
uint Length = Data[1];
IntPtr MessagePtr = new IntPtr(Data[2]);
var Length = Data.Pop(); ;
var MessagePtr = new IntPtr(Data.Pop());
Report.FileName = Context.OwningProcess.ReadString(MessagePtr, Length);
@ -57,20 +78,19 @@ namespace CxbxDebugger
public IntPtr Address { get; set; }
}
public static KernelPatch GetKernelPatchReport(DebuggerThread Context, uint[] Data)
public static KernelPatch GetKernelPatchReport(DebuggerThread Context, DataProcessor Data)
{
KernelPatch Report = new KernelPatch();
StringType Type = (StringType)Data[0];
var Type = (StringType)Data.Pop();
if (Type != StringType.CHAR)
throw new Exception("GetKernelPatchReport expects a string message");
uint Length = Data[1];
IntPtr MessagePtr = new IntPtr(Data[2]);
var Length = Data.Pop();
var MessagePtr = new IntPtr(Data.Pop());
Report.Name = Context.OwningProcess.ReadString(MessagePtr, Length);
Report.Address = new IntPtr(Data[3]);
Report.Address = new IntPtr(Data.Pop());
return Report;
}
@ -82,23 +102,21 @@ namespace CxbxDebugger
public bool Succeeded { get; set; }
}
public static FileOpened GetFileOpenedReport(DebuggerThread Context, uint[] Data)
public static FileOpened GetFileOpenedReport(DebuggerThread Context, DataProcessor Data)
{
FileOpened Report = new FileOpened();
Report.Handle = new IntPtr(Data[0]);
StringType Type = (StringType)Data[1];
Report.Handle = new IntPtr(Data.Pop());
var Type = (StringType)Data.Pop();
if (Type != StringType.WCHAR)
throw new Exception("GetFileOpenedReport expects a widestring message");
uint Length = Data[2];
IntPtr MessagePtr = new IntPtr(Data[3]);
var Length = Data.Pop();
var MessagePtr = new IntPtr(Data.Pop());
Report.FileName = Context.OwningProcess.ReadWString(MessagePtr, Length);
Report.Succeeded = Data[4] != 0;
Report.Succeeded = Data.Pop() != 0;
return Report;
}
@ -110,13 +128,13 @@ namespace CxbxDebugger
public uint Offset { get; set; }
}
public static FileRead GetFileReadReport(DebuggerThread Context, uint[] Data)
public static FileRead GetFileReadReport(DebuggerThread Context, DataProcessor Data)
{
FileRead Report = new FileRead();
Report.Handle = new IntPtr(Data[0]);
Report.Length = Data[1];
Report.Offset = Data[2];
Report.Handle = new IntPtr(Data.Pop());
Report.Length = Data.Pop();
Report.Offset = Data.Pop();
return Report;
}
@ -128,13 +146,13 @@ namespace CxbxDebugger
public uint Offset { get; set; }
}
public static FileWrite GetFileWriteReport(DebuggerThread Context, uint[] Data)
public static FileWrite GetFileWriteReport(DebuggerThread Context, DataProcessor Data)
{
FileWrite Report = new FileWrite();
Report.Handle = new IntPtr(Data[0]);
Report.Length = Data[1];
Report.Offset = Data[2];
Report.Handle = new IntPtr(Data.Pop());
Report.Length = Data.Pop();
Report.Offset = Data.Pop();
return Report;
}
@ -144,18 +162,20 @@ namespace CxbxDebugger
public IntPtr Handle { get; set; }
}
public static FileClosed GetFileClosedReport(DebuggerThread Context, uint[] Data)
public static FileClosed GetFileClosedReport(DebuggerThread Context, DataProcessor Data)
{
// TODO: Restructure this library
uint InvalidHandle = (uint)VsChromium.Core.Win32.Handles.NativeMethods.INVALID_HANDLE_VALUE;
var Handle = Data.Pop();
// Skip invalid file handles
if (Data[0] == InvalidHandle)
if (Handle == InvalidHandle)
return null;
FileClosed Report = new FileClosed();
Report.Handle = new IntPtr(Data[0]);
Report.Handle = new IntPtr(Handle);
return Report;
}
@ -169,59 +189,78 @@ namespace CxbxDebugger
public IntPtr ParameterBase { get; set; }
}
public static ExceptionHandledQuery GetExceptionHandledQuery(DebuggerThread Context, uint[] Data)
public static ExceptionHandledQuery GetExceptionHandledQuery(DebuggerThread Context, DataProcessor Data)
{
ExceptionHandledQuery Query = new ExceptionHandledQuery();
Query.ReponseAddr = new IntPtr(Data[0]);
Query.ExceptionAddress = Data[1];
Query.ExceptionCode = Data[2];
Query.ParameterCount = Data[3];
Query.ParameterBase = new IntPtr(Data[4]);
Query.ReponseAddr = new IntPtr(Data.Pop());
Query.ExceptionAddress = Data.Pop();
Query.ExceptionCode = Data.Pop();
Query.ParameterCount = Data.Pop();
Query.ParameterBase = new IntPtr(Data.Pop());
return Query;
}
public class DebuggerInit
{
public uint TitleID { get; set; }
public string Title { get; set; }
}
public static DebuggerInit GetDebuggerInitReport(DebuggerThread Context, uint[] Data)
public static DebuggerInit GetDebuggerInitReport(DebuggerThread Context, DataProcessor Data)
{
DebuggerInit Report = new DebuggerInit();
Report.TitleID = Data[0];
StringType Type = (StringType)Data[1];
StringType Type = (StringType)Data.Pop();
if (Type != StringType.CHAR)
throw new Exception("GetDebuggerInitReport expects a string message");
uint Length = Data[2];
IntPtr MessagePtr = new IntPtr(Data[3]);
uint Length = Data.Pop();
IntPtr MessagePtr = new IntPtr(Data.Pop());
Report.Title = Context.OwningProcess.ReadString(MessagePtr, Length);
return Report;
}
public class DebuggerNewTarget
{
public string CommandLine { get; set; }
}
public static DebuggerNewTarget GetDebuggerNewTargetReport(DebuggerThread Context, DataProcessor Data)
{
var Report = new DebuggerNewTarget();
StringType Type = (StringType)Data.Pop();
if (Type != StringType.CHAR)
throw new Exception("GetDebuggerInitReport expects a string message");
uint Length = Data.Pop();
IntPtr MessagePtr = new IntPtr(Data.Pop());
Report.CommandLine = Context.OwningProcess.ReadString(MessagePtr, Length);
return Report;
}
public class MSVCThreadName
{
public string Name { get; set; }
public uint ThreadId { get; set; }
}
public static MSVCThreadName GetMSVCThreadName(DebuggerThread Context, uint[] Data)
public static MSVCThreadName GetMSVCThreadName(DebuggerThread Context, DataProcessor Data)
{
uint Type = Data[0];
var Type = Data.Pop();
if (Type != 0x1000)
return null;
string ReportName = "";
IntPtr MessagePtr = new IntPtr(Data[1]);
IntPtr MessagePtr = new IntPtr(Data.Pop());
if (MessagePtr != IntPtr.Zero)
{
ReportName = Context.OwningProcess.ReadString(MessagePtr);
@ -230,7 +269,7 @@ namespace CxbxDebugger
MSVCThreadName Report = new MSVCThreadName();
Report.Name = ReportName;
Report.ThreadId = Data[2];
Report.ThreadId = Data.Pop();
return Report;
}

View File

@ -114,6 +114,12 @@ namespace CxbxDebugger
if (ebp == 0 || ReturnAddr == ebp)
break;
if ((ReturnAddr & 0x80000000) != 0)
break;
if ((ebp & 0x80000000) != 0)
break;
CallstackCache.AddFrame(new DebuggerStackFrame(new IntPtr(ReturnAddr), new IntPtr(ebp)));
}
while (CallstackCache.CanCollect);

View File

@ -0,0 +1,51 @@
// Written by x1nixmzeng for the Cxbx-Reloaded project
//
namespace CxbxDebugger
{
public enum SessionState
{
Inactive,
Running,
Ended,
}
public enum DebugState
{
Unknown,
Idle,
Suspended,
Breakpoint,
Running,
Terminated,
}
public struct DebugStateInfo
{
public DebugState State;
public string Detail;
}
public interface IDebugWindow
{
void StartSession();
void SuspendSession();
void ResumeSession();
SessionState GetSessionState();
DebugStateInfo GetDebugStateInfo();
}
public interface IDebugContainerWindow
{
void AddDebugSession(string[] Arguments, bool StartAutomatically);
void ReportGameTitle(string GameTitle);
void ReportStatus(IDebugWindow Window, DebugState Status, string Detail);
}
}

View File

@ -18,6 +18,7 @@ namespace CxbxDebugger
Application.SetCompatibleTextRenderingDefault(false);
string[] args = Environment.GetCommandLineArgs();
#if !DEBUG
if( args.Length == 1 )
{
// TODO: Valid usage message
@ -25,8 +26,9 @@ namespace CxbxDebugger
Application.Exit();
}
else
#endif
{
Application.Run(new Form1());
Application.Run(new CxbxDebuggerMain(args));
}
}
}

View File

@ -345,6 +345,10 @@ namespace CxbxDebugger
/// <summary>
///
/// </summary>
StatusHandleNotClosable = 0xC0000235,
/// <summary>
///
/// </summary>
GuardPageViolation = 0x80000001,
/// <summary>
///

View File

@ -2,10 +2,25 @@
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include "Version.h"
#include "CxbxVersion.h"
#include <string>
/*! version string dependent on trace flag */
#ifndef _DEBUG_TRACE
const char* CxbxVersionStr = _GIT_VERSION " (" __DATE__ ")";
const char *CxbxrHashBuild = _GIT_VERSION;
#else
const char* CxbxVersionStr = _GIT_VERSION "-Trace (" __DATE__ ")";
const char *CxbxrHashBuild = _GIT_VERSION "-Trace";
#endif
static constexpr const char *GitVersionStr = _GIT_VERSION;
static constexpr size_t GitVersionLength = std::char_traits<char>::length(GitVersionStr);
static_assert(GitVersionLength < GitVersionMaxLength);
const char *const GetGitVersionStr() {
return GitVersionStr;
}
const size_t GetGitVersionLength() {
return GitVersionLength;
}

View File

@ -1,5 +1,10 @@
#pragma once
#include "version.h"
extern const char* CxbxVersionStr;
extern const char *CxbxrHashBuild;
// Note: GitVersionMaxLength should be large enough to accomodate the longest git version string we can practically expect to have. This is necessary
// to avoid possible mismatches in the string length which can happen if the user mixes different cxbxr versions
inline constexpr size_t GitVersionMaxLength = 80;
const char *const GetGitVersionStr();
const size_t GetGitVersionLength();

View File

@ -1,5 +1,5 @@
#include <Windows.h>
// Default to High Performance Mode on machines with dual graphics
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; // AMD
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; // NVIDIA
#include <Windows.h>
// Default to High Performance Mode on machines with dual graphics
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; // AMD
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; // NVIDIA

View File

@ -0,0 +1,102 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of Cxbx-Reloaded.
// *
// * Cxbx-Reloaded is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2017-2019 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Windows.h> // For PAGE_READWRITE, PAGE_EXECUTE_READWRITE, and PAGE_NOACCESS
#include "util/std_extend.hpp"
#include "AddressRanges.h"
// NOTE: Cannot be use in the header file.
// For InitialMemoryProtection field only. Memory page protection usage, for use by VirtualAlloc
// Shortend symbol aliasses for memory page protection
#define PROT_UNH 0 // UNHANDLED
#define PROT_RW PAGE_READWRITE
#define PROT_XRW PAGE_EXECUTE_READWRITE
#define PROT_NAC PAGE_NOACCESS
const _XboxAddressRanges XboxAddressRanges[] = {
#ifdef DEBUG
#define RANGE_ENTRY(START, END, SIZE, PROT, FLAGS, COMMENT) { START, END, SIZE, PROT, FLAGS, COMMENT }
#else
#define RANGE_ENTRY(START, END, SIZE, PROT, FLAGS, COMMENT) { START, SIZE, PROT, FLAGS }
#endif
// See https://xboxdevwiki.net/Memory
// and https://xboxdevwiki.net/Boot_Process#Paging
// Entry : Start , End , Size , Protect , RangeFlags , Comment
RANGE_ENTRY(USER_ADDRESS1_BASE, USER_ADDRESS1_END, USER_ADDRESS1_SIZE, PROT_XRW, SYSTEM_ALL | MAY_FAIL, "MemLowVirtual (General Xbox type) lower 64 MiB Optional (already reserved via virtual_memory_placeholder)"),
RANGE_ENTRY(USER_ADDRESS2_BASE, USER_ADDRESS2_END, USER_ADDRESS2_SIZE, PROT_XRW, SYSTEM_128MB | MAY_FAIL, "MemLowVirtual (Chihiro / DevKit) ^ + upper 64 MiB"),
RANGE_ENTRY(PHYSICAL_MAP1_BASE, PHYSICAL_MAP1_END, PHYSICAL_MAP1_SIZE, PROT_UNH, SYSTEM_ALL , "MemPhysical (General Xbox type) lower 64 MiB"),
RANGE_ENTRY(PHYSICAL_MAP2_BASE, PHYSICAL_MAP2_END, PHYSICAL_MAP2_SIZE, PROT_UNH, SYSTEM_128MB , "MemPhysical (Chihiro / DevKit) ^ + upper 64 MiB"),
RANGE_ENTRY(DEVKIT_MEMORY_BASE, DEVKIT_MEMORY_END, DEVKIT_MEMORY_SIZE, PROT_NAC, SYSTEM_DEVKIT , "DevKitMemory"), // TODO : Check reserved range (might behave like MemTiled)
RANGE_ENTRY(PAGE_TABLES_BASE , PAGE_TABLES_END , PAGE_TABLES_SIZE , PROT_RW , SYSTEM_ALL , "MemPageTable"), // See PAGE_TABLES_SIZE, which contains one 4 byte entry per PAGE_SIZE
RANGE_ENTRY(SYSTEM_MEMORY_BASE, SYSTEM_MEMORY_END, SYSTEM_MEMORY_SIZE, PROT_RW , SYSTEM_ALL | MAY_FAIL, "SystemMemory Optional"), // TODO : Check reserved range (might behave like MemTiled)
RANGE_ENTRY(TILED_MEMORY_BASE , TILED_MEMORY_END , TILED_MEMORY_SIZE , PROT_UNH, SYSTEM_ALL , "MemTiled Optional (even though it can't be reserved, MapViewOfFileEx to this range still works!?)"),
RANGE_ENTRY(NV2A_DEVICE1_BASE , NV2A_DEVICE1_END , NV2A_DEVICE1_SIZE , PROT_NAC, SYSTEM_ALL , "DeviceNV2A_a (GPU)"),
RANGE_ENTRY(NV2A_PRAMIN_BASE , NV2A_PRAMIN_END , NV2A_PRAMIN_SIZE1 , PROT_RW , SYSTEM_ALL , "MemNV2APRAMIN"),
RANGE_ENTRY(NV2A_DEVICE2_BASE , NV2A_DEVICE2_END , NV2A_DEVICE2_SIZE , PROT_NAC, SYSTEM_ALL , "DeviceNV2A_b (GPU)"),
RANGE_ENTRY(APU_DEVICE_BASE , APU_DEVICE_END , APU_DEVICE_SIZE , PROT_NAC, SYSTEM_ALL , "DeviceAPU"),
RANGE_ENTRY(AC97_DEVICE_BASE , AC97_DEVICE_END , AC97_DEVICE_SIZE , PROT_NAC, SYSTEM_ALL , "DeviceAC97 (ACI)"),
RANGE_ENTRY(USB_DEVICE_BASE , USB_DEVICE_END , USB_DEVICE_SIZE , PROT_NAC, SYSTEM_ALL , "DeviceUSB"),
RANGE_ENTRY(NVNET_DEVICE_BASE , NVNET_DEVICE_END , NVNET_DEVICE_SIZE , PROT_NAC, SYSTEM_ALL , "DeviceNVNet"),
RANGE_ENTRY(FLASH_DEVICE1_BASE, FLASH_DEVICE1_END, FLASH_DEVICEN_SIZE, PROT_NAC, SYSTEM_ALL , "DeviceFlash_a (Flash mirror 1)"),
RANGE_ENTRY(FLASH_DEVICE2_BASE, FLASH_DEVICE2_END, FLASH_DEVICEN_SIZE, PROT_NAC, SYSTEM_ALL , "DeviceFlash_b (Flash mirror 2)"),
RANGE_ENTRY(FLASH_DEVICE3_BASE, FLASH_DEVICE3_END, FLASH_DEVICEN_SIZE, PROT_NAC, SYSTEM_ALL | MAY_FAIL, "DeviceFlash_c (Flash mirror 3)"), // this region fails reservation when running under Ubuntu with wine, so it must be allowed to fail
RANGE_ENTRY(FLASH_DEVICE4_BASE, FLASH_DEVICE4_END, FLASH_DEVICEN_SIZE, PROT_NAC, SYSTEM_ALL | MAY_FAIL, "DeviceFlash_d (Flash mirror 4) Optional (will probably fail reservation, which is acceptable - the 3 other mirrors work just fine"),
#undef RANGE_ENTRY
};
const size_t XboxAddressRanges_size = ARRAY_SIZE(XboxAddressRanges);
bool AddressRangeMatchesFlags(const size_t index, const unsigned int flags)
{
return XboxAddressRanges[index].RangeFlags & flags;
}
bool IsOptionalAddressRange(const size_t index)
{
return AddressRangeMatchesFlags(index, MAY_FAIL);
}
unsigned int AddressRangeGetSystemFlags(const size_t index)
{
return XboxAddressRanges[index].RangeFlags & SYSTEM_ALL;
}
bool VerifyWow64()
{
typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
BOOL bIsWow64 = FALSE;
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(hKernel32, "IsWow64Process");
if (fnIsWow64Process != nullptr) {
HANDLE hCurrentProcess = GetCurrentProcess();
fnIsWow64Process(hCurrentProcess, &bIsWow64);
}
return (bIsWow64 != FALSE);
}

211
src/common/AddressRanges.h Normal file
View File

@ -0,0 +1,211 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of Cxbx-Reloaded.
// *
// * Cxbx-Reloaded is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2017-2019 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2019 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
#include <cstdint> // For uint32_t
#define KiB(x) ((x) * 1024 ) // = 0x00000400
#define MiB(x) ((x) * KiB(1024)) // = 0x00100000
// TODO: Convert the rest of defines to constexpr or const in AddressRanges.h file in master/develop branch.
#define USER_ADDRESS1_BASE 0x00010000
#define USER_ADDRESS1_SIZE (MiB(64) - KiB(64)) // = 0x03FF0000
#define USER_ADDRESS1_END (USER_ADDRESS1_BASE + USER_ADDRESS1_SIZE - 1) // 0x03FFFFFF
#define USER_ADDRESS2_BASE 0x04000000
#define USER_ADDRESS2_SIZE (MiB(64)) // = 0x04000000
#define USER_ADDRESS2_END (USER_ADDRESS2_BASE + USER_ADDRESS2_SIZE - 1) // 0x07FFFFFF
// Base addresses of various components
// Segaboot entry point xor address
inline const uint32_t SEGABOOT_EP_XOR = 0x40000000;
// Kernel Segment Zero
#define KSEG0_BASE 0x80000000
#define PHYSICAL_MAP_BASE 0x80000000
#define PHYSICAL_MAP_SIZE (MiB(256)) // = 0x10000000
#define PHYSICAL_MAP_END (PHYSICAL_MAP_BASE + PHYSICAL_MAP_SIZE - 1) // 0x8FFFFFFF
inline constexpr uint32_t PHYSICAL_MAP1_BASE = 0x80000000;
inline constexpr uint32_t PHYSICAL_MAP1_SIZE = (MiB(64)); // = 0x04000000
inline constexpr uint32_t PHYSICAL_MAP1_END = (PHYSICAL_MAP1_BASE + PHYSICAL_MAP1_SIZE - 1); // 0x83FFFFFF
inline constexpr uint32_t PHYSICAL_MAP2_BASE = 0x84000000;
inline constexpr uint32_t PHYSICAL_MAP2_SIZE = (MiB(64)); // = 0x04000000
inline constexpr uint32_t PHYSICAL_MAP2_END = (PHYSICAL_MAP2_BASE + PHYSICAL_MAP2_SIZE - 1); // 0x8FFFFFFF
#define CONTIGUOUS_MEMORY_BASE KSEG0_BASE // = 0x80000000
#define XBOX_CONTIGUOUS_MEMORY_SIZE (MiB(64))
#define CHIHIRO_CONTIGUOUS_MEMORY_SIZE (MiB(128))
inline constexpr uint32_t DEVKIT_MEMORY_BASE = 0xB0000000;
inline constexpr uint32_t DEVKIT_MEMORY_SIZE = (MiB(256)); // = 0x10000000
inline constexpr uint32_t DEVKIT_MEMORY_END = (DEVKIT_MEMORY_BASE + DEVKIT_MEMORY_SIZE - 1); // 0xBFFFFFFF
inline constexpr uint32_t PAGE_TABLES_BASE = 0xC0000000;
inline constexpr uint32_t PAGE_TABLES_SIZE = (MiB(4)); // = 0x00400000
inline constexpr uint32_t PAGE_TABLES_END = (PAGE_TABLES_BASE + PAGE_TABLES_SIZE - 1); // 0xC03FFFFF
inline constexpr uint32_t SYSTEM_MEMORY_BASE = 0xD0000000;
inline constexpr uint32_t SYSTEM_MEMORY_SIZE = (MiB(512)); // = 0x20000000
inline constexpr uint32_t SYSTEM_MEMORY_END = (SYSTEM_MEMORY_BASE + SYSTEM_MEMORY_SIZE - 1); // 0xEFFFFFFF
inline constexpr uint32_t TILED_MEMORY_BASE = 0xF0000000;
inline constexpr uint32_t TILED_MEMORY_SIZE = (MiB(64)); // = 0x04000000
inline constexpr uint32_t TILED_MEMORY_END = (TILED_MEMORY_BASE + TILED_MEMORY_SIZE - 1); // 0xF3FFFFFF
#define XBOX_WRITE_COMBINED_BASE 0xF0000000 // WC (The WC memory is another name of the tiled memory)
#define XBOX_WRITE_COMBINED_SIZE (MiB(128)) // = 0x08000000
#define XBOX_WRITE_COMBINED_END (XBOX_WRITE_COMBINED_BASE + XBOX_WRITE_COMBINED_SIZE - 1) // 0xF7FFFFFF
#define XBOX_UNCACHED_BASE 0xF8000000 // UC
#define XBOX_UNCACHED_SIZE (MiB(128 - 4)) // = 0x07C00000
#define XBOX_UNCACHED_END (XBOX_UNCACHED_BASE + XBOX_UNCACHED_SIZE - 1) // - 0xFFBFFFFF
inline constexpr uint32_t NV2A_DEVICE1_BASE = 0xFD000000;
inline constexpr uint32_t NV2A_DEVICE1_SIZE = (MiB(7)); // = 0x00700000
inline constexpr uint32_t NV2A_DEVICE1_END = (NV2A_DEVICE1_BASE + NV2A_DEVICE1_SIZE - 1); // 0xFD6FFFFF
inline constexpr uint32_t NV2A_PRAMIN_BASE = 0xFD700000;
inline constexpr uint32_t NV2A_PRAMIN_SIZE1 = (MiB(1)); // = 0x00100000 // TODO: Might be best to merge PCIDevice.h's address ranges into this header file.
inline constexpr uint32_t NV2A_PRAMIN_END = (NV2A_PRAMIN_BASE + NV2A_PRAMIN_SIZE1 - 1); // 0xFD7FFFFF
inline constexpr uint32_t NV2A_DEVICE2_BASE = 0xFD800000;
inline constexpr uint32_t NV2A_DEVICE2_SIZE = (MiB(8)); // = 0x00800000
inline constexpr uint32_t NV2A_DEVICE2_END = (NV2A_DEVICE2_BASE + NV2A_DEVICE2_SIZE - 1); // 0xFDFFFFFF
inline constexpr uint32_t APU_DEVICE_BASE = 0xFE800000;
inline constexpr uint32_t APU_DEVICE_SIZE = (KiB(512)); // = 0x00080000
inline constexpr uint32_t APU_DEVICE_END = (APU_DEVICE_BASE + APU_DEVICE_SIZE - 1); // 0xFE87FFFF
inline constexpr uint32_t AC97_DEVICE_BASE = 0xFEC00000;
inline constexpr uint32_t AC97_DEVICE_SIZE = (KiB(4)); // = 0x0001000
inline constexpr uint32_t AC97_DEVICE_END = (AC97_DEVICE_BASE + AC97_DEVICE_SIZE - 1); // 0xFEC00FFF
inline constexpr uint32_t USB_DEVICE_BASE = 0xFED00000;
inline constexpr uint32_t USB_DEVICE_SIZE = (KiB(4)); // = 0x0001000
inline constexpr uint32_t USB_DEVICE_END = (USB_DEVICE_BASE + USB_DEVICE_SIZE - 1); // 0xFED00FFF
inline constexpr uint32_t NVNET_DEVICE_BASE = 0xFEF00000;
inline constexpr uint32_t NVNET_DEVICE_SIZE = (KiB(1)); // = 0x00000400
inline constexpr uint32_t NVNET_DEVICE_END = (NVNET_DEVICE_BASE + NVNET_DEVICE_SIZE - 1); // 0xFEF003FF
inline constexpr uint32_t FLASH_DEVICEN_SIZE = (MiB(4)); // = 0x00400000
inline constexpr uint32_t FLASH_DEVICE1_BASE = 0xFF000000;
inline constexpr uint32_t FLASH_DEVICE1_END = (FLASH_DEVICE1_BASE + FLASH_DEVICEN_SIZE - 1); // 0xFF3FFFFF
inline constexpr uint32_t FLASH_DEVICE2_BASE = 0xFF400000;
inline constexpr uint32_t FLASH_DEVICE2_END = (FLASH_DEVICE2_BASE + FLASH_DEVICEN_SIZE - 1); // 0xFF7FFFFF
inline constexpr uint32_t FLASH_DEVICE3_BASE = 0xFF800000;
inline constexpr uint32_t FLASH_DEVICE3_END = (FLASH_DEVICE3_BASE + FLASH_DEVICEN_SIZE - 1); // 0xFFBFFFFF
inline constexpr uint32_t FLASH_DEVICE4_BASE = 0xFFC00000;
inline constexpr uint32_t FLASH_DEVICE4_END = (FLASH_DEVICE4_BASE - 1 + FLASH_DEVICEN_SIZE); // 0xFFFFFFFF // -1 must be before size to remove compiler warning.
// Miscellaneous base addresses
#define XBE_IMAGE_BASE 0x00010000
#define PAGE_DIRECTORY_BASE 0xC0300000
#define NV2A_INIT_VECTOR 0xFF000008
// Define virtual base and alternate virtual base of kernel
#define XBOX_KERNEL_BASE (PHYSICAL_MAP_BASE + XBE_IMAGE_BASE)
#define KERNEL_PHYSICAL_ADDRESS XBE_IMAGE_BASE // = 0x10000
#define KERNEL_SIZE sizeof(DUMMY_KERNEL)
#define KERNEL_STACK_SIZE 12288 // 0x03000, needed by PsCreateSystemThreadEx, however the current implementation doesn't use it
// Miscellaneous memory variables
// Xbox pages are (1 << 12) = 0x00001000 = 4096 bytes in size. Large pages are 4 MiB instead
// NOTE: PAGE_SIZE is also defined in xfile.h (oxdk) and linux_wrapper.h (oxdk)
#define PAGE_SHIFT 12 // 2^12 = 4 KiB
#define PAGE_SIZE (1 << PAGE_SHIFT) // = 0x00001000 = KiB(4)
#define PAGE_MASK (PAGE_SIZE - 1)
#define LARGE_PAGE_SHIFT 22 // 2^22 = 4 MiB
#define LARGE_PAGE_SIZE (1 << LARGE_PAGE_SHIFT) // = 0x00400000 = 4 MiB
#define LARGE_PAGE_MASK (LARGE_PAGE_SIZE - 1)
#define BYTES_IN_PHYSICAL_MAP (MiB(256)) // this refers to the system RAM physical window 0x80000000 - 0x8FFFFFFF
#define MAXIMUM_ZERO_BITS 21 // for XbAllocateVirtualMemory
#define MAX_VIRTUAL_ADDRESS 0xFFFFFFFF
#define LOWEST_USER_ADDRESS XBE_IMAGE_BASE // = 0x00010000
#define HIGHEST_USER_ADDRESS 0x7FFEFFFF
#define HIGHEST_VMA_ADDRESS (HIGHEST_USER_ADDRESS - X64KB) // for NtAllocateVirtualMemory
#define USER_MEMORY_SIZE (HIGHEST_USER_ADDRESS - LOWEST_USER_ADDRESS + 1) // 0x7FFE0000 = 2 GiB - 128 KiB
// Memory size per system
#define XBOX_MEMORY_SIZE (MiB(64))
#define CHIHIRO_MEMORY_SIZE (MiB(128))
// Common page calculations
#define ROUND_UP_4K(size) (((size) + PAGE_MASK) & (~PAGE_MASK))
#define ROUND_UP(size, alignment) (((size) + (alignment - 1)) & (~(alignment - 1)))
#define ROUND_DOWN_4K(size) ((size) & (~PAGE_MASK))
#define ROUND_DOWN(size, alignment) ((size) & (~(alignment - 1)))
#define CHECK_ALIGNMENT(size, alignment) (((size) % (alignment)) == 0)
#define PAGE_ALIGN(address) ROUND_DOWN_4K(address)
// Windows' address space allocation granularity;
// See https://blogs.msdn.microsoft.com/oldnewthing/20031008-00/?p=42223
const int BLOCK_SIZE = KiB(64);
extern const struct _XboxAddressRanges {
uint32_t Start;
#ifdef DEBUG
uint32_t End; // TODO : Add validation that this End corresponds to specified Size
#endif
uint32_t Size;
unsigned long InitialMemoryProtection; // Memory page protection, for use by VirtualAlloc
// Shortend symbol aliasses for memory page protection
#define PROT_UNH 0 // UNHANDLED
#define PROT_RW PAGE_READWRITE
#define PROT_XRW PAGE_EXECUTE_READWRITE
#define PROT_NAC PAGE_NOACCESS
unsigned int RangeFlags;
// Range flags (used for system selection and optional marker)
#define MAY_FAIL (1 << 0) // Optional (may fail address range reservation)
#define SYSTEM_XBOX (1 << 1)
#define SYSTEM_DEVKIT (1 << 2)
#define SYSTEM_CHIHIRO (1 << 3)
// Short-hand for sets of system configurations
#define SYSTEM_ALL (SYSTEM_XBOX | SYSTEM_DEVKIT | SYSTEM_CHIHIRO)
#define SYSTEM_128MB ( SYSTEM_DEVKIT | SYSTEM_CHIHIRO)
#ifdef DEBUG
const char *Comment;
#endif
} XboxAddressRanges[];
extern const size_t XboxAddressRanges_size;
extern bool AddressRangeMatchesFlags(const size_t index, const unsigned int flags);
extern bool IsOptionalAddressRange(const size_t index);
extern unsigned int AddressRangeGetSystemFlags(const size_t index);
extern bool VerifyWow64();

View File

@ -37,19 +37,19 @@ namespace CxbxDebugger
// Note: Keep the top 3-bits empty as they are used internally
enum ReportType : DWORD
{
// Debugger report codes:
HLECACHE_FILE = 0x1000,
HLECACHE_FILE = 0x00deed00,
KERNEL_PATCH = 0x00deed01,
FILE_OPENED = 0x00deed02,
FILE_READ = 0x00deed03,
FILE_CLOSED = 0x00deed04,
DEBUGGER_INIT = 0x00deed05,
FILE_WRITE = 0x00deed06,
KERNEL_PATCH = 0x2000,
// Debugger query codes:
FILE_OPENED = 0x3000,
FILE_READ = 0x3001,
FILE_WRITE = 0x3002,
FILE_CLOSED = 0x3003,
OVERRIDE_EXCEPTION = 0x00ceed01,
DEBUGGER_INIT = 0x4000,
DEBUGGER_NEW_TARGET = 0x4001,
OVERRIDE_EXCEPTION = 0x5000,
};
bool IsAttached()
@ -128,8 +128,10 @@ namespace CxbxDebugger
case Internal::KERNEL_PATCH:
case Internal::FILE_OPENED:
case Internal::FILE_READ:
case Internal::FILE_WRITE:
case Internal::FILE_CLOSED:
case Internal::DEBUGGER_INIT:
case Internal::DEBUGGER_NEW_TARGET:
return true;
case Internal::OVERRIDE_EXCEPTION:
@ -148,12 +150,20 @@ namespace CxbxDebugger
{
Internal::ReportHelper Report(Internal::DEBUGGER_INIT);
Report.Add(0); // unused
Report.AddString(XbeTitle);
Report.Send();
}
void ReportNewTarget(const char* CommandLine)
{
Internal::ReportHelper Report(Internal::DEBUGGER_NEW_TARGET);
Report.AddString(CommandLine);
Report.Send();
}
void ReportHLECacheFile(const char* Filename)
{
Internal::ReportHelper Report(Internal::HLECACHE_FILE);

View File

@ -36,6 +36,7 @@ namespace CxbxDebugger
// Report helpers:
void ReportDebuggerInit(const char* XbeTitle);
void ReportNewTarget(const char* CommandLine);
void ReportHLECacheFile(const char* Filename);
void ReportKernelPatch(const char* ImportName, DWORD Address);

View File

@ -27,12 +27,8 @@
#define LOG_PREFIX CXBXR_MODULE::EEPR
#define LOG_PREFIX_INIT CXBXR_MODULE::INIT
// prevent name collisions
namespace xboxkrnl
{
#include <xboxkrnl/xboxkrnl.h> // For XC_VALUE_INDEX and XBOX_EEPROM
};
#include <core\kernel\exports\xboxkrnl.h> // For XC_VALUE_INDEX and XBOX_EEPROM
#include "cxbxr.hpp" // For CxbxrAbort
#include <stdio.h> // For printf
#include <shlobj.h> // For HANDLE, CreateFile, CreateFileMapping, MapViewOfFile
#include <random>
@ -40,14 +36,13 @@ namespace xboxkrnl
#include "EmuEEPROM.h" // For EEPROMInfo, EEPROMInfos
#include "core\kernel\support\Emu.h" // For EmuWarning
#include "..\..\src\devices\LED.h" // For SetLEDSequence
#include "..\core\kernel\init\CxbxKrnl.h"
xboxkrnl::XBOX_EEPROM *EEPROM = nullptr; // Set using CxbxRestoreEEPROM()
xbox::XBOX_EEPROM *EEPROM = nullptr; // Set using CxbxRestoreEEPROM()
// Default value (NA), overwritten with the actual content in the eeprom by CxbxRestoreEEPROM
xboxkrnl::ULONG XboxFactoryGameRegion = XC_GAME_REGION_NA;
xbox::ulong_xt XboxFactoryGameRegion = XC_GAME_REGION_NA;
const EEPROMInfo* EmuFindEEPROMInfo(xboxkrnl::XC_VALUE_INDEX index)
const EEPROMInfo* EmuFindEEPROMInfo(xbox::XC_VALUE_INDEX index)
{
for (int i = 0; EEPROMInfos[i].index != XC_END_MARKER; i++)
if (EEPROMInfos[i].index == index)
@ -79,7 +74,7 @@ static void EepromCRC(unsigned char *crc, unsigned char *data, long dataLen) {
free(CRC_Data);
}
void gen_section_CRCs(xboxkrnl::XBOX_EEPROM* eeprom) {
void gen_section_CRCs(xbox::XBOX_EEPROM* eeprom) {
const long Factory_size = sizeof(eeprom->FactorySettings) - sizeof(eeprom->FactorySettings.Checksum);
const long User_size = sizeof(eeprom->UserSettings) - sizeof(eeprom->UserSettings.Checksum);
EepromCRC(
@ -94,9 +89,10 @@ void gen_section_CRCs(xboxkrnl::XBOX_EEPROM* eeprom) {
);
}
xboxkrnl::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin)
#ifdef CXBXR_EMU
xbox::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin)
{
xboxkrnl::XBOX_EEPROM *pEEPROM;
xbox::XBOX_EEPROM *pEEPROM;
// First, try to open an existing EEPROM.bin file :
HANDLE hFileEEPROM = CreateFile(szFilePath_EEPROM_bin,
@ -126,7 +122,7 @@ xboxkrnl::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin)
}
// Make sure EEPROM.bin is at least 256 bytes in size
SetFilePointer(hFileEEPROM, 256, nullptr, FILE_BEGIN);
SetFilePointer(hFileEEPROM, EEPROM_SIZE, nullptr, FILE_BEGIN);
SetEndOfFile(hFileEEPROM);
HANDLE hFileMappingEEPROM = CreateFileMapping(
@ -145,14 +141,12 @@ xboxkrnl::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin)
LARGE_INTEGER len_li;
GetFileSizeEx(hFileEEPROM, &len_li);
unsigned int FileSize = len_li.u.LowPart;
if (FileSize != 256)
{
CxbxKrnlCleanup("%s : EEPROM.bin file is not 256 bytes large!\n", __func__);
return nullptr;
if (FileSize != 256) {
CxbxrAbort("%s : EEPROM.bin file is not 256 bytes large!\n", __func__);
}
// Map EEPROM.bin contents into memory :
pEEPROM = (xboxkrnl::XBOX_EEPROM *)MapViewOfFile(
pEEPROM = (xbox::XBOX_EEPROM *)MapViewOfFile(
hFileMappingEEPROM,
FILE_MAP_READ | FILE_MAP_WRITE,
/* dwFileOffsetHigh */0,
@ -184,11 +178,11 @@ xboxkrnl::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin)
}
// Read the HDD (and eventually also the online) keys stored in the eeprom file. Users can input them in the eeprom menu
memcpy(xboxkrnl::XboxHDKey, pEEPROM->EncryptedSettings.HDKey, xboxkrnl::XBOX_KEY_LENGTH);
memcpy(xbox::XboxHDKey, pEEPROM->EncryptedSettings.HDKey, xbox::XBOX_KEY_LENGTH);
// Verify the checksum of the eeprom header
UCHAR Checksum[20] = { 0 };
xboxkrnl::XcHMAC(xboxkrnl::XboxEEPROMKey, 16, pEEPROM->EncryptedSettings.Confounder, 8, pEEPROM->EncryptedSettings.HDKey, 20, Checksum);
xbox::XcHMAC(xbox::XboxEEPROMKey, 16, pEEPROM->EncryptedSettings.Confounder, 8, pEEPROM->EncryptedSettings.HDKey, 20, Checksum);
if (memcmp(Checksum, pEEPROM->EncryptedSettings.Checksum, 20))
{
// The checksums do not match. Log this error and flash the LED (red, off, red, off)
@ -198,21 +192,51 @@ xboxkrnl::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin)
return pEEPROM;
}
#endif
void EmuEEPROMReset(xboxkrnl::XBOX_EEPROM* eeprom)
void EmuEEPROMReset(xbox::XBOX_EEPROM* eeprom)
{
memset(eeprom, 0, sizeof(xboxkrnl::XBOX_EEPROM));
memset(eeprom, 0, sizeof(xbox::XBOX_EEPROM));
// Set Factory Settings
// Setup random number generator
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> randomDis(0, 255);
// Factory Settings
eeprom->FactorySettings.AVRegion = AV_STANDARD_NTSC_M | AV_FLAGS_60Hz;
memcpy(eeprom->FactorySettings.SerialNumber, "Cxbx-R ", 12);
// TODO: Ethernet Address
// TODO: Online Key
// Encrypted Section
// Generate a random serial number
std::uniform_int_distribution<> serialDis(0, 9);
std::string serial = "";
for (int i = 0; i < 12; i++) {
serial += std::to_string(serialDis(gen));
}
memset(eeprom->FactorySettings.SerialNumber, 0, 12);
strncpy((char*)eeprom->FactorySettings.SerialNumber, serial.c_str(), 12);
// Generate a random mac address, starting with the Microsoft prefix
eeprom->FactorySettings.EthernetAddr[0] = 0x00;
eeprom->FactorySettings.EthernetAddr[1] = 0x50;
eeprom->FactorySettings.EthernetAddr[2] = 0xF2;
for (int i = 3; i < 6; i++) {
eeprom->FactorySettings.EthernetAddr[i] = randomDis(gen);
}
// Generate a random Online Key
for (int i = 0; i < 16; i++) {
eeprom->FactorySettings.OnlineKey[i] = randomDis(gen);
}
// Encrypted Settings
eeprom->EncryptedSettings.GameRegion = XC_GAME_REGION_NA;
// TODO: HDD Key
xboxkrnl::XcHMAC(xboxkrnl::XboxEEPROMKey, 16, eeprom->EncryptedSettings.Confounder, 8, eeprom->EncryptedSettings.HDKey, 20, eeprom->EncryptedSettings.Checksum);
// Generate a random HDD Key
for (int i = 0; i < 16; i++) {
eeprom->EncryptedSettings.HDKey[i] = randomDis(gen);
}
xbox::XcHMAC(xbox::XboxEEPROMKey, 16, eeprom->EncryptedSettings.Confounder, 8, eeprom->EncryptedSettings.HDKey, 20, eeprom->EncryptedSettings.Checksum);
// User Settings
eeprom->UserSettings.Language = XC_LANGUAGE_ENGLISH; // = English
@ -222,34 +246,5 @@ void EmuEEPROMReset(xboxkrnl::XBOX_EEPROM* eeprom)
eeprom->UserSettings.ParentalControlMovies = XC_PC_MAX; // = XC_PRTL_CRTL_MAX
eeprom->UserSettings.MiscFlags = 0; // No automatic power down
// Online Settings
// Setup the Serial and Mac Generators
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> serialDis (0, 9);
std::uniform_int_distribution<> macOnlineDis(0, 255);
// Generate a random serial number
std::string serial = "";
for (int i = 0; i < 12; i++) {
serial += std::to_string(serialDis(gen));
}
memset(eeprom->FactorySettings.SerialNumber, 0, 12);
strncpy((char*)eeprom->FactorySettings.SerialNumber, serial.c_str(), 12);
// Generate a random mac address
eeprom->FactorySettings.EthernetAddr[0] = 0x00;
eeprom->FactorySettings.EthernetAddr[1] = 0x50;
eeprom->FactorySettings.EthernetAddr[2] = 0xF2;
for (int i = 3; i < 6; i++) {
eeprom->FactorySettings.EthernetAddr[i] = macOnlineDis(gen);
}
// Generate a random Online Key
for (int i = 0; i < 16; i++) {
eeprom->FactorySettings.OnlineKey[i] = macOnlineDis(gen);
}
// TODO: TimeZone Settings
}

View File

@ -27,61 +27,55 @@
#ifndef EMU_EEPROM_H
#define EMU_EEPROM_H
// prevent name collisions
namespace xboxkrnl
{
#undef _WIN32 // Compile-in REG_DWORD and friends, since we lack a <windows> include here
#include <xboxkrnl/xboxkrnl.h> // For XC_VALUE_INDEX and XBOX_EEPROM
#define _WIN32
};
#include <core\kernel\exports\xboxkrnl.h> // For XC_VALUE_INDEX and XBOX_EEPROM
#define EEPROM_SIZE sizeof(xboxkrnl::XBOX_EEPROM)
#define EEPROM_SIZE sizeof(xbox::XBOX_EEPROM)
typedef struct EEPROMInfo {
xboxkrnl::XC_VALUE_INDEX index;
xbox::XC_VALUE_INDEX index;
int value_offset;
int value_type;
int value_length;
} EEPROMInfo;
#define XC_END_MARKER (xboxkrnl::XC_VALUE_INDEX)-1
#define XC_END_MARKER (xbox::XC_VALUE_INDEX)-1
#define EEPROM_INFO_ENTRY(XC, Member, REG_Type) \
{ xboxkrnl::XC, offsetof(xboxkrnl::XBOX_EEPROM, Member), REG_Type, sizeof(((xboxkrnl::XBOX_EEPROM *)0)->Member) }
{ xbox::XC, offsetof(xbox::XBOX_EEPROM, Member), REG_Type, sizeof(((xbox::XBOX_EEPROM *)0)->Member) }
static const EEPROMInfo EEPROMInfos[] = {
EEPROM_INFO_ENTRY(XC_TIMEZONE_BIAS, UserSettings.TimeZoneBias, REG_DWORD),
EEPROM_INFO_ENTRY(XC_TZ_STD_NAME, UserSettings.TimeZoneStdName, REG_BINARY),
EEPROM_INFO_ENTRY(XC_TZ_STD_DATE, UserSettings.TimeZoneStdDate, REG_DWORD),
EEPROM_INFO_ENTRY(XC_TZ_STD_BIAS, UserSettings.TimeZoneStdBias, REG_DWORD),
EEPROM_INFO_ENTRY(XC_TZ_DLT_NAME, UserSettings.TimeZoneDltName, REG_BINARY),
EEPROM_INFO_ENTRY(XC_TZ_DLT_DATE, UserSettings.TimeZoneDltDate, REG_DWORD),
EEPROM_INFO_ENTRY(XC_TZ_DLT_BIAS, UserSettings.TimeZoneDltBias, REG_DWORD),
EEPROM_INFO_ENTRY(XC_LANGUAGE, UserSettings.Language, REG_DWORD),
EEPROM_INFO_ENTRY(XC_VIDEO, UserSettings.VideoFlags, REG_DWORD),
EEPROM_INFO_ENTRY(XC_AUDIO, UserSettings.AudioFlags, REG_DWORD),
EEPROM_INFO_ENTRY(XC_P_CONTROL_GAMES, UserSettings.ParentalControlGames, REG_DWORD), // Zapper queries this. TODO : Should this be REG_NONE?
EEPROM_INFO_ENTRY(XC_P_CONTROL_PASSWORD, UserSettings.ParentalControlPassword, REG_DWORD),
EEPROM_INFO_ENTRY(XC_P_CONTROL_MOVIES, UserSettings.ParentalControlMovies, REG_DWORD), // Xbox Dashboard queries this.
EEPROM_INFO_ENTRY(XC_ONLINE_IP_ADDRESS, UserSettings.OnlineIpAddress, REG_DWORD),
EEPROM_INFO_ENTRY(XC_ONLINE_DNS_ADDRESS, UserSettings.OnlineDnsAddress, REG_DWORD),
EEPROM_INFO_ENTRY(XC_ONLINE_DEFAULT_GATEWAY_ADDRESS, UserSettings.OnlineDefaultGatewayAddress, REG_DWORD),
EEPROM_INFO_ENTRY(XC_ONLINE_SUBNET_ADDRESS, UserSettings.OnlineSubnetMask, REG_DWORD),
EEPROM_INFO_ENTRY(XC_MISC, UserSettings.MiscFlags, REG_DWORD),
EEPROM_INFO_ENTRY(XC_DVD_REGION, UserSettings.DvdRegion, REG_DWORD),
EEPROM_INFO_ENTRY(XC_MAX_OS, UserSettings, REG_BINARY),
EEPROM_INFO_ENTRY(XC_TIMEZONE_BIAS, UserSettings.TimeZoneBias, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_TZ_STD_NAME, UserSettings.TimeZoneStdName, xbox::reg_binary),
EEPROM_INFO_ENTRY(XC_TZ_STD_DATE, UserSettings.TimeZoneStdDate, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_TZ_STD_BIAS, UserSettings.TimeZoneStdBias, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_TZ_DLT_NAME, UserSettings.TimeZoneDltName, xbox::reg_binary),
EEPROM_INFO_ENTRY(XC_TZ_DLT_DATE, UserSettings.TimeZoneDltDate, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_TZ_DLT_BIAS, UserSettings.TimeZoneDltBias, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_LANGUAGE, UserSettings.Language, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_VIDEO, UserSettings.VideoFlags, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_AUDIO, UserSettings.AudioFlags, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_P_CONTROL_GAMES, UserSettings.ParentalControlGames, xbox::reg_dword), // Zapper queries this. TODO : Should this be xbox::reg_none?
EEPROM_INFO_ENTRY(XC_P_CONTROL_PASSWORD, UserSettings.ParentalControlPassword, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_P_CONTROL_MOVIES, UserSettings.ParentalControlMovies, xbox::reg_dword), // Xbox Dashboard queries this.
EEPROM_INFO_ENTRY(XC_ONLINE_IP_ADDRESS, UserSettings.OnlineIpAddress, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_ONLINE_DNS_ADDRESS, UserSettings.OnlineDnsAddress, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_ONLINE_DEFAULT_GATEWAY_ADDRESS, UserSettings.OnlineDefaultGatewayAddress, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_ONLINE_SUBNET_ADDRESS, UserSettings.OnlineSubnetMask, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_MISC, UserSettings.MiscFlags, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_DVD_REGION, UserSettings.DvdRegion, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_MAX_OS, UserSettings, xbox::reg_binary),
// XC_MAX_OS is called to return a complete XBOX_USER_SETTINGS structure
//
// One example is from XapipQueryTimeZoneInformation(, REG_DWORD, sizeof(DWORD), where it is used to
// One example is from XapipQueryTimeZoneInformation(, xbox::reg_dword, sizeof(DWORD), where it is used to
// detect the local timezone information.
EEPROM_INFO_ENTRY(XC_FACTORY_SERIAL_NUMBER, FactorySettings.SerialNumber, REG_BINARY),
EEPROM_INFO_ENTRY(XC_FACTORY_ETHERNET_ADDR, FactorySettings.EthernetAddr, REG_BINARY),
EEPROM_INFO_ENTRY(XC_FACTORY_ONLINE_KEY, FactorySettings.OnlineKey, REG_BINARY),
EEPROM_INFO_ENTRY(XC_FACTORY_AV_REGION, FactorySettings.AVRegion, REG_DWORD),
// Note : XC_FACTORY_GAME_REGION is linked to a separate ULONG XboxFactoryGameRegion (of type REG_DWORD)
EEPROM_INFO_ENTRY(XC_FACTORY_GAME_REGION, EncryptedSettings.GameRegion, REG_DWORD),
EEPROM_INFO_ENTRY(XC_ENCRYPTED_SECTION, EncryptedSettings, REG_BINARY),
{ xboxkrnl::XC_MAX_ALL, 0, REG_BINARY, sizeof(xboxkrnl::XBOX_EEPROM) },
EEPROM_INFO_ENTRY(XC_FACTORY_SERIAL_NUMBER, FactorySettings.SerialNumber, xbox::reg_binary),
EEPROM_INFO_ENTRY(XC_FACTORY_ETHERNET_ADDR, FactorySettings.EthernetAddr, xbox::reg_binary),
EEPROM_INFO_ENTRY(XC_FACTORY_ONLINE_KEY, FactorySettings.OnlineKey, xbox::reg_binary),
EEPROM_INFO_ENTRY(XC_FACTORY_AV_REGION, FactorySettings.AVRegion, xbox::reg_dword),
// Note : XC_FACTORY_GAME_REGION is linked to a separate ULONG XboxFactoryGameRegion (of type xbox::reg_dword)
EEPROM_INFO_ENTRY(XC_FACTORY_GAME_REGION, EncryptedSettings.GameRegion, xbox::reg_dword),
EEPROM_INFO_ENTRY(XC_ENCRYPTED_SECTION, EncryptedSettings, xbox::reg_binary),
{ xbox::XC_MAX_ALL, 0, xbox::reg_binary, sizeof(xbox::XBOX_EEPROM) },
{ XC_END_MARKER }
};
@ -145,16 +139,16 @@ static const EEPROMInfo EEPROMInfos[] = {
#define DVD_REGION_RESERVED 7
#define DVD_REGION_INTERNATIONAL 8
extern xboxkrnl::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin);
extern xbox::XBOX_EEPROM *CxbxRestoreEEPROM(char *szFilePath_EEPROM_bin);
extern const EEPROMInfo* EmuFindEEPROMInfo(xboxkrnl::XC_VALUE_INDEX index);
extern const EEPROMInfo* EmuFindEEPROMInfo(xbox::XC_VALUE_INDEX index);
extern xboxkrnl::XBOX_EEPROM *EEPROM;
extern xbox::XBOX_EEPROM *EEPROM;
extern xboxkrnl::ULONG XboxFactoryGameRegion;
extern xbox::ulong_xt XboxFactoryGameRegion;
extern void EmuEEPROMReset(xboxkrnl::XBOX_EEPROM* eeprom);
extern void EmuEEPROMReset(xbox::XBOX_EEPROM* eeprom);
void gen_section_CRCs(xboxkrnl::XBOX_EEPROM*);
void gen_section_CRCs(xbox::XBOX_EEPROM*);
#endif // EMU_EEPROM_H

View File

@ -27,14 +27,14 @@
#include "common\Error.h"
const std::string& Error::GetError()
const std::string Error::GetError()
{
return m_strError;
return std::string(m_szError);
}
bool Error::HasError() const
{
return HasFatalError() || !m_strError.empty();
return HasFatalError() || (m_szError[0] != '\0');
}
bool Error::HasFatalError() const
@ -46,7 +46,7 @@ bool Error::ClearError()
{
if (m_bFatal) { return false; }
m_strError.clear();
m_szError[0] = '\0';
m_bFatal = false;
return true;
@ -54,11 +54,17 @@ bool Error::ClearError()
void Error::SetError(const std::string& strError)
{
m_strError = strError;
// assert(strError.length()) < sizeof(m_szError));
memset(m_szError, '\0', sizeof(m_szError));
memcpy(m_szError, strError.c_str(), strError.length());
}
void Error::SetFatalError(const std::string& strError)
{
m_strError = strError;
// assert(strError.length()) < sizeof(m_szError));
memset(m_szError, '\0', sizeof(m_szError));
memcpy(m_szError, strError.c_str(), strError.length());
m_bFatal = true;
}

View File

@ -33,7 +33,7 @@
class Error
{
public:
const std::string& GetError();
const std::string GetError();
bool HasError() const;
bool HasFatalError() const;
@ -42,15 +42,15 @@ public:
protected:
// protected constructor so this class must be inherited from
Error() : m_bFatal(false) { }
Error() : m_szError("\0"), m_bFatal(false) { }
// protected so only derived class may set an error
void SetError(const std::string& strStrError);
void SetFatalError(const std::string& strError);
private:
std::string m_strError;
bool m_bFatal;
char m_szError[60]; // Cannot be std::string, which sizeof() differs between builds
uint32_t m_bFatal; // Cannot be bool, to avoid bit packing altering memory layout
};
#endif

187
src/common/FilePaths.cpp Normal file
View File

@ -0,0 +1,187 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx-Reloaded project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::FILE
#define LOG_PREFIX_INIT CXBXR_MODULE::INIT
#include <filesystem>
#include "common/cxbxr.hpp"
#include "Settings.hpp"
#include "EmuShared.h"
#include "xxhash.h" // for XXH3_64bits
#include "core/kernel/common/xbox.h"
#include "Logging.h"
char szFilePath_CxbxReloaded_Exe[MAX_PATH] = { 0 };
char szFilePath_EEPROM_bin[MAX_PATH] = { 0 };
std::string g_DataFilePath;
std::string g_DiskBasePath;
std::string g_MuBasePath;
//TODO: Possible move CxbxResolveHostToFullPath inline function someplace else if become useful elsewhere.
// Let filesystem library clean it up for us, including resolve host's symbolic link path.
// Since internal kernel do translate to full path than preserved host symoblic link path.
void CxbxResolveHostToFullPath(std::filesystem::path& file_path, std::string_view finish_error_sentence) {
std::error_code error;
std::filesystem::path sanityPath = std::filesystem::canonical(file_path, error);
if (error) {
// The MS implementation of std::filesystem::canonical internally calls GetFinalPathNameByHandleW, which fails with ERROR_FILE_NOT_FOUND when called
// on a file inside a mounted xiso under Windows with the xbox-iso-vfs tool because of this known dokany bug https://github.com/dokan-dev/dokany/issues/343
EmuLogInit(LOG_LEVEL::WARNING, "Could not resolve to %s: %s, dokany in use? The error was: %s",
finish_error_sentence.data(), file_path.string().c_str(), error.message().c_str());
sanityPath = std::filesystem::absolute(std::filesystem::weakly_canonical(file_path, error), error);
if (error) {
CxbxrAbortEx(LOG_PREFIX_INIT, "Could not resolve to %s: %s. The error was: %s", finish_error_sentence.data(), file_path.string().c_str(), error.message().c_str());
}
}
file_path = sanityPath;
}
// TODO: Eventually, we should remove this function to start using std::filesystem::path method for all host paths.
void CxbxResolveHostToFullPath(std::string& file_path, std::string_view finish_error_sentence) {
std::filesystem::path sanityPath(file_path);
CxbxResolveHostToFullPath(sanityPath, finish_error_sentence);
file_path = sanityPath.string();
}
// NOTE: Do NOT modify g_<custom>BasePath variables after this call!
void CxbxrInitFilePaths()
{
if (g_Settings) {
g_DataFilePath = g_Settings->GetDataLocation();
}
else {
char dataLoc[MAX_PATH];
g_EmuShared->GetDataLocation(dataLoc);
g_DataFilePath = dataLoc;
}
// Make sure our data folder exists :
bool result = std::filesystem::exists(g_DataFilePath);
if (!result && !std::filesystem::create_directory(g_DataFilePath)) {
CxbxrAbort("%s : Couldn't create Cxbx-Reloaded's data folder!", __func__);
}
// Make sure the EmuDisk folder exists
g_DiskBasePath = g_DataFilePath + "\\EmuDisk";
result = std::filesystem::exists(g_DiskBasePath);
if (!result && !std::filesystem::create_directory(g_DiskBasePath)) {
CxbxrAbort("%s : Couldn't create Cxbx-Reloaded EmuDisk folder!", __func__);
}
CxbxResolveHostToFullPath(g_DiskBasePath, "Cxbx-Reloaded's EmuDisk directory");
g_DiskBasePath = std::filesystem::path(g_DiskBasePath).append("").string();
// Make sure the EmuDMu folder exists
g_MuBasePath = g_DataFilePath + "\\EmuMu";
result = std::filesystem::exists(g_MuBasePath);
if (!result && !std::filesystem::create_directory(g_MuBasePath)) {
CxbxrAbort("%s : Couldn't create Cxbx-Reloaded EmuMu folder!", __func__);
}
CxbxResolveHostToFullPath(g_MuBasePath, "Cxbx-Reloaded's EmuMu directory");
g_MuBasePath = std::filesystem::path(g_MuBasePath).append("").string();
snprintf(szFilePath_EEPROM_bin, MAX_PATH, "%s\\EEPROM.bin", g_DataFilePath.c_str());
GetModuleFileName(GetModuleHandle(nullptr), szFilePath_CxbxReloaded_Exe, MAX_PATH);
}
// Loads a keys.bin file as generated by dump-xbox
// See https://github.com/JayFoxRox/xqemu-tools/blob/master/dump-xbox.c
void LoadXboxKeys()
{
std::string keys_path = g_DataFilePath + "\\keys.bin";
// Attempt to open Keys.bin
FILE* fp = fopen(keys_path.c_str(), "rb");
if (fp != nullptr) {
// Determine size of Keys.bin
xbox::XBOX_KEY_DATA keys[2];
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
rewind(fp);
// If the size of Keys.bin is correct (two keys), read it
if (size == xbox::XBOX_KEY_LENGTH * 2) {
fread(keys, xbox::XBOX_KEY_LENGTH, 2, fp);
memcpy(xbox::XboxEEPROMKey, &keys[0], xbox::XBOX_KEY_LENGTH);
memcpy(xbox::XboxCertificateKey, &keys[1], xbox::XBOX_KEY_LENGTH);
}
else {
EmuLog(LOG_LEVEL::WARNING, "Keys.bin has an incorrect filesize. Should be %d bytes", xbox::XBOX_KEY_LENGTH * 2);
}
fclose(fp);
return;
}
// If we didn't already exit the function, keys.bin could not be loaded
EmuLog(LOG_LEVEL::WARNING, "Failed to load Keys.bin. Cxbx-Reloaded will be unable to read Save Data from a real Xbox");
}
static HANDLE hMapDataHash = nullptr;
bool CxbxrLockFilePath()
{
std::stringstream filePathHash("Local\\");
uint64_t hashValue = XXH3_64bits(g_DataFilePath.c_str(), g_DataFilePath.length() + 1);
if (!hashValue) {
CxbxrAbort("%s : Couldn't generate Cxbx-Reloaded's data folder hash!", __func__);
}
filePathHash << std::hex << hashValue;
hMapDataHash = CreateFileMapping(
INVALID_HANDLE_VALUE, // Paging file
nullptr, // default security attributes
PAGE_READONLY, // readonly access
0, // size: high 32 bits
/*Dummy size*/4, // size: low 32 bits
filePathHash.str().c_str() // name of map object
);
if (hMapDataHash == nullptr) {
return false;
}
if (GetLastError() == ERROR_ALREADY_EXISTS) {
PopupError(nullptr, "Data path directory is currently in use.\nUse a different data path directory or stop emulation from another process.");
CloseHandle(hMapDataHash);
return false;
}
return true;
}
void CxbxrUnlockFilePath()
{
// Close opened file path lockdown shared memory.
if (hMapDataHash) {
CloseHandle(hMapDataHash);
hMapDataHash = nullptr;
}
}

53
src/common/FilePaths.hpp Normal file
View File

@ -0,0 +1,53 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx-Reloaded project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
extern char szFilePath_CxbxReloaded_Exe[MAX_PATH];
extern char szFilePath_EEPROM_bin[MAX_PATH];
extern std::string g_DataFilePath;
extern std::string g_DiskBasePath;
extern std::string g_MuBasePath;
#include <filesystem>
//TODO: Possible move CxbxResolveHostToFullPath inline function someplace else if become useful elsewhere.
// Let filesystem library clean it up for us, including resolve host's symbolic link path.
// Since internal kernel do translate to full path than preserved host symoblic link path.
void CxbxResolveHostToFullPath(std::filesystem::path& file_path, std::string_view finish_error_sentence);
// TODO: Eventually, we should remove this function to start using std::filesystem::path method for all host paths.
void CxbxResolveHostToFullPath(std::string& file_path, std::string_view finish_error_sentence);
// NOTE: Do NOT modify g_<custom>BasePath variables after this call!
void CxbxrInitFilePaths();
// Loads a keys.bin file as generated by dump-xbox
// See https://github.com/JayFoxRox/xqemu-tools/blob/master/dump-xbox.c
void LoadXboxKeys();
bool CxbxrLockFilePath();
void CxbxrUnlockFilePath();

View File

@ -38,6 +38,7 @@ typedef enum class _IPC_UPDATE_GUI {
, XBOX_LED_COLOUR
, LOG_ENABLED
, KRNL_IS_READY
, OVERLAY
} IPC_UPDATE_GUI;
void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value);
@ -48,10 +49,11 @@ void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value);
// ******************************************************************
typedef enum class _IPC_UPDATE_KERNEL {
CONFIG_LOGGING_SYNC = 0
, CONFIG_INPUT_SYNC
CONFIG_LOGGING_SYNC = 0,
CONFIG_INPUT_SYNC,
CONFIG_CHANGE_TIME
} IPC_UPDATE_KERNEL;
void ipc_send_kernel_update(IPC_UPDATE_KERNEL command, const unsigned int value, const unsigned int hwnd);
void ipc_send_kernel_update(IPC_UPDATE_KERNEL command, const int value, const unsigned int hwnd);
#endif

View File

@ -27,117 +27,122 @@
#include <windows.h> // for PULONG
#include "Logging.h"
#include "common\Settings.hpp"
#include "Logging.h"
#include "common\Settings.hpp"
#include "EmuShared.h"
// For thread_local, see : https://en.cppreference.com/w/cpp/language/storage_duration
// TODO : Use Boost.Format https://www.boost.org/doc/libs/1_53_0/libs/format/index.html
thread_local std::string _logThreadPrefix;
std::atomic_bool g_EnabledModules[to_underlying(CXBXR_MODULE::MAX)] = { false };
const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)] = {
"CXBXR ",
"XBE ",
"INIT ",
"VMEM ",
"PMEM ",
"GUI ",
"EEPR ",
"RSA ",
"POOLMEM ",
"D3D8 ",
"D3DST ",
"D3DCVT ",
"DSOUND ",
"XAPI ",
"XACT ",
"XGRP ",
"XONLINE ",
"FS ",
"PSHB ",
"PXSH ",
"VTXSH ",
"VSHCACHE",
"VTXB ",
"DINP ",
"XINP ",
"SDL ",
"FILE ",
"X86 ",
"HLE ",
"NET ",
"MCPX ",
"NV2A ",
"SMC ",
"OHCI ",
"USB ",
"HUB ",
"XIDCTRL ",
"ADM ",
"INPSYS ",
"DSBUFFER",
"DSSTREAM",
"DS3DCALC",
"XMO ",
"KRNL ",
"LOG ",
"XBOX ",
"XBDM ",
"AV ",
"DBG ",
"EX ",
"FSC ",
"HAL ",
"IO ",
"KD ",
"KE ",
"KI ",
"MM ",
"NT ",
"OB ",
"PS ",
"RTL ",
"XC ",
"XE ",
};
std::atomic_int g_CurrentLogLevel = to_underlying(LOG_LEVEL::INFO);
const char log_debug[] = "DEBUG: ";
const char log_info[] = "INFO : ";
const char log_warn[] = "WARN : ";
const char log_error[] = "ERROR: ";
const char log_fatal[] = "FATAL: ";
const char log_unkwn[] = "???? : ";
// Do not use EmuLogOutput function outside of this file.
void EmuLogOutput(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, va_list argp)
thread_local std::string _logThreadPrefix;
std::atomic_bool g_EnabledModules[to_underlying(CXBXR_MODULE::MAX)] = { false };
const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)] = {
"CXBXR ",
"XBE ",
"INIT ",
"VMEM ",
"PMEM ",
"GUI ",
"EEPR ",
"RSA ",
"POOLMEM ",
"D3D8 ",
"D3DST ",
"D3DCVT ",
"DSOUND ",
"XAPI ",
"XACT ",
"XGRP ",
"XONLINE ",
"FS ",
"PSHB ",
"PXSH ",
"VTXSH ",
"VSHCACHE",
"VTXB ",
"DINP ",
"XINP ",
"SDL ",
"FILE ",
"X86 ",
"HLE ",
"NET ",
"MCPX ",
"NV2A ",
"SMC ",
"OHCI ",
"USB ",
"HUB ",
"XIDCTRL ",
"ADM ",
"INPSYS ",
"DSBUFFER",
"DSSTREAM",
"DS3DCALC",
"XMO ",
"RINP ",
"JVS ",
"LIBUSB ",
"KRNL ",
"LOG ",
"XBOX ",
"XBDM ",
"AV ",
"DBG ",
"EX ",
"FSC ",
"HAL ",
"IO ",
"KD ",
"KE ",
"KI ",
"MM ",
"NT ",
"OB ",
"PS ",
"RTL ",
"XC ",
"XE ",
};
std::atomic_int g_CurrentLogLevel = to_underlying(LOG_LEVEL::INFO);
std::atomic_bool g_CurrentLogPopupTestCase = true;
static bool g_disablePopupMessages = false;
const char log_debug[] = "DEBUG: ";
const char log_info[] = "INFO : ";
const char log_warn[] = "WARN : ";
const char log_error[] = "ERROR: ";
const char log_fatal[] = "FATAL: ";
const char log_unkwn[] = "???? : ";
// Do not use EmuLogOutput function outside of this file.
void EmuLogOutput(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, const va_list argp)
{
LOG_THREAD_INIT;
const char* level_str;
LOG_THREAD_INIT;
const char* level_str;
switch (level) {
default:
level_str = log_unkwn;
default:
level_str = log_unkwn;
break;
case LOG_LEVEL::DEBUG:
level_str = log_debug;
case LOG_LEVEL::DEBUG:
level_str = log_debug;
break;
case LOG_LEVEL::INFO:
level_str = log_info;
case LOG_LEVEL::INFO:
level_str = log_info;
break;
case LOG_LEVEL::WARNING:
level_str = log_warn;
break;
case LOG_LEVEL::ERROR2:
level_str = log_error;
case LOG_LEVEL::WARNING:
level_str = log_warn;
break;
case LOG_LEVEL::FATAL:
level_str = log_fatal;
case LOG_LEVEL::ERROR2:
level_str = log_error;
break;
case LOG_LEVEL::FATAL:
level_str = log_fatal;
break;
}
std::cout << _logThreadPrefix << level_str
std::cout << _logThreadPrefix << level_str
<< g_EnumModules2String[to_underlying(cxbxr_module)];
vfprintf(stdout, szWarningMessage, argp);
@ -145,16 +150,23 @@ void EmuLogOutput(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarn
fprintf(stdout, "\n");
fflush(stdout);
}
// print out a custom message to the console or kernel debug log file
void NTAPI EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, ...)
}
inline void EmuLogOutputEx(const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const char *szWarningMessage, ...)
{
va_list argp;
va_start(argp, szWarningMessage);
EmuLogOutput(cxbxr_module, level, szWarningMessage, argp);
va_end(argp);
}
// print out a custom message to the console or kernel debug log file
void EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, ...)
{
if (szWarningMessage == NULL) {
return;
}
LOG_CHECK_ENABLED_EX(cxbxr_module, level) {
LOG_CHECK_ENABLED_EX(cxbxr_module, level) {
if (g_bPrintfOn) {
LOG_THREAD_INIT;
@ -165,11 +177,11 @@ void NTAPI EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWa
EmuLogOutput(cxbxr_module, level, szWarningMessage, argp);
va_end(argp);
}
}
}
}
void NTAPI EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...)
}
void EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...)
{
if (szWarningMessage == NULL) {
return;
@ -181,53 +193,156 @@ void NTAPI EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...)
EmuLogOutput(CXBXR_MODULE::INIT, level, szWarningMessage, argp);
va_end(argp);
}
// Set up the logging variables for the GUI process
inline void log_get_settings()
{
log_set_config(g_Settings->m_core.LogLevel, g_Settings->m_core.LoggedModules);
}
inline void log_sync_config()
{
int LogLevel;
unsigned int LoggedModules[NUM_INTEGERS_LOG];
g_EmuShared->GetLogLv(&LogLevel);
g_EmuShared->GetLogModules(LoggedModules);
log_set_config(LogLevel, LoggedModules);
}
void log_set_config(int LogLevel, unsigned int* LoggedModules)
{
g_CurrentLogLevel = LogLevel;
for (unsigned int index = to_underlying(CXBXR_MODULE::CXBXR); index < to_underlying(CXBXR_MODULE::MAX); index++) {
if (LoggedModules[index / 32] & (1 << (index % 32))) {
g_EnabledModules[index] = true;
}
else {
g_EnabledModules[index] = false;
}
}
}
// Generate active log filter output.
void log_generate_active_filter_output(const CXBXR_MODULE cxbxr_module)
}
// Set up the logging variables for the GUI process
inline void log_get_settings()
{
LOG_THREAD_INIT;
std::string generic_output_str = _logThreadPrefix + log_info + g_EnumModules2String[to_underlying(cxbxr_module)];
std::cout << generic_output_str << "Current log level: " << g_CurrentLogLevel << std::endl;
generic_output_str.append("Active log filter: ");
for (unsigned int index = to_underlying(CXBXR_MODULE::CXBXR); index < to_underlying(CXBXR_MODULE::MAX); index++) {
if (g_EnabledModules[index]) {
std::cout << generic_output_str << g_EnumModules2String[index] << "\n";
}
}
log_set_config(g_Settings->m_core.LogLevel, g_Settings->m_core.LoggedModules, g_Settings->m_core.bLogPopupTestCase);
}
inline void log_sync_config()
{
int LogLevel;
unsigned int LoggedModules[NUM_INTEGERS_LOG];
bool LogPopupTestCase;
g_EmuShared->GetLogLv(&LogLevel);
g_EmuShared->GetLogModules(LoggedModules);
g_EmuShared->GetLogPopupTestCase(&LogPopupTestCase);
log_set_config(LogLevel, LoggedModules, LogPopupTestCase);
}
void log_set_config(int LogLevel, unsigned int* LoggedModules, bool LogPopupTestCase)
{
g_CurrentLogLevel = LogLevel;
for (unsigned int index = to_underlying(CXBXR_MODULE::CXBXR); index < to_underlying(CXBXR_MODULE::MAX); index++) {
if (LoggedModules[index / 32] & (1 << (index % 32))) {
g_EnabledModules[index] = true;
}
else {
g_EnabledModules[index] = false;
}
}
g_CurrentLogPopupTestCase = LogPopupTestCase;
}
// Generate active log filter output.
void log_generate_active_filter_output(const CXBXR_MODULE cxbxr_module)
{
LOG_THREAD_INIT;
std::string generic_output_str = _logThreadPrefix + log_info + g_EnumModules2String[to_underlying(cxbxr_module)];
std::cout << generic_output_str << "Current log level: " << g_CurrentLogLevel << std::endl;
generic_output_str.append("Active log filter: ");
for (unsigned int index = to_underlying(CXBXR_MODULE::CXBXR); index < to_underlying(CXBXR_MODULE::MAX); index++) {
if (g_EnabledModules[index]) {
std::cout << generic_output_str << g_EnumModules2String[index] << "\n";
}
}
std::cout << std::flush;
}
// Use kernel managed environment
void log_init_popup_msg()
{
Settings::s_video vSettings;
g_EmuShared->GetVideoSettings(&vSettings);
g_disablePopupMessages = vSettings.bFullScreen;
}
// TODO: Move PopupPlatformHandler into common GUI's window source code or use imgui in the future.
// PopupPlatformHandler is intended to be use as internal wrapper function.
static PopupReturn PopupPlatformHandler(const char* msg, const PopupReturn ret_default, const UINT uType, const HWND hWnd)
{
int ret = MessageBox(hWnd, msg, /*lpCaption=*/TEXT("Cxbx-Reloaded"), uType);
switch (ret) {
default:
case IDCANCEL:
return PopupReturn::Cancel;
case IDOK:
return PopupReturn::Ok;
case IDABORT:
return PopupReturn::Abort;
case IDRETRY:
return PopupReturn::Retry;
case IDIGNORE:
return PopupReturn::Ignore;
case IDYES:
return PopupReturn::Yes;
case IDNO:
return PopupReturn::No;
}
}
PopupReturn PopupCustomEx(const void* hwnd, const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const PopupIcon icon, const PopupButtons buttons, const PopupReturn ret_default, const char *message, ...)
{
UINT uType = MB_TOPMOST | MB_SETFOREGROUND;
// Make assert whenever the format string is null pointer which isn't allow in here.
assert(message != nullptr);
switch (icon) {
case PopupIcon::Warning: {
uType |= MB_ICONWARNING;
break;
}
case PopupIcon::Error: {
uType |= MB_ICONERROR; // Note : MB_ICONERROR == MB_ICONSTOP == MB_ICONHAND
break;
}
case PopupIcon::Info: {
uType |= MB_ICONINFORMATION;
break;
}
case PopupIcon::Question:
case PopupIcon::Unknown:
default: {
uType |= MB_ICONQUESTION;
break;
}
}
switch (buttons) {
default:
case PopupButtons::Ok:
uType |= MB_OK;
break;
case PopupButtons::OkCancel:
uType |= MB_OKCANCEL;
break;
case PopupButtons::AbortRetryIgnore:
uType |= MB_ABORTRETRYIGNORE;
break;
case PopupButtons::YesNoCancel:
uType |= MB_YESNOCANCEL;
break;
case PopupButtons::YesNo:
uType |= MB_YESNO;
break;
case PopupButtons::RetryCancel:
uType |= MB_RETRYCANCEL;
break;
}
va_list argp;
va_start(argp, message);
// allocate predicted buffer size then write to buffer afterward.
std::string Buffer(1+std::vsnprintf(nullptr, 0, message, argp), '\0');
vsnprintf(Buffer.data(), Buffer.size(), message, argp);
va_end(argp);
EmuLogOutputEx(cxbxr_module, level, "Popup : %s", Buffer.c_str());
// If user is using exclusive fullscreen, we need to refrain all popups.
if (g_disablePopupMessages) {
return ret_default;
}
return PopupPlatformHandler(Buffer.data(), ret_default, uType, (const HWND)hwnd);
}
const bool needs_escape(const wint_t _char)
{
// Escaping is needed for control characters,
@ -281,8 +396,13 @@ inline void output_wchar(std::ostream& os, wchar_t c)
default: os << "\\x" << std::setfill('0') << std::setw(4) << std::right << std::hex << std::uppercase << (wint_t)c;
}
}
else
os << c;
else {
const wchar_t *wc = reinterpret_cast<const wchar_t *>(&c);
std::string dst(2, '\0');
std::mbstate_t ps{};
std::wcsrtombs(dst.data(), &wc, 1, &ps);
os << dst;
}
}
LOG_SANITIZE_HEADER(hex1, uint8_t)
@ -341,7 +461,7 @@ LOG_SANITIZE_HEADER(sanitized_char_pointer, char *)
while (*v && max_length--) {
os << *v++;
}
}
}
return os << "\"";
}
@ -355,7 +475,7 @@ LOG_SANITIZE_HEADER(sanitized_wchar_pointer, wchar_t *)
return os << "NULL";
bool needsEscaping = false;
int max_length = container.max;
int max_length = container.max;
while (*v && max_length--)
if (needs_escape(*v++))
{

View File

@ -17,7 +17,7 @@
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2019 ergo720
// *
// * All rights reserved
@ -29,107 +29,162 @@
#include <windows.h> // For DWORD
#include <sstream> // For std::stringstream
#include <iostream> // For std::cout
#include <iomanip> // For std::setw
#include <iomanip> // For std::setw
#include <atomic> // For atomic_bool and atomic_uint
#include "common\util\CxbxUtil.h" // For g_bPrintfOn and to_underlying
// NOTE: using ERROR2 since windows.h imports an ERROR macro which would conflict otherwise
typedef enum class _LOG_LEVEL {
DEBUG = 0,
INFO,
WARNING,
ERROR2,
FATAL,
MAX,
#include "common\util\CxbxUtil.h" // For g_bPrintfOn and to_underlying
// NOTE: using ERROR2 since windows.h imports an ERROR macro which would conflict otherwise
typedef enum class _LOG_LEVEL {
DEBUG = 0,
INFO,
WARNING,
ERROR2,
FATAL,
MAX,
}LOG_LEVEL;
typedef enum class _CXBXR_MODULE: unsigned int {
// general
CXBXR = 0,
XBE,
INIT,
VMEM,
PMEM,
GUI,
EEPR,
RSA,
POOLMEM,
D3D8,
D3DST,
D3DCVT,
DSOUND,
XAPI,
XACT,
XGRP,
XONLINE,
FS,
PSHB,
PXSH,
VTXSH,
VSHCACHE,
VTXB,
DINP,
XINP,
SDL,
FILE,
X86,
HLE,
NET,
MCPX,
NV2A,
SMC,
OHCI,
USB,
HUB,
XIDCTRL,
ADM,
INPSYS,
DSBUFFER,
DSSTREAM,
DS3DCALC,
XMO,
// kernel
KRNL,
LOG,
XBOX,
XBDM,
AV,
DBG,
EX,
FSC,
HAL,
IO,
KD,
KE,
KI,
MM,
NT,
OB,
PS,
RTL,
XC,
XE,
// max
MAX,
}CXBXR_MODULE;
extern std::atomic_bool g_EnabledModules[to_underlying(CXBXR_MODULE::MAX)];
extern const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)];
extern std::atomic_int g_CurrentLogLevel;
typedef enum class _CXBXR_MODULE: unsigned int {
// general
CXBXR = 0,
XBE,
INIT,
VMEM,
PMEM,
GUI,
EEPR,
RSA,
POOLMEM,
D3D8,
D3DST,
D3DCVT,
DSOUND,
XAPI,
XACT,
XGRP,
XONLINE,
FS,
PSHB,
PXSH,
VTXSH,
VSHCACHE,
VTXB,
DINP,
XINP,
SDL,
FILE,
X86,
HLE,
NET,
MCPX,
NV2A,
SMC,
OHCI,
USB,
HUB,
XIDCTRL,
ADM,
INPSYS,
DSBUFFER,
DSSTREAM,
DS3DCALC,
XMO,
RINP,
JVS,
LIBUSB,
// kernel
KRNL,
LOG,
XBOX,
XBDM,
AV,
DBG,
EX,
FSC,
HAL,
IO,
KD,
KE,
KI,
MM,
NT,
OB,
PS,
RTL,
XC,
XE,
// max
MAX,
}CXBXR_MODULE;
// print out a log message to the console or kernel debug log file if level is high enough
void NTAPI EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, ...);
void NTAPI EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...);
#define EmuLog(level, fmt, ...) EmuLogEx(LOG_PREFIX, level, fmt, ##__VA_ARGS__)
extern inline void log_get_settings();
extern inline void log_sync_config();
void log_set_config(int LogLevel, unsigned int* LoggedModules);
void log_generate_active_filter_output(const CXBXR_MODULE cxbxr_module);
extern std::atomic_bool g_EnabledModules[to_underlying(CXBXR_MODULE::MAX)];
extern const char* g_EnumModules2String[to_underlying(CXBXR_MODULE::MAX)];
extern std::atomic_int g_CurrentLogLevel;
extern std::atomic_bool g_CurrentLogPopupTestCase;
// print out a log message to the console or kernel debug log file if level is high enough
void EmuLogEx(CXBXR_MODULE cxbxr_module, LOG_LEVEL level, const char *szWarningMessage, ...);
void EmuLogInit(LOG_LEVEL level, const char *szWarningMessage, ...);
#define EmuLog(level, fmt, ...) EmuLogEx(LOG_PREFIX, level, fmt, ##__VA_ARGS__)
extern inline void log_get_settings();
extern inline void log_sync_config();
void log_set_config(int LogLevel, unsigned int* LoggedModules, bool LogPopupTestCase);
void log_generate_active_filter_output(const CXBXR_MODULE cxbxr_module);
// Use emulation environment to manage popup messages
// If log_init_popup_msg is not called at earliest point of emulation.
// Then users will have a chance of popup message appear during start of emulation in full screen.
void log_init_popup_msg();
typedef enum class _PopupIcon {
Unknown = 0,
Question,
Info,
Warning,
Error
} PopupIcon;
typedef enum class _PopupButtons {
Unknown = 0,
Ok,
OkCancel,
AbortRetryIgnore,
YesNoCancel,
YesNo,
RetryCancel
} PopupButtons;
typedef enum class _PopupReturn {
Unknown = 0,
Ok,
Cancel,
Abort,
Retry,
Ignore,
Yes,
No
} PopupReturn;
PopupReturn PopupCustomEx(const void* hwnd, const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const PopupIcon icon, const PopupButtons buttons, const PopupReturn ret_default, const char* message, ...);
#define PopupCustom(hwnd, level, icon, buttons, ret_default, fmt, ...) PopupCustomEx(hwnd, LOG_PREFIX, level, icon, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupQuestionEx(hwnd, level, buttons, ret_default, fmt, ...) PopupCustom(hwnd, level, PopupIcon::Question, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupQuestion(hwnd, fmt, ...) PopupQuestionEx(hwnd, LOG_LEVEL::INFO, PopupButtons::YesNoCancel, PopupReturn::Cancel, fmt, ## __VA_ARGS__)
#define PopupInfoEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::INFO, PopupIcon::Info, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupInfo(hwnd, fmt, ...) (void)PopupInfoEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
#define PopupWarningEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::WARNING, PopupIcon::Warning, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupWarning(hwnd, fmt, ...) (void)PopupWarningEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
#define PopupErrorEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::ERROR2, PopupIcon::Error, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupError(hwnd, fmt, ...) (void)PopupErrorEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
#define PopupFatalEx(hwnd, buttons, ret_default, fmt, ...) PopupCustom(hwnd, LOG_LEVEL::FATAL, PopupIcon::Error, buttons, ret_default, fmt, ## __VA_ARGS__)
#define PopupFatal(hwnd, fmt, ...) (void)PopupFatalEx(hwnd, PopupButtons::Ok, PopupReturn::Ok, fmt, ## __VA_ARGS__)
// For LOG_TEST_CASE
extern inline void EmuLogOutputEx(const CXBXR_MODULE cxbxr_module, const LOG_LEVEL level, const char *szWarningMessage, ...);
//
// __FILENAME__
@ -170,9 +225,30 @@ extern inline void output_wchar(std::ostream& os, wchar_t c);
// By default, sanitization functions simply return the given argument
// (type and value) which results in calls to standard output writers.
template<class T>
inline T _log_sanitize(T value, int ignored_length = 0)
inline auto _log_sanitize(T value, int ignored_length = 0)
{
return value;
// This is necessary because C++20 has deleted the overloaded operator<< of ostream for wchar_t, char8_t, char16_t and char32_t.
// The proper solution is to use wide strings in all our logging macros/functions, see https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/issues/743
if constexpr (std::is_same_v<xbox::wchar_xt, std::remove_cvref_t<std::remove_pointer_t<T>>>) {
if constexpr (std::is_pointer_v<T>) {
const wchar_t *wstr = reinterpret_cast<const wchar_t *>(value);
std::size_t len = std::wcslen(wstr);
std::string dst(len + 1, '\0');
std::mbstate_t ps{};
std::wcsrtombs(dst.data(), &wstr, len, &ps);
return dst;
}
else {
const wchar_t *wstr = reinterpret_cast<const wchar_t *>(&value);
std::string dst(2, '\0');
std::mbstate_t ps{};
std::wcsrtombs(dst.data(), &wstr, 1, &ps);
return dst;
}
}
else {
return value;
}
}
#if 0 // TODO FIXME : Disabled for now, as this is incorrectly called for INT types too
@ -187,12 +263,12 @@ inline const char * _log_sanitize(BOOL value, int ignored_length = 0)
#define LOG_SANITIZE_HEADER(C, T) \
std::ostream& operator<<( \
std::ostream& os, \
const Sane##C& container) \
const Sane##C& container) \
#define LOG_SANITIZE(C, T) \
struct Sane##C \
{ \
T value; \
T value; \
int max; \
Sane##C(T _v, int _m = 80) : value(_v), max(_m) { } \
}; \
@ -239,13 +315,13 @@ constexpr const char* remove_prefix(const char* str, const char *prefix) {
return (str_skip_prefix(str, prefix) == str + str_length(prefix)) ? str_skip_prefix(str, prefix) : str;
}
constexpr char* xtl_prefix = "XTL::";
constexpr char* emupatch_prefix = "EmuPatch_"; // See #define EMUPATCH
static constexpr const char* xbox_prefix = "xbox::";
static constexpr const char* emupatch_prefix = "EmuPatch_"; // See #define EMUPATCH
constexpr const char* remove_emupatch_prefix(const char* str) {
// return an empty string when str isn't given
// skip XTL:: and/or EmuPatch_ prefix if present
return remove_prefix(remove_prefix(str, xtl_prefix), emupatch_prefix);
// skip xbox:: and/or EmuPatch_ prefix if present
return remove_prefix(remove_prefix(str, xbox_prefix), emupatch_prefix);
}
#define LOG_ARG_START "\n " << std::setfill(' ') << std::setw(20) << std::left
@ -258,14 +334,14 @@ constexpr const char* remove_emupatch_prefix(const char* str) {
// For thread_local, see : https://en.cppreference.com/w/cpp/language/storage_duration
// TODO : Use Boost.Format https://www.boost.org/doc/libs/1_53_0/libs/format/index.html
extern thread_local std::string _logThreadPrefix;
// Checks if this log should be printed or not
#define LOG_CHECK_ENABLED_EX(cxbxr_module, level) \
if (g_EnabledModules[to_underlying(cxbxr_module)] && to_underlying(level) >= g_CurrentLogLevel)
// Checks if this log should be printed or not
#define LOG_CHECK_ENABLED(level) \
LOG_CHECK_ENABLED_EX(LOG_PREFIX, level)
// Checks if this log should be printed or not
#define LOG_CHECK_ENABLED_EX(cxbxr_module, level) \
if (g_EnabledModules[to_underlying(cxbxr_module)] && to_underlying(level) >= g_CurrentLogLevel)
// Checks if this log should be printed or not
#define LOG_CHECK_ENABLED(level) \
LOG_CHECK_ENABLED_EX(LOG_PREFIX, level)
#define LOG_THREAD_INIT \
if (_logThreadPrefix.length() == 0) { \
@ -296,7 +372,7 @@ extern thread_local std::string _logThreadPrefix;
msg << _logThreadPrefix << _logFuncPrefix << "(";
#define LOG_FUNC_BEGIN \
LOG_INIT \
LOG_INIT \
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { \
LOG_FUNC_BEGIN_NO_INIT
@ -318,9 +394,47 @@ extern thread_local std::string _logThreadPrefix;
// LOG_FUNC_END closes off function and optional argument logging
#define LOG_FUNC_END \
if (_had_arg) msg << "\n"; \
msg << ");\n"; \
msg << ");\n"; \
std::cout << msg.str(); \
} } while (0); \
} } while (0); \
}
#define LOG_FUNC_BEGIN_ARG_RESULT_NO_INIT \
do { if(g_bPrintfOn) { \
bool _had_arg = false; \
std::stringstream msg; \
msg << _logThreadPrefix << _logFuncPrefix << " returns OUT {";
#define LOG_FUNC_BEGIN_ARG_RESULT \
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { \
LOG_FUNC_BEGIN_ARG_RESULT_NO_INIT
// LOG_FUNC_ARG_RESULT writes output via all available ostream << operator overloads, sanitizing and adding detail where possible
#define LOG_FUNC_ARG_RESULT(arg) \
_had_arg = true; \
msg << LOG_ARG_START << "*"#arg << " : "; \
if (arg != nullptr) { \
msg << _log_sanitize(*arg); \
} else { \
msg << "NOT SET"; \
}
// LOG_FUNC_ARG_RESULT_TYPE writes result output using the overloaded << operator of the given type
#define LOG_FUNC_ARG_RESULT_TYPE(type, arg) \
_had_arg = true; \
msg << LOG_ARG_START << "*"#arg << " : "; \
if (arg != nullptr) { \
msg << (type)*arg; \
} else { \
msg << "NOT SET"; \
}
// LOG_FUNC_END_ARG_RESULT closes off function and optional argument result logging
#define LOG_FUNC_END_ARG_RESULT \
if (_had_arg) msg << "\n"; \
msg << "};\n"; \
std::cout << msg.str(); \
} } while (0); \
}
// LOG_FUNC_RESULT logs the function return result
@ -333,23 +447,23 @@ extern thread_local std::string _logThreadPrefix;
// LOG_FORWARD indicates that an api is implemented by a forward to another API
#define LOG_FORWARD(api) \
LOG_INIT \
LOG_INIT \
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { \
do { if(g_bPrintfOn) { \
std::cout << _logThreadPrefix << _logFuncPrefix << " forwarding to "#api"...\n"; \
} } while (0); \
} } while (0); \
}
// LOG_IGNORED indicates that Cxbx consiously ignores an api
#define LOG_IGNORED() \
do { \
static bool b_echoOnce = true; \
if(g_bPrintfOn && b_echoOnce) { \
if(g_bPrintfOn && b_echoOnce) { \
LOG_CHECK_ENABLED(LOG_LEVEL::INFO) { \
LOG_THREAD_INIT \
LOG_FUNC_INIT(__func__) \
std::cout << _logThreadPrefix << "WARN: " << _logFuncPrefix << " ignored!\n"; \
b_echoOnce = false; \
b_echoOnce = false; \
} \
} \
} while(0)
@ -358,12 +472,12 @@ extern thread_local std::string _logThreadPrefix;
#define LOG_UNIMPLEMENTED() \
do { \
static bool b_echoOnce = true; \
if(g_bPrintfOn && b_echoOnce) { \
if(g_bPrintfOn && b_echoOnce) { \
LOG_CHECK_ENABLED(LOG_LEVEL::INFO) { \
LOG_THREAD_INIT \
LOG_FUNC_INIT(__func__) \
std::cout << _logThreadPrefix << "WARN: " << _logFuncPrefix << " unimplemented!\n"; \
b_echoOnce = false; \
b_echoOnce = false; \
} \
} \
} while(0)
@ -372,12 +486,12 @@ extern thread_local std::string _logThreadPrefix;
#define LOG_INCOMPLETE() \
do { \
static bool b_echoOnce = true; \
if(g_bPrintfOn && b_echoOnce) { \
if(g_bPrintfOn && b_echoOnce) { \
LOG_CHECK_ENABLED(LOG_LEVEL::INFO) { \
LOG_THREAD_INIT \
LOG_FUNC_INIT(__func__) \
std::cout << _logThreadPrefix << "WARN: " << _logFuncPrefix << " incomplete!\n"; \
b_echoOnce = false; \
b_echoOnce = false; \
} \
} \
} while(0)
@ -386,12 +500,12 @@ extern thread_local std::string _logThreadPrefix;
#define LOG_NOT_SUPPORTED() \
do { \
static bool b_echoOnce = true; \
if(g_bPrintfOn && b_echoOnce) { \
if(g_bPrintfOn && b_echoOnce) { \
LOG_CHECK_ENABLED(LOG_LEVEL::INFO) { \
LOG_THREAD_INIT \
LOG_FUNC_INIT(__func__) \
std::cout << _logThreadPrefix << "WARN: " << _logFuncPrefix << " not supported!\n"; \
b_echoOnce = false; \
b_echoOnce = false; \
} \
} \
} while(0)
@ -518,6 +632,6 @@ LOGRENDER_HEADER_BY_REF(Type) \
// An example type rendering, for PVOID
//
LOGRENDER_HEADER_BY_REF(PVOID);
LOGRENDER_HEADER_BY_REF(PVOID);
#endif _LOGGING_H

View File

@ -0,0 +1,324 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of Cxbx-Reloaded.
// *
// * Cxbx-Reloaded is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2017-2019 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2019 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <Windows.h> // For DWORD, CALLBACK, VirtualAlloc, LPVOID, SIZE_T, HMODULE
// NOTE: Cannot be use in loader project due to force exclude std libraries.
//#define DEBUG // Uncomment whenever need to verify memory leaks or bad configure.
#ifdef DEBUG
#include <cstdio> // For printf
#endif
#include <cstdint> // For uint32_t
#include "util/std_extend.hpp"
#include "ReserveAddressRanges.h"
#include "AddressRanges.h"
// Reserve an address range up to the extend of what the host allows.
bool ReserveMemoryRange(int index, blocks_reserved_t blocks_reserved)
{
uint32_t Start = XboxAddressRanges[index].Start;
int Size = XboxAddressRanges[index].Size;
bool HadAnyFailure = false;
// Reserve this range in 64 KiB block increments, so that during emulation
// our memory-management code can VirtualFree() each block individually :
const DWORD Protect = XboxAddressRanges[index].InitialMemoryProtection;
bool NeedsReservationTracking = false;
unsigned int arr_index = BLOCK_REGION_DEVKIT_INDEX_BEGIN;
static HANDLE hFileMapping1;
static HANDLE hFileMapping2;
#ifdef DEBUG
std::printf("DEBUG: ReserveMemoryRange call begin\n");
std::printf(" : Comment = %s\n", XboxAddressRanges[index].Comment);
#endif
switch (Start) {
case PHYSICAL_MAP1_BASE:
hFileMapping1 = CreateFileMapping(
INVALID_HANDLE_VALUE,
nullptr,
PAGE_EXECUTE_READWRITE,
0,
Size,
nullptr);
if (hFileMapping1 == nullptr) {
HadAnyFailure = true;
break;
}
[[fallthrough]];
case PHYSICAL_MAP2_BASE:
case TILED_MEMORY_BASE: {
static bool NeedsInitializationMap = true;
if (NeedsInitializationMap) {
hFileMapping2 = CreateFileMapping(
INVALID_HANDLE_VALUE,
nullptr,
PAGE_EXECUTE_READWRITE,
0,
Size,
nullptr);
if (hFileMapping2 == nullptr) {
HadAnyFailure = true;
break;
}
NeedsInitializationMap = false;
}
LPVOID Result = MapViewOfFileEx(
(Start == PHYSICAL_MAP1_BASE || Start == TILED_MEMORY_BASE) ? hFileMapping1 : hFileMapping2,
(Start == PHYSICAL_MAP1_BASE || Start == PHYSICAL_MAP2_BASE) ?
(FILE_MAP_READ | FILE_MAP_WRITE | FILE_MAP_EXECUTE) : (FILE_MAP_READ | FILE_MAP_WRITE),
0,
0,
Size,
(LPVOID)Start);
#ifdef DEBUG
std::printf(" : MapViewOfFile; Start = 0x%08X; Result = %p\n", Start, Result);
#endif
if (Result == nullptr) {
HadAnyFailure = true;
}
}
break;
case SYSTEM_MEMORY_BASE:
// If additional addresses need to be assign in region's block.
// Then check for nonzero value.
arr_index = BLOCK_REGION_SYSTEM_INDEX_BEGIN;
[[fallthrough]];
case DEVKIT_MEMORY_BASE:
// arr_index's default is BLOCK_REGION_DEVKIT_INDEX_BEGIN which is zero.
// Any block region above zero should be place above this case to override zero value.
//arr_index = BLOCK_REGION_DEVKIT_INDEX_BEGIN;
NeedsReservationTracking = true;
[[fallthrough]];
default: {
while (Size > 0) {
SIZE_T BlockSize = (SIZE_T)(Size > BLOCK_SIZE) ? BLOCK_SIZE : Size;
LPVOID Result = VirtualAlloc((LPVOID)Start, BlockSize, MEM_RESERVE, Protect);
if (Result == nullptr) {
HadAnyFailure = true;
}
#ifdef DEBUG
std::printf(" : Start = %08X; Result = %p;\n", Start, Result);
#endif
// Handle the next block
Start += BLOCK_SIZE;
Size -= BLOCK_SIZE;
if (NeedsReservationTracking) {
if (Result != nullptr) {
blocks_reserved[arr_index / 32] |= (1 << (arr_index % 32));
#ifdef DEBUG
std::printf(" : arr_index = 0x%08X; set bit = 0x%08X;\n", arr_index, (1 << (arr_index % 32)));
std::printf(" : blocks_reserved[%08X] = 0x%08X\n", arr_index/32, blocks_reserved[arr_index/32]);
#endif
}
arr_index++;
}
}
}
}
#ifdef DEBUG
std::printf(" : ReserveMemoryRange call end: HadAnyFailure = %d\n\n", HadAnyFailure);
#endif
// Only a complete success when the entire request was reserved in a single range
// (Otherwise, we have either a complete failure, or reserved it partially over multiple ranges)
return !HadAnyFailure;
}
// Free address range from the host.
void FreeMemoryRange(int index, blocks_reserved_t blocks_reserved)
{
uint32_t Start = XboxAddressRanges[index].Start, _Start;
int Size = XboxAddressRanges[index].Size;
bool NeedsReservationTracking = false;
unsigned int arr_index = BLOCK_REGION_DEVKIT_INDEX_BEGIN;
#ifdef DEBUG
std::printf("DEBUG: FreeMemoryRange call begin\n");
std::printf(" : Comment = %s\n", XboxAddressRanges[index].Comment);
#endif
switch (Start) {
case PHYSICAL_MAP1_BASE:
case PHYSICAL_MAP2_BASE:
case TILED_MEMORY_BASE: {
(void)UnmapViewOfFile((LPVOID)Start);
#ifdef DEBUG
std::printf(" : UnmapViewOfFile; Start = 0x%08X\n", Start);
#endif
}
break;
case SYSTEM_MEMORY_BASE:
// If additional addresses need to be assign in region's block.
// Then check for nonzero value.
arr_index = BLOCK_REGION_SYSTEM_INDEX_BEGIN;
[[fallthrough]];
case DEVKIT_MEMORY_BASE: {
// arr_index's default is BLOCK_REGION_DEVKIT_INDEX_BEGIN which is zero.
// Any block region above zero should be place above this case to override zero value.
//arr_index = BLOCK_REGION_DEVKIT_INDEX_BEGIN;
NeedsReservationTracking = true;
}
[[fallthrough]];
default: {
while (Size > 0) {
_Start = Start; // Require to silence C6001's warning complaint
BOOL Result = VirtualFree((LPVOID)_Start, 0, MEM_RELEASE);
#ifdef DEBUG
std::printf(" : Start = %08X; Result = %d;\n", Start, Result);
#endif
// Handle the next block
Start += BLOCK_SIZE;
Size -= BLOCK_SIZE;
if (NeedsReservationTracking) {
if (Result != 0) {
blocks_reserved[arr_index / 32] &= ~(1 << (arr_index % 32));
#ifdef DEBUG
std::printf(" : arr_index = 0x%08X; clear bit = 0x%08X;\n", arr_index, (1 << (arr_index % 32)));
std::printf(" : blocks_reserved[%08X] = 0x%08X\n", arr_index/32, blocks_reserved[arr_index/32]);
#endif
}
arr_index++;
}
}
}
}
#ifdef DEBUG
std::printf(" : FreeMemoryRange call end\n\n");
#endif
}
bool ReserveAddressRanges(const unsigned int system, blocks_reserved_t blocks_reserved) {
// Loop over all Xbox address ranges
for (size_t i = 0; i < XboxAddressRanges_size; i++) {
// Skip address ranges that don't match the given flags
if (!AddressRangeMatchesFlags(i, system))
continue;
// Try to reserve each address range
if (ReserveMemoryRange(i, blocks_reserved))
continue;
// Some ranges are allowed to fail reserving
if (!IsOptionalAddressRange(i)) {
return false;
}
}
return true;
}
void FreeAddressRanges(const unsigned int system, unsigned int release_systems, blocks_reserved_t blocks_reserved) {
// If reserved_systems is empty, then there's nothing to be freed up.
if (release_systems == 0) {
return;
}
// Loop over all Xbox address ranges
for (size_t i = 0; i < XboxAddressRanges_size; i++) {
// Skip address ranges that do match specific flag
if (AddressRangeMatchesFlags(i, system))
continue;
// Skip address ranges that doesn't match the reserved flags
if (!AddressRangeMatchesFlags(i, release_systems))
continue;
FreeMemoryRange(i, blocks_reserved);
}
}
bool AttemptReserveAddressRanges(unsigned int* p_reserved_systems, blocks_reserved_t blocks_reserved) {
size_t iLast = 0;
unsigned int reserved_systems = *p_reserved_systems, clear_systems = 0;
// Loop over all Xbox address ranges
for (size_t i = 0; i < XboxAddressRanges_size; i++) {
// Once back to original spot, let's resume.
if (i == iLast && clear_systems) {
reserved_systems &= ~clear_systems;
if (reserved_systems == 0) {
*p_reserved_systems = 0;
return false;
}
// Resume virtual allocated range.
clear_systems = 0;
continue;
}
if (clear_systems) {
// Skip address ranges that doesn't match the given flags
if (!AddressRangeMatchesFlags(i, clear_systems))
continue;
// Release incompatible system's memory range
FreeMemoryRange(i, blocks_reserved);
}
else {
// Skip address ranges that don't match the given flags
if (!AddressRangeMatchesFlags(i, reserved_systems))
continue;
// Try to reserve each address range
if (ReserveMemoryRange(i, blocks_reserved))
continue;
// Some ranges are allowed to fail reserving
if (!IsOptionalAddressRange(i)) {
// If not, then let's free them and downgrade host's limitation.
clear_systems = AddressRangeGetSystemFlags(i);
iLast = i;
i = -1; // Reset index back to zero after for statement's increment.
continue;
}
}
}
*p_reserved_systems = reserved_systems;
return true;
}
bool isSystemFlagSupport(unsigned int reserved_systems, unsigned int assign_system)
{
if (reserved_systems & assign_system) {
return true;
}
return false;
}

View File

@ -0,0 +1,47 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of Cxbx-Reloaded.
// *
// * Cxbx-Reloaded is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2017-2019 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
#include <cstdint> // For uint32_t
// First block section will be devkit region (256MiB) = 262144KiB / 64 KiB = 4096 bits needed -> 4096 / 32 (sizeof(uint32_t)) = 128 entries blocks_reserved array.
// Next block section will be system region (512MiB) = 524288KiB / 64KiB = 8192 bits needed -> 8192 / 32 (sizeof(uint32_t)) = 256 entries of blocks_reserved array.
// 1 bit per block_size (64KiB).
typedef uint32_t blocks_reserved_t[384]; // 384 = 128 (devkit region) + 256 (system region)
inline constexpr uint32_t BLOCK_REGION_DEVKIT_INDEX_BEGIN = 0;
inline constexpr uint32_t BLOCK_REGION_DEVKIT_INDEX_END = 4096;
inline constexpr uint32_t BLOCK_REGION_SYSTEM_INDEX_BEGIN = 4096;
inline constexpr uint32_t BLOCK_REGION_SYSTEM_INDEX_END = 12288;
extern bool ReserveAddressRanges(const unsigned int system, blocks_reserved_t blocks_reserved);
extern void FreeAddressRanges(const unsigned int system, unsigned int release_systems, blocks_reserved_t blocks_reserved);
extern bool AttemptReserveAddressRanges(unsigned int* p_reserved_systems, blocks_reserved_t blocks_reserved);
extern bool isSystemFlagSupport(unsigned int reserved_systems, unsigned int assign_system);

View File

@ -1,53 +0,0 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2016 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef RESERVEDMEMORY_H
#define RESERVEDMEMORY_H
#if defined(__cplusplus)
extern "C"
{
#endif
#include "EmuShared.h" // For XBE_MAX_VA, XBE_IMAGE_BASE and CXBX_BASE_OF_CODE
// The following code reserves virtual addresses from 0x00011000 upwards;
#define VM_PLACEHOLDER_SIZE (XBE_MAX_VA - XBE_IMAGE_BASE - CXBX_BASE_OF_CODE)
// First, declare the '.text' section again :
#pragma section(".text") // Note : 'read,write,execute' would cause a warning
// Then place the following variable into the '.text' section :
__declspec(allocate(".text"))
// This variable *MUST* be this large, for it to take up address space
// so that all other code and data in this module are placed outside of the
// maximum virtual memory range.
unsigned char virtual_memory_placeholder[VM_PLACEHOLDER_SIZE]; // = { OPCODE_NOP_90 };
// TODO : Try to get the same result without enlarging our executable by 128 MB!
#if defined(__cplusplus)
}
#endif
#endif // RESERVEDMEMORY_H

View File

@ -27,12 +27,15 @@
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::CXBXR
#include "Settings.hpp"
#include "core\kernel\support\Emu.h"
#include "EmuShared.h"
#include <filesystem>
#include "common\input\InputManager.h"
#include "common\input\layout_xbox_controller.h"
#include "common\input\layout_xbox_device.h"
#include <fstream>
#include "common/util/cliConfig.hpp"
// TODO: Implement Qt support when real CPU emulation is available.
#ifndef QT_VERSION // NOTE: Non-Qt will be using current directory for data
@ -45,21 +48,28 @@ static_assert(false, "Please implement support for cross-platform's user profile
#include <QStandardPaths> // for cross-platform's user profile support
#endif
std::string g_exec_filepath;
// Individual library version
uint16_t g_LibVersion_D3D8 = 0;
uint16_t g_LibVersion_DSOUND = 0;
// NOTE: Update settings_version when add/edit/delete setting's structure.
// NOTE: Update settings_version when conversion to setting's structure is required.
// UPDATE: When settings are removed, use "if (use false && settings_version < {next_version}) {" statement
// until existing settings require replacement or conversion. next_version input is a hardcode number.
// Settings version 10 and later should consider as not backward compatible.
// TODO: Add read-only state when using an older build and add a notification for will not be able save to file.
// The sooner we do this, the better before version upgrade.
///////////////////////////
// * History:
// * 2: (RadWolfie), initial version
// * 3: (ergo720), added logging settings
// * 4: (LukeUsher), added network settings
// * 5: (ergo720), added new input gui settings and revision to core
// * 6: (RadWolfie), added loader executable member to core, only for clean up loader expertimental setting
// * 7: (RadWolfie), fix allowAdminPrivilege not align with other boolean members
// * 8: (ergo720), added general input settings
// * 9: (LukeUsher), replaced HardwareYUV with MaintainAspect
///////////////////////////
const unsigned int settings_version = 5;
const unsigned int settings_version = 9;
Settings* g_Settings = nullptr;
@ -78,6 +88,9 @@ static struct {
const char* RecentXbeFiles = "RecentXbeFiles";
const char* DataStorageToggle = "DataStorageToggle";
const char* DataCustomLocation = "DataCustomLocation";
const char* IgnoreInvalidXbeSig = "IgnoreInvalidXbeSig";
const char *IgnoreInvalidXbeSec = "IgnoreInvalidXbeSec";
const char* ConsoleTypeToggle = "ConsoleTypeToggle";
} sect_gui_keys;
static const char* section_core = "core";
@ -89,6 +102,7 @@ static struct {
const char* AllowAdminPrivilege = "AllowAdminPrivilege";
const char* LoggedModules = "LoggedModules";
const char* LogLevel = "LogLevel";
const char* LogPopupTestCase = "LogPopupTestCase";
} sect_core_keys;
static const char* section_video = "video";
@ -98,10 +112,19 @@ static struct {
const char* Direct3DDevice = "Direct3DDevice";
const char* VSync = "VSync";
const char* FullScreen = "FullScreen";
const char* HardwareYUV = "HardwareYUV";
const char* MaintainAspect = "MaintainAspect";
const char* RenderResolution = "RenderResolution";
} sect_video_keys;
static const char* section_overlay = "overlay";
static struct {
const char* build_hash = "Build Hash";
const char* FPS = "FPS";
const char* hle_lle_stats = "HLE/LLE Stats";
const char* title_name = "Title Name";
const char* file_name = "File Name";
} sect_overlay_keys;
static const char* section_audio = "audio";
static struct {
const char* adapter = "adapter";
@ -117,15 +140,24 @@ static struct {
const char* adapter_name = "adapter_name";
} sect_network_keys;
static const char *section_input_general = "input-general";
static struct {
const char *mo_axis_range = "MouseAxisRange";
const char *mo_wheel_range = "MouseWheelRange";
const char *ignore_kbmo_unfocus = "IgnoreKbMoUnfocus";
} sect_input_general;
static const char* section_controller_dinput = "controller-dinput";
static const char* section_controller_port = "controller-port";
static const char* section_input = "input-port-";
static const char* section_input_port = "input-port-";
static struct {
const char* type = "Type";
const char* device = "DeviceName";
const char* config = "ProfileName";
} sect_input;
const char *top_slot = "TopSlot";
const char *bottom_slot = "BottomSlot";
} sect_input_port;
static const char* section_input_profiles = "input-profile-";
static struct {
@ -144,7 +176,9 @@ static struct {
std::string GenerateExecDirectoryStr()
{
return g_exec_filepath.substr(0, g_exec_filepath.find_last_of("\\/"));
std::string exec_path;
(void)cli_config::GetValue(cli_config::exec, &exec_path);
return exec_path.substr(0, exec_path.find_last_of("\\/"));
}
// NOTE: This function will be only have Qt support, std::filesystem doesn't have generic support.
@ -203,74 +237,33 @@ bool Settings::Init()
// Enter setup installer process
if (!bRet) {
std::string saveFile;
#ifdef RETRO_API_VERSION // TODO: Change me to #ifndef QT_VERSION
// Can only have one option without Qt.
saveFile = GenerateExecDirectoryStr();
std::string setupFile;
m_gui.DataStorageToggle = SetupFile(setupFile);
#else // Only support for Qt compile build.
int iRet = MessageBox(nullptr, szSettings_save_user_option_message, "Cxbx-Reloaded", MB_YESNOCANCEL | MB_ICONQUESTION);
if (iRet == IDYES) {
saveFile = GenerateExecDirectoryStr();
m_gui.DataStorageToggle = CXBX_DATA_EXECDIR;
}
else if (iRet == IDNO){
saveFile = GenerateUserProfileDirectoryStr();
m_gui.DataStorageToggle = CXBX_DATA_APPDATA;
if (saveFile.size() == 0) {
return false;
}
// Check if data directory exists.
bRet = std::filesystem::exists(saveFile);
if (!bRet) {
// Then try create data directory.
bRet = std::filesystem::create_directory(saveFile);
if (!bRet) {
// Unable to create a data directory
return false;
}
}
}
else {
if (m_gui.DataStorageToggle == CXBX_DATA_INVALID) {
return false;
}
#endif
saveFile.append(szSettings_settings_file);
// Call LoadConfig, this will load the config, applying defaults for any missing fields
bRet = LoadConfig();
if (!bRet) {
MessageBox(nullptr, szSettings_setup_error, "Cxbx-Reloaded", MB_OK);
PopupError(nullptr, szSettings_setup_error);
return false;
}
bRet = Save(saveFile);
bRet = Save(setupFile);
}
return bRet;
}
bool Settings::LoadUserConfig()
{
std::string fileSearch = GenerateExecDirectoryStr();
std::string fileSearch;
m_gui.DataStorageToggle = FindSettingsLocation(fileSearch);
fileSearch.append(szSettings_settings_file);
// Check and see if file exists from portable, current, directory.
if (std::filesystem::exists(fileSearch) == false) {
fileSearch = GenerateUserProfileDirectoryStr();
if (fileSearch.size() == 0) {
return false;
}
fileSearch.append(szSettings_settings_file);
// Check if the user profile directory settings file exists.
if (std::filesystem::exists(fileSearch) == false) {
return false;
}
if (m_gui.DataStorageToggle == CXBX_DATA_INVALID) {
return false;
}
return LoadFile(fileSearch);
@ -347,6 +340,11 @@ bool Settings::LoadConfig()
index++;
}
m_gui.bIgnoreInvalidXbeSig = m_si.GetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, /*Default=*/false);
m_gui.bIgnoreInvalidXbeSec = m_si.GetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSec, /*Default=*/false);
m_gui.ConsoleTypeToggle = (EMU_CONSOLE_TYPE)m_si.GetLongValue(section_gui, sect_gui_keys.ConsoleTypeToggle, /*Default=*/EMU_CONSOLE_TYPE_AUTO);
// ==== GUI End =============
// ==== Core Begin ==========
@ -388,9 +386,14 @@ bool Settings::LoadConfig()
m_core.LoggedModules[index] = 0;
index++;
}
m_core.bLogPopupTestCase = m_si.GetBoolValue(section_core, sect_core_keys.LogPopupTestCase, /*Default=*/true);
// ==== Core End ============
// Delete/update legacy configs from previous revisions
RemoveLegacyConfigs(m_core.Revision);
m_core.Revision = settings_version;
// ==== Hack Begin ==========
m_hacks.DisablePixelShaders = m_si.GetBoolValue(section_hack, sect_hack_keys.DisablePixelShaders, /*Default=*/false);
@ -415,7 +418,7 @@ bool Settings::LoadConfig()
m_video.direct3DDevice = m_si.GetLongValue(section_video, sect_video_keys.Direct3DDevice, /*Default=*/0);
m_video.bVSync = m_si.GetBoolValue(section_video, sect_video_keys.VSync, /*Default=*/false);
m_video.bFullScreen = m_si.GetBoolValue(section_video, sect_video_keys.FullScreen, /*Default=*/false);
m_video.bHardwareYUV = m_si.GetBoolValue(section_video, sect_video_keys.HardwareYUV, /*Default=*/false);
m_video.bMaintainAspect = m_si.GetBoolValue(section_video, sect_video_keys.MaintainAspect, /*Default=*/true);
m_video.renderScaleFactor = m_si.GetLongValue(section_video, sect_video_keys.RenderResolution, /*Default=*/1);
// ==== Video End ===========
@ -460,39 +463,74 @@ bool Settings::LoadConfig()
// ==== Network End =========
// ==== Input Begin ====
// ==== Input General Begin ====
m_input_general.MoAxisRange = m_si.GetLongValue(section_input_general, sect_input_general.mo_axis_range, MO_AXIS_DEFAULT_RANGE);
m_input_general.MoWheelRange = m_si.GetLongValue(section_input_general, sect_input_general.mo_wheel_range, MO_WHEEL_DEFAULT_RANGE);
m_input_general.IgnoreKbMoUnfocus = m_si.GetBoolValue(section_input_general, sect_input_general.ignore_kbmo_unfocus, true);
// ==== Input General End ==============
// ==== Input Port Begin ====
for (int port_num = 0; port_num < 4; port_num++) {
std::string current_section = std::string(section_input) + std::to_string(port_num);
int ret = m_si.GetLongValue(current_section.c_str(), sect_input.type, -2);
if (ret == -2) {
m_input[port_num].Type = to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID);
continue;
for (int slot = 0; slot < XBOX_CTRL_NUM_SLOTS; ++slot) {
m_input_port[port_num].Type = to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID);
m_input_port[port_num].SlotType[slot] = to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID);
std::string current_section = std::string(section_input_port) + std::to_string(port_num);
int ret = m_si.GetLongValue(current_section.c_str(), sect_input_port.type, -2);
if (ret == -2) {
continue;
}
m_input_port[port_num].Type = ret;
m_input_port[port_num].DeviceName = m_si.GetValue(current_section.c_str(), sect_input_port.device);
m_input_port[port_num].ProfileName = TrimQuoteFromString(m_si.GetValue(current_section.c_str(), sect_input_port.config));
ret = m_si.GetLongValue(current_section.c_str(), slot == 0 ? sect_input_port.top_slot : sect_input_port.bottom_slot, -2);
if (ret == -2) {
continue;
}
m_input_port[port_num].SlotType[slot] = ret;
}
m_input[port_num].Type = ret;
m_input[port_num].DeviceName = m_si.GetValue(current_section.c_str(), sect_input.device);
m_input[port_num].ProfileName = TrimQuoteFromString(m_si.GetValue(current_section.c_str(), sect_input.config));
}
// ==== Input End ==============
// ==== Input Port End ==============
// ==== Input Profile Begin ====
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
if (dev_num_buttons[device] == 0) {
continue;
}
}
for (int i = 0; i < dev_num_buttons[device]; i++) {
char control_name[30];
std::sprintf(control_name, sect_input_profiles.control, button_xbox_ctrl_names[i][0]);
control_names[device].push_back(control_name);
}
const auto &lambda = [&control_names, &device](int num_buttons, const char *const ctrl_names[]) {
for (int i = 0; i < num_buttons; i++) {
char control_name[XBOX_BUTTON_NAME_LENGTH];
std::sprintf(control_name, sect_input_profiles.control, ctrl_names[i]);
control_names[device].push_back(control_name);
}
};
switch (device)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S):
case to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK):
lambda(dev_num_buttons[device], button_xbox_ctrl_names);
break;
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER):
lambda(dev_num_buttons[device], button_sbc_names);
break;
case to_underlying(XBOX_INPUT_DEVICE::LIGHTGUN):
lambda(dev_num_buttons[device], button_lightgun_names);
break;
}
}
// TODO: add the control names of the other devices
index = 0;
while (true) {
std::string current_section = std::string(section_input_profiles) + std::to_string(index);
@ -513,9 +551,15 @@ bool Settings::LoadConfig()
// ==== Input Profile End ======
// Delete legacy configs from previous revisions
RemoveLegacyConfigs(m_core.Revision);
m_core.Revision = settings_version;
// ==== Overlay Begin =========
m_overlay.build_hash = m_si.GetBoolValue(section_overlay, sect_overlay_keys.build_hash, false);
m_overlay.fps = m_si.GetBoolValue(section_overlay, sect_overlay_keys.FPS, false);
m_overlay.hle_lle_stats = m_si.GetBoolValue(section_overlay, sect_overlay_keys.hle_lle_stats, false);
m_overlay.title_name = m_si.GetBoolValue(section_overlay, sect_overlay_keys.title_name, false);
m_overlay.file_name = m_si.GetBoolValue(section_overlay, sect_overlay_keys.file_name, false);
// ==== Overlay End ===========
return true;
}
@ -544,6 +588,11 @@ bool Settings::Save(std::string file_path)
m_si.SetValue(section_gui, sect_gui_keys.RecentXbeFiles, m_gui.szRecentXbeFiles[i].c_str(), nullptr, false);
}
m_si.SetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, m_gui.bIgnoreInvalidXbeSig, nullptr, true);
m_si.SetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSec, m_gui.bIgnoreInvalidXbeSec, nullptr, true);
m_si.SetLongValue(section_gui, sect_gui_keys.ConsoleTypeToggle, m_gui.ConsoleTypeToggle, nullptr, true, true);
// ==== GUI End =============
// ==== Core Begin ==========
@ -563,6 +612,7 @@ bool Settings::Save(std::string file_path)
stream << "0x" << std::hex << m_core.LoggedModules[i];
m_si.SetValue(section_core, sect_core_keys.LoggedModules, stream.str().c_str(), nullptr, false);
}
m_si.SetBoolValue(section_core, sect_core_keys.LogPopupTestCase, m_core.bLogPopupTestCase, nullptr, true);
// ==== Core End ============
@ -574,8 +624,9 @@ bool Settings::Save(std::string file_path)
m_si.SetLongValue(section_video, sect_video_keys.Direct3DDevice, m_video.direct3DDevice, nullptr, true, true);
m_si.SetBoolValue(section_video, sect_video_keys.VSync, m_video.bVSync, nullptr, true);
m_si.SetBoolValue(section_video, sect_video_keys.FullScreen, m_video.bFullScreen, nullptr, true);
m_si.SetBoolValue(section_video, sect_video_keys.HardwareYUV, m_video.bHardwareYUV, nullptr, true);
m_si.SetBoolValue(section_video, sect_video_keys.MaintainAspect, m_video.bMaintainAspect, nullptr, true);
m_si.SetLongValue(section_video, sect_video_keys.RenderResolution, m_video.renderScaleFactor, nullptr, false, true);
// ==== Video End ===========
// ==== Audio Begin =========
@ -601,36 +652,63 @@ bool Settings::Save(std::string file_path)
// ==== Network End =========
// ==== Input Begin ====
// ==== Input General Begin =======
m_si.SetLongValue(section_input_general, sect_input_general.mo_axis_range, m_input_general.MoAxisRange, nullptr, false, true);
m_si.SetLongValue(section_input_general, sect_input_general.mo_wheel_range, m_input_general.MoWheelRange, nullptr, false, true);
m_si.SetBoolValue(section_input_general, sect_input_general.ignore_kbmo_unfocus, m_input_general.IgnoreKbMoUnfocus, nullptr, true);
// ==== Input General End =========
// ==== Input Port Begin ====
for (int port_num = 0; port_num < 4; port_num++) {
std::string current_section = std::string(section_input) + std::to_string(port_num);
std::string quoted_prf_str = m_input[port_num].ProfileName.insert(0, "\"");
std::string current_section = std::string(section_input_port) + std::to_string(port_num);
std::string quoted_prf_str = m_input_port[port_num].ProfileName.insert(0, "\"");
quoted_prf_str += "\"";
m_si.SetLongValue(current_section.c_str(), sect_input.type, m_input[port_num].Type, nullptr, false, true);
m_si.SetValue(current_section.c_str(), sect_input.device, m_input[port_num].DeviceName.c_str(), nullptr, true);
m_si.SetValue(current_section.c_str(), sect_input.config, quoted_prf_str.c_str(), nullptr, true);
m_si.SetLongValue(current_section.c_str(), sect_input_port.type, m_input_port[port_num].Type, nullptr, false, true);
m_si.SetValue(current_section.c_str(), sect_input_port.device, m_input_port[port_num].DeviceName.c_str(), nullptr, true);
m_si.SetValue(current_section.c_str(), sect_input_port.config, quoted_prf_str.c_str(), nullptr, true);
m_si.SetLongValue(current_section.c_str(), sect_input_port.top_slot, m_input_port[port_num].SlotType[SLOT_TOP], nullptr, false, true);
m_si.SetLongValue(current_section.c_str(), sect_input_port.bottom_slot, m_input_port[port_num].SlotType[SLOT_BOTTOM], nullptr, false, true);
}
// ==== Input End ==============
// ==== Input Port End ==============
// ==== Input Profile Begin ====
std::array<std::vector<std::string>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> control_names;
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
for (int device = 0; device < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); device++) {
if (dev_num_buttons[device] == 0) {
continue;
}
}
for (int i = 0; i < dev_num_buttons[device]; i++) {
char control_name[30];
std::sprintf(control_name, sect_input_profiles.control, button_xbox_ctrl_names[i][0]);
control_names[device].push_back(control_name);
}
const auto &lambda = [&control_names, &device](int num_buttons, const char *const ctrl_names[]) {
for (int i = 0; i < num_buttons; i++) {
char control_name[XBOX_BUTTON_NAME_LENGTH];
std::sprintf(control_name, sect_input_profiles.control, ctrl_names[i]);
control_names[device].push_back(control_name);
}
};
switch (device)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S):
case to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK):
lambda(dev_num_buttons[device], button_xbox_ctrl_names);
break;
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER):
lambda(dev_num_buttons[device], button_sbc_names);
break;
case to_underlying(XBOX_INPUT_DEVICE::LIGHTGUN):
lambda(dev_num_buttons[device], button_lightgun_names);
break;
}
}
// TODO: add the control names of the other devices
int profile_num = 0;
for (int i = 0; i < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX); i++) {
size_t vec_size = m_input_profiles[i].size();
@ -666,6 +744,16 @@ bool Settings::Save(std::string file_path)
// ==== Input Profile End ======
// ==== Overlay Begin =======
m_si.SetBoolValue(section_overlay, sect_overlay_keys.build_hash, m_overlay.build_hash, nullptr, true);
m_si.SetBoolValue(section_overlay, sect_overlay_keys.FPS, m_overlay.fps, nullptr, true);
m_si.SetBoolValue(section_overlay, sect_overlay_keys.hle_lle_stats, m_overlay.hle_lle_stats, nullptr, true);
m_si.SetBoolValue(section_overlay, sect_overlay_keys.title_name, m_overlay.title_name, nullptr, true);
m_si.SetBoolValue(section_overlay, sect_overlay_keys.file_name, m_overlay.file_name, nullptr, true);
// ==== Overlay End =========
// ==== Hack Begin ==========
m_si.SetBoolValue(section_hack, sect_hack_keys.DisablePixelShaders, m_hacks.DisablePixelShaders, nullptr, true);
@ -703,6 +791,7 @@ void Settings::SyncToEmulator()
// register Video settings
g_EmuShared->SetVideoSettings(&m_video);
g_EmuShared->SetOverlaySettings(&m_overlay);
// register Audio settings
g_EmuShared->SetAudioSettings(&m_audio);
@ -710,33 +799,43 @@ void Settings::SyncToEmulator()
// register Network settings
g_EmuShared->SetNetworkSettings(&m_network);
// register input settings
// register xbox device input settings
for (int i = 0; i < 4; i++) {
g_EmuShared->SetInputDevTypeSettings(&m_input[i].Type, i);
if (m_input[i].Type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
g_EmuShared->SetInputDevNameSettings(m_input[i].DeviceName.c_str(), i);
auto it = std::find_if(m_input_profiles[m_input[i].Type].begin(),
m_input_profiles[m_input[i].Type].end(), [this, i](const auto& profile) {
if (profile.ProfileName == m_input[i].ProfileName) {
return true;
g_EmuShared->SetInputDevTypeSettings(&m_input_port[i].Type, i);
g_EmuShared->SetInputSlotTypeSettings(&m_input_port[i].SlotType[SLOT_TOP], i, SLOT_TOP);
g_EmuShared->SetInputSlotTypeSettings(&m_input_port[i].SlotType[SLOT_BOTTOM], i, SLOT_BOTTOM);
if (m_input_port[i].Type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
g_EmuShared->SetInputDevNameSettings(m_input_port[i].DeviceName.c_str(), i);
if (m_input_port[i].Type < to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)) {
auto it = std::find_if(m_input_profiles[m_input_port[i].Type].begin(),
m_input_profiles[m_input_port[i].Type].end(), [this, i](const auto &profile) {
if (profile.ProfileName == m_input_port[i].ProfileName) {
return true;
}
return false;
});
if (it != m_input_profiles[m_input_port[i].Type].end()) {
char controls_name[HIGHEST_NUM_BUTTONS][HOST_BUTTON_NAME_LENGTH];
for (int index = 0; index < dev_num_buttons[m_input_port[i].Type]; index++) {
strncpy(controls_name[index], it->ControlList[index].c_str(), 30);
}
return false;
});
if (it != m_input_profiles[m_input[i].Type].end()) {
char controls_name[XBOX_CTRL_NUM_BUTTONS][30];
for (int index = 0; index < dev_num_buttons[m_input[i].Type]; index++) {
strncpy(controls_name[index], it->ControlList[index].c_str(), 30);
g_EmuShared->SetInputBindingsSettings(controls_name, dev_num_buttons[m_input_port[i].Type], i);
}
g_EmuShared->SetInputBindingsSettings(controls_name, XBOX_CTRL_NUM_BUTTONS, i);
}
}
}
// register Input general settings
g_EmuShared->SetInputGeneralSettings(&m_input_general);
// register Hacks settings
g_EmuShared->SetHackSettings(&m_hacks);
// register data location setting
g_EmuShared->SetStorageLocation(GetDataLocation().c_str());
g_EmuShared->SetDataLocation(GetDataLocation().c_str());
// reset title mount path
g_EmuShared->SetTitleMountPath("");
}
void verifyDebugFilePath(DebugMode& debug_mode, std::string& file_path)
@ -820,17 +919,131 @@ std::string Settings::GetDataLocation()
return m_current_data_location;
}
// Detect where settings file is located and return default data mode.
CXBX_DATA Settings::FindSettingsLocation(std::string& file_path_out)
{
std::string fileSearch = GenerateExecDirectoryStr();
CXBX_DATA ret = CXBX_DATA_EXECDIR;
fileSearch.append(szSettings_settings_file);
// Check and see if file exists from portable, current, directory.
if (std::filesystem::exists(fileSearch) == false) {
fileSearch = GenerateUserProfileDirectoryStr();
if (fileSearch.size() == 0) {
return CXBX_DATA_INVALID;
}
CXBX_DATA ret = CXBX_DATA_APPDATA;
fileSearch.append(szSettings_settings_file);
// Check if the user profile directory settings file exists.
if (std::filesystem::exists(fileSearch) == false) {
return CXBX_DATA_INVALID;
}
}
file_path_out = fileSearch;
return ret;
}
// Enter setup installer process
CXBX_DATA Settings::SetupFile(std::string& file_path_out)
{
std::string setupFile;
CXBX_DATA data_ret = CXBX_DATA_INVALID;
#ifdef RETRO_API_VERSION // TODO: Change me to #ifndef QT_VERSION
// Can only have one option without Qt.
setupFile = GenerateExecDirectoryStr();
#else // Only support for Qt compile build.
PopupReturn eRet = PopupQuestion(nullptr, szSettings_save_user_option_message);
if (eRet == PopupReturn::Yes) {
setupFile = GenerateExecDirectoryStr();
data_ret = CXBX_DATA_EXECDIR;
}
else if (eRet == PopupReturn::No) {
setupFile = GenerateUserProfileDirectoryStr();
data_ret = CXBX_DATA_APPDATA;
if (setupFile.size() != 0) {
// Check if data directory exists.
if (!std::filesystem::exists(setupFile)) {
// Then try create data directory.
if (!std::filesystem::create_directory(setupFile)) {
// Unable to create a data directory
data_ret = CXBX_DATA_INVALID;
}
}
}
}
#endif
if (data_ret == CXBX_DATA_INVALID) {
PopupError(nullptr, szSettings_setup_error);
}
else {
setupFile.append(szSettings_settings_file);
// Create the file, that's it. Load the default configuration later on;
std::ofstream createFile(setupFile);
if (createFile.is_open()) {
createFile.close();
}
file_path_out = setupFile;
}
return data_ret;
}
void Settings::RemoveLegacyConfigs(unsigned int CurrentRevision)
{
switch (CurrentRevision) {
case 2:
case 3:
case 4:
if (CurrentRevision < 5) {
m_si.Delete(section_controller_dinput, nullptr, true);
m_si.Delete(section_controller_port, nullptr, true);
break;
case 5:
default:
break;
}
if (CurrentRevision == 5) {
m_si.Delete(section_core, "LoaderExperiment", true);
}
if (CurrentRevision < 8) {
const std::string kb_str = "Keyboard";
for (unsigned port_num = 0; port_num < 4; ++port_num) {
std::string current_section = std::string(section_input_port) + std::to_string(port_num);
std::string device_name = m_si.GetValue(current_section.c_str(), sect_input_port.device, "");
if (device_name.ends_with(kb_str)) {
device_name += "Mouse";
m_si.SetValue(current_section.c_str(), sect_input_port.device, device_name.c_str(), nullptr, true);
}
}
for (unsigned index = 0; ; ++index) {
std::string current_section = std::string(section_input_profiles) + std::to_string(index);
if (m_si.GetSectionSize(current_section.c_str()) == -1) {
break;
}
std::string device_name = m_si.GetValue(current_section.c_str(), sect_input_profiles.device, "");
// NOTE: with C++20, this can be simplified by simply calling device_name.ends_with()
if (device_name.length() >= kb_str.length()) {
if (device_name.compare(device_name.length() - kb_str.length(), kb_str.length(), kb_str) == 0) {
device_name += "Mouse";
m_si.SetValue(current_section.c_str(), sect_input_profiles.device, device_name.c_str(), nullptr, true);
}
}
}
}
if(CurrentRevision < 9) {
m_si.Delete(section_video, "HardwareYUV", true);
}
// see settings_version for details.
if(false && CurrentRevision < 10) {
m_si.Delete(section_core, "LoaderExecutable", true);
}
}

View File

@ -18,7 +18,7 @@
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2017-2018 RadWolfie
// * (c) 2017-2018 RadWolfie
// * (c) 2019 ergo720
// *
// * All rights reserved
@ -26,33 +26,46 @@
// ******************************************************************
#ifndef SETTINGS_HPP
#define SETTINGS_HPP
#include "Cxbx.h"
#include "SimpleIni.h"
#include "input\InputDevice.h"
#include "SimpleIni.h"
#include "common\input\InputManager.h"
#include "common\util\CxbxUtil.h"
#include <string>
#include <array>
#include <string>
#include <array>
#include "core/common/imgui/settings.h"
extern std::string g_exec_filepath;
// Individual library version
extern uint16_t g_LibVersion_D3D8;
// Individual library version
extern uint16_t g_LibVersion_D3D8;
extern uint16_t g_LibVersion_DSOUND;
#define szSettings_alloc_error "ERROR: Unable to allocate Settings class."
#define assert_check_shared_memory(type) \
"Invalid "#type" size, please verify structure is align, not adding new member, or is using placeholder reserves." \
" Otherwise, please perform versioning upgrade and update "#type" sizeof check."
// Toggle emulation console mode.
typedef enum _EMU_CONSOLE_TYPE {
EMU_CONSOLE_TYPE_AUTO = 0,
EMU_CONSOLE_TYPE_RETAIL = 1,
EMU_CONSOLE_TYPE_DEVKIT = 2,
EMU_CONSOLE_TYPE_CHIHIRO = 3,
} EMU_CONSOLE_TYPE;
// Cxbx-Reloaded's data storage location.
typedef enum _CXBX_DATA {
CXBX_DATA_INVALID = -1,
CXBX_DATA_APPDATA = 0,
CXBX_DATA_EXECDIR = 1,
CXBX_DATA_CUSTOM = 2,
} CXBX_DATA;
} CXBX_DATA;
// ******************************************************************
// * Define number of integers required to store logging settings
// ******************************************************************
#define NUM_INTEGERS_LOG 2
#define NUM_INTEGERS_LOG 3
enum {
LLE_NONE = 0,
@ -74,6 +87,8 @@ public:
void SyncToEmulator();
void Verify();
std::string GetDataLocation();
static CXBX_DATA FindSettingsLocation(std::string& file_path_out);
static CXBX_DATA SetupFile(std::string& file_path_out);
// GUI settings
struct s_gui {
@ -82,23 +97,27 @@ public:
std::string szRecentXbeFiles[10];
unsigned int DataStorageToggle;
std::string szCustomLocation = "";
bool bIgnoreInvalidXbeSig;
bool bIgnoreInvalidXbeSec;
unsigned int ConsoleTypeToggle;
} m_gui;
// Core settings
struct s_core {
struct s_core {
unsigned int Revision;
unsigned int FlagsLLE;
DebugMode KrnlDebugMode;
char szKrnlDebug[MAX_PATH] = "";
char szStorageLocation[MAX_PATH] = "";
bool allowAdminPrivilege;
unsigned int LoggedModules[NUM_INTEGERS_LOG];
char szStorageLocation[xbox::max_path] = "";
unsigned int LoggedModules[NUM_INTEGERS_LOG];
int LogLevel = 1;
bool Reserved2 = 0;
bool Reserved3 = 0;
bool bUnused_WasUseLoaderExec;
bool allowAdminPrivilege;
bool bLogPopupTestCase;
bool Reserved4 = 0;
int Reserved99[10] = { 0 };
} m_core;
static_assert(sizeof(s_core) == 0x250, assert_check_shared_memory(s_core));
// Video settings
struct s_video {
@ -107,11 +126,12 @@ public:
unsigned int direct3DDevice;
bool bVSync;
bool bFullScreen;
bool bHardwareYUV;
bool bMaintainAspect;
bool Reserved3;
int renderScaleFactor = 1;
int Reserved99[9] = { 0 };
} m_video;
static_assert(sizeof(s_video) == 0x98, assert_check_shared_memory(s_video));
// Audio settings
struct s_audio {
@ -122,33 +142,45 @@ public:
bool mute_on_unfocus;
int Reserved99[14] = { 0 };
} m_audio;
struct s_input {
int Type;
std::string DeviceName;
std::string ProfileName;
};
std::array<s_input, 4> m_input;
struct s_input_profiles {
int Type;
std::string ProfileName;
std::string DeviceName;
std::vector<std::string> ControlList;
};
std::array<std::vector<s_input_profiles>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> m_input_profiles;
static_assert(sizeof(s_audio) == 0x4C, assert_check_shared_memory(s_audio));
// Input general settings
struct s_input_general {
long MoAxisRange;
long MoWheelRange;
bool IgnoreKbMoUnfocus;
bool Reserved1[3];
} m_input_general;
static_assert(sizeof(s_input_general) == 0xC, assert_check_shared_memory(s_input_general));
struct s_input_port {
int Type;
int SlotType[XBOX_CTRL_NUM_SLOTS];
std::string DeviceName;
std::string ProfileName;
};
std::array<s_input_port, 4> m_input_port;
struct s_input_profiles {
int Type;
std::string ProfileName;
std::string DeviceName;
std::vector<std::string> ControlList;
};
std::array<std::vector<s_input_profiles>, to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)> m_input_profiles;
// Network settings
struct s_network {
char adapter_name[MAX_PATH] = "";
} m_network;
static_assert(sizeof(s_network) == 0x104, assert_check_shared_memory(s_network));
// Hack settings
// NOTE: When removing fields, replace them with place-holders
// The size and order of this structure should *not* be allowed to change
// Hack settings
// NOTE: When removing fields, replace them with place-holders
// The size and order of this structure should *not* be allowed to change
// TODO: Fix IPC/Shared Memory so this isn't necessary
struct s_hack {
bool DisablePixelShaders;
bool DisablePixelShaders;
bool Reserved2;
bool UseAllCores;
bool SkipRdtscPatching;
@ -158,8 +190,11 @@ public:
bool Reserved8 = 0;
int Reserved99[8] = { 0 };
} m_hacks;
static_assert(sizeof(s_hack) == 0x28, assert_check_shared_memory(s_hack));
private:
overlay_settings m_overlay;
private:
void RemoveLegacyConfigs(unsigned int CurrentRevision);
std::string m_file_path = "";
CSimpleIniA m_si;

View File

@ -24,149 +24,165 @@
// * All rights reserved
// *
// ******************************************************************
#ifdef _WIN32
#include <windows.h>
#endif
#include <core\kernel\exports\xboxkrnl.h>
#include <windows.h>
#include <thread>
#include <vector>
#include <vector>
#include <mutex>
#include <array>
#include "Timer.h"
#include "common\util\CxbxUtil.h"
#include "core\kernel\init\CxbxKrnl.h"
#ifdef __linux__
#include <time.h>
#endif
// Virtual clocks will probably become useful once LLE CPU is implemented, but for now we don't need them.
// See the QEMUClockType QEMU_CLOCK_VIRTUAL of XQEMU for more info.
#define CLOCK_REALTIME 0
//#define CLOCK_VIRTUALTIME 1
#include "common\util\CxbxUtil.h"
#include "core\kernel\support\EmuFS.h"
#include "core\kernel\exports\EmuKrnlPs.hpp"
#include "core\kernel\exports\EmuKrnl.h"
#include "devices\Xbox.h"
#include "devices\usb\OHCI.h"
#include "core\hle\DSOUND\DirectSound\DirectSoundGlobal.hpp"
// Vector storing all the timers created
static std::vector<TimerObject*> TimerList;
// The frequency of the high resolution clock of the host
uint64_t HostClockFrequency;
// Lock to acquire when accessing TimerList
std::mutex TimerMtx;
static std::atomic_uint64_t last_qpc; // last time when QPC was called
static std::atomic_uint64_t exec_time; // total execution time in us since the emulation started
static uint64_t pit_last; // last time when the pit time was updated
static uint64_t pit_last_qpc; // last QPC time of the pit
// The frequency of the high resolution clock of the host, and the start time
int64_t HostQPCFrequency, HostQPCStartTime;
// Returns the current time of the timer
inline uint64_t GetTime_NS(TimerObject* Timer)
void timer_init()
{
#ifdef _WIN32
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
uint64_t Ret = Muldiv64(li.QuadPart, SCALE_S_IN_NS, (uint32_t)HostClockFrequency);
#elif __linux__
static struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
uint64_t Ret = Muldiv64(ts.tv_sec, SCALE_S_IN_NS, 1) + ts.tv_nsec;
#else
#error "Unsupported OS"
#endif
return Ret;
QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(&HostQPCFrequency));
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&HostQPCStartTime));
pit_last_qpc = last_qpc = HostQPCStartTime;
pit_last = get_now();
// Synchronize xbox system time with host time
LARGE_INTEGER HostSystemTime;
GetSystemTimeAsFileTime((LPFILETIME)&HostSystemTime);
xbox::KeSystemTime.High2Time = HostSystemTime.u.HighPart;
xbox::KeSystemTime.LowPart = HostSystemTime.u.LowPart;
xbox::KeSystemTime.High1Time = HostSystemTime.u.HighPart;
}
// Calculates the next expire time of the timer
static inline uint64_t GetNextExpireTime(TimerObject* Timer)
// More precise sleep, but with increased CPU usage
void SleepPrecise(std::chrono::steady_clock::time_point targetTime)
{
return GetTime_NS(Timer) + Timer->ExpireTime_MS.load();
using namespace std::chrono;
// If we don't need to wait, return right away
// TODO use waitable timers?
// TODO fetch the timer resolution to determine the sleep threshold?
// TODO adaptive wait? https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/
// Try to sleep for as much of the wait as we can
// to save CPU usage / power
// We expect sleep to overshoot, so give ourselves some extra time
// Note currently we ask Windows to give us 1ms timer resolution
constexpr auto sleepThreshold = 2ms; // Minimum remaining time before we attempt to use sleep
auto sleepFor = (targetTime - sleepThreshold) - steady_clock::now();
auto sleepMs = duration_cast<milliseconds>(sleepFor).count();
// Sleep if required
if (sleepMs >= 0) {
Sleep((DWORD)sleepMs);
}
// Spin wait
while (steady_clock::now() < targetTime) {
;
}
}
// Deallocates the memory of the timer
void Timer_Destroy(TimerObject* Timer)
// NOTE: the pit device is not implemented right now, so we put this here
static uint64_t pit_next(uint64_t now)
{
unsigned int index, i;
std::lock_guard<std::mutex>lock(TimerMtx);
index = TimerList.size();
for (i = 0; i < index; i++) {
if (Timer == TimerList[i]) {
index = i;
constexpr uint64_t pit_period = 1000;
uint64_t next = pit_last + pit_period;
if (now >= next) {
xbox::KiClockIsr(now - pit_last);
pit_last = get_now();
return pit_period;
}
return pit_last + pit_period - now; // time remaining until next clock interrupt
}
static void update_non_periodic_events()
{
// update dsound
dsound_worker();
// check for hw interrupts
for (int i = 0; i < MAX_BUS_INTERRUPT_LEVEL; i++) {
// If the interrupt is pending and connected, process it
if (g_bEnableAllInterrupts && HalSystemInterrupts[i].IsPending() && EmuInterruptList[i] && EmuInterruptList[i]->Connected) {
HalSystemInterrupts[i].Trigger(EmuInterruptList[i]);
}
}
assert(index != TimerList.size());
delete Timer;
TimerList.erase(TimerList.begin() + index);
}
// Thread that runs the timer
void ClockThread(TimerObject* Timer)
{
uint64_t NewExpireTime;
if (!Timer->Name.empty()) {
CxbxSetThreadName(Timer->Name.c_str());
}
if (Timer->CpuAffinity != nullptr) {
InitXboxThread(*Timer->CpuAffinity);
}
NewExpireTime = GetNextExpireTime(Timer);
uint64_t get_now()
{
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
uint64_t elapsed_us = now.QuadPart - last_qpc;
last_qpc = now.QuadPart;
elapsed_us *= 1000000;
elapsed_us /= HostQPCFrequency;
exec_time += elapsed_us;
return exec_time;
}
static uint64_t get_next(uint64_t now)
{
std::array<uint64_t, 5> next = {
pit_next(now),
g_NV2A->vblank_next(now),
g_NV2A->ptimer_next(now),
g_USB0->m_HostController->OHCI_next(now),
dsound_next(now)
};
return *std::min_element(next.begin(), next.end());
}
xbox::void_xt NTAPI system_events(xbox::PVOID arg)
{
// Testing shows that, if this thread has the same priority of the other xbox threads, it can take tens, even hundreds of ms to complete a single loop.
// So we increase its priority to above normal, so that it scheduled more often
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
// Always run this thread at dpc level to prevent it from ever executing APCs/DPCs
xbox::KeRaiseIrqlToDpcLevel();
while (true) {
if (GetTime_NS(Timer) > NewExpireTime) {
if (Timer->Exit.load()) {
Timer_Destroy(Timer);
return;
const uint64_t last_time = get_now();
const uint64_t nearest_next = get_next(last_time);
while (true) {
update_non_periodic_events();
uint64_t elapsed_us = get_now() - last_time;
if (elapsed_us >= nearest_next) {
break;
}
Timer->Callback(Timer->Opaque);
NewExpireTime = GetNextExpireTime(Timer);
}
Sleep(1); // prevent burning the cpu
std::this_thread::yield();
}
}
}
// Changes the expire time of a timer
void Timer_ChangeExpireTime(TimerObject* Timer, uint64_t Expire_ms)
int64_t Timer_GetScaledPerformanceCounter(int64_t Period)
{
Timer->ExpireTime_MS.store(Expire_ms);
LARGE_INTEGER currentQPC;
QueryPerformanceCounter(&currentQPC);
// Scale frequency with overflow avoidance, like in std::chrono
// https://github.com/microsoft/STL/blob/6d2f8b0ed88ea6cba26cc2151f47f678442c1663/stl/inc/chrono#L703
const int64_t currentTime = currentQPC.QuadPart - HostQPCStartTime;
const int64_t whole = (currentTime / HostQPCFrequency) * Period;
const int64_t part = (currentTime % HostQPCFrequency) * Period / HostQPCFrequency;
return whole + part;
}
// Destroys the timer
void Timer_Exit(TimerObject* Timer)
{
Timer->Exit.store(true);
}
// Allocates the memory for the timer object
TimerObject* Timer_Create(TimerCB Callback, void* Arg, std::string Name, unsigned long* Affinity)
{
std::lock_guard<std::mutex>lock(TimerMtx);
TimerObject* pTimer = new TimerObject;
pTimer->Type = CLOCK_REALTIME;
pTimer->Callback = Callback;
pTimer->ExpireTime_MS.store(0);
pTimer->Exit.store(false);
pTimer->Opaque = Arg;
Name.empty() ? pTimer->Name = "Unnamed thread" : pTimer->Name = Name;
pTimer->CpuAffinity = Affinity;
TimerList.emplace_back(pTimer);
return pTimer;
}
// Starts the timer
// Expire_MS must be expressed in NS
void Timer_Start(TimerObject* Timer, uint64_t Expire_MS)
{
Timer->ExpireTime_MS.store(Expire_MS);
std::thread(ClockThread, Timer).detach();
}
// Retrives the frequency of the high resolution clock of the host
void Timer_Init()
{
#ifdef _WIN32
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
HostClockFrequency = freq.QuadPart;
#elif __linux__
ClockFrequency = 0;
#else
#error "Unsupported OS"
#endif
}

View File

@ -28,39 +28,24 @@
#ifndef TIMER_H
#define TIMER_H
#include <atomic>
#include <atomic>
#include <mutex>
#define SCALE_S_IN_NS 1000000000
#define SCALE_MS_IN_NS 1000000
#define SCALE_US_IN_NS 1000
#define SCALE_NS_IN_NS 1
#define SCALE_NS_IN_NS 1
#define SCALE_S_IN_US 1000000
#define SCALE_MS_IN_US 1000
#define SCALE_US_IN_US 1
/* typedef of the timer object and the callback function */
typedef void(*TimerCB)(void*);
typedef struct _TimerObject
{
int Type; // timer type
std::atomic_uint64_t ExpireTime_MS; // when the timer expires (ms)
std::atomic_bool Exit; // indicates that the timer should be destroyed
TimerCB Callback; // function to call when the timer expires
void* Opaque; // opaque argument to pass to the callback
std::string Name; // the name of the timer thread (if any)
unsigned long* CpuAffinity; // the cpu affinity of the timer thread (if any)
}
TimerObject;
extern uint64_t HostClockFrequency;
extern int64_t HostQPCFrequency;
/* Timer exported functions */
TimerObject* Timer_Create(TimerCB Callback, void* Arg, std::string Name, unsigned long* Affinity);
void Timer_Start(TimerObject* Timer, uint64_t Expire_MS);
void Timer_Exit(TimerObject* Timer);
void Timer_ChangeExpireTime(TimerObject* Timer, uint64_t Expire_ms);
inline uint64_t GetTime_NS(TimerObject* Timer);
void Timer_Init();
void timer_init();
uint64_t get_now();
int64_t Timer_GetScaledPerformanceCounter(int64_t Period);
void SleepPrecise(std::chrono::steady_clock::time_point targetTime);
#endif

View File

@ -0,0 +1,68 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of Cxbx-Reloaded.
// *
// * Cxbx-Reloaded is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2017-2019 Patrick van Logchem <pvanlogchem@gmail.com>
// * (c) 2019 ego720
// *
// * All rights reserved
// *
// ******************************************************************
#include "AddressRanges.h"
#include "core\kernel\init\CxbxKrnl.h" // For CXBX_BASE_ADDR
bool VerifyBaseAddr()
{
/*! CXBX_BASE_ADDR is defined as 0x00010000, which is the base address of
the cxbxr-ldr.exe host executable.
Set in cxbxr-ldr.exe Project options, Linker, Advanced, Base Address */
return ((UINT_PTR)GetModuleHandle(nullptr) == CXBX_BASE_ADDR);
}
void UnreserveMemoryRange(const int index)
{
uint32_t Start = XboxAddressRanges[index].Start;
int Size = XboxAddressRanges[index].Size;
while (Size > 0) {
VirtualFree((LPVOID)Start, (SIZE_T)0, MEM_RELEASE); // To release, dwSize must be zero!
Start += BLOCK_SIZE;
Size -= BLOCK_SIZE;
}
}
bool AllocateMemoryRange(const int index)
{
uint32_t Start = XboxAddressRanges[index].Start;
int Size = XboxAddressRanges[index].Size;
while (Size > 0) {
int BlockSize = (Size > BLOCK_SIZE) ? BLOCK_SIZE : Size;
if (nullptr == VirtualAlloc((void*)Start, BlockSize, MEM_COMMIT, PAGE_READWRITE)) { // MEM_RESERVE already done by Cxbx-Loader.exe
return false;
}
Start += BLOCK_SIZE;
Size -= BLOCK_SIZE;
}
return true;
}

View File

@ -0,0 +1,32 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of Cxbx-Reloaded.
// *
// * Cxbx-Reloaded is free software; you can redistribute it
// * and/or modify it under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2017-2019 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
extern bool VerifyBaseAddr();
extern void UnreserveMemoryRange(const int index);
extern bool AllocateMemoryRange(const int index);

View File

@ -0,0 +1,51 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// *
// * (c) 2020 RadWolfie
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
#include <cstdint>
// Convert frequency to pitch helper
static inline int32_t converter_freq2pitch(uint32_t freq) {
// NOTE: pitch = 0 is equal to 48 KHz.
/* For research purpose of how to convert frequency to pitch and back to frequency.
// Edit hertz variable to see the result.
float hertz = 12000.0f;
float hertzRatio = 48000.0f; // base frequency
float pitchRatio = 4096.0f; // pitch per octave
// Convert hertz to pitch
float pitch = log2(hertz / hertzRatio) * pitchRatio;
// Convert pitch to hertz
hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/
return static_cast<int32_t>(log2(freq / 48000.0f) * 4096.0f);
}
// Convert pitch to frequency helper
static inline uint32_t converter_pitch2freq(int32_t pitch) {
//* See research documentation above for conversion example.
return static_cast<uint32_t>(exp((pitch / 4096.0f) * log(2)) * 48000.0f);
}

File diff suppressed because it is too large Load Diff

View File

@ -23,42 +23,42 @@
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMUDES_H
#define EMUDES_H
#define MBEDTLS_DES_KEY_SIZE 8
#define MBEDTLS_DES_ENCRYPT 1
#define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
/**
* \brief DES context structure
*/
typedef struct
{
uint32_t sk[32]; /*!< DES subkeys */
}
mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_context;
void mbedtls_des_key_set_parity(unsigned char* Key, unsigned long KeyLenght);
void mbedtls_des_setkey_enc(mbedtls_des_context* ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
void mbedtls_des_crypt_ecb(mbedtls_des_context* ctx, const unsigned char input[8], unsigned char output[8], unsigned long encrypt);
int mbedtls_des_crypt_cbc(mbedtls_des_context* ctx, unsigned long mode, unsigned long length, unsigned char iv[8], const unsigned char* input, unsigned char* output);
void mbedtls_des3_set3key_enc(mbedtls_des3_context* ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]);
void mbedtls_des3_crypt_ecb(mbedtls_des3_context* ctx, const unsigned char input[8], unsigned char output[8], unsigned long encrypt);
int mbedtls_des3_crypt_cbc(mbedtls_des3_context* ctx, unsigned long mode, unsigned long length, unsigned char iv[8], const unsigned char *input, unsigned char *output);
#endif EMUDES_H
// ******************************************************************
#ifndef EMUDES_H
#define EMUDES_H
#define MBEDTLS_DES_KEY_SIZE 8
#define MBEDTLS_DES_ENCRYPT 1
#define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
/**
* \brief DES context structure
*/
typedef struct
{
uint32_t sk[32]; /*!< DES subkeys */
}
mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_context;
void mbedtls_des_key_set_parity(unsigned char* Key, unsigned long KeyLenght);
void mbedtls_des_setkey_enc(mbedtls_des_context* ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
void mbedtls_des_crypt_ecb(mbedtls_des_context* ctx, const unsigned char input[8], unsigned char output[8], unsigned long encrypt);
int mbedtls_des_crypt_cbc(mbedtls_des_context* ctx, unsigned long mode, unsigned long length, unsigned char iv[8], const unsigned char* input, unsigned char* output);
void mbedtls_des3_set3key_enc(mbedtls_des3_context* ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]);
void mbedtls_des3_crypt_ecb(mbedtls_des3_context* ctx, const unsigned char input[8], unsigned char output[8], unsigned long encrypt);
int mbedtls_des3_crypt_cbc(mbedtls_des3_context* ctx, unsigned long mode, unsigned long length, unsigned char iv[8], const unsigned char *input, unsigned char *output);
#endif EMUDES_H

View File

@ -1,161 +1,161 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018 ergo720
// * (c) 2019 Jannik Vogel
// *
// * All rights reserved
// *
// ******************************************************************
// Acknowledgment:
// verify_hash, RSApkcs1paddingtable and RSA_PUBLIC_KEY are from the
// file xboxlib.c of the xbedump tool (and that file only, GPLv2).
// https://github.com/XboxDev/xbedump/blob/master/xboxlib.c
// mbedtls_swap_endianness is extracted from mbedtls_mpi_read_binary used in the file bignum.h of ReactOS
// https://github.com/reactos/reactos
// xboxlib.c license
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#define LOG_PREFIX CXBXR_MODULE::RSA
#include "EmuRsa.h"
#include "core\kernel\support\Emu.h" // For EmuLog
#include "tomcrypt.h"
#include "tommath.h"
#define CHK_MP_RET(x) do { int ret = (x); if (ret != MP_OKAY) return false; } while(0)
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018 ergo720
// * (c) 2019 Jannik Vogel
// *
// * All rights reserved
// *
// ******************************************************************
// Acknowledgment:
// verify_hash, RSApkcs1paddingtable and RSA_PUBLIC_KEY are from the
// file xboxlib.c of the xbedump tool (and that file only, GPLv2).
// https://github.com/XboxDev/xbedump/blob/master/xboxlib.c
// mbedtls_swap_endianness is extracted from mbedtls_mpi_read_binary used in the file bignum.h of ReactOS
// https://github.com/reactos/reactos
// xboxlib.c license
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: GPL-2.0
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#define LOG_PREFIX CXBXR_MODULE::RSA
#include "EmuRsa.h"
#include "core\kernel\support\Emu.h" // For EmuLog
#include "tomcrypt.h"
#include "tommath.h"
#define CHK_MP_RET(x) do { int ret = (x); if (ret != MP_OKAY) return false; } while(0)
const unsigned char RSApkcs1paddingtable[3][16] = {
{ 0x0F, 0x14,0x04,0x00,0x05,0x1A,0x02,0x03,0x0E,0x2B,0x05,0x06,0x09,0x30,0x21,0x30 },
{ 0x0D, 0x14,0x04,0x1A,0x02,0x03,0x0E,0x2B,0x05,0x06,0x07,0x30,0x1F,0x30,0x00,0x00 },
{ 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
};
// Move this to CxbxUtil.h if it's ever needed in other places of the emu as well
void mbedtls_swap_endianness(const unsigned char* in_buf, unsigned char* out_buf, size_t size)
{
size_t i, j, n;
uint32_t* out_buf_uint = (uint32_t*)out_buf;
memset(out_buf_uint, 0, size);
for (n = 0; n < size; n++)
if (in_buf[n] != 0)
break;
for (i = size, j = 0; i > n; i--, j++) {
out_buf_uint[j / 4] |= ((uint32_t)in_buf[i - 1]) << ((j % 4) << 3);
}
}
void init_tom_lib()
{
// NOTE: init_LTM has been deprecated in favor to crypt_mp_init("L"). However, in the latest master branch crypt_mp_init
// is still undefined.
static bool need_init = true;
if (need_init) {
init_LTM();
need_init = false;
}
}
bool xbox_exp_mod(unsigned char* pA, const unsigned char* pB, const unsigned char* pC, const unsigned char* pD,
size_t a_size, size_t b_size, size_t c_size, size_t d_size)
{
mp_int a, b, c, d;
CHK_MP_RET(mp_init(&a));
CHK_MP_RET(mp_init(&b));
CHK_MP_RET(mp_init(&c));
CHK_MP_RET(mp_init(&d));
CHK_MP_RET(mp_import(&b, 1, -1, b_size, 0, 0, pB));
CHK_MP_RET(mp_import(&c, 1, -1, c_size, 0, 0, pC));
CHK_MP_RET(mp_import(&d, 1, -1, d_size, 0, 0, pD));
CHK_MP_RET(mp_exptmod(&b, &c, &d, &a));
CHK_MP_RET(mp_export(pA, NULL, -1, a_size, 0, 0, &a));
return true;
}
bool xbox_rsa_public(const unsigned char* in_buf, unsigned char* out_buf, RSA_PUBLIC_KEY key)
{
rsa_key tom_key;
unsigned char in_buf_be[256] = { 0 };
unsigned char out_buf_be[256] = { 0 };
unsigned long out_len = 256;
unsigned char modulus_be[256] = { 0 };
unsigned char exp_be[4] = { 0 };
// We must swap the data since libtom expects the data to be in big endian
mbedtls_swap_endianness (key.KeyData.Modulus, modulus_be, 256);
mbedtls_swap_endianness (key.KeyData.Exponent, exp_be, 4);
mbedtls_swap_endianness (in_buf, in_buf_be, 256);
if (rsa_set_key(modulus_be, 256, exp_be, 4, NULL, 0, &tom_key) != CRYPT_OK) {
EmuLog(LOG_LEVEL::WARNING, "Failed to load rsa key");
return false;
}
if (rsa_exptmod(in_buf_be, 256, out_buf_be, &out_len, PK_PUBLIC, &tom_key) != CRYPT_OK) {
EmuLog(LOG_LEVEL::WARNING, "rsa_exptmod failed");
return false;
}
mbedtls_swap_endianness(out_buf_be, out_buf, 256);
return true;
}
bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer, RSA_PUBLIC_KEY key)
{
};
// Move this to CxbxUtil.h if it's ever needed in other places of the emu as well
void mbedtls_swap_endianness(const unsigned char* in_buf, unsigned char* out_buf, size_t size)
{
size_t i, j, n;
uint32_t* out_buf_uint = (uint32_t*)out_buf;
memset(out_buf_uint, 0, size);
for (n = 0; n < size; n++)
if (in_buf[n] != 0)
break;
for (i = size, j = 0; i > n; i--, j++) {
out_buf_uint[j / 4] |= ((uint32_t)in_buf[i - 1]) << ((j % 4) << 3);
}
}
void init_tom_lib()
{
// NOTE: init_LTM has been deprecated in favor to crypt_mp_init("L"). However, in the latest master branch crypt_mp_init
// is still undefined.
static bool need_init = true;
if (need_init) {
init_LTM();
need_init = false;
}
}
bool xbox_exp_mod(unsigned char* pA, const unsigned char* pB, const unsigned char* pC, const unsigned char* pD,
size_t a_size, size_t b_size, size_t c_size, size_t d_size)
{
mp_int a, b, c, d;
CHK_MP_RET(mp_init(&a));
CHK_MP_RET(mp_init(&b));
CHK_MP_RET(mp_init(&c));
CHK_MP_RET(mp_init(&d));
CHK_MP_RET(mp_import(&b, 1, -1, b_size, 0, 0, pB));
CHK_MP_RET(mp_import(&c, 1, -1, c_size, 0, 0, pC));
CHK_MP_RET(mp_import(&d, 1, -1, d_size, 0, 0, pD));
CHK_MP_RET(mp_exptmod(&b, &c, &d, &a));
CHK_MP_RET(mp_export(pA, NULL, -1, a_size, 0, 0, &a));
return true;
}
bool xbox_rsa_public(const unsigned char* in_buf, unsigned char* out_buf, RSA_PUBLIC_KEY key)
{
rsa_key tom_key;
unsigned char in_buf_be[256] = { 0 };
unsigned char out_buf_be[256] = { 0 };
unsigned long out_len = 256;
unsigned char modulus_be[256] = { 0 };
unsigned char exp_be[4] = { 0 };
// We must swap the data since libtom expects the data to be in big endian
mbedtls_swap_endianness (key.KeyData.Modulus, modulus_be, 256);
mbedtls_swap_endianness (key.KeyData.Exponent, exp_be, 4);
mbedtls_swap_endianness (in_buf, in_buf_be, 256);
if (rsa_set_key(modulus_be, 256, exp_be, 4, NULL, 0, &tom_key) != CRYPT_OK) {
EmuLog(LOG_LEVEL::WARNING, "Failed to load rsa key");
return false;
}
if (rsa_exptmod(in_buf_be, 256, out_buf_be, &out_len, PK_PUBLIC, &tom_key) != CRYPT_OK) {
EmuLog(LOG_LEVEL::WARNING, "rsa_exptmod failed");
return false;
}
mbedtls_swap_endianness(out_buf_be, out_buf, 256);
return true;
}
bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer, RSA_PUBLIC_KEY key)
{
unsigned char cmphash[20];
int a;
int zero_position = 20;
@ -192,5 +192,5 @@ bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer,
if (decryptBuffer[i] != 0xff) return false;
}
return true;
}
return true;
}

View File

@ -1,55 +1,55 @@
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018-2019 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMURSA_H
#define EMURSA_H
#include <cstdlib> // For size_t
#pragma pack(4)
typedef union _RSA_PUBLIC_KEY
{
unsigned char Default[284];
struct {
char Magic[4]; // "RSA1"
unsigned int Bloblen; // 264 (Modulus + Exponent + Modulussize)
unsigned char Bitlen[4]; // 2048
unsigned int ModulusSize; // 255 (bytes in the Modulus)
unsigned char Exponent[4]; // Public exponent
unsigned char Modulus[256]; // Bit endian style
unsigned char Unknown[8]; // ?
}KeyData;
} RSA_PUBLIC_KEY;
#pragma pack()
void init_tom_lib();
bool xbox_exp_mod(unsigned char* pA, const unsigned char* pB, const unsigned char* pC, const unsigned char* pD,
size_t a_size, size_t b_size, size_t c_size, size_t d_size);
bool xbox_rsa_public(const unsigned char* in_buf, unsigned char* out_buf, RSA_PUBLIC_KEY key);
bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer, RSA_PUBLIC_KEY key);
#endif
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2018-2019 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMURSA_H
#define EMURSA_H
#include <cstdlib> // For size_t
#pragma pack(4)
typedef union _RSA_PUBLIC_KEY
{
unsigned char Default[284];
struct {
char Magic[4]; // "RSA1"
unsigned int Bloblen; // 264 (Modulus + Exponent + Modulussize)
unsigned char Bitlen[4]; // 2048
unsigned int ModulusSize; // 255 (bytes in the Modulus)
unsigned char Exponent[4]; // Public exponent
unsigned char Modulus[256]; // Bit endian style
unsigned char Unknown[8]; // ?
}KeyData;
} RSA_PUBLIC_KEY;
#pragma pack()
void init_tom_lib();
bool xbox_exp_mod(unsigned char* pA, const unsigned char* pB, const unsigned char* pC, const unsigned char* pD,
size_t a_size, size_t b_size, size_t c_size, size_t d_size);
bool xbox_rsa_public(const unsigned char* in_buf, unsigned char* out_buf, RSA_PUBLIC_KEY key);
bool verify_hash(const unsigned char* hash, const unsigned char* decryptBuffer, RSA_PUBLIC_KEY key);
#endif

View File

@ -43,7 +43,7 @@ A million repetitions of "a"
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
/* #define SHA1HANDSOFF * Copies data before messing with it. */
// Acknowledgment: Steve Reid
// Acknowledgment: Steve Reid
// https://github.com/clibs/sha1
#define SHA1HANDSOFF

169
src/common/cxbxr.cpp Normal file
View File

@ -0,0 +1,169 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx-Reloaded project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::FILE
#ifdef CXBXR_EMU
#include "core/kernel/support/EmuFile.h" // For g_io_mu_metadata
#include "common/Timer.h" // For Timer_Shutdown
#include "core/common/video/RenderBase.hpp" // For g_renderbase
#include "core/kernel/memory-manager/VMManager.h"
extern void CxbxrKrnlSuspendThreads();
#endif
#include "cxbxr.hpp"
#include "EmuShared.h"
#include "Settings.hpp"
#include "Logging.h"
#include "win32/WineEnv.h"
#include "Settings.hpp"
volatile bool g_bPrintfOn = true;
bool CreateSettings()
{
g_Settings = new Settings();
if (g_Settings == nullptr) {
PopupError(nullptr, szSettings_alloc_error);
return false;
}
if (!g_Settings->Init()) {
return false;
}
log_get_settings();
return true;
}
bool HandleFirstLaunch()
{
bool bFirstLaunch;
g_EmuShared->GetIsFirstLaunch(&bFirstLaunch);
/* check if process is launch with elevated access then prompt for continue on or not. */
if (!bFirstLaunch) {
if (!CreateSettings()) {
return false;
}
// Wine will always run programs as administrator by default, it can be safely disregard.
// Since Wine doesn't use root permission. Unless user is running Wine as root.
bool bElevated = CxbxrIsElevated();
if (bElevated && !isWineEnv() && !g_Settings->m_core.allowAdminPrivilege) {
PopupReturn ret = PopupWarningEx(nullptr, PopupButtons::YesNo, PopupReturn::No,
"Cxbx-Reloaded has detected that it has been launched with Administrator rights.\n"
"\nThis is dangerous, as a maliciously modified Xbox titles could take control of your system.\n"
"\nAre you sure you want to continue?");
if (ret != PopupReturn::Yes) {
return false;
}
}
g_EmuShared->SetIsFirstLaunch(true);
}
return true;
}
[[noreturn]] void CxbxrShutDown(bool is_reboot)
{
if (!is_reboot) {
// Clear all kernel boot flags. These (together with the shared memory) persist until Cxbx-Reloaded is closed otherwise.
int BootFlags = 0;
g_EmuShared->SetBootFlags(&BootFlags);
}
// NOTE: This causes a hang when exiting while NV2A is processing
// This is okay for now: It won't leak memory or resources since TerminateProcess will free everything
// delete g_NV2A; // TODO : g_pXbox
// Shutdown the input device manager
g_InputDeviceManager.Shutdown();
#ifdef CXBXR_EMU
// NOTE: this code causes freezes/crashes at shutdown, so avoid for now
// This is very important process to prevent false positive report and allow IDEs to continue debug multiple reboots.
//CxbxrKrnlSuspendThreads();
if (g_io_mu_metadata) {
delete g_io_mu_metadata;
g_io_mu_metadata = nullptr;
}
// Shutdown the render manager
if (g_renderbase != nullptr) {
g_renderbase->Shutdown();
g_renderbase = nullptr;
}
// NOTE: Require to be after g_renderbase's shutdown process.
// NOTE: Must be last step of shutdown process and before CxbxUnlockFilePath call!
// Shutdown the memory manager
g_VMManager.Shutdown();
CxbxrUnlockFilePath();
if (CxbxKrnl_hEmuParent != NULL && !is_reboot) {
SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, WM_DESTROY, 0);
}
#endif
EmuShared::Cleanup();
TerminateProcess(GetCurrentProcess(), 0);
}
[[noreturn]] void CxbxrAbortEx(CXBXR_MODULE cxbxr_module, const char* szErrorMessage, ...)
{
// print out error message (if exists)
if (szErrorMessage != NULL)
{
char szBuffer2[1024];
va_list argp;
va_start(argp, szErrorMessage);
vsprintf(szBuffer2, szErrorMessage, argp);
va_end(argp);
(void)PopupCustomEx(nullptr, cxbxr_module, LOG_LEVEL::FATAL, PopupIcon::Error, PopupButtons::Ok, PopupReturn::Ok, "Received Fatal Message:\n\n* %s\n", szBuffer2); // Will also EmuLogEx
}
EmuLogInit(LOG_LEVEL::INFO, "MAIN: Terminating Process");
fflush(stdout);
// cleanup debug output
{
FreeConsole();
char buffer[16];
if (GetConsoleTitle(buffer, 16) != NULL)
freopen("nul", "w", stdout);
}
CxbxrShutDown();
}

58
src/common/cxbxr.hpp Normal file
View File

@ -0,0 +1,58 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx-Reloaded project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
#include <string>
#include <optional>
#include "Logging.h"
bool CreateSettings();
bool HandleFirstLaunch();
// TODO: Eventually, we should remove this function to start using std::filesystem::path method for all host paths.
void CxbxResolveHostToFullPath(std::string& file_path, std::string_view finish_error_sentence);
// Loads a keys.bin file as generated by dump-xbox
// See https://github.com/JayFoxRox/xqemu-tools/blob/master/dump-xbox.c
void LoadXboxKeys();
bool CxbxrLockFilePath();
void CxbxrUnlockFilePath();
// Hybrid functions depending on specific platforms
bool CxbxrIsElevated();
std::optional<std::string> CxbxrExec(bool useDebugger, void** hProcess, bool requestHandleProcess);
/*! cleanup emulation */
[[noreturn]] void CxbxrAbortEx(CXBXR_MODULE cxbxr_module, const char* szErrorMessage, ...);
#define CxbxrAbort(fmt, ...) CxbxrAbortEx(LOG_PREFIX, fmt, ##__VA_ARGS__)
/*! terminate gracefully the emulation */
[[noreturn]] void CxbxrShutDown(bool is_reboot = false);

View File

@ -27,8 +27,8 @@
#include "Button.h"
#include "InputWindow.h"
#include "layout_xbox_controller.h" // TODO: Needs a better fix for custom input device support.
#include "..\..\gui\ResCxbx.h"
#include "layout_xbox_device.h" // TODO: Needs a better fix for custom input device support.
#include "gui/resource/ResCxbx.h"
void Button::EnableButton(bool enable) const
@ -51,27 +51,41 @@ void Button::GetText(char* const text, size_t size) const
SendMessage(m_button_hwnd, WM_GETTEXT, size, reinterpret_cast<LPARAM>(text));
}
std::string Button::GetName(int api, int idx) const
void Button::AddTooltip(HWND hwnd, HWND tooltip_hwnd, std::string_view text) const
{
assert(api == XINPUT_DEFAULT || api == DINPUT_DEFAULT);
return button_xbox_ctrl_names[idx][api];
assert((hwnd != NULL) && (tooltip_hwnd != NULL));
std::string tooltip_text(text);
TOOLINFO tool = { 0 };
tool.cbSize = sizeof(tool);
tool.hwnd = hwnd;
tool.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
tool.uId = reinterpret_cast<UINT_PTR>(m_button_hwnd);
tool.lpszText = tooltip_text.data();
SendMessage(tooltip_hwnd, TTM_ADDTOOL, 0, reinterpret_cast<LPARAM>(&tool));
}
LRESULT CALLBACK ButtonSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
LRESULT CALLBACK ButtonDukeSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
// Remove the window subclass when this window is destroyed
case WM_NCDESTROY: {
RemoveWindowSubclass(hWnd, ButtonSubclassProc, uIdSubclass);
RemoveWindowSubclass(hWnd, ButtonDukeSubclassProc, uIdSubclass);
}
break;
case WM_RBUTTONDOWN: {
reinterpret_cast<Button*>(dwRefData)->ClearText();
g_InputWindow->UpdateProfile(std::string(), BUTTON_CLEAR);
if (reinterpret_cast<Button*>(dwRefData)->GetId() == IDC_SET_MOTOR) {
g_InputWindow->UpdateProfile(std::string(), RUMBLE_CLEAR);
Button *button = reinterpret_cast<Button *>(dwRefData);
if (wParam & MK_SHIFT) {
static_cast<DukeInputWindow *>(button->GetWnd())->SwapMoCursorAxis(button);
}
else if (!(wParam & ~MK_RBUTTON)) {
button->ClearText();
static_cast<DukeInputWindow *>(button->GetWnd())->UpdateProfile(std::string(), BUTTON_CLEAR);
if (button->GetId() == IDC_SET_MOTOR) {
static_cast<DukeInputWindow *>(button->GetWnd())->UpdateProfile(std::string(), RUMBLE_CLEAR);
}
}
}
break;
@ -80,3 +94,47 @@ LRESULT CALLBACK ButtonSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK ButtonSbcSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
// Remove the window subclass when this window is destroyed
case WM_NCDESTROY: {
RemoveWindowSubclass(hWnd, ButtonSbcSubclassProc, uIdSubclass);
}
break;
case WM_RBUTTONDOWN: {
Button *button = reinterpret_cast<Button *>(dwRefData);
button->ClearText();
static_cast<SbcInputWindow *>(button->GetWnd())->UpdateProfile(std::string(), BUTTON_CLEAR);
}
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK ButtonLightgunSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
// Remove the window subclass when this window is destroyed
case WM_NCDESTROY: {
RemoveWindowSubclass(hWnd, ButtonLightgunSubclassProc, uIdSubclass);
}
break;
case WM_RBUTTONDOWN: {
Button *button = reinterpret_cast<Button *>(dwRefData);
button->ClearText();
static_cast<LightgunInputWindow *>(button->GetWnd())->UpdateProfile(std::string(), BUTTON_CLEAR);
}
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

View File

@ -31,27 +31,36 @@
#include <Commctrl.h>
#include <string>
#define LIGHTGUN_NUM_BUTTONS 17
#define XBOX_CTRL_NUM_BUTTONS 25
#define SBC_NUM_BUTTONS 56
#define HIGHEST_NUM_BUTTONS SBC_NUM_BUTTONS
#define XBOX_BUTTON_NAME_LENGTH 30
#define HOST_BUTTON_NAME_LENGTH 30
/* Represents the gui buttons of the xbox device currently being configured */
class Button
{
public:
Button(int id, int index, HWND hwnd) : m_id(id), m_index(index), m_button_hwnd(GetDlgItem(hwnd, m_id)) {};
Button(int id, int index, HWND hwnd, void *wnd) : m_id(id), m_index(index), m_button_hwnd(GetDlgItem(hwnd, m_id)), m_wnd(wnd) {};
void EnableButton(bool enable) const;
void UpdateText(const char* text) const;
void ClearText() const;
void GetText(char* const text, size_t size) const;
std::string GetName(int api, int idx) const;
int GetId() const { return m_id; }
int GetIndex() const { return m_index; }
void *GetWnd() const { return m_wnd; }
void AddTooltip(HWND hwnd, HWND tooltip_hwnd, std::string_view text) const;
private:
int m_id;
int m_index;
HWND m_button_hwnd;
void *m_wnd;
};
LRESULT CALLBACK ButtonSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK ButtonDukeSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK ButtonSbcSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK ButtonLightgunSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);

View File

@ -37,6 +37,7 @@
#include "DInputKeyboardMouse.h"
#include "InputManager.h"
#include "core\kernel\support\Emu.h"
#include <algorithm>
// Unfortunately, sdl doesn't seem to be able to capture keyboard/mouse input from windows it didn't create (we currently use
// win32 for that). So unless we create sdl windows, we will have to keep dinput around to handle keyboard/mouse input.
@ -51,8 +52,6 @@ namespace DInput
#include "DInputKeyboardCodes.h"
};
bool bKbMoEnumerated = false;
void InitKeyboardMouse(IDirectInput8* idi8)
{
// From Dolphin: "mouse and keyboard are a combined device, to allow shift+click and stuff
@ -60,26 +59,27 @@ namespace DInput
// other devices so there can be a separated Keyboard and mouse, as well as combined KeyboardMouse"
LPDIRECTINPUTDEVICE8 kb_device = nullptr;
//LPDIRECTINPUTDEVICE8 mo_device = nullptr;
LPDIRECTINPUTDEVICE8 mo_device = nullptr;
if (SUCCEEDED(idi8->CreateDevice(GUID_SysKeyboard, &kb_device, nullptr)) &&
SUCCEEDED(kb_device->SetDataFormat(&c_dfDIKeyboard)) &&
SUCCEEDED(kb_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) //&&
//SUCCEEDED(idi8->CreateDevice(GUID_SysMouse, &mo_device, nullptr)) &&
//SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2)) &&
//SUCCEEDED(mo_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
SUCCEEDED(kb_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)) &&
SUCCEEDED(idi8->CreateDevice(GUID_SysMouse, &mo_device, nullptr)) &&
SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2)) &&
SUCCEEDED(mo_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
{
g_InputDeviceManager.AddDevice(std::make_shared<KeyboardMouse>(kb_device));
g_InputDeviceManager.AddDevice(std::make_shared<KeyboardMouse>(kb_device, mo_device));
bKbMoEnumerated = true;
return;
}
if (kb_device)
if (kb_device) {
kb_device->Release();
#if 0
if (mo_device)
}
if (mo_device) {
mo_device->Release();
#endif
}
}
void PopulateDevices()
@ -104,36 +104,46 @@ namespace DInput
PopulateDevices();
}
KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device)
: m_kb_device(kb_device)//, m_mo_device(mo_device)
KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRECTINPUTDEVICE8 mo_device)
: m_kb_device(kb_device), m_mo_device(mo_device)
{
m_kb_device->Acquire();
//m_mo_device->Acquire();
m_mo_device->Acquire();
memset(&m_state_in, 0, sizeof(m_state_in));
std::memset(&m_state_in, 0, sizeof(m_state_in));
// KEYBOARD
// add keys
for (uint8_t i = 0; i < sizeof(named_keys) / sizeof(*named_keys); ++i) {
AddInput(new Key(i, m_state_in.keyboard[named_keys[i].code]));
}
#if 0
// MOUSE
// get caps
DIDEVCAPS mouse_caps;
memset(&mouse_caps, 0, sizeof(mouse_caps));
std::memset(&mouse_caps, 0, sizeof(mouse_caps));
mouse_caps.dwSize = sizeof(mouse_caps);
m_mo_device->GetCapabilities(&mouse_caps);
// mouse buttons
for (unsigned char i = 0; i < mouse_caps.dwButtons; ++i) {
AddInput(new Button(i, m_state_in.mouse.rgbButtons[i]));
}
// cursor, with a hax for-loop
for (unsigned int i = 0; i < 4; ++i) {
AddInput(new Cursor(!!(i & 2), (&m_state_in.cursor.x)[i / 2], !!(i & 1)));
// mouse axes
for (unsigned int i = 0; i < mouse_caps.dwAxes; ++i) {
const LONG &ax = (&m_state_in.mouse.lX)[i];
// each axis gets a negative and a positive input instance associated with it
AddInput(new Axis(i, ax, (2 == i) ? mo_wheel_range_neg : mo_axis_range_neg));
AddInput(new Axis(i, ax, (2 == i) ? mo_wheel_range_pos : mo_axis_range_pos));
}
#endif
// mouse cursor
AddInput(new Cursor(0, m_state_in.cursor.x, -1.0));
AddInput(new Cursor(0, m_state_in.cursor.x, 1.0));
AddInput(new Cursor(1, m_state_in.cursor.y, -1.0));
AddInput(new Cursor(1, m_state_in.cursor.y, 1.0));
}
KeyboardMouse::~KeyboardMouse()
@ -141,85 +151,66 @@ namespace DInput
// kb
m_kb_device->Unacquire();
m_kb_device->Release();
#if 0
// mouse
m_mo_device->Unacquire();
m_mo_device->Release();
#endif
}
void GetMousePos(ControlState* const x, ControlState* const y)
{
POINT point = { 1, 1 };
GetCursorPos(&point);
// Get the cursor position relative to the upper left corner of the current window
HWND hwnd = WindowFromPoint(point);
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == GetCurrentProcessId())
{
ScreenToClient(hwnd, &point);
// Get the size of the current window.
RECT rect;
GetClientRect(hwnd, &rect);
// Width and height is the size of the rendering window
unsigned int win_width = rect.right - rect.left;
unsigned int win_height = rect.bottom - rect.top;
// Return the mouse position as a range from -1 to 1
*x = (ControlState)point.x / (ControlState)win_width * 2 - 1;
*y = (ControlState)point.y / (ControlState)win_height * 2 - 1;
}
else
{
*x = (ControlState)0;
*y = (ControlState)0;
}
}
bool KeyboardMouse::UpdateInput()
{
// Update keyboard and mouse button states
if (static_cast<uint8_t>(mo_leave_wnd) & static_cast<uint8_t>(IgnoreKbMoUnfocus)) {
std::memset(&m_state_in, 0, sizeof(m_state_in));
return true;
}
DIMOUSESTATE2 tmp_mouse;
HRESULT kb_hr = m_kb_device->GetDeviceState(sizeof(m_state_in.keyboard), &m_state_in.keyboard);
//HRESULT mo_hr = m_mo_device->GetDeviceState(sizeof(m_state_in.mouse), &m_state_in.mouse);
HRESULT mo_hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse);
if (DIERR_INPUTLOST == kb_hr || DIERR_NOTACQUIRED == kb_hr) {
m_kb_device->Acquire();
}
#if 0
if (DIERR_INPUTLOST == mo_hr || DIERR_NOTACQUIRED == mo_hr) {
m_mo_device->Acquire();
}
#endif
if (SUCCEEDED(kb_hr)) //&& SUCCEEDED(mo_hr))
if (SUCCEEDED(kb_hr) && SUCCEEDED(mo_hr))
{
#if 0
ControlState temp_x, temp_y;
// NOTE: the /= 2 will cause the mouse input to naturally decay to zero if the mouse did not change its position
for (unsigned int i = 0; i < 3; ++i) {
((&m_state_in.mouse.lX)[i] += (&tmp_mouse.lX)[i]) /= 2;
}
// Update absolute mouse position
GetMousePos(&m_state_in.cursor.x, &m_state_in.cursor.y);
std::memcpy(m_state_in.mouse.rgbButtons, tmp_mouse.rgbButtons, sizeof(m_state_in.mouse.rgbButtons));
UpdateCursorPosition();
// Save current absolute mouse position
temp_x = m_state_in.cursor.x;
temp_y = m_state_in.cursor.y;
// Update relative mouse motion
m_state_in.cursor.x -= m_state_in.cursor.last_x;
m_state_in.cursor.y -= m_state_in.cursor.last_y;
// Update previous absolute mouse position
m_state_in.cursor.last_x = temp_x;
m_state_in.cursor.last_y = temp_y;
#endif
return true;
}
return false;
}
void KeyboardMouse::UpdateCursorPosition()
{
POINT point = {};
GetCursorPos(&point);
ScreenToClient(m_hwnd, &point);
RECT rect;
GetClientRect(m_hwnd, &rect);
const auto width = std::max(rect.right - rect.left, 1l);
const auto height = std::max(rect.bottom - rect.top, 1l);
// Convert the window client coordinates to normalized device coordinates
m_state_in.cursor.x = ((2 * static_cast<ControlState>(point.x)) / width) - 1;
m_state_in.cursor.y = ((-2 * static_cast<ControlState>(point.y)) / height) + 1;
}
std::string KeyboardMouse::GetDeviceName() const
{
return "Keyboard";
return "KeyboardMouse";
}
std::string KeyboardMouse::GetAPI() const
@ -237,11 +228,19 @@ namespace DInput
return std::string("Click ") + char('0' + m_index);
}
std::string KeyboardMouse::Axis::GetName() const
{
static char tmpstr[] = "Axis ..";
tmpstr[5] = (char)('X' + m_index);
tmpstr[6] = (m_range < 0 ? '-' : '+');
return tmpstr;
}
std::string KeyboardMouse::Cursor::GetName() const
{
static char tmpstr[] = "Cursor ..";
tmpstr[7] = (char)('X' + m_index);
tmpstr[8] = (m_positive ? '+' : '-');
tmpstr[8] = (m_range == 1.0 ? '+' : '-');
return tmpstr;
}
@ -255,8 +254,13 @@ namespace DInput
return (m_button != 0);
}
ControlState KeyboardMouse::Axis::GetState() const
{
return std::clamp(ControlState(m_axis) / m_range, 0.0, 1.0);
}
ControlState KeyboardMouse::Cursor::GetState() const
{
return std::max(0.0, ControlState(m_axis) / (m_positive ? 1.0 : -1.0));
return std::max(0.0, m_cursor / m_range);
}
}

View File

@ -34,18 +34,25 @@
namespace DInput
{
extern bool bKbMoEnumerated;
inline bool bKbMoEnumerated = false;
inline bool mo_leave_wnd = false;
inline bool IgnoreKbMoUnfocus = true;
inline LONG mo_axis_range_pos = 0;
inline LONG mo_axis_range_neg = 0;
inline LONG mo_wheel_range_pos = 0;
inline LONG mo_wheel_range_neg = 0;
void GetDeviceChanges();
void PopulateDevices();
class KeyboardMouse : public InputDevice
{
public:
KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device);
KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRECTINPUTDEVICE8 mo_device);
~KeyboardMouse();
std::string GetDeviceName() const override;
std::string GetAPI() const override;
bool UpdateInput() override;
void SetHwnd(HWND hwnd) { m_hwnd = hwnd; }
private:
@ -73,19 +80,34 @@ namespace DInput
const uint8_t m_index;
};
class Cursor : public Input
// gives mouse input based on relative motion
class Axis : public Input
{
public:
Cursor(uint8_t index, const ControlState& axis, const bool positive)
: m_axis(axis), m_index(index), m_positive(positive) {}
Axis(uint8_t index, const LONG &axis, const LONG &range) : m_axis(axis), m_range(range), m_index(index) {}
std::string GetName() const override;
bool IsDetectable() override { return true; }
ControlState GetState() const override;
private:
const ControlState& m_axis;
const LONG &m_axis;
const LONG &m_range;
const uint8_t m_index;
};
// gives mouse input based on cursor position relative to the rendering window
class Cursor : public Input
{
public:
Cursor(uint8_t index, const ControlState &cursor, const ControlState range)
: m_cursor(cursor), m_index(index), m_range(range) {}
std::string GetName() const override;
ControlState GetState() const override;
bool IsDetectable() const override { return false; }
private:
const ControlState &m_cursor;
const ControlState m_range;
const uint8_t m_index;
const bool m_positive;
};
struct State
@ -94,12 +116,15 @@ namespace DInput
DIMOUSESTATE2 mouse;
struct
{
ControlState x, y, last_x, last_y;
ControlState x, y;
} cursor;
};
void UpdateCursorPosition();
const LPDIRECTINPUTDEVICE8 m_kb_device;
//const LPDIRECTINPUTDEVICE8 m_mo_device;
const LPDIRECTINPUTDEVICE8 m_mo_device;
State m_state_in;
HWND m_hwnd;
};
}

View File

@ -25,35 +25,64 @@
// *
// ******************************************************************
#include"Button.h"
#include <algorithm>
#include "Button.h"
#include "InputManager.h"
#include "layout_xbox_controller.h"
#include "..\..\gui\ResCxbx.h"
#include "layout_xbox_device.h"
#include "gui/resource/ResCxbx.h"
EmuDevice::EmuDevice(int type, HWND hwnd)
static const char *tooltip_text_toggle = "Left-click: start input detection\nRight-click: clear binding\nShift + right-click: toggle mouse input mode";
static const char *tooltip_text_no_toggle = "Left-click: start input detection\nRight-click: clear binding";
EmuDevice::EmuDevice(int type, HWND hwnd, void *wnd)
{
m_hwnd = hwnd;
CreateTooltipWindow();
switch (type)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
m_hwnd = hwnd;
for (int i = 0; i < ARRAY_SIZE(button_xbox_ctrl_id); i++) {
m_buttons.push_back(new Button(button_xbox_ctrl_id[i], i, hwnd));
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S):
case to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK): {
for (size_t i = 0; i < ARRAY_SIZE(button_xbox_ctrl_id); i++) {
m_buttons.push_back(new Button(button_xbox_ctrl_id[i], i, hwnd, wnd));
m_buttons.back()->AddTooltip(m_hwnd, m_tooltip_hwnd, tooltip_text_toggle);
// Install the subclass for the button control
SetWindowSubclass(GetDlgItem(hwnd, button_xbox_ctrl_id[i]), ButtonSubclassProc, 0, reinterpret_cast<DWORD_PTR>(m_buttons[i]));
SetWindowSubclass(GetDlgItem(hwnd, button_xbox_ctrl_id[i]), ButtonDukeSubclassProc, 0, reinterpret_cast<DWORD_PTR>(m_buttons[i]));
}
}
break;
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
for (size_t i = 0; i < ARRAY_SIZE(button_sbc_id); i++) {
m_buttons.push_back(new Button(button_sbc_id[i], i, hwnd, wnd));
m_buttons.back()->AddTooltip(m_hwnd, m_tooltip_hwnd, tooltip_text_no_toggle);
// Install the subclass for the button control
SetWindowSubclass(GetDlgItem(hwnd, button_sbc_id[i]), ButtonSbcSubclassProc, 0, reinterpret_cast<DWORD_PTR>(m_buttons[i]));
}
}
break;
case to_underlying(XBOX_INPUT_DEVICE::LIGHTGUN): {
for (size_t i = 0; i < ARRAY_SIZE(button_lightgun_id); i++) {
m_buttons.push_back(new Button(button_lightgun_id[i], i, hwnd, wnd));
m_buttons.back()->AddTooltip(m_hwnd, m_tooltip_hwnd, tooltip_text_no_toggle);
// Install the subclass for the button control
SetWindowSubclass(GetDlgItem(hwnd, button_lightgun_id[i]), ButtonLightgunSubclassProc, 0, reinterpret_cast<DWORD_PTR>(m_buttons[i]));
}
}
break;
default:
break;
}
}
EmuDevice::~EmuDevice()
{
DestroyWindow(m_tooltip_hwnd);
for (auto button : m_buttons) {
delete button;
}
@ -76,10 +105,11 @@ Button* EmuDevice::FindButtonByIndex(int index)
return m_buttons[index];
}
void EmuDevice::BindDefault(int api)
template<size_t size>
void EmuDevice::BindDefault(const std::array<const char *, size> &arr)
{
std::for_each(m_buttons.begin(), m_buttons.end(), [&api](const auto button) {
button->UpdateText(button->GetName(api, button->GetIndex()).c_str());
std::for_each(m_buttons.begin(), m_buttons.end(), [&arr](const auto button) {
button->UpdateText(arr[button->GetIndex()]);
});
}
@ -89,3 +119,20 @@ void EmuDevice::ClearButtons()
button->ClearText();
});
}
void EmuDevice::CreateTooltipWindow()
{
m_tooltip_hwnd = CreateWindow(TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
m_hwnd, NULL,
GetModuleHandle(NULL), NULL);
SendMessage(m_tooltip_hwnd, TTM_ACTIVATE, TRUE, 0);
SendMessage(m_tooltip_hwnd, TTM_SETMAXTIPWIDTH, 0, 500);
SendMessage(m_tooltip_hwnd, TTM_SETDELAYTIME, TTDT_AUTOPOP, 15000);
}
template void EmuDevice::BindDefault(const std::array<const char*, XBOX_CTRL_NUM_BUTTONS>& arr);
template void EmuDevice::BindDefault(const std::array<const char *, LIGHTGUN_NUM_BUTTONS> &arr);

View File

@ -29,21 +29,29 @@
#include "Button.h"
#include "common\util\CxbxUtil.h"
#include <array>
/* Represents the guest device currently being configured in the gui */
class EmuDevice
{
public:
EmuDevice(int type, HWND hwnd);
EmuDevice(int type, HWND hwnd, void *wnd);
~EmuDevice();
Button* FindButtonById(int id);
Button* FindButtonByIndex(int index);
void BindDefault(int api);
template<size_t size>
void BindDefault(const std::array<const char *, size> &arr);
void ClearButtons();
private:
void CreateTooltipWindow();
std::vector<Button*> m_buttons;
HWND m_hwnd;
HWND m_tooltip_hwnd;
};
extern template void EmuDevice::BindDefault(const std::array<const char *, XBOX_CTRL_NUM_BUTTONS> &arr);
extern template void EmuDevice::BindDefault(const std::array<const char *, LIGHTGUN_NUM_BUTTONS> &arr);

View File

@ -33,8 +33,10 @@
// https://github.com/dolphin-emu/dolphin
#include "InputDevice.h"
#include "InputManager.h"
#include "common\util\CxbxUtil.h"
#include <algorithm>
#include <charconv>
std::string GetInputDeviceName(int dev_type)
@ -43,46 +45,53 @@ std::string GetInputDeviceName(int dev_type)
switch (dev_type)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
str = "MS Gamepad Duke";
}
break;
break;
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S):
str = "MS Gamepad S";
}
break;
break;
case to_underlying(XBOX_INPUT_DEVICE::LIGHT_GUN): {
str = "Light gun";
}
break;
case to_underlying(XBOX_INPUT_DEVICE::LIGHTGUN):
str = "EMS TopGun II";
break;
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL): {
case to_underlying(XBOX_INPUT_DEVICE::STEERING_WHEEL):
str = "Steering wheel";
}
break;
break;
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT): {
case to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT):
str = "Memory unit";
}
break;
break;
case to_underlying(XBOX_INPUT_DEVICE::IR_DONGLE): {
case to_underlying(XBOX_INPUT_DEVICE::IR_DONGLE):
str = "IR dongle";
}
break;
break;
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER): {
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER):
str = "Steel battalion controller";
}
break;
break;
case to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK):
str = "Arcade joystick";
break;
case to_underlying(XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER):
str = "Passthrough steel battalion controller";
break;
case to_underlying(XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER):
str = "Passthrough original xbox gamepad";
break;
case to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID):
case to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX): {
str = "None";
break;
case to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX):
str = "Invalid";
}
break;
break;
default:
str = "Unknown";
@ -91,6 +100,33 @@ std::string GetInputDeviceName(int dev_type)
return str;
}
std::string PortUserFormat(std::string_view port)
{
int port_num, slot;
PortStr2Int(port, &port_num, &slot);
++port_num;
if (slot != PORT_INVALID) {
++slot;
return std::to_string(port_num) + "." + std::to_string(slot);
}
else {
return std::to_string(port_num);
}
}
void PortStr2Int(std::string_view port, int *port_num, int *slot)
{
*slot = PORT_INVALID;
auto ret = std::from_chars(port.data(), port.data() + port.size(), *port_num);
assert(ret.ec != std::errc::invalid_argument);
if (ret.ptr != port.data() + port.size()) {
++ret.ptr;
ret = std::from_chars(ret.ptr, port.data() + port.size(), *slot);
assert(ret.ec != std::errc::invalid_argument);
assert(ret.ptr == port.data() + port.size());
}
}
// Destructor, delete all inputs/outputs on device destruction
InputDevice::~InputDevice()
{
@ -131,3 +167,31 @@ const std::vector<InputDevice::IoControl*> InputDevice::GetIoControls()
});
return vec;
}
const auto InputDevice::FindPort(std::string_view Port) const
{
return std::find_if(m_XboxPort.begin(), m_XboxPort.end(), [Port](std::string_view CurrPort) {
if (CurrPort == Port) {
return true;
}
return false;
});
}
void InputDevice::SetPort2(std::string_view Port, bool Connect)
{
if (Connect) {
m_XboxPort.emplace_back(Port);
}
else {
const auto &it = FindPort(Port);
if (it != m_XboxPort.end()) {
m_XboxPort.erase(it);
}
}
}
bool InputDevice::GetPort(std::string_view Port) const
{
return FindPort(Port) != m_XboxPort.end() ? true : false;
}

View File

@ -36,18 +36,11 @@
#include <condition_variable>
#include "SDL.h"
#define PORT_INVALID -1
#define PORT_1 0
#define PORT_2 1
#define PORT_3 2
#define PORT_4 3
#define PORT_INC(port) ((port) + 1)
#define PORT_DEC(port) ((port) - 1)
#define DIRECTION_IN 0
#define DIRECTION_OUT 1
#define MO_AXIS_DEFAULT_RANGE 10l
#define MO_WHEEL_DEFAULT_RANGE 80l
typedef double ControlState;
@ -56,20 +49,30 @@ typedef enum class _XBOX_INPUT_DEVICE : int {
DEVICE_INVALID = -1,
MS_CONTROLLER_DUKE,
MS_CONTROLLER_S,
LIGHT_GUN,
LIGHTGUN,
STEERING_WHEEL,
MEMORY_UNIT,
IR_DONGLE,
STEEL_BATTALION_CONTROLLER,
ARCADE_STICK,
DEVICE_MAX,
// Devices with the HW_ prefix (= hardware) indicate a real xbox device. Always add these after DEVICE_MAX
HW_STEEL_BATTALION_CONTROLLER,
HW_XBOX_CONTROLLER,
}
XBOX_INPUT_DEVICE;
// Lookup array used to translate a gui port to an xbox usb port and vice versa
extern int Gui2XboxPortArray[4];
// Flags that indicate that WM_MOUSELEAVE and WM_MOUSEMOVE respectively are being tracked in the rendering window procedure
inline bool g_bIsTrackingMoLeave = false;
inline bool g_bIsTrackingMoMove = false;
// Global function used to retrieve the printable name of a xid type
// Retrieves the printable name of a xid type
std::string GetInputDeviceName(int dev_type);
// Converts the port number in the user format
std::string PortUserFormat(std::string_view);
// Extracts port and slot number from a port formatted as a string
void PortStr2Int(std::string_view port, int *port_num, int *slot);
/* Abstract class which represents a host device usable for input/output */
class InputDevice
@ -87,7 +90,7 @@ public:
{
public:
virtual ControlState GetState() const = 0;
virtual bool IsDetectable() { return true; }
virtual bool IsDetectable() const { return true; };
};
class Output : public IoControl
@ -117,9 +120,12 @@ public:
// sets the ID of this device
void SetId(int ID) { m_ID = ID; }
// retrieves the port this device is attached to
bool GetPort(int Port) const { return m_XboxPort[Port]; }
bool GetPort(std::string_view Port) const;
// sets the port this device is attached to
void SetPort(int Port, bool Connect) { m_XboxPort[Port] = Connect; }
// NOTE: using SetPort2 to avoid a collision with the SetPort macro provided by Windows headers
void SetPort2(std::string_view Port, bool Connect);
// retuns true if it is a libusb device, false otherwise
virtual bool IsLibusb() const { return false; };
protected:
@ -127,6 +133,8 @@ protected:
void AddInput(Input* const In);
// adds an output control to the device
void AddOutput(Output* const Out);
// searches for a port
const auto FindPort(std::string_view Port) const;
// indicates that the device has new input data available
bool m_bDirty;
// lock for the bindings map
@ -134,52 +142,32 @@ protected:
public:
// retrieves the map of input bindings
const std::map<int, IoControl*> GetBindings() const {
const std::map<int, IoControl*> GetBindings(const std::string &Port) const {
std::lock_guard<std::mutex> lck(m_BindingsMtx);
return m_Bindings;
return m_Bindings.find(Port)->second;
}
// sets a pair in the map of the input bindings
void SetBindings(int XButton, IoControl* Control) {
void SetBindings(int XButton, IoControl* Control, const std::string &Port) {
std::lock_guard<std::mutex> lck(m_BindingsMtx);
m_Bindings[XButton] = Control;
m_Bindings[Port][XButton] = Control;
}
protected:
class FullAnalogSurface : public Input
{
public:
FullAnalogSurface(Input* Low, Input* High) : m_Low(*Low), m_High(*High) {}
ControlState GetState() const override
{
return (1 + m_High.GetState() - m_Low.GetState()) / 2;
}
std::string GetName() const override { return m_Low.GetName() + *m_High.GetName().rbegin(); }
private:
Input& m_Low;
Input& m_High;
};
void AddAnalogInputs(Input* Low, Input* High)
{
AddInput(Low);
AddInput(High);
AddInput(new FullAnalogSurface(Low, High));
AddInput(new FullAnalogSurface(High, Low));
// clears all input bindings for the specified xbox port
void ClearBindings(const std::string &Port) {
std::lock_guard<std::mutex> lck(m_BindingsMtx);
m_Bindings[Port].clear();
}
private:
// arbitrary ID assigned by to the device
// arbitrary ID assigned to the device
int m_ID;
// all the input controls detected and usable on this device
std::vector<Input*> m_Inputs;
// all the output controls detected and usable on this device
std::vector<Output*> m_Outputs;
// xbox port(s) this device is attached to
bool m_XboxPort[4] = { false };
// button bindings to the xbox device buttons
std::map<int, IoControl*> m_Bindings;
std::vector<std::string> m_XboxPort;
// per xbox port button bindings to the xbox device buttons
std::unordered_map<std::string, std::map<int, IoControl*>> m_Bindings;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -31,17 +31,62 @@
#include <thread>
#include "InputDevice.h"
#include "EmuDevice.h"
#include <imgui.h>
// Prevent a collision with the SetPort provided by Windows
#ifdef WIN32
#undef SetPort
#endif
#define PORT_INVALID -1
#define PORT_1 0
#define PORT_2 1
#define PORT_3 2
#define PORT_4 3
#define XBOX_NUM_PORTS 4
#define SLOT_TOP 0
#define SLOT_BOTTOM 1
#define XBOX_CTRL_NUM_SLOTS 2
#define CTRL_OFFSET 0
#define MU_OFFSET 4
#define MAX_DEVS (XBOX_NUM_PORTS + XBOX_CTRL_NUM_SLOTS * XBOX_NUM_PORTS)
#define XID_PACKET_HEADER 2
#define LIGHTGUN_GRIP_DELAY 30
extern int dev_num_buttons[to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)];
inline XBOX_INPUT_DEVICE input_support_list[] = {
XBOX_INPUT_DEVICE::DEVICE_INVALID,
XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE,
XBOX_INPUT_DEVICE::MS_CONTROLLER_S,
XBOX_INPUT_DEVICE::LIGHTGUN,
XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER,
XBOX_INPUT_DEVICE::ARCADE_STICK,
XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER,
XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER,
};
inline XBOX_INPUT_DEVICE slot_support_list[] = {
XBOX_INPUT_DEVICE::DEVICE_INVALID,
XBOX_INPUT_DEVICE::MEMORY_UNIT,
// Microphone
// Phantasy star online keyboard
};
#pragma pack(1)
// xpad in/out buffers stripped of the first two bytes
// Class-specific xid descriptor, used by libusb
struct XidDesc {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdXid;
uint8_t bType;
uint8_t bSubType;
uint8_t bMaxInputReportSize;
uint8_t bMaxOutputReportSize;
uint16_t wAlternateProductIds[4];
};
// xpad in/out buffers stripped of the first two bytes as used by xinput
struct XpadInput {
uint16_t wButtons;
uint8_t bAnalogButtons[8];
@ -56,16 +101,119 @@ struct XpadOutput {
uint16_t right_actuator_strength;
};
// xpad in/out buffers as used by xid
struct XidGamepadInput {
uint8_t bReportId;
uint8_t bLength;
XpadInput InBuffer;
};
struct XidGamepadOutput {
uint8_t bReportId;
uint8_t bLength;
XpadOutput OutBuffer;
};
// same as above, but for the SBC
struct SBCInput {
uint16_t wButtons[3];
uint8_t bPad1;
uint8_t sAimingX;
uint8_t bPad2;
uint8_t sAimingY;
uint8_t bPad3;
int8_t sRotationLever;
uint8_t bPad4;
int8_t sSightChangeX;
uint8_t bPad5;
int8_t sSightChangeY;
uint8_t bPad6;
uint8_t wLeftPedal;
uint8_t bPad7;
uint8_t wMiddlePedal;
uint8_t bPad8;
uint8_t wRightPedal;
uint8_t ucTunerDial;
uint8_t ucGearLever;
};
struct SBCOutput {
uint8_t LedState[20];
};
struct XidSBCInput {
uint8_t bReportId;
uint8_t bLength;
SBCInput InBuffer;
};
struct XidSBCOutput {
uint8_t bReportId;
uint8_t bLength;
SBCOutput OutBuffer;
};
#pragma pack()
struct LightGunData {
xbox::short_xt offset_x;
xbox::short_xt offset_y;
xbox::short_xt offset_upp_x;
xbox::short_xt offset_upp_y;
uint8_t last_in_state;
uint8_t last_turbo;
uint8_t turbo_delay;
uint8_t turbo;
uint8_t laser;
};
struct SbcData {
uint16_t last_in_state;
};
union InputBuff {
XidGamepadInput ctrl;
XidSBCInput sbc;
};
struct DeviceInfo {
xbox::HANDLE hHandle; // device handle returned by xapi
bool bAutoPoll; // autopoll on/off, as instructed by the title in XInputOpen
bool bAutoPollDefault; // default autopoll value, depending on device type
uint8_t ucType; // xapi type
uint8_t ucSubType; // xapi subtype
uint8_t ucInputStateSize; // input state size in bytes, does not include dwPacketNumber
uint8_t ucFeedbackSize; // feedback size in bytes, does not include FeedbackHeader
uint32_t dwPacketNumber; // increases by one when the input state changes
InputBuff buff; // input buffer
// device-specific additional data
union {
LightGunData ligthgun;
SbcData sbc;
};
};
struct DeviceState {
std::string port;
int port_idx;
XBOX_INPUT_DEVICE type;
bool bPendingRemoval;
bool bSignaled;
DeviceInfo info;
DeviceState *slots[XBOX_CTRL_NUM_SLOTS];
DeviceState *upstream;
};
extern DeviceState g_devs[MAX_DEVS];
class InputDeviceManager
{
public:
void Initialize(bool is_gui);
void Initialize(bool is_gui, HWND hwnd);
void Shutdown();
// read/write the input/output from/to the device attached to the supplied xbox port
bool UpdateXboxPortInput(int usb_port, void* Buffer, int Direction, int xid_type);
bool UpdateXboxPortInput(int port, void *buffer, int direction, int type);
// add the device to the list of availble devices
void AddDevice(std::shared_ptr<InputDevice> Device);
// remove the device from the list of availble devices
@ -73,26 +221,38 @@ public:
// update device list
void RefreshDevices();
// get the name of the devices currently detected
std::vector<std::string> GetDeviceList() const;
std::vector<std::string> GetDeviceList(std::function<bool(const InputDevice *)> Callback) const;
// find device from its gui name
std::shared_ptr<InputDevice> FindDevice(const std::string& QualifiedName) const;
// find device from its sdl id
std::shared_ptr<InputDevice> FindDevice(SDL_JoystickID id) const;
// find device from its xbox port
std::shared_ptr<InputDevice> FindDevice(int usb_port, int dummy) const;
std::shared_ptr<InputDevice> FindDevice(std::string_view port) const;
// attach/detach guest devices to the emulated machine
void UpdateDevices(int port, bool ack);
void UpdateDevices(std::string_view port, bool ack);
// update input options
void UpdateOpt(bool is_gui);
// device hotplug event handler
void HotplugHandler(bool is_sdl);
// converts xinput -> screen coordinates to display the lightgun laser on the rendering window
ImVec2 CalcLaserPos(int port);
private:
// update input for an xbox controller
bool UpdateInputXpad(std::shared_ptr<InputDevice>& Device, void* Buffer, int Direction);
bool UpdateInputXpad(std::shared_ptr<InputDevice>& Device, void* Buffer, int Direction, const std::string &Port);
// update input for a lightgun
bool UpdateInputLightgun(std::shared_ptr<InputDevice> &Device, void *Buffer, int Direction, int Port_num, const std::string &Port);
// update input for a Steel Battalion controller
bool UpdateInputSBC(std::shared_ptr<InputDevice>& Device, void* Buffer, int Direction, int Port_num, const std::string &Port);
// update input for a passthrough xbox device
bool UpdateInputHw(std::shared_ptr<InputDevice> &Device, void *Buffer, int Direction);
// bind a host device to an emulated device
void BindHostDevice(int port, int usb_port, int type);
void BindHostDevice(int type, std::string_view port);
// connect a device to the emulated machine
void ConnectDevice(int port, int usb_port, int type);
void ConnectDevice(DeviceState *dev, DeviceState *upstream, int type, std::string_view port);
// disconnect a device from the emulated machine
void DisconnectDevice(int port, int usb_port, bool ack);
void DisconnectDevice(DeviceState *dev, std::string_view port, bool ack);
// all enumerated devices currently detected and supported
std::vector<std::shared_ptr<InputDevice>> m_Devices;
@ -104,12 +264,14 @@ private:
std::thread m_PollingThread;
// used to indicate that the manager is shutting down
bool m_bPendingShutdown;
// handle of the rendering or the input gui window
HWND m_hwnd;
};
extern InputDeviceManager g_InputDeviceManager;
// hle input functions
bool ConstructHleInputDevice(int Type, int Port);
void DestructHleInputDevice(int Port);
void ConstructHleInputDevice(DeviceState *dev, DeviceState *upstream, int type, std::string_view port);
void DestructHleInputDevice(DeviceState *dev);
#endif

View File

@ -25,79 +25,17 @@
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::GUI
#include "InputWindow.h"
#include "..\..\gui\ResCxbx.h"
#include "gui/resource/ResCxbx.h"
#include "common\IPCHybrid.hpp"
#include "EmuShared.h"
#include "Logging.h"
#include <future>
#define INPUT_TIMEOUT 5000
#define OUTPUT_TIMEOUT 3000
constexpr ControlState INPUT_DETECT_THRESHOLD = 0.55; // arbitrary number, using what Dolphin uses
InputWindow* g_InputWindow = nullptr;
void InputWindow::Initialize(HWND hwnd, int port_num, int dev_type)
{
// Save window/device specific variables
m_hwnd_window = hwnd;
m_hwnd_device_list = GetDlgItem(m_hwnd_window, IDC_DEVICE_LIST);
m_hwnd_profile_list = GetDlgItem(m_hwnd_window, IDC_XID_PROFILE_NAME);
m_hwnd_default = GetDlgItem(m_hwnd_window, IDC_XID_DEFAULT);
m_dev_type = dev_type;
m_max_num_buttons = dev_num_buttons[dev_type];
m_port_num = port_num;
m_bHasChanges = false;
m_bIsBinding = false;
// Set window icon
SetClassLong(m_hwnd_window, GCL_HICON, (LONG)LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_CXBX)));
// Set window title
std::string title;
switch (m_dev_type)
{
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE): {
title += "Xbox Controller Duke at port ";
}
break;
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
title += "Xbox Controller S at port ";
}
break;
default:
break;
}
SendMessage(m_hwnd_window, WM_SETTEXT, 0,
reinterpret_cast<LPARAM>((title + std::to_string(PORT_INC(m_port_num))).c_str()));
// Set the maximum profile name lenght the user can enter in the profile combobox
SendMessage(m_hwnd_profile_list, CB_LIMITTEXT, 49, 0);
// construct emu device
m_DeviceConfig = new EmuDevice(m_dev_type, m_hwnd_window);
// Enumerate devices
UpdateDeviceList();
// Load currently saved profile for this port/device type
LoadDefaultProfile();
// Load currently selected host device
UpdateCurrentDevice();
// Load rumble binding
char rumble[30];
m_DeviceConfig->FindButtonByIndex(m_max_num_buttons - 1)->GetText(rumble, sizeof(rumble));
m_rumble = rumble;
// Install the subclass for the profile combobox
SetWindowSubclass(GetWindow(m_hwnd_profile_list, GW_CHILD), ProfileNameSubclassProc, 0, 0);
}
constexpr ControlState INPUT_DETECT_THRESHOLD = 0.35; // NOTE: this should probably be made user configurable
InputWindow::~InputWindow()
{
@ -108,10 +46,10 @@ InputWindow::~InputWindow()
bool InputWindow::IsProfileSaved()
{
if (m_bHasChanges) {
int ret = MessageBox(m_hwnd_window, "Current configuration is not saved. Save before closing?", "Cxbx-Reloaded", MB_YESNOCANCEL | MB_ICONWARNING | MB_APPLMODAL);
PopupReturn ret = PopupQuestion(m_hwnd_window, "Current configuration is not saved. Save before closing?");
switch (ret)
{
case IDYES: {
case PopupReturn::Yes: {
char name[50];
SendMessage(m_hwnd_profile_list, WM_GETTEXT, sizeof(name), reinterpret_cast<LPARAM>(name));
if (SaveProfile(std::string(name))) {
@ -120,17 +58,18 @@ bool InputWindow::IsProfileSaved()
return false;
}
case IDNO: {
case PopupReturn::No: {
return true;
}
case IDCANCEL:
case PopupReturn::Cancel:
default: {
return false;
}
}
}
return true;
}
@ -139,16 +78,22 @@ void InputWindow::UpdateDeviceList()
g_InputDeviceManager.RefreshDevices();
// Populate device list
LRESULT num_devices = SendMessage(m_hwnd_device_list, CB_GETCOUNT, 0, 0);
for (int i = 0; i < num_devices; i++) {
for (int i = 0; i < m_num_devices; i++) {
SendMessage(m_hwnd_device_list, CB_DELETESTRING, 0, 0);
}
std::vector<std::string> dev_list = g_InputDeviceManager.GetDeviceList();
// Add everything but libusb devices
std::vector<std::string> dev_list = g_InputDeviceManager.GetDeviceList([](const auto &Device) {
if (Device->IsLibusb()) {
return false;
}
return true;
});
for (const auto& str : dev_list) {
SendMessage(m_hwnd_device_list, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(str.c_str()));
++m_num_devices;
}
if (!dev_list.empty()) {
if (m_num_devices) {
SendMessage(m_hwnd_device_list, CB_SETCURSEL, 0, 0);
}
@ -183,7 +128,7 @@ InputDevice::Input* InputWindow::DetectInput(InputDevice* const Device, int ms)
Device->UpdateInput();
std::vector<bool>::iterator state = initial_states.begin();
for (; i != e && s == e; i++, state++) {
if ((*i)->IsDetectable() && (*i)->GetState() > INPUT_DETECT_THRESHOLD) {
if ((*i)->IsDetectable() && ((*i)->GetState() > INPUT_DETECT_THRESHOLD)) {
if (*state == false) {
// input was not initially pressed or it was but released afterwards
s = i;
@ -205,56 +150,6 @@ InputDevice::Input* InputWindow::DetectInput(InputDevice* const Device, int ms)
return nullptr; // no input
}
void InputWindow::BindButton(int ControlID)
{
// Check if binding thread is still active
// testcase: spacebar and enter keys; without this fix will cause repeat binding result.
if (m_bIsBinding) {
return;
}
auto dev = g_InputDeviceManager.FindDevice(m_host_dev);
if (dev != nullptr) {
m_bIsBinding = true;
// Don't block the message processing loop
std::thread([this, dev, ControlID]() {
EnableWindow(m_hwnd_window, FALSE);
char current_text[30];
Button* xbox_button = m_DeviceConfig->FindButtonById(ControlID);
xbox_button->GetText(current_text, sizeof(current_text));
xbox_button->UpdateText("...");
std::future<InputDevice::Input*> fut = std::async(std::launch::async, &InputWindow::DetectInput, this, dev.get(), INPUT_TIMEOUT);
InputDevice::Input* dev_button = fut.get();
if (dev_button) {
xbox_button->UpdateText(dev_button->GetName().c_str());
m_bHasChanges = true;
}
else {
xbox_button->UpdateText(current_text);
}
m_bIsBinding = false;
EnableWindow(m_hwnd_window, TRUE);
}).detach();
}
}
void InputWindow::BindDefault()
{
int api = EnableDefaultButton();
if (api != -1) {
m_DeviceConfig->BindDefault(api);
m_bHasChanges = true;
}
}
void InputWindow::ClearBindings()
{
m_DeviceConfig->ClearButtons();
m_rumble = std::string();
m_bHasChanges = true;
}
int InputWindow::EnableDefaultButton()
{
if (std::strncmp(m_host_dev.c_str(), "XInput", std::strlen("XInput")) == 0) {
@ -271,6 +166,65 @@ int InputWindow::EnableDefaultButton()
}
}
void InputWindow::BindButton(int ControlID, bool auto_swap)
{
// Check if binding thread is still active
// testcase: spacebar and enter keys; without this fix will cause repeat binding result.
if (m_bIsBinding) {
return;
}
auto dev = g_InputDeviceManager.FindDevice(m_host_dev);
if (dev != nullptr) {
m_bIsBinding = true;
// Don't block the message processing loop
std::thread([this, dev, ControlID, auto_swap]() {
EnableWindow(m_hwnd_window, FALSE);
char current_text[HOST_BUTTON_NAME_LENGTH];
Button* xbox_button = m_DeviceConfig->FindButtonById(ControlID);
xbox_button->GetText(current_text, sizeof(current_text));
xbox_button->UpdateText("...");
std::future<InputDevice::Input*> fut = std::async(std::launch::async, &InputWindow::DetectInput, this, dev.get(), INPUT_TIMEOUT);
InputDevice::Input* dev_button = fut.get();
if (dev_button) {
xbox_button->UpdateText(dev_button->GetName().c_str());
if (auto_swap) {
SwapMoCursorAxis(xbox_button);
}
m_bHasChanges = true;
}
else {
xbox_button->UpdateText(current_text);
}
m_bIsBinding = false;
EnableWindow(m_hwnd_window, TRUE);
}).detach();
}
}
void InputWindow::UpdateProfile(const std::string &name, int command)
{
switch (command)
{
case PROFILE_LOAD:
LoadProfile(name);
break;
case PROFILE_SAVE:
SaveProfile(name);
break;
case PROFILE_DELETE:
DeleteProfile(name);
break;
case BUTTON_CLEAR:
m_bHasChanges = true;
break;
}
}
InputWindow::ProfileIt InputWindow::FindProfile(const std::string& name)
{
auto it = std::find_if(g_Settings->m_input_profiles[m_dev_type].begin(),
@ -280,40 +234,6 @@ InputWindow::ProfileIt InputWindow::FindProfile(const std::string& name)
return it;
}
void InputWindow::UpdateProfile(const std::string& name, int command)
{
switch (command)
{
case PROFILE_LOAD: {
LoadProfile(name);
}
break;
case PROFILE_SAVE: {
SaveProfile(name);
}
break;
case PROFILE_DELETE: {
DeleteProfile(name);
}
break;
case RUMBLE_CLEAR: {
m_rumble = std::string();
}
break;
case BUTTON_CLEAR: {
m_bHasChanges = true;
}
break;
default:
break;
}
}
void InputWindow::LoadProfile(const std::string& name)
{
ProfileIt profile = FindProfile(name);
@ -334,19 +254,19 @@ void InputWindow::LoadProfile(const std::string& name)
for (int index = 0; index < m_max_num_buttons; index++) {
m_DeviceConfig->FindButtonByIndex(index)->UpdateText(profile->ControlList[index].c_str());
}
g_Settings->m_input[m_port_num].DeviceName = profile->DeviceName;
g_Settings->m_input[m_port_num].ProfileName = profile->ProfileName;
g_Settings->m_input_port[m_port_num].DeviceName = profile->DeviceName;
g_Settings->m_input_port[m_port_num].ProfileName = profile->ProfileName;
m_bHasChanges = false;
}
bool InputWindow::SaveProfile(const std::string& name)
{
if (name == std::string()) {
MessageBox(m_hwnd_window, "Cannot save. Profile name must not be empty", "Cxbx-Reloaded", MB_OK | MB_ICONSTOP | MB_APPLMODAL);
PopupError(m_hwnd_window, "Cannot save. Profile name must not be empty.");
return false;
}
if (m_host_dev == std::string()) {
MessageBox(m_hwnd_window, "Cannot save. No input devices detected", "Cxbx-Reloaded", MB_OK | MB_ICONSTOP | MB_APPLMODAL);
PopupError(m_hwnd_window, "Cannot save. No input devices detected.", "Cxbx-Reloaded");
return false;
}
OverwriteProfile(name);
@ -355,15 +275,16 @@ bool InputWindow::SaveProfile(const std::string& name)
profile.ProfileName = name;
profile.DeviceName = m_host_dev;
for (int index = 0; index < m_max_num_buttons; index++) {
char dev_button[30];
char dev_button[HOST_BUTTON_NAME_LENGTH];
m_DeviceConfig->FindButtonByIndex(index)->GetText(dev_button, sizeof(dev_button));
profile.ControlList.push_back(dev_button);
}
SendMessage(m_hwnd_profile_list, CB_SETCURSEL, SendMessage(m_hwnd_profile_list, CB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(profile.ProfileName.c_str())), 0);
g_Settings->m_input[m_port_num].DeviceName = profile.DeviceName;
g_Settings->m_input[m_port_num].ProfileName = profile.ProfileName;
g_Settings->m_input_port[m_port_num].DeviceName = profile.DeviceName;
g_Settings->m_input_port[m_port_num].ProfileName = profile.ProfileName;
g_Settings->m_input_profiles[m_dev_type].push_back(std::move(profile));
m_bHasChanges = false;
return true;
}
@ -376,16 +297,16 @@ void InputWindow::DeleteProfile(const std::string& name)
}
SendMessage(m_hwnd_profile_list, CB_DELETESTRING, SendMessage(m_hwnd_profile_list, CB_FINDSTRINGEXACT, 1,
reinterpret_cast<LPARAM>(profile->ProfileName.c_str())), 0);
if (profile->ProfileName == g_Settings->m_input[m_port_num].ProfileName) {
if (profile->ProfileName == g_Settings->m_input_port[m_port_num].ProfileName) {
SendMessage(m_hwnd_profile_list, CB_SETCURSEL, -1, 0);
UpdateCurrentDevice();
ClearBindings();
g_Settings->m_input[m_port_num].DeviceName = "";
g_Settings->m_input[m_port_num].ProfileName = "";
g_Settings->m_input_port[m_port_num].DeviceName = "";
g_Settings->m_input_port[m_port_num].ProfileName = "";
m_bHasChanges = false;
}
else {
LoadProfile(g_Settings->m_input[m_port_num].ProfileName);
LoadProfile(g_Settings->m_input_port[m_port_num].ProfileName);
}
g_Settings->m_input_profiles[m_dev_type].erase(profile);
}
@ -408,84 +329,85 @@ void InputWindow::LoadDefaultProfile()
SendMessage(m_hwnd_profile_list, CB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(g_Settings->m_input_profiles[m_dev_type][index].ProfileName.c_str()));
}
LoadProfile(g_Settings->m_input[m_port_num].ProfileName);
LoadProfile(g_Settings->m_input_port[m_port_num].ProfileName);
}
void InputWindow::UpdateCurrentDevice()
{
char device_name[50];
SendMessage(m_hwnd_device_list, WM_GETTEXT, sizeof(device_name), reinterpret_cast<LPARAM>(device_name));
m_host_dev = device_name;
if (m_num_devices) {
char device_name[50];
SendMessage(m_hwnd_device_list, WM_GETTEXT, sizeof(device_name), reinterpret_cast<LPARAM>(device_name));
m_host_dev = device_name;
}
else {
m_host_dev = "";
}
EnableDefaultButton();
}
void InputWindow::InitRumble(HWND hwnd)
void InputWindow::SwapMoCursorAxis(Button *button)
{
m_hwnd_rumble = hwnd;
m_hwnd_rumble_list = GetDlgItem(m_hwnd_rumble, IDC_RUMBLE_LIST);
SendMessage(m_hwnd_rumble_list, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(""));
auto dev = g_InputDeviceManager.FindDevice(m_host_dev);
if (dev != nullptr) {
auto outputs = dev->GetOutputs();
for (const auto out : outputs) {
SendMessage(m_hwnd_rumble_list, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(out->GetName().c_str()));
// Axis X+ <-> Cursor X+
// Axis X- <-> Cursor X-
// Axis Y+ <-> Cursor Y-
// Axis Y- <-> Cursor Y+
if (m_host_dev.ends_with("KeyboardMouse")) {
assert(button != nullptr);
char control_name[HOST_BUTTON_NAME_LENGTH];
button->GetText(control_name, sizeof(control_name));
if (std::string_view(control_name).starts_with("Axis")) {
switch (control_name[5])
{
case 'X':
if (control_name[6] == '+') {
button->UpdateText("Cursor X+");
}
else {
button->UpdateText("Cursor X-");
}
m_bHasChanges = true;
break;
case 'Y':
if (control_name[6] == '+') {
button->UpdateText("Cursor Y-");
}
else {
button->UpdateText("Cursor Y+");
}
m_bHasChanges = true;
break;
}
return;
}
if (std::string_view(control_name).starts_with("Cursor")) {
switch (control_name[7])
{
case 'X':
if (control_name[8] == '+') {
button->UpdateText("Axis X+");
}
else {
button->UpdateText("Axis X-");
}
m_bHasChanges = true;
break;
case 'Y':
if (control_name[8] == '+') {
button->UpdateText("Axis Y-");
}
else {
button->UpdateText("Axis Y+");
}
m_bHasChanges = true;
break;
}
}
}
SendMessage(m_hwnd_rumble_list, CB_SETCURSEL, SendMessage(m_hwnd_rumble_list, CB_FINDSTRINGEXACT, 1,
reinterpret_cast<LPARAM>(m_rumble.c_str())), 0);
}
void InputWindow::UpdateRumble(int command)
{
switch (command)
{
case RUMBLE_SET: {
char rumble[30];
SendMessage(m_hwnd_rumble_list, WM_GETTEXT, sizeof(rumble), reinterpret_cast<LPARAM>(rumble));
m_rumble = rumble;
}
break;
case RUMBLE_UPDATE: {
m_DeviceConfig->FindButtonByIndex(m_max_num_buttons - 1)->UpdateText(m_rumble.c_str());
}
break;
case RUMBLE_TEST: {
DetectOutput(OUTPUT_TIMEOUT);
}
break;
default:
break;
}
}
void InputWindow::DetectOutput(int ms)
{
if (m_rumble == std::string()) {
return;
}
auto dev = g_InputDeviceManager.FindDevice(m_host_dev);
if (dev != nullptr) {
// Don't block the message processing loop
std::thread([this, dev, ms]() {
EnableWindow(m_hwnd_rumble, FALSE);
SendMessage(m_hwnd_rumble_list, WM_SETTEXT, 0, reinterpret_cast<LPARAM>("..."));
auto outputs = dev->GetOutputs();
for (const auto out : outputs) {
if (out->GetName() == m_rumble) {
out->SetState(1.0, 1.0);
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
for (const auto out : outputs) {
if (out->GetName() == m_rumble) {
out->SetState(0.0, 0.0);
}
}
SendMessage(m_hwnd_rumble_list, WM_SETTEXT, 0, reinterpret_cast<LPARAM>("Test"));
EnableWindow(m_hwnd_rumble, TRUE);
}).detach();
}
}

View File

@ -40,8 +40,11 @@
#define RUMBLE_CLEAR 7
#define BUTTON_CLEAR 8
#define XINPUT_DEFAULT 1
#define DINPUT_DEFAULT 2
#define XINPUT_DEFAULT 0
#define DINPUT_DEFAULT 1
#define INPUT_TIMEOUT 5000
#define OUTPUT_TIMEOUT 3000
LRESULT CALLBACK ProfileNameSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
@ -49,30 +52,28 @@ LRESULT CALLBACK ProfileNameSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
class InputWindow
{
public:
void Initialize(HWND hwnd, int port_num, int dev_type);
void InitRumble(HWND hwnd);
virtual void Initialize(HWND hwnd, int port_num, int dev_type) = 0;
~InputWindow();
void UpdateDeviceList();
void BindButton(int ControlID);
void BindDefault();
void ClearBindings();
void UpdateProfile(const std::string& name, int command);
void UpdateRumble(int command);
virtual void UpdateDeviceList();
void BindButton(int ControlID, bool auto_swap = false);
virtual void ClearBindings() = 0;
virtual void UpdateProfile(const std::string& name, int command);
void UpdateCurrentDevice();
bool IsProfileSaved();
void SwapMoCursorAxis(Button *button);
private:
protected:
typedef std::vector<Settings::s_input_profiles>::iterator ProfileIt;
InputDevice::Input* DetectInput(InputDevice* const Device, int ms);
void DetectOutput(int ms);
ProfileIt FindProfile(const std::string& name);
void LoadProfile(const std::string& name);
bool SaveProfile(const std::string& name);
void DeleteProfile(const std::string& name);
void OverwriteProfile(const std::string& name);
void LoadDefaultProfile();
int EnableDefaultButton();
virtual int EnableDefaultButton();
// xbox device under configuration
EmuDevice* m_DeviceConfig;
@ -82,12 +83,10 @@ private:
HWND m_hwnd_device_list;
// handle of the profile list combobox
HWND m_hwnd_profile_list;
// handle of the rumble window
HWND m_hwnd_rumble;
// handle of the rumble combobox
HWND m_hwnd_rumble_list;
// handle of the default bindings button
HWND m_hwnd_default;
// number of devices displayed in the device list combobox
int m_num_devices;
// type of the device
int m_dev_type;
// num of buttons of device under configuration
@ -96,12 +95,71 @@ private:
int m_port_num;
// host device under configuration
std::string m_host_dev;
// currently selected rumble control
std::string m_rumble;
// indicates if the current profile has unsaved changes
bool m_bHasChanges;
// prevent current input attempt to set the previous input at same time
std::atomic<bool> m_bIsBinding;
};
extern InputWindow* g_InputWindow;
class DukeInputWindow : public InputWindow
{
public:
void Initialize(HWND hwnd, int port_num, int dev_type) override;
void InitRumble(HWND hwnd);
void UpdateRumble(int command);
void BindDefault();
void ClearBindings() override;
void UpdateProfile(const std::string &name, int command) override;
void SaveSlotConfig();
private:
void DetectOutput(int ms);
// handle of the rumble window
HWND m_hwnd_rumble;
// handle of the rumble combobox
HWND m_hwnd_rumble_list;
// handles of the slot combobox
HWND m_hwnd_slot_list[XBOX_CTRL_NUM_SLOTS];
// currently selected rumble control
std::string m_rumble;
};
class SbcInputWindow : public InputWindow
{
public:
void Initialize(HWND hwnd, int port_num, int dev_type) override;
~SbcInputWindow();
void ClearBindings() override;
private:
int EnableDefaultButton() override;
};
class LibusbInputWindow : public InputWindow
{
public:
void Initialize(HWND hwnd, int port_num, int dev_type) override;
~LibusbInputWindow();
void ClearBindings() override;
void UpdateDeviceList() override;
void TestInput();
private:
int EnableDefaultButton() override;
// handle of the test button
HWND m_hwnd_device_test;
};
class LightgunInputWindow : public InputWindow
{
public:
void Initialize(HWND hwnd, int port_num, int dev_type) override;
~LightgunInputWindow();
void BindDefault();
void ClearBindings() override;
};

View File

@ -0,0 +1,325 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2021 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::LIBUSB
#include "LibusbDevice.h"
#include "InputManager.h"
#include "core\kernel\support\Emu.h"
#include "core\hle\XAPI\Xapi.h"
// Sanity check: ensure that our libusb version is high enough for libusb_get_device_descriptor to succeed and to pass nullptr to libusb_interrupt_transfer
static_assert(LIBUSB_API_VERSION >= 0x01000105);
namespace Libusb
{
int InitStatus = NOT_INIT;
// These come from here https://github.com/xboxdrv/xboxdrv/blob/ac6ebb1228962220482ea03743cadbe18754246c/src/xpad_device.cpp#L29
static constexpr uint16_t SupportedDevices_VidPid[][2] = { // vid, pid
0x0d2f, 0x0002,
0x045e, 0x0202,
0x045e, 0x0285,
0x045e, 0x0287,
0x045e, 0x0289,
0x046d, 0xca84,
0x046d, 0xca88,
0x05fd, 0x1007,
0x05fd, 0x107a,
0x0738, 0x4516,
0x0738, 0x4522,
0x0738, 0x4526,
0x0738, 0x4536,
0x0738, 0x4556,
0x0c12, 0x8802,
0x0c12, 0x8810,
0x0c12, 0x9902,
0x0e4c, 0x1097,
0x0e4c, 0x2390,
0x0e6f, 0x0003,
0x0e6f, 0x0005,
0x0e6f, 0x0006,
0x0f30, 0x0202,
0x0f30, 0x8888,
0x102c, 0xff0c,
0x044f, 0x0f07,
0x0e8f, 0x3008,
};
static constexpr const char *SupportedDevices_Name[] = {
"Andamiro Pump It Up pad",
"Microsoft X-Box pad v1 (US)",
"Microsoft X-Box pad (Japan)",
"Microsoft Xbox Controller S",
"Microsoft X-Box pad v2 (US)",
"Logitech Xbox Cordless Controller",
"Logitech Compact Controller for Xbox",
"Mad Catz Controller (unverified)",
"InterAct 'PowerPad Pro' X-Box pad (Germany)",
"Mad Catz Control Pad",
"Mad Catz LumiCON",
"Mad Catz Control Pad Pro",
"Mad Catz MicroCON",
"Mad Catz Lynx Wireless Controller",
"Zeroplus Xbox Controller",
"Zeroplus Xbox Controller",
"HAMA VibraX - *FAULTY HARDWARE*",
"Radica Gamester Controller",
"Radica Games Jtech Controller",
"Logic3 Freebird wireless Controller",
"Eclipse wireless Controller",
"Edge wireless Controller",
"Joytech Advanced Controller",
"BigBen XBMiniPad Controller",
"Joytech Wireless Advanced Controller",
"Thrustmaster, Inc. Controller",
"Generic xbox control (dealextreme)",
};
static_assert(ARRAY_SIZE(SupportedDevices_VidPid) == ARRAY_SIZE(SupportedDevices_Name));
void Init(std::mutex &Mtx)
{
std::unique_lock<std::mutex> lck(Mtx);
// We only use a single libusb session per cxbxr process, so we do not need to use a libusb context
if (libusb_init(nullptr) != 0) {
EmuLog(LOG_LEVEL::ERROR2, "Failed to initialize Libusb!");
InitStatus = INIT_ERROR;
return;
}
InitStatus = INIT_SUCCESS;
}
void DeInit()
{
InitStatus = NOT_INIT;
libusb_exit(nullptr);
}
void PopulateDevices()
{
// NOTE: the libusb docs say that the list is always appended with a NULL element at the end
libusb_device **List;
ssize_t DevicesConnected = libusb_get_device_list(nullptr, &List) - 1;
if (DevicesConnected < 0) {
EmuLog(LOG_LEVEL::ERROR2, "Failed to enumerate devices. The error was: %s", libusb_strerror(DevicesConnected));
return;
}
for (ssize_t i = 0; i < DevicesConnected; ++i) {
libusb_device *LibusbDev = List[i];
libusb_device_descriptor Desc;
libusb_get_device_descriptor(LibusbDev, &Desc); // always succeeds when LIBUSB_API_VERSION >= 0x01000102
auto Device = std::make_shared<LibusbDevice>(&Desc, LibusbDev);
if (Device->IsLibusb()) {
g_InputDeviceManager.AddDevice(std::move(Device));
}
}
libusb_free_device_list(List, 1);
}
void GetDeviceChanges()
{
g_InputDeviceManager.RemoveDevice([](const auto &Device) {
return Device->IsLibusb();
});
PopulateDevices();
}
LibusbDevice::LibusbDevice(libusb_device_descriptor *Desc, libusb_device *Dev)
{
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
// The SBC's VID and PID are taken from https://xboxdevwiki.net/Xbox_Input_Devices#Steel_Battalion_Controller
if ((Desc->idVendor == 0x0a7b) && (Desc->idProduct == 0xd000)) {
m_Type = XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER;
m_UcType = XINPUT_DEVTYPE_STEELBATTALION;
m_UcSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD;
m_Name = "Steel battalion controller";
m_BufferInSize = sizeof(XidSBCInput);
m_BufferOutSize = sizeof(XidSBCOutput);
assert(Desc->bcdUSB == 0x110); // must be a usb 1.1 device
}
else {
for (size_t i = 0; i < ARRAY_SIZE(SupportedDevices_VidPid); ++i) {
if ((Desc->idVendor == SupportedDevices_VidPid[i][0]) && (Desc->idProduct == SupportedDevices_VidPid[i][1])) {
m_Type = XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER;
m_UcType = XINPUT_DEVTYPE_GAMEPAD;
m_UcSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD;
m_Name = SupportedDevices_Name[i];
m_BufferInSize = sizeof(XidGamepadInput);
m_BufferOutSize = sizeof(XidGamepadOutput);
assert(Desc->bcdUSB == 0x110); // must be a usb 1.1 device
break;
}
}
}
if (m_Type == XBOX_INPUT_DEVICE::DEVICE_INVALID) { return; }
// check if we are able to open device through libusb
if (int err = libusb_open(Dev, &m_hDev)) {
// Couldn't open device, create an error log report then don't use it.
EmuLog(LOG_LEVEL::ERROR2, "Unable to open original xbox device \"%s\" (%hX:%hX), libusb's error was: %s",
m_Name.c_str(), Desc->idVendor, Desc->idProduct, libusb_strerror(err));
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
return;
}
// If we are able to open device, continue with query process.
else {
// Duke, S and SBC have 1 configuration, 1 interface and 2 endpoints (input and output) and use the default alternate setting zero.
// The code below assumes that third-party controllers follow suit.
libusb_config_descriptor *ConfDesc;
if (libusb_get_active_config_descriptor(Dev, &ConfDesc) == 0) {
if (ConfDesc->bNumInterfaces == 1) {
auto Iface = ConfDesc->interface[0];
if (Iface.num_altsetting == 1) {
auto Setting = Iface.altsetting[0];
m_IfaceNum = Setting.bInterfaceNumber;
if (Setting.bNumEndpoints >= 1) {
m_HasEndpointOut = false;
for (uint8_t i = 0; i < Setting.bNumEndpoints; ++i) {
auto Endpoint = Setting.endpoint[i];
if (Endpoint.bEndpointAddress & 0x80) {
m_EndpointIn = Endpoint.bEndpointAddress;
m_IntervalIn = Endpoint.bInterval;
}
else {
// third-party controllers that don't support rumble probably won't have an out endpoint
m_EndpointOut = Endpoint.bEndpointAddress;
m_IntervalOut = Endpoint.bInterval;
m_HasEndpointOut = true;
}
}
EmuLog(LOG_LEVEL::INFO, "Out endpoint %s", m_HasEndpointOut ? "present" : "not present");
if (int err = libusb_claim_interface(m_hDev, m_IfaceNum)) {
EmuLog(LOG_LEVEL::INFO, "Rejected device %s because libusb could not claim its interface. The error was: %s",
m_Name.c_str(), libusb_strerror(err));
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
}
else {
// Grab the xid descriptor so that we can report real type/subtype values back to the title when it calls XInputGetCapabilities
XidDesc XidDesc;
if (libusb_control_transfer(m_hDev, 0xC1, 6, 0x4200, m_IfaceNum, reinterpret_cast<uint8_t *>(&XidDesc), sizeof(XidDesc), m_IntervalIn)
== sizeof(XidDesc)) { // submit a GET_DESCRIPTOR request
// Dump the xid descriptor to the log
EmuLog(LOG_LEVEL::INFO, "Xid descriptor dump:\nbLength: %#010X\nbDescriptorType: %#010X\nbcdXid: %#010X\nbType: %#010X\n"
"bSubType: %#010X\nbMaxInputReportSize: %#010X\nbMaxOutputReportSize: %#010X\nwAlternateProductIds[0]: %#010X\n"
"wAlternateProductIds[1]: %#010X\nwAlternateProductIds[2]: %#010X\nwAlternateProductIds[3]: %#010X\n",
XidDesc.bLength, XidDesc.bDescriptorType, XidDesc.bcdXid, XidDesc.bType, XidDesc.bSubType, XidDesc.bMaxInputReportSize, XidDesc.bMaxOutputReportSize,
XidDesc.wAlternateProductIds[0], XidDesc.wAlternateProductIds[1], XidDesc.wAlternateProductIds[2], XidDesc.wAlternateProductIds[3]);
if (XidDesc.bDescriptorType == 0x42) {
m_UcType = XidDesc.bType;
m_UcSubType = XidDesc.bSubType;
}
else {
EmuLog(LOG_LEVEL::INFO, "The xid descriptor for device %s reported an unexpected descriptor type, assuming a default subtype", m_Name);
}
}
else {
EmuLog(LOG_LEVEL::INFO, "Could not retrieve the xid descriptor for device %s, assuming a default subtype", m_Name);
}
}
}
else {
EmuLog(LOG_LEVEL::INFO, "Rejected device %s because of unexpected number of endpoints, bNumEndpoints: %d",
m_Name.c_str(), Setting.bNumEndpoints);
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
}
}
else {
EmuLog(LOG_LEVEL::INFO, "Rejected device %s because of unexpected number of alternative settings, num_altsetting: %d",
m_Name.c_str(), Iface.num_altsetting);
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
}
}
else {
EmuLog(LOG_LEVEL::INFO, "Rejected device %s because of unexpected number of interfaces, bNumInterfaces: %d",
m_Name.c_str(), ConfDesc->bNumInterfaces);
m_Type = XBOX_INPUT_DEVICE::DEVICE_INVALID;
}
libusb_free_config_descriptor(ConfDesc);
}
}
if (m_Type == XBOX_INPUT_DEVICE::DEVICE_INVALID) { libusb_close(m_hDev); }
}
LibusbDevice::~LibusbDevice()
{
if (m_Type != XBOX_INPUT_DEVICE::DEVICE_INVALID) {
libusb_release_interface(m_hDev, m_IfaceNum);
libusb_close(m_hDev);
}
}
bool LibusbDevice::UpdateInput()
{
// Dummy, it should never be called. It's only here to override the pure function UpdateInput in InputDevice
assert(0);
return false;
}
bool LibusbDevice::ExecuteIo(void *Buffer, int Direction)
{
// NOTE: a SET_REPORT control transfer to the SBC doesn't seem to work, the parameters might not be appropriate for it... So, we use
// the interrupt pipes for everything instead
*static_cast<uint8_t *>(Buffer) = 0; // write bReportId
if (Direction == DIRECTION_IN) {
*(static_cast<uint8_t *>(Buffer) + 1) = m_BufferInSize; // write bLength
if (libusb_interrupt_transfer(m_hDev, m_EndpointIn, static_cast<uint8_t *>(Buffer), m_BufferInSize, nullptr, m_IntervalIn) != 0) {
return false;
}
}
else {
if (m_HasEndpointOut) {
*(static_cast<uint8_t *>(Buffer) + 1) = m_BufferOutSize; // write bLength
if (libusb_interrupt_transfer(m_hDev, m_EndpointOut, static_cast<uint8_t *>(Buffer), m_BufferOutSize, nullptr, m_IntervalOut) != 0) {
return false;
}
}
}
return true;
}
std::string LibusbDevice::GetDeviceName() const
{
return m_Name;
}
std::string LibusbDevice::GetAPI() const
{
return "Libusb";
}
}

View File

@ -0,0 +1,91 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2021 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
#include "InputDevice.h"
// Suppress warning in libusb about zero sized array
#pragma warning(push)
#pragma warning(disable: 4200)
#include "libusb.h"
#pragma warning(pop)
namespace Libusb
{
typedef enum _INIT_STATUS : int
{
NOT_INIT = -2,
INIT_ERROR,
INIT_SUCCESS,
}
INIT_STATUS;
extern int InitStatus;
// initialize Libusb
void Init(std::mutex &Mtx);
// shutdown Libusb
void DeInit();
// refresh the device list in response to a refresh command from the input GUI
void PopulateDevices();
// update the device list
void GetDeviceChanges();
class LibusbDevice : public InputDevice
{
public:
~LibusbDevice();
bool UpdateInput() override;
bool ExecuteIo(void *Buffer, int Direction);
LibusbDevice(libusb_device_descriptor *Desc, libusb_device *Dev);
std::string GetDeviceName() const override;
std::string GetAPI() const override;
bool IsLibusb() const override { return m_Type != XBOX_INPUT_DEVICE::DEVICE_INVALID; }
XBOX_INPUT_DEVICE GetLibusbType() const { return m_Type; }
uint8_t GetUcType() { return m_UcType; }
uint8_t GetUcSubType() { return m_UcSubType; }
private:
XBOX_INPUT_DEVICE m_Type;
uint8_t m_UcType;
uint8_t m_UcSubType;
std::string m_Name;
libusb_device_handle *m_hDev;
unsigned char m_EndpointIn;
unsigned char m_EndpointOut;
uint8_t m_IntervalIn;
uint8_t m_IntervalOut;
uint8_t m_BufferInSize;
uint8_t m_BufferOutSize;
uint8_t m_IfaceNum;
bool m_HasEndpointOut;
};
}

View File

@ -0,0 +1,84 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
// ******************************************************************
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2021 ergo720
// *
// * All rights reserved
// *
// ******************************************************************
#define LOG_PREFIX CXBXR_MODULE::RINP
#include "RawDevice.h"
#include "Logging.h"
#include <array>
// NOTE: we don't implement host input devices controlled by rawinput, we only use the api to detect device changes for xinput
namespace RawInput
{
int InitStatus = NOT_INIT;
bool IgnoreHotplug = true;
void Init(std::mutex &Mtx, bool is_gui, HWND hwnd)
{
std::unique_lock<std::mutex> lck(Mtx);
if (is_gui) {
// We don't need to monitor xinput device changes from the gui, because there we have the refresh button to detect changes
InitStatus = INIT_SUCCESS;
return;
}
std::array<RAWINPUTDEVICE, 3> devices;
// joystick devices
devices[0].usUsagePage = 0x01;
devices[0].usUsage = 0x04;
devices[0].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
devices[0].hwndTarget = hwnd;
// gamepad devices
devices[1].usUsagePage = 0x01;
devices[1].usUsage = 0x05;
devices[1].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
devices[1].hwndTarget = hwnd;
// multi axis controller devices
devices[2].usUsagePage = 0x01;
devices[2].usUsage = 0x08;
devices[2].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
devices[2].hwndTarget = hwnd;
if (!RegisterRawInputDevices(devices.data(), static_cast<UINT>(devices.size()),
static_cast<UINT>(sizeof(decltype(devices)::value_type))))
{
EmuLog(LOG_LEVEL::ERROR2, "RegisterRawInputDevices failed: %i", GetLastError());
InitStatus = INIT_ERROR;
return;
}
InitStatus = INIT_SUCCESS;
}
void DeInit()
{
InitStatus = NOT_INIT;
IgnoreHotplug = true;
}
}

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